comparison audioio/AudioCallbackPlaySource.h @ 101:89a689720ee9 spectrogram-cache-rejig

* Merge from trunk
author Chris Cannam
date Wed, 27 Feb 2008 11:59:42 +0000
parents eb596ef12041
children
comparison
equal deleted inserted replaced
59:bf1a53489ccc 101:89a689720ee9
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>
35
36 namespace RubberBand {
37 class RubberBandStretcher;
38 }
34 39
35 class Model; 40 class Model;
36 class ViewManager; 41 class ViewManager;
37 class AudioGenerator; 42 class AudioGenerator;
38 class PlayParameters; 43 class PlayParameters;
39 class PhaseVocoderTimeStretcher;
40 class RealTimePluginInstance; 44 class RealTimePluginInstance;
45 class AudioCallbackPlayTarget;
41 46
42 /** 47 /**
43 * AudioCallbackPlaySource manages audio data supply to callback-based 48 * AudioCallbackPlaySource manages audio data supply to callback-based
44 * 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
45 * per channel, filled during playback by a non-realtime thread, and 50 * per channel, filled during playback by a non-realtime thread, and
93 /** 98 /**
94 * Return the frame number that is currently expected to be coming 99 * Return the frame number that is currently expected to be coming
95 * out of the speakers. (i.e. compensating for playback latency.) 100 * out of the speakers. (i.e. compensating for playback latency.)
96 */ 101 */
97 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();
98 109
99 /** 110 /**
100 * 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).
101 */ 112 */
102 virtual size_t getPlayEndFrame() { return m_lastModelEndFrame; } 113 virtual size_t getPlayEndFrame() { return m_lastModelEndFrame; }
103 114
104 /** 115 /**
105 * Set the block size of the target audio device. This should 116 * Set the target and the block size of the target audio device.
106 * be called by the target class. 117 * This should be called by the target class.
107 */ 118 */
108 void setTargetBlockSize(size_t); 119 void setTarget(AudioCallbackPlayTarget *, size_t blockSize);
109 120
110 /** 121 /**
111 * 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.
112 */ 126 */
113 size_t getTargetBlockSize() const; 127 size_t getTargetBlockSize() const;
114 128
115 /** 129 /**
116 * Set the playback latency of the target audio device, in frames 130 * Set the playback latency of the target audio device, in frames
183 * realtime thread. 197 * realtime thread.
184 */ 198 */
185 size_t getSourceSamples(size_t count, float **buffer); 199 size_t getSourceSamples(size_t count, float **buffer);
186 200
187 /** 201 /**
188 * Set the time stretcher factor (i.e. playback speed). Also 202 * Set the time stretcher factor (i.e. playback speed).
189 * specify whether the time stretcher will be variable rate 203 */
190 * (sharpening transients), and whether time stretching will be 204 void setTimeStretch(float factor);
191 * carried out on data mixed down to mono for speed.
192 */
193 void setTimeStretch(float factor, bool sharpen, bool mono);
194 205
195 /** 206 /**
196 * 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
197 * highest quality. 208 * highest quality.
198 */ 209 */
272 size_t m_sourceChannelCount; 283 size_t m_sourceChannelCount;
273 size_t m_blockSize; 284 size_t m_blockSize;
274 size_t m_sourceSampleRate; 285 size_t m_sourceSampleRate;
275 size_t m_targetSampleRate; 286 size_t m_targetSampleRate;
276 size_t m_playLatency; 287 size_t m_playLatency;
288 AudioCallbackPlayTarget *m_target;
289 double m_lastRetrievalTimestamp;
290 size_t m_lastRetrievedBlockSize;
277 bool m_playing; 291 bool m_playing;
278 bool m_exiting; 292 bool m_exiting;
279 size_t m_lastModelEndFrame; 293 size_t m_lastModelEndFrame;
280 static const size_t m_ringBufferSize; 294 static const size_t m_ringBufferSize;
281 float m_outputLeft; 295 float m_outputLeft;
282 float m_outputRight; 296 float m_outputRight;
283 RealTimePluginInstance *m_auditioningPlugin; 297 RealTimePluginInstance *m_auditioningPlugin;
284 bool m_auditioningPluginBypassed; 298 bool m_auditioningPluginBypassed;
285 Scavenger<RealTimePluginInstance> m_pluginScavenger; 299 Scavenger<RealTimePluginInstance> m_pluginScavenger;
300 size_t m_playStartFrame;
301 bool m_playStartFramePassed;
302 RealTime m_playStartedAt;
286 303
287 RingBuffer<float> *getWriteRingBuffer(size_t c) { 304 RingBuffer<float> *getWriteRingBuffer(size_t c) {
288 if (m_writeBuffers && c < m_writeBuffers->size()) { 305 if (m_writeBuffers && c < m_writeBuffers->size()) {
289 return (*m_writeBuffers)[c]; 306 return (*m_writeBuffers)[c];
290 } else { 307 } else {
302 } 319 }
303 320
304 void clearRingBuffers(bool haveLock = false, size_t count = 0); 321 void clearRingBuffers(bool haveLock = false, size_t count = 0);
305 void unifyRingBuffers(); 322 void unifyRingBuffers();
306 323
307 PhaseVocoderTimeStretcher *m_timeStretcher; 324 RubberBand::RubberBandStretcher *m_timeStretcher;
308 Scavenger<PhaseVocoderTimeStretcher> m_timeStretcherScavenger; 325 float m_stretchRatio;
326
327 size_t m_stretcherInputCount;
328 float **m_stretcherInputs;
329 size_t *m_stretcherInputSizes;
309 330
310 // Called from fill thread, m_playing true, mutex held 331 // Called from fill thread, m_playing true, mutex held
311 // Return true if work done 332 // Return true if work done
312 bool fillBuffers(); 333 bool fillBuffers();
313 334
317 // frame argument passed in, in the case of looping). 338 // frame argument passed in, in the case of looping).
318 size_t mixModels(size_t &frame, size_t count, float **buffers); 339 size_t mixModels(size_t &frame, size_t count, float **buffers);
319 340
320 // Called from getSourceSamples. 341 // Called from getSourceSamples.
321 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);
322 350
323 class FillThread : public Thread 351 class FillThread : public Thread
324 { 352 {
325 public: 353 public:
326 FillThread(AudioCallbackPlaySource &source) : 354 FillThread(AudioCallbackPlaySource &source) :