comparison audioio/AudioPortAudioTarget.cpp @ 91:9fc4b256c283

* PortAudio driver: do not specify frames per buffer, let PA decide * Remove old non-RubberBand time stretcher -- it doesn't work with varying buffer sizes such as the PA driver may now be using * Rewrite getCurrentPlayingFrame for greater correctness when using long buffer sizes (interpolating according to audio stream timestamp) * Several changes to make the timestretch management RT safe(r)
author Chris Cannam
date Fri, 08 Feb 2008 17:51:15 +0000
parents 0948bf800422
children dd6d0bc05030
comparison
equal deleted inserted replaced
90:db267a315058 91:9fc4b256c283
67 op.device = 0; 67 op.device = 0;
68 op.channelCount = 2; 68 op.channelCount = 2;
69 op.sampleFormat = paFloat32; 69 op.sampleFormat = paFloat32;
70 op.suggestedLatency = 0.2; 70 op.suggestedLatency = 0.2;
71 op.hostApiSpecificStreamInfo = 0; 71 op.hostApiSpecificStreamInfo = 0;
72 err = Pa_OpenStream(&m_stream, 0, &op, m_sampleRate, m_bufferSize, 72 err = Pa_OpenStream(&m_stream, 0, &op, m_sampleRate,
73 paFramesPerBufferUnspecified,
73 paNoFlag, processStatic, this); 74 paNoFlag, processStatic, this);
74 #endif 75 #endif
75 76
76 if (err != paNoError) { 77 if (err != paNoError) {
77 std::cerr << "ERROR: AudioPortAudioTarget: Failed to open PortAudio stream: " << Pa_GetErrorText(err) << std::endl; 78 std::cerr << "ERROR: AudioPortAudioTarget: Failed to open PortAudio stream: " << Pa_GetErrorText(err) << std::endl;
81 } 82 }
82 83
83 #ifndef HAVE_PORTAUDIO_V18 84 #ifndef HAVE_PORTAUDIO_V18
84 const PaStreamInfo *info = Pa_GetStreamInfo(m_stream); 85 const PaStreamInfo *info = Pa_GetStreamInfo(m_stream);
85 m_latency = int(info->outputLatency * m_sampleRate + 0.001); 86 m_latency = int(info->outputLatency * m_sampleRate + 0.001);
87 m_bufferSize = m_latency;
86 #endif 88 #endif
87 89
88 std::cerr << "PortAudio latency = " << m_latency << " frames" << std::endl; 90 std::cerr << "PortAudio latency = " << m_latency << " frames" << std::endl;
89 91
90 err = Pa_StartStream(m_stream); 92 err = Pa_StartStream(m_stream);
97 return; 99 return;
98 } 100 }
99 101
100 if (m_source) { 102 if (m_source) {
101 std::cerr << "AudioPortAudioTarget: block size " << m_bufferSize << std::endl; 103 std::cerr << "AudioPortAudioTarget: block size " << m_bufferSize << std::endl;
102 m_source->setTargetBlockSize(m_bufferSize); 104 m_source->setTarget(this, m_bufferSize);
103 m_source->setTargetSampleRate(m_sampleRate); 105 m_source->setTargetSampleRate(m_sampleRate);
104 m_source->setTargetPlayLatency(m_latency); 106 m_source->setTargetPlayLatency(m_latency);
105 } 107 }
106 108
107 #ifdef DEBUG_PORT_AUDIO_TARGET 109 #ifdef DEBUG_PORT_AUDIO_TARGET
110 } 112 }
111 113
112 AudioPortAudioTarget::~AudioPortAudioTarget() 114 AudioPortAudioTarget::~AudioPortAudioTarget()
113 { 115 {
114 std::cerr << "AudioPortAudioTarget::~AudioPortAudioTarget()" << std::endl; 116 std::cerr << "AudioPortAudioTarget::~AudioPortAudioTarget()" << std::endl;
117
118 if (m_source) {
119 m_source->setTarget(0, m_bufferSize);
120 }
115 121
116 shutdown(); 122 shutdown();
117 123
118 if (m_stream) { 124 if (m_stream) {
119 125
146 152
147 bool 153 bool
148 AudioPortAudioTarget::isOK() const 154 AudioPortAudioTarget::isOK() const
149 { 155 {
150 return (m_stream != 0); 156 return (m_stream != 0);
157 }
158
159 double
160 AudioPortAudioTarget::getCurrentTime() const
161 {
162 if (!m_stream) return 0.0;
163 else return Pa_GetStreamTime(m_stream);
151 } 164 }
152 165
153 #ifdef HAVE_PORTAUDIO_V18 166 #ifdef HAVE_PORTAUDIO_V18
154 int 167 int
155 AudioPortAudioTarget::processStatic(void *input, void *output, 168 AudioPortAudioTarget::processStatic(void *input, void *output,