diff --git a/aegisub/src/audio_controller.cpp b/aegisub/src/audio_controller.cpp index 4e7480f00..3ca5ffc6c 100644 --- a/aegisub/src/audio_controller.cpp +++ b/aegisub/src/audio_controller.cpp @@ -114,14 +114,24 @@ void AudioController::OnPlaybackTimer(wxTimerEvent &) void AudioController::OnComputerSuspending(wxPowerEvent &) { Stop(); - player->CloseStream(); + delete player; + player = 0; } void AudioController::OnComputerResuming(wxPowerEvent &) { if (provider) - player->OpenStream(); + { + try + { + player = AudioPlayerFactory::GetAudioPlayer(provider); + } + catch (...) + { + CloseAudio(); + } + } } #endif @@ -135,9 +145,7 @@ void AudioController::OnAudioPlayerChanged() try { - player = AudioPlayerFactory::GetAudioPlayer(); - player->SetProvider(provider); - player->OpenStream(); + player = AudioPlayerFactory::GetAudioPlayer(provider); } catch (...) { @@ -238,15 +246,11 @@ void AudioController::OpenAudio(const wxString &url) try { - player = AudioPlayerFactory::GetAudioPlayer(); - player->SetProvider(provider); - player->OpenStream(); + player = AudioPlayerFactory::GetAudioPlayer(provider); } catch (...) { - delete player; delete provider; - player = 0; provider = 0; throw; } diff --git a/aegisub/src/audio_player.cpp b/aegisub/src/audio_player.cpp index e3e310c5e..7f9f8a4ad 100644 --- a/aegisub/src/audio_player.cpp +++ b/aegisub/src/audio_player.cpp @@ -60,18 +60,19 @@ #include "compat.h" #include "main.h" -AudioPlayer::AudioPlayer() { - provider = NULL; +AudioPlayer::AudioPlayer(AudioProvider *provider) +: provider(provider) +{ } -AudioPlayer* AudioPlayerFactory::GetAudioPlayer() { +AudioPlayer* AudioPlayerFactory::GetAudioPlayer(AudioProvider *provider) { std::vector list = GetClasses(OPT_GET("Audio/Player")->GetString()); if (list.empty()) throw agi::NoAudioPlayersError("No audio players are available.", 0); std::string error; for (size_t i = 0; i < list.size(); ++i) { try { - return Create(list[i]); + return Create(list[i], provider); } catch (agi::AudioPlayerOpenError const& err) { error += list[i] + " factory: " + err.GetChainedMessage() + "\n"; @@ -102,4 +103,4 @@ void AudioPlayerFactory::RegisterProviders() { #endif } -template<> AudioPlayerFactory::map *FactoryBase::classes = NULL; +template<> AudioPlayerFactory::map *FactoryBase::classes = NULL; diff --git a/aegisub/src/audio_player_alsa.cpp b/aegisub/src/audio_player_alsa.cpp index f2b74307e..691154d29 100644 --- a/aegisub/src/audio_player_alsa.cpp +++ b/aegisub/src/audio_player_alsa.cpp @@ -366,42 +366,22 @@ do_setup: } -AlsaPlayer::AlsaPlayer() -: ps(new PlaybackState) +AlsaPlayer::AlsaPlayer(AudioProvider *provider) +: AudioPlayer(provider) +, ps(new PlaybackState) { - open = false; -} - - -AlsaPlayer::~AlsaPlayer() -{ - CloseStream(); -} - - -void AlsaPlayer::OpenStream() -{ - if (open) return; - - CloseStream(); - - ps->Reset(); ps->provider = provider; wxString device_name = lagi_wxString(OPT_GET("Player/Audio/ALSA/Device")->GetString()); ps->device_name = std::string(device_name.utf8_str()); - if (pthread_create(&thread, 0, &playback_thread, ps.get()) == 0) - open = true; - else + if (pthread_create(&thread, 0, &playback_thread, ps.get()) != 0) throw agi::AudioPlayerOpenError("AlsaPlayer: Creating the playback thread failed", 0); } -void AlsaPlayer::CloseStream() +AlsaPlayer::~AlsaPlayer() { - if (!open) return; - { PthreadMutexLocker ml(ps->mutex); ps->signal_stop = true; @@ -411,15 +391,11 @@ void AlsaPlayer::CloseStream() } pthread_join(thread, 0); // FIXME: check for errors - - open = false; } void AlsaPlayer::Play(int64_t start, int64_t count) { - OpenStream(); - PthreadMutexLocker ml(ps->mutex); ps->signal_start = true; ps->signal_stop = true; // make sure to stop any ongoing playback first @@ -431,8 +407,6 @@ void AlsaPlayer::Play(int64_t start, int64_t count) void AlsaPlayer::Stop() { - if (!open) return; - PthreadMutexLocker ml(ps->mutex); ps->signal_stop = true; LOG_D("audio/player/alsa") << "stop stream, stop signal"; @@ -442,13 +416,12 @@ void AlsaPlayer::Stop() bool AlsaPlayer::IsPlaying() { PthreadMutexLocker ml(ps->mutex); - return open && ps->playing; + return ps->playing; } void AlsaPlayer::SetEndPosition(int64_t pos) { - if (!open) return; PthreadMutexLocker ml(ps->mutex); ps->end_position = pos; } @@ -456,8 +429,6 @@ void AlsaPlayer::SetEndPosition(int64_t pos) void AlsaPlayer::SetCurrentPosition(int64_t pos) { - if (!open) return; - PthreadMutexLocker ml(ps->mutex); if (!ps->playing) return; @@ -471,14 +442,12 @@ void AlsaPlayer::SetCurrentPosition(int64_t pos) int64_t AlsaPlayer::GetStartPosition() { - if (!open) return 0; PthreadMutexLocker ml(ps->mutex); return ps->start_position; } int64_t AlsaPlayer::GetEndPosition() { - if (!open) return 0; PthreadMutexLocker ml(ps->mutex); return ps->end_position; } @@ -486,8 +455,6 @@ int64_t AlsaPlayer::GetEndPosition() int64_t AlsaPlayer::GetCurrentPosition() { - if (!open) return 0; - int64_t lastpos; timespec lasttime; int64_t samplerate; @@ -516,8 +483,6 @@ int64_t AlsaPlayer::GetCurrentPosition() void AlsaPlayer::SetVolume(double vol) { - if (!open) return; - PthreadMutexLocker ml(ps->mutex); ps->volume = vol; ps->signal_volume = true; @@ -527,8 +492,6 @@ void AlsaPlayer::SetVolume(double vol) double AlsaPlayer::GetVolume() { - if (!open) return 1.0; - PthreadMutexLocker ml(ps->mutex); return ps->volume; } diff --git a/aegisub/src/audio_player_alsa.h b/aegisub/src/audio_player_alsa.h index a28e0322e..48fa445e3 100644 --- a/aegisub/src/audio_player_alsa.h +++ b/aegisub/src/audio_player_alsa.h @@ -47,15 +47,11 @@ struct PlaybackState; class AlsaPlayer : public AudioPlayer { agi::scoped_ptr ps; pthread_t thread; - bool open; public: - AlsaPlayer(); + AlsaPlayer(AudioProvider *provider); ~AlsaPlayer(); - void OpenStream(); - void CloseStream(); - void Play(int64_t start, int64_t count); void Stop(); bool IsPlaying(); diff --git a/aegisub/src/audio_player_dsound.cpp b/aegisub/src/audio_player_dsound.cpp index a6198369d..fff18a026 100644 --- a/aegisub/src/audio_player_dsound.cpp +++ b/aegisub/src/audio_player_dsound.cpp @@ -46,30 +46,20 @@ #include "main.h" #include "utils.h" -/// @brief Constructor -/// -DirectSoundPlayer::DirectSoundPlayer() { - playing = false; - volume = 1.0f; - playPos = 0; - startPos = 0; - endPos = 0; - offset = 0; - - buffer = NULL; - directSound = NULL; - thread = NULL; -} - -/// @brief Destructor -/// -DirectSoundPlayer::~DirectSoundPlayer() { - CloseStream(); -} - -/// @brief Open stream -/// -void DirectSoundPlayer::OpenStream() { +DirectSoundPlayer::DirectSoundPlayer(AudioProvider *provider) +: AudioPlayer(provider) +, playing(false) +, volume(1.0f) +, offset(0) +, bufSize(0) +, playPos(0) +, startPos(0) +, endPos(0) +, startTime(0) +, directSound(0) +, buffer(0) +, thread(0) +{ // Initialize the DirectSound object HRESULT res; res = DirectSoundCreate8(&DSDEVID_DefaultPlayback,&directSound,NULL); // TODO: support selecting audio device @@ -114,10 +104,7 @@ void DirectSoundPlayer::OpenStream() { offset = 0; } -/// @brief Close stream -/// -void DirectSoundPlayer::CloseStream() { - // Stop it +DirectSoundPlayer::~DirectSoundPlayer() { Stop(); // Unref the DirectSound buffer diff --git a/aegisub/src/audio_player_dsound.h b/aegisub/src/audio_player_dsound.h index 22ad73974..2fd3dcb0a 100644 --- a/aegisub/src/audio_player_dsound.h +++ b/aegisub/src/audio_player_dsound.h @@ -115,42 +115,21 @@ private: DirectSoundPlayerThread *thread; public: - DirectSoundPlayer(); + DirectSoundPlayer(AudioProvider *provider); ~DirectSoundPlayer(); - void OpenStream(); - void CloseStream(); - void Play(int64_t start,int64_t count); void Stop(); - /// @brief DOCME - /// @return - /// bool IsPlaying() { return playing; } - /// @brief DOCME - /// @return - /// int64_t GetStartPosition() { return startPos; } - - /// @brief DOCME - /// @return - /// int64_t GetEndPosition() { return endPos; } int64_t GetCurrentPosition(); void SetEndPosition(int64_t pos); void SetCurrentPosition(int64_t pos); - /// @brief DOCME - /// @param vol - /// @return - /// void SetVolume(double vol) { volume = vol; } - - /// @brief DOCME - /// @return - /// double GetVolume() { return volume; } }; #endif diff --git a/aegisub/src/audio_player_dsound2.cpp b/aegisub/src/audio_player_dsound2.cpp index 80ef1be67..e4e47c20c 100644 --- a/aegisub/src/audio_player_dsound2.cpp +++ b/aegisub/src/audio_player_dsound2.cpp @@ -801,7 +801,8 @@ bool DirectSoundPlayer2Thread::IsDead() } } -DirectSoundPlayer2::DirectSoundPlayer2() +DirectSoundPlayer2::DirectSoundPlayer2(AudioProvider *provider) +: AudioPlayer(provider) { // The buffer will hold BufferLength times WantedLatency milliseconds of audio WantedLatency = OPT_GET("Player/Audio/DirectSound/Buffer Latency")->GetInt(); @@ -812,6 +813,16 @@ DirectSoundPlayer2::DirectSoundPlayer2() WantedLatency = 100; if (BufferLength <= 0) BufferLength = 5; + + try + { + thread.reset(new DirectSoundPlayer2Thread(provider, WantedLatency, BufferLength)); + } + catch (const char *msg) + { + LOG_E("audio/player/dsound") << msg; + throw agi::AudioPlayerOpenError(msg, 0); + } } DirectSoundPlayer2::~DirectSoundPlayer2() @@ -828,47 +839,10 @@ bool DirectSoundPlayer2::IsThreadAlive() return thread; } -void DirectSoundPlayer2::OpenStream() -{ - if (IsThreadAlive()) return; - - try - { - thread.reset(new DirectSoundPlayer2Thread(provider, WantedLatency, BufferLength)); - } - catch (const char *msg) - { - LOG_E("audio/player/dsound") << msg; - } -} - -void DirectSoundPlayer2::CloseStream() -{ - thread.reset(); -} - -void DirectSoundPlayer2::SetProvider(AudioProvider *new_provider) -{ - try - { - if (IsThreadAlive() && new_provider != provider) - { - thread.reset(new DirectSoundPlayer2Thread(new_provider, WantedLatency, BufferLength)); - } - - AudioPlayer::SetProvider(new_provider); - } - catch (const char *msg) - { - LOG_E("audio/player/dsound") << msg; - } -} - void DirectSoundPlayer2::Play(int64_t start,int64_t count) { try { - OpenStream(); thread->Play(start, count); } catch (const char *msg) diff --git a/aegisub/src/audio_player_dsound2.h b/aegisub/src/audio_player_dsound2.h index 0cd3cbfbd..8dcb02e40 100644 --- a/aegisub/src/audio_player_dsound2.h +++ b/aegisub/src/audio_player_dsound2.h @@ -64,23 +64,10 @@ class DirectSoundPlayer2 : public AudioPlayer { public: /// @brief Constructor - DirectSoundPlayer2(); + DirectSoundPlayer2(AudioProvider *provider); /// @brief Destructor ~DirectSoundPlayer2(); - /// @brief Prepare for playback - /// - /// This means creating the playback thread - void OpenStream(); - /// @brief Shutdown playback - void CloseStream(); - - /// @brief Change audio provider used - /// @param provider New audio provider to use - /// - /// Will re-create the playback thread if the provider changed and playback was open - void SetProvider(AudioProvider *provider); - /// @brief Start playback /// @param start First audio frame to play /// @param count Number of audio frames to play diff --git a/aegisub/src/audio_player_openal.cpp b/aegisub/src/audio_player_openal.cpp index 5f53e503f..b3089c12f 100644 --- a/aegisub/src/audio_player_openal.cpp +++ b/aegisub/src/audio_player_openal.cpp @@ -52,8 +52,8 @@ DEFINE_SIMPLE_EXCEPTION(OpenALException, agi::AudioPlayerOpenError, "audio/open/player/openal") -OpenALPlayer::OpenALPlayer() -: open(false) +OpenALPlayer::OpenALPlayer(AudioProvider *provider) +: AudioPlayer(provider) , playing(false) , volume(1.f) , samplerate(0) @@ -64,17 +64,6 @@ OpenALPlayer::OpenALPlayer() , device(0) , context(0) { -} - -OpenALPlayer::~OpenALPlayer() -{ - CloseStream(); -} - -void OpenALPlayer::OpenStream() -{ - CloseStream(); - bpf = provider->GetChannels() * provider->GetBytesPerSample(); try { // Open device @@ -112,27 +101,16 @@ void OpenALPlayer::OpenStream() // Determine buffer length samplerate = provider->GetSampleRate(); decode_buffer.resize(samplerate * bpf / num_buffers / 2); // buffers for half a second of audio - - // Now ready - open = true; } -void OpenALPlayer::CloseStream() +OpenALPlayer::~OpenALPlayer() { - if (!open) return; - Stop(); alDeleteSources(1, &source); alDeleteBuffers(num_buffers, buffers); alcDestroyContext(context); alcCloseDevice(device); - - context = 0; - device = 0; - - // No longer working - open = false; } void OpenALPlayer::Play(int64_t start, int64_t count) @@ -165,7 +143,6 @@ void OpenALPlayer::Play(int64_t start, int64_t count) void OpenALPlayer::Stop() { - if (!open) return; if (!playing) return; // Reset data diff --git a/aegisub/src/audio_player_openal.h b/aegisub/src/audio_player_openal.h index 91caaadc1..3f306481c 100644 --- a/aegisub/src/audio_player_openal.h +++ b/aegisub/src/audio_player_openal.h @@ -64,7 +64,6 @@ class OpenALPlayer : public AudioPlayer, wxTimer { /// Number of OpenAL buffers to use static const ALsizei num_buffers = 8; - bool open; ///< Is the player ready to play? bool playing; ///< Is audio currently playing? float volume; ///< Current audio volume @@ -106,12 +105,9 @@ protected: void Notify(); public: - OpenALPlayer(); + OpenALPlayer(AudioProvider *provider); ~OpenALPlayer(); - void OpenStream(); - void CloseStream(); - void Play(int64_t start,int64_t count); void Stop(); bool IsPlaying() { return playing; } diff --git a/aegisub/src/audio_player_oss.cpp b/aegisub/src/audio_player_oss.cpp index f9c6a917b..63fbb65ba 100644 --- a/aegisub/src/audio_player_oss.cpp +++ b/aegisub/src/audio_player_oss.cpp @@ -52,25 +52,29 @@ DEFINE_SIMPLE_EXCEPTION(OSSError, agi::AudioPlayerOpenError, "audio/player/open/oss") -OSSPlayer::OSSPlayer() +OSSPlayer::OSSPlayer(AudioProvider *provider) +: AudioPlayer(provider) +, rate(0) +, thread(0) +, playing(false) +, volume(1.0f) +, start_frame(0) +, cur_frame(0) +, end_frame(0) +, bpf(0) +, dspdev(0) { - volume = 1.0f; - open = false; - playing = false; - start_frame = cur_frame = end_frame = bpf = 0; - provider = 0; - thread = 0; + OpenStream(); } OSSPlayer::~OSSPlayer() { - CloseStream(); + Stop(); + ::close(dspdev); } void OSSPlayer::OpenStream() { - CloseStream(); - bpf = provider->GetChannels() * provider->GetBytesPerSample(); // Open device @@ -114,20 +118,6 @@ void OSSPlayer::OpenStream() if (ioctl(dspdev, SNDCTL_DSP_SPEED, &rate) < 0) { throw OSSError("OSS player: setting samplerate failed", 0); } - - // Now ready - open = true; -} - -void OSSPlayer::CloseStream() -{ - if (!open) return; - - Stop(); - ::close(dspdev); - - // No longer working - open = false; } void OSSPlayer::Play(int64_t start, int64_t count) @@ -146,7 +136,6 @@ void OSSPlayer::Play(int64_t start, int64_t count) void OSSPlayer::Stop() { - if (!open) return; if (!playing) return; // Stop the thread diff --git a/aegisub/src/audio_player_oss.h b/aegisub/src/audio_player_oss.h index d94c1bbe7..afa0296d9 100644 --- a/aegisub/src/audio_player_oss.h +++ b/aegisub/src/audio_player_oss.h @@ -79,13 +79,10 @@ public: class OSSPlayer : public AudioPlayer { friend class OSSPlayerThread; - /// Is the output file handle initialized and ready to be written to? - bool open; - /// sample rate of audio unsigned int rate; - /// Worker thread that does the actual writing + /// Worker thread that does the actual writing OSSPlayerThread *thread; /// Is the player currently playing? @@ -106,15 +103,14 @@ class OSSPlayer : public AudioPlayer { /// bytes per frame unsigned long bpf; - // OSS audio device handle + /// OSS audio device handle volatile int dspdev; -public: - OSSPlayer(); - ~OSSPlayer(); - void OpenStream(); - void CloseStream(); + +public: + OSSPlayer(AudioProvider *provider); + ~OSSPlayer(); void Play(int64_t start, int64_t count); void Stop(); diff --git a/aegisub/src/audio_player_portaudio.cpp b/aegisub/src/audio_player_portaudio.cpp index 16f3faa0d..d81d6ecfd 100644 --- a/aegisub/src/audio_player_portaudio.cpp +++ b/aegisub/src/audio_player_portaudio.cpp @@ -71,9 +71,11 @@ static const PaHostApiTypeId pa_host_api_priority[] = { }; static const size_t pa_host_api_priority_count = sizeof(pa_host_api_priority) / sizeof(pa_host_api_priority[0]); -PortAudioPlayer::PortAudioPlayer() -: volume(1.0f) +PortAudioPlayer::PortAudioPlayer(AudioProvider *provider) +: AudioPlayer(provider) +, volume(1.0f) , pa_start(0.0) +, stream(0) { PaError err = Pa_Initialize(); @@ -92,6 +94,9 @@ PortAudioPlayer::PortAudioPlayer() if (devices.empty()) throw PortAudioError("No PortAudio output devices found", 0); + + if (provider) + OpenStream(); } void PortAudioPlayer::GatherDevices(PaHostApiIndex host_idx) { @@ -120,6 +125,10 @@ void PortAudioPlayer::GatherDevices(PaHostApiIndex host_idx) { } PortAudioPlayer::~PortAudioPlayer() { + if (stream) { + Stop(); + Pa_CloseStream(stream); + } Pa_Terminate(); } @@ -172,11 +181,6 @@ void PortAudioPlayer::OpenStream() { throw PortAudioError("Failed initializing PortAudio stream: " + error, 0); } -void PortAudioPlayer::CloseStream() { - Stop(); - Pa_CloseStream(stream); -} - void PortAudioPlayer::paStreamFinishedCallback(void *) { LOG_D("audio/player/portaudio") << "stopping stream"; } @@ -271,7 +275,7 @@ wxArrayString PortAudioPlayer::GetOutputDevices() { list.push_back("Default"); try { - PortAudioPlayer player; + PortAudioPlayer player(0); for (std::map::iterator it = player.devices.begin(); it != player.devices.end(); ++it) list.push_back(lagi_wxString(it->first)); diff --git a/aegisub/src/audio_player_portaudio.h b/aegisub/src/audio_player_portaudio.h index d026272dc..dcb64afc5 100644 --- a/aegisub/src/audio_player_portaudio.h +++ b/aegisub/src/audio_player_portaudio.h @@ -48,6 +48,8 @@ extern "C" { #include #endif +class wxArrayString; + /// @class PortAudioPlayer /// @brief PortAudio Player /// @@ -93,18 +95,15 @@ class PortAudioPlayer : public AudioPlayer { /// @param host_idx Host API ID void GatherDevices(PaHostApiIndex host_idx); + void OpenStream(); + public: /// @brief Constructor - PortAudioPlayer(); + PortAudioPlayer(AudioProvider *provider); /// @brief Destructor ~PortAudioPlayer(); - /// @brief Open stream - void OpenStream(); - /// @brief Close stream - void CloseStream(); - /// @brief Play audio. /// @param start Start position. /// @param count Frame count diff --git a/aegisub/src/audio_player_pulse.cpp b/aegisub/src/audio_player_pulse.cpp index 518ed6dc4..cbfe9e6fd 100644 --- a/aegisub/src/audio_player_pulse.cpp +++ b/aegisub/src/audio_player_pulse.cpp @@ -39,7 +39,9 @@ #ifdef WITH_LIBPULSE #ifndef AGI_PRE -#include +#include + +#include #endif #include "audio_player_pulse.h" @@ -48,38 +50,30 @@ #include "include/aegisub/audio_provider.h" #include "utils.h" -PulseAudioPlayer::PulseAudioPlayer() -: context_notify(0, 1) +#include + +PulseAudioPlayer::PulseAudioPlayer(AudioProvider *provider) +: AudioPlayer(provider) +, volume(1.0f) +, is_playing(false) +, start_frame(0) +, cur_frame(0) +, end_frame(0) +, bpf(0) +, context_notify(0, 1) , context_success(0, 1) , stream_notify(0, 1) , stream_success(0, 1) +, paerror(0) { - volume = 1.0f; - paerror = 0; - open = false; - is_playing = false; -} - -PulseAudioPlayer::~PulseAudioPlayer() -{ - CloseStream(); -} - -void PulseAudioPlayer::OpenStream() -{ - if (open) CloseStream(); - // Initialise a mainloop - //printf("Initialising threaded main loop\n"); mainloop = pa_threaded_mainloop_new(); - if (!mainloop) { + if (!mainloop) throw agi::AudioPlayerOpenError("Failed to initialise PulseAudio threaded mainloop object", 0); - } - //printf("Starting main loop\n"); + pa_threaded_mainloop_start(mainloop); // Create context - //printf("Creating context\n"); context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), "Aegisub"); if (!context) { pa_threaded_mainloop_free(mainloop); @@ -88,8 +82,8 @@ void PulseAudioPlayer::OpenStream() pa_context_set_state_callback(context, (pa_context_notify_cb_t)pa_context_notify, this); // Connect the context - //printf("Connecting context\n"); pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); + // Wait for connection while (true) { context_notify.Wait(); @@ -105,7 +99,6 @@ void PulseAudioPlayer::OpenStream() } // otherwise loop once more } - //printf("Context connected\n"); // Set up stream bpf = provider->GetChannels() * provider->GetBytesPerSample(); @@ -115,7 +108,7 @@ void PulseAudioPlayer::OpenStream() ss.channels = provider->GetChannels(); pa_channel_map map; pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_DEFAULT); - //printf("Creating stream\n"); + stream = pa_stream_new(context, "Sound", &ss, &map); if (!stream) { // argh! @@ -129,10 +122,9 @@ void PulseAudioPlayer::OpenStream() pa_stream_set_write_callback(stream, (pa_stream_request_cb_t)pa_stream_write, this); // Connect stream - //printf("Connecting playback stream\n"); paerror = pa_stream_connect_playback(stream, NULL, NULL, (pa_stream_flags_t)(PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_NOT_MONOTONOUS|PA_STREAM_AUTO_TIMING_UPDATE), NULL, NULL); if (paerror) { - printf("PulseAudio reported error: %s (%d)\n", pa_strerror(paerror), paerror); + LOG_E("audio/player/pulse") << "Stream connection failed: " << pa_strerror(paerror) << "(" << paerror << ")"; throw agi::AudioPlayerOpenError(std::string("PulseAudio reported error: ") + pa_strerror(paerror), 0); } while (true) { @@ -141,22 +133,14 @@ void PulseAudioPlayer::OpenStream() break; } else if (sstate == PA_STREAM_FAILED) { paerror = pa_context_errno(context); - printf("PulseAudio player: Stream connection failed: %s (%d)\n", pa_strerror(paerror), paerror); + LOG_E("audio/player/pulse") << "Stream connection failed: " << pa_strerror(paerror) << "(" << paerror << ")"; throw agi::AudioPlayerOpenError("PulseAudio player: Something went wrong connecting the stream", 0); } } - //printf("Connected playback stream, now playing\n\n"); - - // Hopefully this marks success - //printf("Finished opening PulseAudio\n\n"); - open = true; } -void PulseAudioPlayer::CloseStream() +PulseAudioPlayer::~PulseAudioPlayer() { - if (!open) return; - //printf("Closing PuseAudio\n"); - if (is_playing) Stop(); // Hope for the best and just do things as quickly as possible @@ -166,16 +150,10 @@ void PulseAudioPlayer::CloseStream() pa_context_unref(context); pa_threaded_mainloop_stop(mainloop); pa_threaded_mainloop_free(mainloop); - - //printf("Closed PulseAudio\n"); - open = false; } void PulseAudioPlayer::Play(int64_t start,int64_t count) { - //printf("Starting PulseAudio playback\n"); - if (!open) OpenStream(); - if (is_playing) { // If we're already playing, do a quick "reset" is_playing = false; @@ -187,14 +165,13 @@ void PulseAudioPlayer::Play(int64_t start,int64_t count) pa_operation_unref(op); if (!stream_success_val) { paerror = pa_context_errno(context); - printf("PulseAudio player: Error flushing stream: %s (%d)\n", pa_strerror(paerror), paerror); + LOG_E("audio/player/pulse") << "Error flushing stream: " << pa_strerror(paerror) << "(" << paerror << ")"; } } start_frame = start; cur_frame = start; end_frame = start + count; - //printf("start=%lu end=%lu\n", start_frame, end_frame); is_playing = true; @@ -202,9 +179,8 @@ void PulseAudioPlayer::Play(int64_t start,int64_t count) pa_threaded_mainloop_lock(mainloop); paerror = pa_stream_get_time(stream, (pa_usec_t*) &play_start_time); pa_threaded_mainloop_unlock(mainloop); - if (paerror) { - printf("PulseAudio player: Error getting stream time: %s (%d)\n", pa_strerror(paerror), paerror); - } + if (paerror) + LOG_E("audio/player/pulse") << "Error getting stream time: " << pa_strerror(paerror) << "(" << paerror << ")"; PulseAudioPlayer::pa_stream_write(stream, pa_stream_writable_size(stream), this); @@ -215,14 +191,13 @@ void PulseAudioPlayer::Play(int64_t start,int64_t count) pa_operation_unref(op); if (!stream_success_val) { paerror = pa_context_errno(context); - printf("PulseAudio player: Error triggering stream: %s (%d)\n", pa_strerror(paerror), paerror); + LOG_E("audio/player/pulse") << "Error triggering stream: " << pa_strerror(paerror) << "(" << paerror << ")"; } } void PulseAudioPlayer::Stop() { if (!is_playing) return; - //printf("Stopping PulseAudio\n"); is_playing = false; @@ -231,7 +206,6 @@ void PulseAudioPlayer::Stop() end_frame = 0; // Flush the stream of data - //printf("Flushing stream\n"); pa_threaded_mainloop_lock(mainloop); pa_operation *op = pa_stream_flush(stream, (pa_stream_success_cb_t)pa_stream_success, this); pa_threaded_mainloop_unlock(mainloop); @@ -239,16 +213,8 @@ void PulseAudioPlayer::Stop() pa_operation_unref(op); if (!stream_success_val) { paerror = pa_context_errno(context); - printf("PulseAudio player: Error flushing stream: %s (%d)\n", pa_strerror(paerror), paerror); + LOG_E("audio/player/pulse") << "Error flushing stream: " << pa_strerror(paerror) << "(" << paerror << ")"; } - - // And unref it - //printf("Stopped stream\n\n"); -} - -bool PulseAudioPlayer::IsPlaying() -{ - return is_playing; } void PulseAudioPlayer::SetEndPosition(int64_t pos) @@ -261,16 +227,6 @@ void PulseAudioPlayer::SetCurrentPosition(int64_t pos) cur_frame = pos; } -int64_t PulseAudioPlayer::GetStartPosition() -{ - return start_frame; -} - -int64_t PulseAudioPlayer::GetEndPosition() -{ - return end_frame; -} - int64_t PulseAudioPlayer::GetCurrentPosition() { if (!is_playing) return 0; @@ -317,7 +273,6 @@ void PulseAudioPlayer::pa_stream_write(pa_stream *p, size_t length, PulseAudioPl thread->is_playing = false; pa_operation *op = pa_stream_drain(p, NULL, NULL); pa_operation_unref(op); - //printf("PA requested more buffer, but no more to stream\n"); return; } else if (thread->cur_frame >= thread->end_frame) { @@ -328,12 +283,10 @@ void PulseAudioPlayer::pa_stream_write(pa_stream *p, size_t length, PulseAudioPl return; } - //printf("PA requested more buffer, %lu bytes\n", (unsigned long)length); unsigned long bpf = thread->bpf; unsigned long frames = length / thread->bpf; unsigned long maxframes = thread->end_frame - thread->cur_frame; if (frames > maxframes) frames = maxframes; - //printf("Handing it %lu frames\n", frames); void *buf = malloc(frames * bpf); thread->provider->GetAudioWithVolume(buf, thread->cur_frame, frames, thread->volume); ::pa_stream_write(p, buf, frames*bpf, free, 0, PA_SEEK_RELATIVE); diff --git a/aegisub/src/audio_player_pulse.h b/aegisub/src/audio_player_pulse.h index 07437ab46..4d1bad04d 100644 --- a/aegisub/src/audio_player_pulse.h +++ b/aegisub/src/audio_player_pulse.h @@ -47,14 +47,9 @@ class PulseAudioPlayer; /// /// DOCME class PulseAudioPlayer : public AudioPlayer { -private: - /// DOCME float volume; - /// DOCME - bool open; - /// DOCME bool is_playing; @@ -124,18 +119,15 @@ private: static void pa_stream_notify(pa_stream *p, PulseAudioPlayer *thread); public: - PulseAudioPlayer(); + PulseAudioPlayer(AudioProvider *provider); ~PulseAudioPlayer(); - void OpenStream(); - void CloseStream(); - void Play(int64_t start,int64_t count); void Stop(); - bool IsPlaying(); + bool IsPlaying() { return is_playing; } - int64_t GetStartPosition(); - int64_t GetEndPosition(); + int64_t GetStartPosition() { return start_frame; } + int64_t GetEndPosition() { return end_frame; } int64_t GetCurrentPosition(); void SetEndPosition(int64_t pos); void SetCurrentPosition(int64_t pos); diff --git a/aegisub/src/include/aegisub/audio_player.h b/aegisub/src/include/aegisub/audio_player.h index d2d818bfe..e39fdc918 100644 --- a/aegisub/src/include/aegisub/audio_player.h +++ b/aegisub/src/include/aegisub/audio_player.h @@ -50,12 +50,9 @@ protected: AudioProvider *provider; public: - AudioPlayer(); + AudioPlayer(AudioProvider *provider); virtual ~AudioPlayer() { } - virtual void OpenStream()=0; - virtual void CloseStream()=0; - virtual void Play(int64_t start,int64_t count)=0; // Play sample range virtual void Stop()=0; // Stop playing virtual bool IsPlaying()=0; @@ -68,12 +65,10 @@ public: virtual int64_t GetCurrentPosition()=0; virtual void SetEndPosition(int64_t pos)=0; virtual void SetCurrentPosition(int64_t pos)=0; - - virtual void SetProvider(AudioProvider *new_provider) { provider = new_provider; } }; -class AudioPlayerFactory : public Factory0 { +class AudioPlayerFactory : public Factory1 { public: static void RegisterProviders(); - static AudioPlayer *GetAudioPlayer(); + static AudioPlayer *GetAudioPlayer(AudioProvider *provider); };