comparison audio/AudioCallbackPlaySource.h @ 746:771ec060c1d2

Merge from branch audio-source-refactor. Pull out auditioning effect wrapper and time stretch wrapper from play source; corresponding changes to plugin memory management etc.
author Chris Cannam
date Fri, 03 Apr 2020 12:14:05 +0100
parents 6508d9d216c7
children eae885290abc
comparison
equal deleted inserted replaced
743:7b1d30af4b38 746:771ec060c1d2
34 #include <samplerate.h> 34 #include <samplerate.h>
35 35
36 #include <set> 36 #include <set>
37 #include <map> 37 #include <map>
38 38
39 namespace RubberBand {
40 class RubberBandStretcher;
41 }
42
43 namespace breakfastquay { 39 namespace breakfastquay {
44 class ResamplerWrapper; 40 class ResamplerWrapper;
45 } 41 }
46 42
47 class Model; 43 class Model;
48 class ViewManagerBase; 44 class ViewManagerBase;
49 class AudioGenerator; 45 class AudioGenerator;
50 class PlayParameters; 46 class PlayParameters;
51 class RealTimePluginInstance; 47 class RealTimePluginInstance;
52 class AudioCallbackPlayTarget; 48 class AudioCallbackPlayTarget;
49 class TimeStretchWrapper;
50 class EffectWrapper;
53 51
54 /** 52 /**
55 * AudioCallbackPlaySource manages audio data supply to callback-based 53 * AudioCallbackPlaySource manages audio data supply to callback-based
56 * audio APIs such as JACK or CoreAudio. It maintains one ring buffer 54 * audio APIs such as JACK or CoreAudio. It maintains one ring buffer
57 * per channel, filled during playback by a non-realtime thread, and 55 * per channel, filled during playback by a non-realtime thread, and
65 Q_OBJECT 63 Q_OBJECT
66 64
67 public: 65 public:
68 AudioCallbackPlaySource(ViewManagerBase *, QString clientName); 66 AudioCallbackPlaySource(ViewManagerBase *, QString clientName);
69 virtual ~AudioCallbackPlaySource(); 67 virtual ~AudioCallbackPlaySource();
68
69 /**
70 * Return an ApplicationPlaybackSource interface to this
71 * class. Although this class implements ApplicationPlaybackSource
72 * itself, the object returned here may be a wrapper which
73 * provides facilities not implemented in this class, such as
74 * time-stretching, resampling, and an auditioning effect. The
75 * returned pointer points to an object which is owned by this
76 * object. Caller must ensure the lifetime of this object exceeds
77 * the scope which the returned pointer is retained.
78 */
79 breakfastquay::ApplicationPlaybackSource *getApplicationPlaybackSource();
70 80
71 /** 81 /**
72 * Add a data model to be played from. The source can mix 82 * Add a data model to be played from. The source can mix
73 * playback from a number of sources including dense and sparse 83 * playback from a number of sources including dense and sparse
74 * models. The models must match in sample rate, but they don't 84 * models. The models must match in sample rate, but they don't
122 132
123 /** 133 /**
124 * Set the playback target. 134 * Set the playback target.
125 */ 135 */
126 virtual void setSystemPlaybackTarget(breakfastquay::SystemPlaybackTarget *); 136 virtual void setSystemPlaybackTarget(breakfastquay::SystemPlaybackTarget *);
127
128 /**
129 * Set the resampler wrapper, if one is in use.
130 */
131 virtual void setResamplerWrapper(breakfastquay::ResamplerWrapper *);
132 137
133 /** 138 /**
134 * Set the block size of the target audio device. This should be 139 * Set the block size of the target audio device. This should be
135 * called by the target class. 140 * called by the target class.
136 */ 141 */
286 * setAuditioningEffect (depending on real-time constraints). 291 * setAuditioningEffect (depending on real-time constraints).
287 * 292 *
288 * Pass a null pointer to remove the current auditioning plugin, 293 * Pass a null pointer to remove the current auditioning plugin,
289 * if any. 294 * if any.
290 */ 295 */
291 virtual void setAuditioningEffect(Auditionable *plugin) override; 296 virtual void setAuditioningEffect(std::shared_ptr<Auditionable> plugin)
297 override;
292 298
293 /** 299 /**
294 * Specify that only the given set of models should be played. 300 * Specify that only the given set of models should be played.
295 */ 301 */
296 void setSoloModelSet(std::set<ModelId>s); 302 void setSoloModelSet(std::set<ModelId>s);
313 bool willResample); 319 bool willResample);
314 320
315 void channelCountIncreased(int count); // target channel count (see getTargetChannelCount()) 321 void channelCountIncreased(int count); // target channel count (see getTargetChannelCount())
316 322
317 void audioOverloadPluginDisabled(); 323 void audioOverloadPluginDisabled();
318 void audioTimeStretchMultiChannelDisabled();
319 324
320 void activity(QString); 325 void activity(QString);
321 326
322 public slots: 327 public slots:
323 void audioProcessingOverload() override; 328 void audioProcessingOverload() override;
367 sv_frame_t m_lastModelEndFrame; 372 sv_frame_t m_lastModelEndFrame;
368 int m_ringBufferSize; 373 int m_ringBufferSize;
369 float m_outputLeft; 374 float m_outputLeft;
370 float m_outputRight; 375 float m_outputRight;
371 bool m_levelsSet; 376 bool m_levelsSet;
372 RealTimePluginInstance *m_auditioningPlugin;
373 bool m_auditioningPluginBypassed;
374 bool m_auditioningPluginFailed;
375 Scavenger<RealTimePluginInstance> m_pluginScavenger; 377 Scavenger<RealTimePluginInstance> m_pluginScavenger;
376 sv_frame_t m_playStartFrame; 378 sv_frame_t m_playStartFrame;
377 bool m_playStartFramePassed; 379 bool m_playStartFramePassed;
378 RealTime m_playStartedAt; 380 RealTime m_playStartedAt;
379 381
395 } 397 }
396 398
397 void clearRingBuffers(bool haveLock = false, int count = 0); 399 void clearRingBuffers(bool haveLock = false, int count = 0);
398 void unifyRingBuffers(); 400 void unifyRingBuffers();
399 401
400 RubberBand::RubberBandStretcher *m_timeStretcher;
401 RubberBand::RubberBandStretcher *m_monoStretcher;
402 double m_stretchRatio;
403 bool m_stretchMono;
404
405 int m_stretcherInputCount;
406 float **m_stretcherInputs;
407 sv_frame_t *m_stretcherInputSizes;
408
409 // Called from fill thread, m_playing true, mutex held 402 // Called from fill thread, m_playing true, mutex held
410 // Return true if work done 403 // Return true if work done
411 bool fillBuffers(); 404 bool fillBuffers();
412 405
413 // Called from fillBuffers. Return the number of frames written, 406 // Called from fillBuffers. Return the number of frames written,
414 // which will be count or fewer. Return in the frame argument the 407 // which will be count or fewer. Return in the frame argument the
415 // new buffered frame position (which may be earlier than the 408 // new buffered frame position (which may be earlier than the
416 // frame argument passed in, in the case of looping). 409 // frame argument passed in, in the case of looping).
417 sv_frame_t mixModels(sv_frame_t &frame, sv_frame_t count, float **buffers); 410 sv_frame_t mixModels(sv_frame_t &frame, sv_frame_t count, float **buffers);
418
419 // Called from getSourceSamples.
420 void applyAuditioningEffect(sv_frame_t count, float *const *buffers);
421 411
422 // Ranges of current selections, if play selection is active 412 // Ranges of current selections, if play selection is active
423 std::vector<RealTime> m_rangeStarts; 413 std::vector<RealTime> m_rangeStarts;
424 std::vector<RealTime> m_rangeDurations; 414 std::vector<RealTime> m_rangeDurations;
425 void rebuildRangeLists(); 415 void rebuildRangeLists();
440 }; 430 };
441 431
442 QMutex m_mutex; 432 QMutex m_mutex;
443 QWaitCondition m_condition; 433 QWaitCondition m_condition;
444 FillThread *m_fillThread; 434 FillThread *m_fillThread;
445 breakfastquay::ResamplerWrapper *m_resamplerWrapper; // I don't own this 435 breakfastquay::ResamplerWrapper *m_resamplerWrapper;
436 TimeStretchWrapper *m_timeStretchWrapper;
437 EffectWrapper *m_auditioningEffectWrapper;
438 void checkWrappers();
446 }; 439 };
447 440
448 #endif 441 #endif
449 442
450