Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.h @ 100:22bf057ea151 1.2-stable
* merge from trunk (1.2 ended up being tracked from trunk, but we may want
this branch for fixes later)
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 10:32:45 +0000 |
parents | ae2627ac7db2 |
children |
comparison
equal
deleted
inserted
replaced
71:a8acc7841d70 | 100:22bf057ea151 |
---|---|
24 #include <QObject> | 24 #include <QObject> |
25 #include <QMutex> | 25 #include <QMutex> |
26 #include <QWaitCondition> | 26 #include <QWaitCondition> |
27 | 27 |
28 #include "base/Thread.h" | 28 #include "base/Thread.h" |
29 #include "base/RealTime.h" | |
29 | 30 |
30 #include <samplerate.h> | 31 #include <samplerate.h> |
31 | 32 |
32 #include <set> | 33 #include <set> |
33 #include <map> | 34 #include <map> |
34 | 35 |
35 #ifdef HAVE_RUBBERBAND | 36 namespace RubberBand { |
36 #include <rubberband/RubberBandStretcher.h> | 37 class RubberBandStretcher; |
37 #else | 38 } |
38 class PhaseVocoderTimeStretcher; | |
39 #endif | |
40 | 39 |
41 class Model; | 40 class Model; |
42 class ViewManager; | 41 class ViewManager; |
43 class AudioGenerator; | 42 class AudioGenerator; |
44 class PlayParameters; | 43 class PlayParameters; |
45 class RealTimePluginInstance; | 44 class RealTimePluginInstance; |
45 class AudioCallbackPlayTarget; | |
46 | 46 |
47 /** | 47 /** |
48 * AudioCallbackPlaySource manages audio data supply to callback-based | 48 * AudioCallbackPlaySource manages audio data supply to callback-based |
49 * audio APIs such as JACK or CoreAudio. It maintains one ring buffer | 49 * audio APIs such as JACK or CoreAudio. It maintains one ring buffer |
50 * per channel, filled during playback by a non-realtime thread, and | 50 * per channel, filled during playback by a non-realtime thread, and |
98 /** | 98 /** |
99 * Return the frame number that is currently expected to be coming | 99 * Return the frame number that is currently expected to be coming |
100 * out of the speakers. (i.e. compensating for playback latency.) | 100 * out of the speakers. (i.e. compensating for playback latency.) |
101 */ | 101 */ |
102 virtual size_t getCurrentPlayingFrame(); | 102 virtual size_t getCurrentPlayingFrame(); |
103 | |
104 /** | |
105 * Return the last frame that would come out of the speakers if we | |
106 * stopped playback right now. | |
107 */ | |
108 virtual size_t getCurrentBufferedFrame(); | |
103 | 109 |
104 /** | 110 /** |
105 * Return the frame at which playback is expected to end (if not looping). | 111 * Return the frame at which playback is expected to end (if not looping). |
106 */ | 112 */ |
107 virtual size_t getPlayEndFrame() { return m_lastModelEndFrame; } | 113 virtual size_t getPlayEndFrame() { return m_lastModelEndFrame; } |
108 | 114 |
109 /** | 115 /** |
110 * Set the block size of the target audio device. This should | 116 * Set the target and the block size of the target audio device. |
111 * be called by the target class. | 117 * This should be called by the target class. |
112 */ | 118 */ |
113 void setTargetBlockSize(size_t); | 119 void setTarget(AudioCallbackPlayTarget *, size_t blockSize); |
114 | 120 |
115 /** | 121 /** |
116 * Get the block size of the target audio device. | 122 * Get the block size of the target audio device. This may be an |
123 * estimate or upper bound, if the target has a variable block | |
124 * size; the source should behave itself even if this value turns | |
125 * out to be inaccurate. | |
117 */ | 126 */ |
118 size_t getTargetBlockSize() const; | 127 size_t getTargetBlockSize() const; |
119 | 128 |
120 /** | 129 /** |
121 * Set the playback latency of the target audio device, in frames | 130 * Set the playback latency of the target audio device, in frames |
188 * realtime thread. | 197 * realtime thread. |
189 */ | 198 */ |
190 size_t getSourceSamples(size_t count, float **buffer); | 199 size_t getSourceSamples(size_t count, float **buffer); |
191 | 200 |
192 /** | 201 /** |
193 * Set the time stretcher factor (i.e. playback speed). Also | 202 * Set the time stretcher factor (i.e. playback speed). |
194 * specify whether the time stretcher will be variable rate | 203 */ |
195 * (sharpening transients), and whether time stretching will be | 204 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 | 205 |
200 /** | 206 /** |
201 * Set the resampler quality, 0 - 2 where 0 is fastest and 2 is | 207 * Set the resampler quality, 0 - 2 where 0 is fastest and 2 is |
202 * highest quality. | 208 * highest quality. |
203 */ | 209 */ |
277 size_t m_sourceChannelCount; | 283 size_t m_sourceChannelCount; |
278 size_t m_blockSize; | 284 size_t m_blockSize; |
279 size_t m_sourceSampleRate; | 285 size_t m_sourceSampleRate; |
280 size_t m_targetSampleRate; | 286 size_t m_targetSampleRate; |
281 size_t m_playLatency; | 287 size_t m_playLatency; |
288 AudioCallbackPlayTarget *m_target; | |
289 double m_lastRetrievalTimestamp; | |
290 size_t m_lastRetrievedBlockSize; | |
282 bool m_playing; | 291 bool m_playing; |
283 bool m_exiting; | 292 bool m_exiting; |
284 size_t m_lastModelEndFrame; | 293 size_t m_lastModelEndFrame; |
285 static const size_t m_ringBufferSize; | 294 static const size_t m_ringBufferSize; |
286 float m_outputLeft; | 295 float m_outputLeft; |
287 float m_outputRight; | 296 float m_outputRight; |
288 RealTimePluginInstance *m_auditioningPlugin; | 297 RealTimePluginInstance *m_auditioningPlugin; |
289 bool m_auditioningPluginBypassed; | 298 bool m_auditioningPluginBypassed; |
290 Scavenger<RealTimePluginInstance> m_pluginScavenger; | 299 Scavenger<RealTimePluginInstance> m_pluginScavenger; |
300 size_t m_playStartFrame; | |
301 bool m_playStartFramePassed; | |
302 RealTime m_playStartedAt; | |
291 | 303 |
292 RingBuffer<float> *getWriteRingBuffer(size_t c) { | 304 RingBuffer<float> *getWriteRingBuffer(size_t c) { |
293 if (m_writeBuffers && c < m_writeBuffers->size()) { | 305 if (m_writeBuffers && c < m_writeBuffers->size()) { |
294 return (*m_writeBuffers)[c]; | 306 return (*m_writeBuffers)[c]; |
295 } else { | 307 } else { |
307 } | 319 } |
308 | 320 |
309 void clearRingBuffers(bool haveLock = false, size_t count = 0); | 321 void clearRingBuffers(bool haveLock = false, size_t count = 0); |
310 void unifyRingBuffers(); | 322 void unifyRingBuffers(); |
311 | 323 |
312 #ifdef HAVE_RUBBERBAND | |
313 RubberBand::RubberBandStretcher *m_timeStretcher; | 324 RubberBand::RubberBandStretcher *m_timeStretcher; |
314 QMutex m_timeStretchRatioMutex; | 325 float m_stretchRatio; |
315 #else | 326 |
316 PhaseVocoderTimeStretcher *m_timeStretcher; | 327 size_t m_stretcherInputCount; |
317 Scavenger<PhaseVocoderTimeStretcher> m_timeStretcherScavenger; | 328 float **m_stretcherInputs; |
318 #endif | 329 size_t *m_stretcherInputSizes; |
319 | 330 |
320 // Called from fill thread, m_playing true, mutex held | 331 // Called from fill thread, m_playing true, mutex held |
321 // Return true if work done | 332 // Return true if work done |
322 bool fillBuffers(); | 333 bool fillBuffers(); |
323 | 334 |
327 // frame argument passed in, in the case of looping). | 338 // frame argument passed in, in the case of looping). |
328 size_t mixModels(size_t &frame, size_t count, float **buffers); | 339 size_t mixModels(size_t &frame, size_t count, float **buffers); |
329 | 340 |
330 // Called from getSourceSamples. | 341 // Called from getSourceSamples. |
331 void applyAuditioningEffect(size_t count, float **buffers); | 342 void applyAuditioningEffect(size_t count, float **buffers); |
343 | |
344 // Ranges of current selections, if play selection is active | |
345 std::vector<RealTime> m_rangeStarts; | |
346 std::vector<RealTime> m_rangeDurations; | |
347 void rebuildRangeLists(); | |
348 | |
349 size_t getCurrentFrame(RealTime outputLatency); | |
332 | 350 |
333 class FillThread : public Thread | 351 class FillThread : public Thread |
334 { | 352 { |
335 public: | 353 public: |
336 FillThread(AudioCallbackPlaySource &source) : | 354 FillThread(AudioCallbackPlaySource &source) : |