* Remove a short-lived hack (hours?) and replace it with a

PaStreamFinishedCallback which is called anytime a PaCallback is exited with
  anything other than 0. (normal operation)  paStreamFinishedCallback handles
  stopping the audio stream when we've run to the end of the current selection
  or the stream is stopped.
* Add framesPerBuffer to paCallback debug output in preperation for dynamic
  buffers.
* Set paPrimeOutputBuffersUsingStreamCallback in Pa_OpenStream to prime the
  output buffer using the callback rather than initing with empty space which
  is the default.
* Indent paCallback decleration another level.

Originally committed to SVN as r2807.
This commit is contained in:
Amar Takhar 2009-04-17 02:14:42 +00:00
parent a3f9735d38
commit 235af35603
2 changed files with 45 additions and 19 deletions

View File

@ -94,14 +94,15 @@ int PortAudioPlayer::paCallback(const void *inputBuffer, void *outputBuffer, uns
AudioProvider *provider = player->GetProvider();
#ifdef PORTAUDIO2_DEBUG
printf("paCallBack: playPos: %lld startPos: %lld paStart: %f Pa_GetStreamTime: %f AdcTime: %f DacTime: %f CPU: %f\n",
printf("paCallBack: playPos: %lld startPos: %lld paStart: %f Pa_GetStreamTime: %f AdcTime: %f DacTime: %f framesPerBuffer: %lu CPU: %f\n",
player->playPos, player->startPos, player->paStart, Pa_GetStreamTime(player->stream),
timeInfo->inputBufferAdcTime, timeInfo->outputBufferDacTime, Pa_GetStreamCpuLoad(player->stream));
timeInfo->inputBufferAdcTime, timeInfo->outputBufferDacTime, framesPerBuffer, Pa_GetStreamCpuLoad(player->stream));
#endif
// Calculate how much left
int64_t lenAvailable = (player->endPos - player->playPos) > 0 ? framesPerBuffer : 0;
// Play something
if (lenAvailable > 0) {
provider->GetAudioWithVolume(outputBuffer, player->playPos, lenAvailable, player->GetVolume());
@ -112,19 +113,17 @@ int PortAudioPlayer::paCallback(const void *inputBuffer, void *outputBuffer, uns
// Continue as normal
return 0;
}
else {
// Set the end position to be less then the current play position.
player->endPos = player->endPos - (framesPerBuffer + 8192);
// Abort stream and stop the callback.
return paAbort;
}
}
////////
// Play
void PortAudioPlayer::Play(int64_t start,int64_t count) {
PaError err;
// Stop if it's already playing
wxMutexLocker locker(PAMutex);
@ -135,7 +134,16 @@ void PortAudioPlayer::Play(int64_t start,int64_t count) {
// Start playing
if (!playing) {
PaError err = Pa_StartStream(stream);
err = Pa_SetStreamFinishedCallback(stream, paStreamFinishedCallback);
if (err != paNoError) {
wxLogDebug(_T("PortAudioPlayer::Play Could not set FinishedCallback\n"));
return;
}
err = Pa_StartStream(stream);
if (err != paNoError) {
return;
}
@ -164,6 +172,21 @@ void PortAudioPlayer::Stop(bool timerToo) {
}
}
//////////////////////////////////////////////
// Called when the callback has finished.
void PortAudioPlayer::paStreamFinishedCallback(void *userData) {
PortAudioPlayer *player = (PortAudioPlayer *) userData;
player->playing = false;
if (player->displayTimer) {
player->displayTimer->Stop();
}
wxLogDebug(_T("PortAudioPlayer::paStreamFinishedCallback Stopping stream."));
}
///////////////
// Open stream
@ -191,7 +214,7 @@ void PortAudioPlayer::OpenStream() {
wxLogDebug(_T("PortAudioPlayer::OpenStream Output channels: %d, Latency: %f Sample Rate: %ld\n"),
pa_output_p.channelCount, pa_output_p.suggestedLatency, pa_output_p.sampleFormat);
PaError err = Pa_OpenStream(&stream, NULL, &pa_output_p, provider->GetSampleRate(), 256, paClipOff, paCallback, this);
PaError err = Pa_OpenStream(&stream, NULL, &pa_output_p, provider->GetSampleRate(), 256, paPrimeOutputBuffersUsingStreamCallback, paCallback, this);
if (err != paNoError) {
@ -213,6 +236,7 @@ void PortAudioPlayer::CloseStream() {
} catch (...) {}
}
////////////////////////
/// Get current stream position.
int64_t PortAudioPlayer::GetCurrentPosition()

View File

@ -75,6 +75,8 @@ static int paCallback(
statusFlags,
void *userData);
static void paStreamFinishedCallback(void *userData);
public:
PortAudioPlayer();
~PortAudioPlayer();