00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _AUDIO_CALLBACK_PLAY_SOURCE_H_
00017 #define _AUDIO_CALLBACK_PLAY_SOURCE_H_
00018
00019 #include "base/RingBuffer.h"
00020 #include "base/AudioPlaySource.h"
00021 #include "base/PropertyContainer.h"
00022 #include "base/Scavenger.h"
00023
00024 #include <QObject>
00025 #include <QMutex>
00026 #include <QWaitCondition>
00027
00028 #include "base/Thread.h"
00029 #include "base/RealTime.h"
00030
00031 #include <samplerate.h>
00032
00033 #include <set>
00034 #include <map>
00035
00036 namespace RubberBand {
00037 class RubberBandStretcher;
00038 }
00039
00040 class Model;
00041 class ViewManager;
00042 class AudioGenerator;
00043 class PlayParameters;
00044 class RealTimePluginInstance;
00045 class AudioCallbackPlayTarget;
00046
00054 class AudioCallbackPlaySource : public virtual QObject,
00055 public AudioPlaySource
00056 {
00057 Q_OBJECT
00058
00059 public:
00060 AudioCallbackPlaySource(ViewManager *, QString clientName);
00061 virtual ~AudioCallbackPlaySource();
00062
00069 virtual void addModel(Model *model);
00070
00074 virtual void removeModel(Model *model);
00075
00079 virtual void clearModels();
00080
00086 virtual void play(size_t startFrame);
00087
00091 virtual void stop();
00092
00096 virtual bool isPlaying() const { return m_playing; }
00097
00102 virtual size_t getCurrentPlayingFrame();
00103
00108 virtual size_t getCurrentBufferedFrame();
00109
00113 virtual size_t getPlayEndFrame() { return m_lastModelEndFrame; }
00114
00119 void setTarget(AudioCallbackPlayTarget *, size_t blockSize);
00120
00127 size_t getTargetBlockSize() const;
00128
00136 void setTargetPlayLatency(size_t);
00137
00141 size_t getTargetPlayLatency() const;
00142
00150 void setTargetSampleRate(size_t);
00151
00156 virtual size_t getTargetSampleRate() const;
00157
00162 void setOutputLevels(float left, float right);
00163
00168 virtual bool getOutputLevels(float &left, float &right);
00169
00175 size_t getSourceChannelCount() const;
00176
00185 size_t getTargetChannelCount() const;
00186
00192 virtual size_t getSourceSampleRate() const;
00193
00199 size_t getSourceSamples(size_t count, float **buffer);
00200
00204 void setTimeStretch(float factor);
00205
00210 void setResampleQuality(int q);
00211
00227 void setAuditioningPlugin(RealTimePluginInstance *plugin);
00228
00232 void setSoloModelSet(std::set<Model *>s);
00233
00238 void clearSoloModelSet();
00239
00240 QString getClientName() const { return m_clientName; }
00241
00242 signals:
00243 void modelReplaced();
00244
00245 void playStatusChanged(bool isPlaying);
00246
00247 void sampleRateMismatch(size_t requested, size_t available, bool willResample);
00248
00249 void audioOverloadPluginDisabled();
00250
00251 public slots:
00252 void audioProcessingOverload();
00253
00254 protected slots:
00255 void selectionChanged();
00256 void playLoopModeChanged();
00257 void playSelectionModeChanged();
00258 void playParametersChanged(PlayParameters *);
00259 void preferenceChanged(PropertyContainer::PropertyName);
00260 void modelChanged(size_t startFrame, size_t endFrame);
00261
00262 protected:
00263 ViewManager *m_viewManager;
00264 AudioGenerator *m_audioGenerator;
00265 QString m_clientName;
00266
00267 class RingBufferVector : public std::vector<RingBuffer<float> *> {
00268 public:
00269 virtual ~RingBufferVector() {
00270 while (!empty()) {
00271 delete *begin();
00272 erase(begin());
00273 }
00274 }
00275 };
00276
00277 std::set<Model *> m_models;
00278 RingBufferVector *m_readBuffers;
00279 RingBufferVector *m_writeBuffers;
00280 size_t m_readBufferFill;
00281 size_t m_writeBufferFill;
00282 Scavenger<RingBufferVector> m_bufferScavenger;
00283 size_t m_sourceChannelCount;
00284 size_t m_blockSize;
00285 size_t m_sourceSampleRate;
00286 size_t m_targetSampleRate;
00287 size_t m_playLatency;
00288 AudioCallbackPlayTarget *m_target;
00289 double m_lastRetrievalTimestamp;
00290 size_t m_lastRetrievedBlockSize;
00291 bool m_playing;
00292 bool m_exiting;
00293 size_t m_lastModelEndFrame;
00294 static const size_t m_ringBufferSize;
00295 float m_outputLeft;
00296 float m_outputRight;
00297 RealTimePluginInstance *m_auditioningPlugin;
00298 bool m_auditioningPluginBypassed;
00299 Scavenger<RealTimePluginInstance> m_pluginScavenger;
00300 size_t m_playStartFrame;
00301 bool m_playStartFramePassed;
00302 RealTime m_playStartedAt;
00303
00304 RingBuffer<float> *getWriteRingBuffer(size_t c) {
00305 if (m_writeBuffers && c < m_writeBuffers->size()) {
00306 return (*m_writeBuffers)[c];
00307 } else {
00308 return 0;
00309 }
00310 }
00311
00312 RingBuffer<float> *getReadRingBuffer(size_t c) {
00313 RingBufferVector *rb = m_readBuffers;
00314 if (rb && c < rb->size()) {
00315 return (*rb)[c];
00316 } else {
00317 return 0;
00318 }
00319 }
00320
00321 void clearRingBuffers(bool haveLock = false, size_t count = 0);
00322 void unifyRingBuffers();
00323
00324 RubberBand::RubberBandStretcher *m_timeStretcher;
00325 float m_stretchRatio;
00326
00327 size_t m_stretcherInputCount;
00328 float **m_stretcherInputs;
00329 size_t *m_stretcherInputSizes;
00330
00331
00332
00333 bool fillBuffers();
00334
00335
00336
00337
00338
00339 size_t mixModels(size_t &frame, size_t count, float **buffers);
00340
00341
00342 void applyAuditioningEffect(size_t count, float **buffers);
00343
00344
00345 std::vector<RealTime> m_rangeStarts;
00346 std::vector<RealTime> m_rangeDurations;
00347 void rebuildRangeLists();
00348
00349 size_t getCurrentFrame(RealTime outputLatency);
00350
00351 class FillThread : public Thread
00352 {
00353 public:
00354 FillThread(AudioCallbackPlaySource &source) :
00355 Thread(Thread::NonRTThread),
00356 m_source(source) { }
00357
00358 virtual void run();
00359
00360 protected:
00361 AudioCallbackPlaySource &m_source;
00362 };
00363
00364 QMutex m_mutex;
00365 QWaitCondition m_condition;
00366 FillThread *m_fillThread;
00367 SRC_STATE *m_converter;
00368 SRC_STATE *m_crapConverter;
00369 int m_resampleQuality;
00370 void initialiseConverter();
00371 };
00372
00373 #endif
00374
00375