mirror of https://github.com/odrling/Aegisub
Made audio players register manually.
Originally committed to SVN as r1893.
This commit is contained in:
parent
30d1aeb551
commit
ee61192c43
|
@ -39,6 +39,21 @@
|
|||
#include <wx/wxprec.h>
|
||||
#include "audio_player.h"
|
||||
#include "options.h"
|
||||
#ifdef WITH_ALSA
|
||||
#include "audio_player_alsa.h"
|
||||
#endif
|
||||
#ifdef WITH_DIRECTSOUND
|
||||
#include "audio_player_dsound.h"
|
||||
#endif
|
||||
#ifdef WITH_OPENAL
|
||||
#include "audio_player_openal.h"
|
||||
#endif
|
||||
#ifdef WITH_PORTAUDIO
|
||||
#include "audio_player_portaudio.h"
|
||||
#endif
|
||||
#ifdef WITH_PULSEAUDIO
|
||||
#include "audio_player_pulse.h"
|
||||
#endif
|
||||
|
||||
|
||||
///////////////
|
||||
|
@ -112,6 +127,12 @@ void AudioPlayer::OnStopAudio(wxCommandEvent &event) {
|
|||
//////////////
|
||||
// Get player
|
||||
AudioPlayer* AudioPlayerFactory::GetAudioPlayer() {
|
||||
// Register factories
|
||||
// HACK: fix me
|
||||
static bool init = false;
|
||||
if (!init) RegisterFactories();
|
||||
init = true;
|
||||
|
||||
// List of providers
|
||||
wxArrayString list = GetFactoryList(Options.AsText(_T("Audio player")));
|
||||
|
||||
|
@ -135,6 +156,27 @@ AudioPlayer* AudioPlayerFactory::GetAudioPlayer() {
|
|||
}
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// Register all factories
|
||||
void AudioPlayerFactory::RegisterFactories() {
|
||||
#ifdef WITH_ALSA
|
||||
new AlsaPlayerFactory();
|
||||
#endif
|
||||
#ifdef WITH_DIRECTSOUND
|
||||
new DirectSoundPlayerFactory();
|
||||
#endif
|
||||
#ifdef WITH_OPENAL
|
||||
new OpenALPlayerFactory();
|
||||
#endif
|
||||
#ifdef WITH_PORTAUDIO
|
||||
new PortAudioPlayerFactory();
|
||||
#endif
|
||||
#ifdef WITH_PULSEAUDIO
|
||||
new PulseAudioPlayerFactory();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//////////
|
||||
// Static
|
||||
template <class AudioPlayerFactory> std::map<wxString,AudioPlayerFactory*>* AegisubFactory<AudioPlayerFactory>::factories=NULL;
|
||||
|
|
|
@ -104,6 +104,7 @@ protected:
|
|||
public:
|
||||
virtual ~AudioPlayerFactory() {}
|
||||
static AudioPlayer *GetAudioPlayer();
|
||||
static void RegisterFactories();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -45,75 +45,10 @@
|
|||
#include "utils.h"
|
||||
#include "main.h"
|
||||
#include "frame_main.h"
|
||||
#include "audio_player.h"
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "audio_player_alsa.h"
|
||||
#include "options.h"
|
||||
|
||||
|
||||
///////////////
|
||||
// Alsa player
|
||||
class AlsaPlayer : public AudioPlayer {
|
||||
private:
|
||||
bool open;
|
||||
volatile bool playing;
|
||||
volatile float volume;
|
||||
|
||||
volatile unsigned long start_frame; // first frame of playback
|
||||
volatile unsigned long cur_frame; // last written frame + 1
|
||||
volatile unsigned long end_frame; // last frame to play
|
||||
unsigned long bpf; // bytes per frame
|
||||
|
||||
AudioProvider *provider;
|
||||
snd_pcm_t *pcm_handle; // device handle
|
||||
snd_pcm_stream_t stream; // stream direction
|
||||
snd_async_handler_t *pcm_callback;
|
||||
|
||||
snd_pcm_format_t sample_format;
|
||||
unsigned int rate; // sample rate of audio
|
||||
unsigned int real_rate; // actual sample rate played back
|
||||
unsigned int period_len; // length of period in microseconds
|
||||
unsigned int buflen; // length of buffer in microseconds
|
||||
snd_pcm_uframes_t period; // size of period in frames
|
||||
snd_pcm_uframes_t bufsize; // size of buffer in frames
|
||||
|
||||
void SetUpHardware();
|
||||
void SetUpAsync();
|
||||
|
||||
static void async_write_handler(snd_async_handler_t *pcm_callback);
|
||||
|
||||
public:
|
||||
AlsaPlayer();
|
||||
~AlsaPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying();
|
||||
|
||||
int64_t GetStartPosition();
|
||||
int64_t GetEndPosition();
|
||||
int64_t GetCurrentPosition();
|
||||
void SetEndPosition(int64_t pos);
|
||||
void SetCurrentPosition(int64_t pos);
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class AlsaPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new AlsaPlayer(); }
|
||||
AlsaPlayerFactory() : AudioPlayerFactory(_T("alsa")) {}
|
||||
} registerAlsaPlayer;
|
||||
|
||||
|
||||
|
||||
///////////////
|
||||
// Constructor
|
||||
AlsaPlayer::AlsaPlayer()
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
// Copyright (c) 2007, Niels Martin Hansen
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:jiifurusu@gmail.com
|
||||
//
|
||||
|
||||
|
||||
#ifdef WITH_ALSA
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include <wx/wxprec.h>
|
||||
#include "audio_player.h"
|
||||
#include "audio_provider.h"
|
||||
#include "utils.h"
|
||||
#include "main.h"
|
||||
#include "frame_main.h"
|
||||
#include "audio_player.h"
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "options.h"
|
||||
|
||||
|
||||
///////////////
|
||||
// Alsa player
|
||||
class AlsaPlayer : public AudioPlayer {
|
||||
private:
|
||||
bool open;
|
||||
volatile bool playing;
|
||||
volatile float volume;
|
||||
|
||||
volatile unsigned long start_frame; // first frame of playback
|
||||
volatile unsigned long cur_frame; // last written frame + 1
|
||||
volatile unsigned long end_frame; // last frame to play
|
||||
unsigned long bpf; // bytes per frame
|
||||
|
||||
AudioProvider *provider;
|
||||
snd_pcm_t *pcm_handle; // device handle
|
||||
snd_pcm_stream_t stream; // stream direction
|
||||
snd_async_handler_t *pcm_callback;
|
||||
|
||||
snd_pcm_format_t sample_format;
|
||||
unsigned int rate; // sample rate of audio
|
||||
unsigned int real_rate; // actual sample rate played back
|
||||
unsigned int period_len; // length of period in microseconds
|
||||
unsigned int buflen; // length of buffer in microseconds
|
||||
snd_pcm_uframes_t period; // size of period in frames
|
||||
snd_pcm_uframes_t bufsize; // size of buffer in frames
|
||||
|
||||
void SetUpHardware();
|
||||
void SetUpAsync();
|
||||
|
||||
static void async_write_handler(snd_async_handler_t *pcm_callback);
|
||||
|
||||
public:
|
||||
AlsaPlayer();
|
||||
~AlsaPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying();
|
||||
|
||||
int64_t GetStartPosition();
|
||||
int64_t GetEndPosition();
|
||||
int64_t GetCurrentPosition();
|
||||
void SetEndPosition(int64_t pos);
|
||||
void SetCurrentPosition(int64_t pos);
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class AlsaPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new AlsaPlayer(); }
|
||||
AlsaPlayerFactory() : AudioPlayerFactory(_T("alsa")) {}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -44,101 +44,7 @@
|
|||
#include "utils.h"
|
||||
#include "main.h"
|
||||
#include "frame_main.h"
|
||||
#include "audio_player.h"
|
||||
#include <mmsystem.h>
|
||||
#include <dsound.h>
|
||||
|
||||
|
||||
//////////////
|
||||
// Prototypes
|
||||
class DirectSoundPlayer;
|
||||
|
||||
|
||||
//////////
|
||||
// Thread
|
||||
class DirectSoundPlayerThread : public wxThread {
|
||||
private:
|
||||
DirectSoundPlayer *parent;
|
||||
HANDLE stopnotify;
|
||||
|
||||
public:
|
||||
void Stop(); // Notify thread to stop audio playback. Thread safe.
|
||||
DirectSoundPlayerThread(DirectSoundPlayer *parent);
|
||||
~DirectSoundPlayerThread();
|
||||
|
||||
wxThread::ExitCode Entry();
|
||||
};
|
||||
/*
|
||||
TODO: Rewrite playback thread to manage all of the buffer, and properly marshal the IDirectSound8
|
||||
object into the thread for creating the buffer there.
|
||||
The thread should own the buffer and manage all of the playback.
|
||||
It must be created with start and duration set, and begins playback at the given position.
|
||||
New functions:
|
||||
* Seek(pos) : Restart playback from the given position
|
||||
* SetEnd(pos) : Set new end point
|
||||
* GetPosition() : Get the current sample number being played
|
||||
* Stop() : Stop playback immediately
|
||||
|
||||
Instead of using a stop event, use a playback parameters changed event. When that one's fired,
|
||||
detect which were actually changed and act accordingly.
|
||||
All but GetPosition() set appropriate fields and then raise the parameters changed event.
|
||||
*/
|
||||
|
||||
|
||||
////////////////////
|
||||
// Portaudio player
|
||||
class DirectSoundPlayer : public AudioPlayer {
|
||||
friend class DirectSoundPlayerThread;
|
||||
|
||||
private:
|
||||
volatile bool playing;
|
||||
float volume;
|
||||
int offset;
|
||||
DWORD bufSize;
|
||||
|
||||
volatile int64_t playPos;
|
||||
int64_t startPos;
|
||||
volatile int64_t endPos;
|
||||
DWORD startTime;
|
||||
|
||||
IDirectSound8 *directSound;
|
||||
IDirectSoundBuffer8 *buffer;
|
||||
|
||||
bool FillBuffer(bool fill);
|
||||
|
||||
DirectSoundPlayerThread *thread;
|
||||
|
||||
public:
|
||||
DirectSoundPlayer();
|
||||
~DirectSoundPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying() { return playing; }
|
||||
|
||||
int64_t GetStartPosition() { return startPos; }
|
||||
int64_t GetEndPosition() { return endPos; }
|
||||
int64_t GetCurrentPosition();
|
||||
void SetEndPosition(int64_t pos);
|
||||
void SetCurrentPosition(int64_t pos);
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
|
||||
//wxMutex *GetMutex() { return &DSMutex; }
|
||||
};
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class DirectSoundPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new DirectSoundPlayer(); }
|
||||
DirectSoundPlayerFactory() : AudioPlayerFactory(_T("dsound")) {}
|
||||
} registerDirectSoundPlayer;
|
||||
#include "audio_player_dsound.h"
|
||||
|
||||
|
||||
///////////////
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
// Copyright (c) 2006, Rodrigo Braz Monteiro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:zeratul@cellosoft.com
|
||||
//
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#ifdef WITH_DIRECTSOUND
|
||||
|
||||
#include <wx/wxprec.h>
|
||||
#include "audio_player.h"
|
||||
#include "audio_provider.h"
|
||||
#include "utils.h"
|
||||
#include "main.h"
|
||||
#include "frame_main.h"
|
||||
#include "audio_player.h"
|
||||
#include <mmsystem.h>
|
||||
#include <dsound.h>
|
||||
|
||||
|
||||
//////////////
|
||||
// Prototypes
|
||||
class DirectSoundPlayer;
|
||||
|
||||
|
||||
//////////
|
||||
// Thread
|
||||
class DirectSoundPlayerThread : public wxThread {
|
||||
private:
|
||||
DirectSoundPlayer *parent;
|
||||
HANDLE stopnotify;
|
||||
|
||||
public:
|
||||
void Stop(); // Notify thread to stop audio playback. Thread safe.
|
||||
DirectSoundPlayerThread(DirectSoundPlayer *parent);
|
||||
~DirectSoundPlayerThread();
|
||||
|
||||
wxThread::ExitCode Entry();
|
||||
};
|
||||
/*
|
||||
TODO: Rewrite playback thread to manage all of the buffer, and properly marshal the IDirectSound8
|
||||
object into the thread for creating the buffer there.
|
||||
The thread should own the buffer and manage all of the playback.
|
||||
It must be created with start and duration set, and begins playback at the given position.
|
||||
New functions:
|
||||
* Seek(pos) : Restart playback from the given position
|
||||
* SetEnd(pos) : Set new end point
|
||||
* GetPosition() : Get the current sample number being played
|
||||
* Stop() : Stop playback immediately
|
||||
|
||||
Instead of using a stop event, use a playback parameters changed event. When that one's fired,
|
||||
detect which were actually changed and act accordingly.
|
||||
All but GetPosition() set appropriate fields and then raise the parameters changed event.
|
||||
*/
|
||||
|
||||
|
||||
////////////////////
|
||||
// Portaudio player
|
||||
class DirectSoundPlayer : public AudioPlayer {
|
||||
friend class DirectSoundPlayerThread;
|
||||
|
||||
private:
|
||||
volatile bool playing;
|
||||
float volume;
|
||||
int offset;
|
||||
DWORD bufSize;
|
||||
|
||||
volatile int64_t playPos;
|
||||
int64_t startPos;
|
||||
volatile int64_t endPos;
|
||||
DWORD startTime;
|
||||
|
||||
IDirectSound8 *directSound;
|
||||
IDirectSoundBuffer8 *buffer;
|
||||
|
||||
bool FillBuffer(bool fill);
|
||||
|
||||
DirectSoundPlayerThread *thread;
|
||||
|
||||
public:
|
||||
DirectSoundPlayer();
|
||||
~DirectSoundPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying() { return playing; }
|
||||
|
||||
int64_t GetStartPosition() { return startPos; }
|
||||
int64_t GetEndPosition() { return endPos; }
|
||||
int64_t GetCurrentPosition();
|
||||
void SetEndPosition(int64_t pos);
|
||||
void SetCurrentPosition(int64_t pos);
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
|
||||
//wxMutex *GetMutex() { return &DSMutex; }
|
||||
};
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class DirectSoundPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new DirectSoundPlayer(); }
|
||||
DirectSoundPlayerFactory() : AudioPlayerFactory(_T("dsound")) {}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -45,7 +45,7 @@
|
|||
#include "utils.h"
|
||||
#include "main.h"
|
||||
#include "frame_main.h"
|
||||
#include "audio_player.h"
|
||||
#include "audio_player_openal.h"
|
||||
#include "options.h"
|
||||
#ifdef __APPLE__
|
||||
#include <OpenAL/AL.h>
|
||||
|
@ -62,73 +62,6 @@
|
|||
#endif
|
||||
|
||||
|
||||
/////////////////
|
||||
// OpenAL player
|
||||
class OpenALPlayer : public AudioPlayer, wxTimer {
|
||||
private:
|
||||
bool open;
|
||||
volatile bool playing;
|
||||
volatile float volume;
|
||||
|
||||
static const ALsizei num_buffers = 8;
|
||||
ALsizei buffer_length;
|
||||
ALsizei samplerate;
|
||||
|
||||
volatile unsigned long start_frame; // first frame of playback
|
||||
volatile unsigned long cur_frame; // last written frame + 1
|
||||
volatile unsigned long end_frame; // last frame to play
|
||||
unsigned long bpf; // bytes per frame
|
||||
|
||||
AudioProvider *provider;
|
||||
ALCdevice *device; // device handle
|
||||
ALCcontext *context; // sound context
|
||||
ALuint buffers[num_buffers]; // sound buffers
|
||||
ALuint source; // playback source
|
||||
|
||||
ALsizei buf_first_free; // index into buffers, first free (unqueued) buffer
|
||||
ALsizei buf_first_queued; // index into buffers, first queued (non-free) buffer
|
||||
ALsizei buffers_free; // number of free buffers
|
||||
ALsizei buffers_played;
|
||||
wxStopWatch playback_segment_timer;
|
||||
|
||||
void FillBuffers(ALsizei count);
|
||||
|
||||
protected:
|
||||
void Notify(); // from wxTimer
|
||||
|
||||
public:
|
||||
OpenALPlayer();
|
||||
~OpenALPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying();
|
||||
|
||||
int64_t GetStartPosition();
|
||||
int64_t GetEndPosition();
|
||||
int64_t GetCurrentPosition();
|
||||
void SetEndPosition(int64_t pos);
|
||||
void SetCurrentPosition(int64_t pos);
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class OpenALPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new OpenALPlayer(); }
|
||||
OpenALPlayerFactory() : AudioPlayerFactory(_T("openal")) {}
|
||||
} registerOALPlayer;
|
||||
|
||||
|
||||
|
||||
///////////////
|
||||
// Constructor
|
||||
OpenALPlayer::OpenALPlayer()
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright (c) 2007, Niels Martin Hansen
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:jiifurusu@gmail.com
|
||||
//
|
||||
|
||||
|
||||
#ifdef WITH_OPENAL
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include <wx/wxprec.h>
|
||||
#include "audio_player.h"
|
||||
#include "audio_provider.h"
|
||||
#include "utils.h"
|
||||
#include "main.h"
|
||||
#include "frame_main.h"
|
||||
#include "audio_player.h"
|
||||
#include "options.h"
|
||||
#ifdef __APPLE__
|
||||
#include <OpenAL/AL.h>
|
||||
#include <OpenAL/ALC.h>
|
||||
#else
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////
|
||||
// OpenAL player
|
||||
class OpenALPlayer : public AudioPlayer, wxTimer {
|
||||
private:
|
||||
bool open;
|
||||
volatile bool playing;
|
||||
volatile float volume;
|
||||
|
||||
static const ALsizei num_buffers = 8;
|
||||
ALsizei buffer_length;
|
||||
ALsizei samplerate;
|
||||
|
||||
volatile unsigned long start_frame; // first frame of playback
|
||||
volatile unsigned long cur_frame; // last written frame + 1
|
||||
volatile unsigned long end_frame; // last frame to play
|
||||
unsigned long bpf; // bytes per frame
|
||||
|
||||
AudioProvider *provider;
|
||||
ALCdevice *device; // device handle
|
||||
ALCcontext *context; // sound context
|
||||
ALuint buffers[num_buffers]; // sound buffers
|
||||
ALuint source; // playback source
|
||||
|
||||
ALsizei buf_first_free; // index into buffers, first free (unqueued) buffer
|
||||
ALsizei buf_first_queued; // index into buffers, first queued (non-free) buffer
|
||||
ALsizei buffers_free; // number of free buffers
|
||||
ALsizei buffers_played;
|
||||
wxStopWatch playback_segment_timer;
|
||||
|
||||
void FillBuffers(ALsizei count);
|
||||
|
||||
protected:
|
||||
void Notify(); // from wxTimer
|
||||
|
||||
public:
|
||||
OpenALPlayer();
|
||||
~OpenALPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying();
|
||||
|
||||
int64_t GetStartPosition();
|
||||
int64_t GetEndPosition();
|
||||
int64_t GetCurrentPosition();
|
||||
void SetEndPosition(int64_t pos);
|
||||
void SetCurrentPosition(int64_t pos);
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class OpenALPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new OpenALPlayer(); }
|
||||
OpenALPlayerFactory() : AudioPlayerFactory(_T("openal")) {}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -39,12 +39,9 @@
|
|||
|
||||
///////////
|
||||
// Headers
|
||||
#include "audio_player.h"
|
||||
#include "audio_player_portaudio.h"
|
||||
#include "audio_provider.h"
|
||||
#include "utils.h"
|
||||
extern "C" {
|
||||
#include <portaudio.h>
|
||||
}
|
||||
|
||||
#ifdef HAVE_PA_GETSTREAMTIME
|
||||
#define Pa_StreamTime Pa_GetStreamTime /* PortAudio v19 */
|
||||
|
@ -59,66 +56,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
|
||||
////////////////////
|
||||
// Portaudio player
|
||||
class PortAudioPlayer : public AudioPlayer {
|
||||
private:
|
||||
static int pa_refcount;
|
||||
wxMutex PAMutex;
|
||||
volatile bool stopping;
|
||||
//bool softStop;
|
||||
bool playing;
|
||||
float volume;
|
||||
|
||||
volatile int64_t playPos;
|
||||
volatile int64_t startPos;
|
||||
volatile int64_t endPos;
|
||||
void *stream;
|
||||
PaTimestamp paStart;
|
||||
volatile int64_t realPlayPos;
|
||||
|
||||
#ifndef HAVE_PA_GETSTREAMTIME
|
||||
static int paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userData);
|
||||
#else
|
||||
static int paCallback(const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo *timei,
|
||||
PaStreamCallbackFlags flags, void *userData);
|
||||
#endif
|
||||
|
||||
public:
|
||||
PortAudioPlayer();
|
||||
~PortAudioPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying() { return playing; }
|
||||
|
||||
int64_t GetStartPosition() { return startPos; }
|
||||
int64_t GetEndPosition() { return endPos; }
|
||||
int64_t GetCurrentPosition() { return realPlayPos; }
|
||||
void SetEndPosition(int64_t pos) { endPos = pos; }
|
||||
void SetCurrentPosition(int64_t pos) { playPos = pos; realPlayPos = pos; }
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
|
||||
wxMutex *GetMutex() { return &PAMutex; }
|
||||
};
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class PortAudioPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new PortAudioPlayer(); }
|
||||
PortAudioPlayerFactory() : AudioPlayerFactory(_T("portaudio")) {}
|
||||
} registerPortAudioPlayer;
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Reference counter
|
||||
int PortAudioPlayer::pa_refcount = 0;
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
// Copyright (c) 2005-2007, Rodrigo Braz Monteiro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:zeratul@cellosoft.com
|
||||
//
|
||||
|
||||
|
||||
#ifdef WITH_PORTAUDIO
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "audio_player.h"
|
||||
#include "audio_provider.h"
|
||||
#include "utils.h"
|
||||
extern "C" {
|
||||
#include <portaudio.h>
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
// Portaudio player
|
||||
class PortAudioPlayer : public AudioPlayer {
|
||||
private:
|
||||
static int pa_refcount;
|
||||
wxMutex PAMutex;
|
||||
volatile bool stopping;
|
||||
//bool softStop;
|
||||
bool playing;
|
||||
float volume;
|
||||
|
||||
volatile int64_t playPos;
|
||||
volatile int64_t startPos;
|
||||
volatile int64_t endPos;
|
||||
void *stream;
|
||||
PaTimestamp paStart;
|
||||
volatile int64_t realPlayPos;
|
||||
|
||||
#ifndef HAVE_PA_GETSTREAMTIME
|
||||
static int paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userData);
|
||||
#else
|
||||
static int paCallback(const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo *timei,
|
||||
PaStreamCallbackFlags flags, void *userData);
|
||||
#endif
|
||||
|
||||
public:
|
||||
PortAudioPlayer();
|
||||
~PortAudioPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying() { return playing; }
|
||||
|
||||
int64_t GetStartPosition() { return startPos; }
|
||||
int64_t GetEndPosition() { return endPos; }
|
||||
int64_t GetCurrentPosition() { return realPlayPos; }
|
||||
void SetEndPosition(int64_t pos) { endPos = pos; }
|
||||
void SetCurrentPosition(int64_t pos) { playPos = pos; realPlayPos = pos; }
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
|
||||
wxMutex *GetMutex() { return &PAMutex; }
|
||||
};
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class PortAudioPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new PortAudioPlayer(); }
|
||||
PortAudioPlayerFactory() : AudioPlayerFactory(_T("portaudio")) {}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -41,92 +41,10 @@
|
|||
// Headers
|
||||
#include <wx/wxprec.h>
|
||||
#include <stdio.h>
|
||||
#include "audio_player.h"
|
||||
#include "audio_player_pulse.h"
|
||||
#include "audio_provider.h"
|
||||
#include "utils.h"
|
||||
#include "options.h"
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
|
||||
//////////////
|
||||
// Prototypes
|
||||
class PulseAudioPlayer;
|
||||
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Pulse Audio player
|
||||
class PulseAudioPlayer : public AudioPlayer {
|
||||
private:
|
||||
float volume;
|
||||
bool open;
|
||||
bool is_playing;
|
||||
|
||||
// Audio data info
|
||||
volatile unsigned long start_frame;
|
||||
volatile unsigned long cur_frame;
|
||||
volatile unsigned long end_frame;
|
||||
unsigned long bpf; // bytes per frame
|
||||
|
||||
// Used for synchronising with async events
|
||||
wxSemaphore context_notify;
|
||||
wxSemaphore context_success;
|
||||
volatile int context_success_val;
|
||||
wxSemaphore stream_notify;
|
||||
wxSemaphore stream_success;
|
||||
volatile int stream_success_val;
|
||||
|
||||
// PulseAudio data
|
||||
pa_threaded_mainloop *mainloop; // pulseaudio mainloop handle
|
||||
pa_context *context; // connection context
|
||||
volatile pa_context_state_t cstate;
|
||||
pa_stream *stream;
|
||||
volatile pa_stream_state_t sstate;
|
||||
volatile pa_usec_t play_start_time; // timestamp when playback was started
|
||||
int paerror;
|
||||
|
||||
// Called by PA to notify about contetxt operation completion
|
||||
static void pa_context_success(pa_context *c, int success, PulseAudioPlayer *thread);
|
||||
// Called by PA to notify about other context-related stuff
|
||||
static void pa_context_notify(pa_context *c, PulseAudioPlayer *thread);
|
||||
// Called by PA when a stream operation completes
|
||||
static void pa_stream_success(pa_stream *p, int success, PulseAudioPlayer *thread);
|
||||
// Called by PA to request more data written to stream
|
||||
static void pa_stream_write(pa_stream *p, size_t length, PulseAudioPlayer *thread);
|
||||
// Called by PA to notify about other stream-related stuff
|
||||
static void pa_stream_notify(pa_stream *p, PulseAudioPlayer *thread);
|
||||
|
||||
public:
|
||||
PulseAudioPlayer();
|
||||
~PulseAudioPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying();
|
||||
|
||||
int64_t GetStartPosition();
|
||||
int64_t GetEndPosition();
|
||||
int64_t GetCurrentPosition();
|
||||
void SetEndPosition(int64_t pos);
|
||||
void SetCurrentPosition(int64_t pos);
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class PulseAudioPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new PulseAudioPlayer(); }
|
||||
PulseAudioPlayerFactory() : AudioPlayerFactory(_T("pulse")) {}
|
||||
} registerPulsePlayer;
|
||||
|
||||
|
||||
|
||||
///////////////
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright (c) 2007, Niels Martin Hansen
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:jiifurusu@gmail.com
|
||||
//
|
||||
|
||||
|
||||
#ifdef WITH_PULSEAUDIO
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include <wx/wxprec.h>
|
||||
#include <stdio.h>
|
||||
#include "audio_player.h"
|
||||
#include "audio_provider.h"
|
||||
#include "utils.h"
|
||||
#include "options.h"
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
|
||||
//////////////
|
||||
// Prototypes
|
||||
class PulseAudioPlayer;
|
||||
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Pulse Audio player
|
||||
class PulseAudioPlayer : public AudioPlayer {
|
||||
private:
|
||||
float volume;
|
||||
bool open;
|
||||
bool is_playing;
|
||||
|
||||
// Audio data info
|
||||
volatile unsigned long start_frame;
|
||||
volatile unsigned long cur_frame;
|
||||
volatile unsigned long end_frame;
|
||||
unsigned long bpf; // bytes per frame
|
||||
|
||||
// Used for synchronising with async events
|
||||
wxSemaphore context_notify;
|
||||
wxSemaphore context_success;
|
||||
volatile int context_success_val;
|
||||
wxSemaphore stream_notify;
|
||||
wxSemaphore stream_success;
|
||||
volatile int stream_success_val;
|
||||
|
||||
// PulseAudio data
|
||||
pa_threaded_mainloop *mainloop; // pulseaudio mainloop handle
|
||||
pa_context *context; // connection context
|
||||
volatile pa_context_state_t cstate;
|
||||
pa_stream *stream;
|
||||
volatile pa_stream_state_t sstate;
|
||||
volatile pa_usec_t play_start_time; // timestamp when playback was started
|
||||
int paerror;
|
||||
|
||||
// Called by PA to notify about contetxt operation completion
|
||||
static void pa_context_success(pa_context *c, int success, PulseAudioPlayer *thread);
|
||||
// Called by PA to notify about other context-related stuff
|
||||
static void pa_context_notify(pa_context *c, PulseAudioPlayer *thread);
|
||||
// Called by PA when a stream operation completes
|
||||
static void pa_stream_success(pa_stream *p, int success, PulseAudioPlayer *thread);
|
||||
// Called by PA to request more data written to stream
|
||||
static void pa_stream_write(pa_stream *p, size_t length, PulseAudioPlayer *thread);
|
||||
// Called by PA to notify about other stream-related stuff
|
||||
static void pa_stream_notify(pa_stream *p, PulseAudioPlayer *thread);
|
||||
|
||||
public:
|
||||
PulseAudioPlayer();
|
||||
~PulseAudioPlayer();
|
||||
|
||||
void OpenStream();
|
||||
void CloseStream();
|
||||
|
||||
void Play(int64_t start,int64_t count);
|
||||
void Stop(bool timerToo=true);
|
||||
bool IsPlaying();
|
||||
|
||||
int64_t GetStartPosition();
|
||||
int64_t GetEndPosition();
|
||||
int64_t GetCurrentPosition();
|
||||
void SetEndPosition(int64_t pos);
|
||||
void SetCurrentPosition(int64_t pos);
|
||||
|
||||
void SetVolume(double vol) { volume = vol; }
|
||||
double GetVolume() { return volume; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Factory
|
||||
class PulseAudioPlayerFactory : public AudioPlayerFactory {
|
||||
public:
|
||||
AudioPlayer *CreatePlayer() { return new PulseAudioPlayer(); }
|
||||
PulseAudioPlayerFactory() : AudioPlayerFactory(_T("pulse")) {}
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue