Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.h @ 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 | ae2627ac7db2 |
children | 737b373246b5 |
comparison
equal
deleted
inserted
replaced
90:db267a315058 | 91:9fc4b256c283 |
---|---|
30 #include <samplerate.h> | 30 #include <samplerate.h> |
31 | 31 |
32 #include <set> | 32 #include <set> |
33 #include <map> | 33 #include <map> |
34 | 34 |
35 #ifdef HAVE_RUBBERBAND | 35 namespace RubberBand { |
36 #include <rubberband/RubberBandStretcher.h> | 36 class RubberBandStretcher; |
37 #else | 37 } |
38 class PhaseVocoderTimeStretcher; | |
39 #endif | |
40 | 38 |
41 class Model; | 39 class Model; |
42 class ViewManager; | 40 class ViewManager; |
43 class AudioGenerator; | 41 class AudioGenerator; |
44 class PlayParameters; | 42 class PlayParameters; |
45 class RealTimePluginInstance; | 43 class RealTimePluginInstance; |
44 class AudioCallbackPlayTarget; | |
46 | 45 |
47 /** | 46 /** |
48 * AudioCallbackPlaySource manages audio data supply to callback-based | 47 * AudioCallbackPlaySource manages audio data supply to callback-based |
49 * audio APIs such as JACK or CoreAudio. It maintains one ring buffer | 48 * audio APIs such as JACK or CoreAudio. It maintains one ring buffer |
50 * per channel, filled during playback by a non-realtime thread, and | 49 * per channel, filled during playback by a non-realtime thread, and |
105 * Return the frame at which playback is expected to end (if not looping). | 104 * Return the frame at which playback is expected to end (if not looping). |
106 */ | 105 */ |
107 virtual size_t getPlayEndFrame() { return m_lastModelEndFrame; } | 106 virtual size_t getPlayEndFrame() { return m_lastModelEndFrame; } |
108 | 107 |
109 /** | 108 /** |
110 * Set the block size of the target audio device. This should | 109 * Set the target and the block size of the target audio device. |
111 * be called by the target class. | 110 * This should be called by the target class. |
112 */ | 111 */ |
113 void setTargetBlockSize(size_t); | 112 void setTarget(AudioCallbackPlayTarget *, size_t blockSize); |
114 | 113 |
115 /** | 114 /** |
116 * Get the block size of the target audio device. | 115 * Get the block size of the target audio device. This may be an |
116 * estimate or upper bound, if the target has a variable block | |
117 * size; the source should behave itself even if this value turns | |
118 * out to be inaccurate. | |
117 */ | 119 */ |
118 size_t getTargetBlockSize() const; | 120 size_t getTargetBlockSize() const; |
119 | 121 |
120 /** | 122 /** |
121 * Set the playback latency of the target audio device, in frames | 123 * Set the playback latency of the target audio device, in frames |
188 * realtime thread. | 190 * realtime thread. |
189 */ | 191 */ |
190 size_t getSourceSamples(size_t count, float **buffer); | 192 size_t getSourceSamples(size_t count, float **buffer); |
191 | 193 |
192 /** | 194 /** |
193 * Set the time stretcher factor (i.e. playback speed). Also | 195 * Set the time stretcher factor (i.e. playback speed). |
194 * specify whether the time stretcher will be variable rate | 196 */ |
195 * (sharpening transients), and whether time stretching will be | 197 void setTimeStretch(float factor); |
196 * carried out on data mixed down to mono for speed. | |
197 */ | |
198 void setTimeStretch(float factor, bool sharpen, bool mono); | |
199 | 198 |
200 /** | 199 /** |
201 * Set the resampler quality, 0 - 2 where 0 is fastest and 2 is | 200 * Set the resampler quality, 0 - 2 where 0 is fastest and 2 is |
202 * highest quality. | 201 * highest quality. |
203 */ | 202 */ |
277 size_t m_sourceChannelCount; | 276 size_t m_sourceChannelCount; |
278 size_t m_blockSize; | 277 size_t m_blockSize; |
279 size_t m_sourceSampleRate; | 278 size_t m_sourceSampleRate; |
280 size_t m_targetSampleRate; | 279 size_t m_targetSampleRate; |
281 size_t m_playLatency; | 280 size_t m_playLatency; |
281 AudioCallbackPlayTarget *m_target; | |
282 double m_lastRetrievalTimestamp; | |
283 size_t m_lastRetrievedBlockSize; | |
282 bool m_playing; | 284 bool m_playing; |
283 bool m_exiting; | 285 bool m_exiting; |
284 size_t m_lastModelEndFrame; | 286 size_t m_lastModelEndFrame; |
285 static const size_t m_ringBufferSize; | 287 static const size_t m_ringBufferSize; |
286 float m_outputLeft; | 288 float m_outputLeft; |
307 } | 309 } |
308 | 310 |
309 void clearRingBuffers(bool haveLock = false, size_t count = 0); | 311 void clearRingBuffers(bool haveLock = false, size_t count = 0); |
310 void unifyRingBuffers(); | 312 void unifyRingBuffers(); |
311 | 313 |
312 #ifdef HAVE_RUBBERBAND | |
313 RubberBand::RubberBandStretcher *m_timeStretcher; | 314 RubberBand::RubberBandStretcher *m_timeStretcher; |
314 QMutex m_timeStretchRatioMutex; | 315 float m_stretchRatio; |
315 #else | 316 |
316 PhaseVocoderTimeStretcher *m_timeStretcher; | 317 size_t m_stretcherInputCount; |
317 Scavenger<PhaseVocoderTimeStretcher> m_timeStretcherScavenger; | 318 float **m_stretcherInputs; |
318 #endif | 319 size_t *m_stretcherInputSizes; |
319 | 320 |
320 // Called from fill thread, m_playing true, mutex held | 321 // Called from fill thread, m_playing true, mutex held |
321 // Return true if work done | 322 // Return true if work done |
322 bool fillBuffers(); | 323 bool fillBuffers(); |
323 | 324 |