Mercurial > hg > svapp
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, |