Mercurial > hg > svapp
diff audioio/AudioPortAudioTarget.cpp @ 101:89a689720ee9 spectrogram-cache-rejig
* Merge from trunk
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 11:59:42 +0000 |
parents | bf1a53489ccc |
children |
line wrap: on
line diff
--- a/audioio/AudioPortAudioTarget.cpp Sun Nov 11 20:34:41 2007 +0000 +++ b/audioio/AudioPortAudioTarget.cpp Wed Feb 27 11:59:42 2008 +0000 @@ -29,7 +29,8 @@ m_stream(0), m_bufferSize(0), m_sampleRate(0), - m_latency(0) + m_latency(0), + m_done(false) { PaError err; @@ -47,7 +48,7 @@ return; } - m_bufferSize = 1024; + m_bufferSize = 2048; m_sampleRate = 44100; if (m_source && (m_source->getSourceSampleRate() != 0)) { m_sampleRate = m_source->getSourceSampleRate(); @@ -62,11 +63,29 @@ m_sampleRate, m_bufferSize, 0, processStatic, this); #else - err = Pa_OpenDefaultStream(&m_stream, 0, 2, paFloat32, - m_sampleRate, m_bufferSize, - processStatic, this); + PaStreamParameters op; + op.device = Pa_GetDefaultOutputDevice(); + op.channelCount = 2; + op.sampleFormat = paFloat32; + op.suggestedLatency = 0.2; + op.hostApiSpecificStreamInfo = 0; + err = Pa_OpenStream(&m_stream, 0, &op, m_sampleRate, + paFramesPerBufferUnspecified, + paNoFlag, processStatic, this); #endif +#ifndef HAVE_PORTAUDIO_V18 + if (err != paNoError) { + + std::cerr << "WARNING: AudioPortAudioTarget: Failed to open PortAudio stream with default frames per buffer, trying again with fixed frames per buffer..." << std::endl; + + err = Pa_OpenStream(&m_stream, 0, &op, m_sampleRate, + 1024, + paNoFlag, processStatic, this); + m_bufferSize = 1024; + } +#endif + if (err != paNoError) { std::cerr << "ERROR: AudioPortAudioTarget: Failed to open PortAudio stream: " << Pa_GetErrorText(err) << std::endl; m_stream = 0; @@ -77,6 +96,7 @@ #ifndef HAVE_PORTAUDIO_V18 const PaStreamInfo *info = Pa_GetStreamInfo(m_stream); m_latency = int(info->outputLatency * m_sampleRate + 0.001); + if (m_bufferSize < m_latency) m_bufferSize = m_latency; #endif std::cerr << "PortAudio latency = " << m_latency << " frames" << std::endl; @@ -93,7 +113,7 @@ if (m_source) { std::cerr << "AudioPortAudioTarget: block size " << m_bufferSize << std::endl; - m_source->setTargetBlockSize(m_bufferSize); + m_source->setTarget(this, m_bufferSize); m_source->setTargetSampleRate(m_sampleRate); m_source->setTargetPlayLatency(m_latency); } @@ -105,17 +125,41 @@ AudioPortAudioTarget::~AudioPortAudioTarget() { + std::cerr << "AudioPortAudioTarget::~AudioPortAudioTarget()" << std::endl; + + if (m_source) { + m_source->setTarget(0, m_bufferSize); + } + + shutdown(); + if (m_stream) { + + std::cerr << "closing stream" << std::endl; + PaError err; err = Pa_CloseStream(m_stream); if (err != paNoError) { std::cerr << "ERROR: AudioPortAudioTarget: Failed to close PortAudio stream: " << Pa_GetErrorText(err) << std::endl; } + + std::cerr << "terminating" << std::endl; + err = Pa_Terminate(); if (err != paNoError) { std::cerr << "ERROR: AudioPortAudioTarget: Failed to terminate PortAudio: " << Pa_GetErrorText(err) << std::endl; } } + + m_stream = 0; + + std::cerr << "AudioPortAudioTarget::~AudioPortAudioTarget() done" << std::endl; +} + +void +AudioPortAudioTarget::shutdown() +{ + m_done = true; } bool @@ -124,6 +168,13 @@ return (m_stream != 0); } +double +AudioPortAudioTarget::getCurrentTime() const +{ + if (!m_stream) return 0.0; + else return Pa_GetStreamTime(m_stream); +} + #ifdef HAVE_PORTAUDIO_V18 int AudioPortAudioTarget::processStatic(void *input, void *output, @@ -169,7 +220,7 @@ std::cout << "AudioPortAudioTarget::process(" << nframes << ")" << std::endl; #endif - if (!m_source) return 0; + if (!m_source || m_done) return 0; float *output = (float *)outputBuffer;