From ee61192c43ddda4184bfff2135fe1db717ea5d68 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Wed, 5 Mar 2008 02:43:01 +0000 Subject: [PATCH] Made audio players register manually. Originally committed to SVN as r1893. --- aegisub/audio_player.cpp | 42 +++++++++ aegisub/audio_player.h | 1 + aegisub/audio_player_alsa.cpp | 67 +------------- aegisub/audio_player_alsa.h | 115 +++++++++++++++++++++++ aegisub/audio_player_dsound.cpp | 96 +------------------ aegisub/audio_player_dsound.h | 143 +++++++++++++++++++++++++++++ aegisub/audio_player_openal.cpp | 69 +------------- aegisub/audio_player_openal.h | 124 +++++++++++++++++++++++++ aegisub/audio_player_portaudio.cpp | 65 +------------ aegisub/audio_player_portaudio.h | 109 ++++++++++++++++++++++ aegisub/audio_player_pulse.cpp | 84 +---------------- aegisub/audio_player_pulse.h | 130 ++++++++++++++++++++++++++ 12 files changed, 669 insertions(+), 376 deletions(-) create mode 100644 aegisub/audio_player_alsa.h create mode 100644 aegisub/audio_player_dsound.h create mode 100644 aegisub/audio_player_openal.h create mode 100644 aegisub/audio_player_portaudio.h create mode 100644 aegisub/audio_player_pulse.h diff --git a/aegisub/audio_player.cpp b/aegisub/audio_player.cpp index 094da8f84..ea2f4b6f6 100644 --- a/aegisub/audio_player.cpp +++ b/aegisub/audio_player.cpp @@ -39,6 +39,21 @@ #include #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 std::map* AegisubFactory::factories=NULL; diff --git a/aegisub/audio_player.h b/aegisub/audio_player.h index b16b25532..4190e4ee8 100644 --- a/aegisub/audio_player.h +++ b/aegisub/audio_player.h @@ -104,6 +104,7 @@ protected: public: virtual ~AudioPlayerFactory() {} static AudioPlayer *GetAudioPlayer(); + static void RegisterFactories(); }; diff --git a/aegisub/audio_player_alsa.cpp b/aegisub/audio_player_alsa.cpp index 20444a19e..3976cce3e 100644 --- a/aegisub/audio_player_alsa.cpp +++ b/aegisub/audio_player_alsa.cpp @@ -45,75 +45,10 @@ #include "utils.h" #include "main.h" #include "frame_main.h" -#include "audio_player.h" -#include +#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() diff --git a/aegisub/audio_player_alsa.h b/aegisub/audio_player_alsa.h new file mode 100644 index 000000000..1cd796374 --- /dev/null +++ b/aegisub/audio_player_alsa.h @@ -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 +#include "audio_player.h" +#include "audio_provider.h" +#include "utils.h" +#include "main.h" +#include "frame_main.h" +#include "audio_player.h" +#include +#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 diff --git a/aegisub/audio_player_dsound.cpp b/aegisub/audio_player_dsound.cpp index f3c1df054..845486c8d 100644 --- a/aegisub/audio_player_dsound.cpp +++ b/aegisub/audio_player_dsound.cpp @@ -44,101 +44,7 @@ #include "utils.h" #include "main.h" #include "frame_main.h" -#include "audio_player.h" -#include -#include - - -////////////// -// 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" /////////////// diff --git a/aegisub/audio_player_dsound.h b/aegisub/audio_player_dsound.h new file mode 100644 index 000000000..105d2833c --- /dev/null +++ b/aegisub/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 +#include "audio_player.h" +#include "audio_provider.h" +#include "utils.h" +#include "main.h" +#include "frame_main.h" +#include "audio_player.h" +#include +#include + + +////////////// +// 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 diff --git a/aegisub/audio_player_openal.cpp b/aegisub/audio_player_openal.cpp index 26d50cb1e..ae744dc7e 100644 --- a/aegisub/audio_player_openal.cpp +++ b/aegisub/audio_player_openal.cpp @@ -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 @@ -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() diff --git a/aegisub/audio_player_openal.h b/aegisub/audio_player_openal.h new file mode 100644 index 000000000..08cf38750 --- /dev/null +++ b/aegisub/audio_player_openal.h @@ -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 +#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 +#include +#else +#include +#include +#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 diff --git a/aegisub/audio_player_portaudio.cpp b/aegisub/audio_player_portaudio.cpp index 877282ca4..d0f65662e 100644 --- a/aegisub/audio_player_portaudio.cpp +++ b/aegisub/audio_player_portaudio.cpp @@ -39,12 +39,9 @@ /////////// // Headers -#include "audio_player.h" +#include "audio_player_portaudio.h" #include "audio_provider.h" #include "utils.h" -extern "C" { -#include -} #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; diff --git a/aegisub/audio_player_portaudio.h b/aegisub/audio_player_portaudio.h new file mode 100644 index 000000000..b08445c15 --- /dev/null +++ b/aegisub/audio_player_portaudio.h @@ -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 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 diff --git a/aegisub/audio_player_pulse.cpp b/aegisub/audio_player_pulse.cpp index 08e9a399e..7b9983228 100644 --- a/aegisub/audio_player_pulse.cpp +++ b/aegisub/audio_player_pulse.cpp @@ -41,92 +41,10 @@ // Headers #include #include -#include "audio_player.h" +#include "audio_player_pulse.h" #include "audio_provider.h" #include "utils.h" #include "options.h" -#include - - -////////////// -// 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; - /////////////// diff --git a/aegisub/audio_player_pulse.h b/aegisub/audio_player_pulse.h new file mode 100644 index 000000000..97b50779d --- /dev/null +++ b/aegisub/audio_player_pulse.h @@ -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 +#include +#include "audio_player.h" +#include "audio_provider.h" +#include "utils.h" +#include "options.h" +#include + + +////////////// +// 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