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;