From af84de21ab9beea8ff7ccbecbb7f68fa8def6bb6 Mon Sep 17 00:00:00 2001 From: Amar Takhar Date: Wed, 15 Apr 2009 10:26:22 +0000 Subject: [PATCH] * Fix paCallback decleration * Switch from PaOpenDefaultStream to Pa_OpenStream. * Add Debug output * Add GetOutputDevices which returns a list of available devices (unused) Originally committed to SVN as r2796. --- aegisub/src/audio_player_portaudio2.cpp | 56 ++++++++++++++++++++++--- aegisub/src/audio_player_portaudio2.h | 18 ++++---- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/aegisub/src/audio_player_portaudio2.cpp b/aegisub/src/audio_player_portaudio2.cpp index 30557ac4b..8153f98fe 100644 --- a/aegisub/src/audio_player_portaudio2.cpp +++ b/aegisub/src/audio_player_portaudio2.cpp @@ -64,11 +64,13 @@ PortAudioPlayer::PortAudioPlayer() { // Initialize portaudio if (!pa_refcount) { PaError err = Pa_Initialize(); + if (err != paNoError) { static wchar_t errormsg[2048]; swprintf(errormsg, 2048, L"Failed opening PortAudio: %s", Pa_GetErrorText(err)); throw (const wchar_t *)errormsg; } + pa_refcount++; } @@ -88,9 +90,8 @@ PortAudioPlayer::~PortAudioPlayer() { } ////////////////////// -// PortAudio callback - - int PortAudioPlayer::paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { +/// PortAudio callback +int PortAudioPlayer::paCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { // Get provider PortAudioPlayer *player = (PortAudioPlayer *) userData; @@ -128,7 +129,13 @@ PortAudioPlayer::~PortAudioPlayer() { player->playPos += framesPerBuffer; const PaStreamInfo* streamInfo = Pa_GetStreamInfo(player->stream); - player->realPlayPos = (timeInfo->outputBufferDacTime * streamInfo->sampleRate) + player->startPos; + player->realPlayPos = (timeInfo->inputBufferAdcTime * streamInfo->sampleRate) + player->startPos; + +/* +printf("playPos: %lld startPos: %lld paStart: %f currentTime: %f realPlayPos: %lld Pa_GetStreamTime: %f AdcTime: %f DacTime: %f\n", +player->playPos, player->startPos, player->paStart, timeInfo->currentTime, player->realPlayPos, Pa_GetStreamTime(player->stream), +timeInfo->inputBufferAdcTime, timeInfo->outputBufferDacTime); +*/ // Cap to start if lower return end; @@ -183,9 +190,27 @@ void PortAudioPlayer::Stop(bool timerToo) { // Open stream void PortAudioPlayer::OpenStream() { // Open stream - PaError err = Pa_OpenDefaultStream(&stream,0,provider->GetChannels(),paInt16,provider->GetSampleRate(),256,paCallback,this); + PaStreamParameters pa_output_p; + + PaDeviceIndex pa_device = Pa_GetDefaultOutputDevice(); + + pa_output_p.device = pa_device; + pa_output_p.channelCount = provider->GetChannels(); + pa_output_p.sampleFormat = paInt16; + pa_output_p.suggestedLatency = Pa_GetDeviceInfo(pa_device)->defaultLowOutputLatency; + pa_output_p.hostApiSpecificStreamInfo = NULL; + + wxLogDebug(_T("PortAudioPlayer::OpenStream Output Device: %d, Output channels: %d, Latency: %f Sample Rate: %ld\n"), + pa_device, pa_output_p.channelCount, pa_output_p.suggestedLatency, pa_output_p.sampleFormat); + + PaError err = Pa_OpenStream(&stream, NULL, &pa_output_p, provider->GetSampleRate(), 256, paNoFlag, paCallback, this); if (err != paNoError) { + + const PaHostErrorInfo *pa_err = Pa_GetLastHostErrorInfo(); + if (pa_err->errorCode != 0) { + wxLogDebug(_T("PortAudioPlayer::OpenStream HostError: API: %d, %s (%ld)\n"), pa_err->hostApiType, pa_err->errorText, pa_err->errorCode); + } throw wxString(_T("Failed initializing PortAudio stream with error: ") + wxString(Pa_GetErrorText(err),wxConvLocal)); } } @@ -201,4 +226,25 @@ void PortAudioPlayer::CloseStream() { } +/////////////// +/// Return a list of available output devices. +/// @param Setting from config file. +wxArrayString PortAudioPlayer::GetOutputDevices(wxString favorite) { + wxArrayString list; + int devices = Pa_GetDeviceCount(); + int i; + + if (devices < 0) { + // some error here + } + + for (i=0; iname, wxConvUTF8); + list.Insert(name, i); + } + + return list; +} + #endif // WITH_PORTAUDIO2 diff --git a/aegisub/src/audio_player_portaudio2.h b/aegisub/src/audio_player_portaudio2.h index 59171c7cb..7cde462ab 100644 --- a/aegisub/src/audio_player_portaudio2.h +++ b/aegisub/src/audio_player_portaudio2.h @@ -66,14 +66,15 @@ private: PaTime paStart; volatile int64_t realPlayPos; -// static int paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTime outTime, void *userData); -static int paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData); -/* - static int paCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo *timei, - PaStreamCallbackFlags flags, void *userData); -*/ +static int paCallback( + const void *inputBuffer, + void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* + timeInfo, + PaStreamCallbackFlags + statusFlags, + void *userData); public: PortAudioPlayer(); @@ -95,6 +96,7 @@ public: void SetVolume(double vol) { volume = vol; } double GetVolume() { return volume; } + wxArrayString GetOutputDevices(wxString favorite=0); wxMutex *GetMutex() { return &PAMutex; } };