Mercurial > hg > svapp
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) : |