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) :