svapp
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2006 Chris Cannam and QMUL. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 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 ViewManagerBase; 00042 class AudioGenerator; 00043 class PlayParameters; 00044 class RealTimePluginInstance; 00045 class AudioCallbackPlayTarget; 00046 00054 class AudioCallbackPlaySource : public QObject, 00055 public AudioPlaySource 00056 { 00057 Q_OBJECT 00058 00059 public: 00060 AudioCallbackPlaySource(ViewManagerBase *, 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(int startFrame); 00087 00091 virtual void stop(); 00092 00096 virtual bool isPlaying() const { return m_playing; } 00097 00102 virtual int getCurrentPlayingFrame(); 00103 00108 virtual int getCurrentBufferedFrame(); 00109 00113 virtual int getPlayEndFrame() { return m_lastModelEndFrame; } 00114 00119 void setTarget(AudioCallbackPlayTarget *, int blockSize); 00120 00127 int getTargetBlockSize() const; 00128 00136 void setTargetPlayLatency(int); 00137 00141 int getTargetPlayLatency() const; 00142 00150 void setTargetSampleRate(int); 00151 00156 virtual int getTargetSampleRate() const; 00157 00162 void setOutputLevels(float left, float right); 00163 00168 virtual bool getOutputLevels(float &left, float &right); 00169 00175 int getSourceChannelCount() const; 00176 00185 int getTargetChannelCount() const; 00186 00192 virtual int getSourceSampleRate() const; 00193 00199 int getSourceSamples(int count, float **buffer); 00200 00204 void setTimeStretch(float factor); 00205 00210 void setResampleQuality(int q); 00211 00227 void setAuditioningEffect(Auditionable *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(int requested, int available, bool willResample); 00248 00249 void audioOverloadPluginDisabled(); 00250 void audioTimeStretchMultiChannelDisabled(); 00251 00252 void activity(QString); 00253 00254 public slots: 00255 void audioProcessingOverload(); 00256 00257 protected slots: 00258 void selectionChanged(); 00259 void playLoopModeChanged(); 00260 void playSelectionModeChanged(); 00261 void playParametersChanged(PlayParameters *); 00262 void preferenceChanged(PropertyContainer::PropertyName); 00263 void modelChangedWithin(int startFrame, int endFrame); 00264 00265 protected: 00266 ViewManagerBase *m_viewManager; 00267 AudioGenerator *m_audioGenerator; 00268 QString m_clientName; 00269 00270 class RingBufferVector : public std::vector<RingBuffer<float> *> { 00271 public: 00272 virtual ~RingBufferVector() { 00273 while (!empty()) { 00274 delete *begin(); 00275 erase(begin()); 00276 } 00277 } 00278 }; 00279 00280 std::set<Model *> m_models; 00281 RingBufferVector *m_readBuffers; 00282 RingBufferVector *m_writeBuffers; 00283 int m_readBufferFill; 00284 int m_writeBufferFill; 00285 Scavenger<RingBufferVector> m_bufferScavenger; 00286 int m_sourceChannelCount; 00287 int m_blockSize; 00288 int m_sourceSampleRate; 00289 int m_targetSampleRate; 00290 int m_playLatency; 00291 AudioCallbackPlayTarget *m_target; 00292 double m_lastRetrievalTimestamp; 00293 int m_lastRetrievedBlockSize; 00294 bool m_trustworthyTimestamps; 00295 int m_lastCurrentFrame; 00296 bool m_playing; 00297 bool m_exiting; 00298 int m_lastModelEndFrame; 00299 int m_ringBufferSize; 00300 float m_outputLeft; 00301 float m_outputRight; 00302 RealTimePluginInstance *m_auditioningPlugin; 00303 bool m_auditioningPluginBypassed; 00304 Scavenger<RealTimePluginInstance> m_pluginScavenger; 00305 int m_playStartFrame; 00306 bool m_playStartFramePassed; 00307 RealTime m_playStartedAt; 00308 00309 RingBuffer<float> *getWriteRingBuffer(int c) { 00310 if (m_writeBuffers && c < (int)m_writeBuffers->size()) { 00311 return (*m_writeBuffers)[c]; 00312 } else { 00313 return 0; 00314 } 00315 } 00316 00317 RingBuffer<float> *getReadRingBuffer(int c) { 00318 RingBufferVector *rb = m_readBuffers; 00319 if (rb && c < (int)rb->size()) { 00320 return (*rb)[c]; 00321 } else { 00322 return 0; 00323 } 00324 } 00325 00326 void clearRingBuffers(bool haveLock = false, int count = 0); 00327 void unifyRingBuffers(); 00328 00329 RubberBand::RubberBandStretcher *m_timeStretcher; 00330 RubberBand::RubberBandStretcher *m_monoStretcher; 00331 float m_stretchRatio; 00332 bool m_stretchMono; 00333 00334 int m_stretcherInputCount; 00335 float **m_stretcherInputs; 00336 int *m_stretcherInputSizes; 00337 00338 // Called from fill thread, m_playing true, mutex held 00339 // Return true if work done 00340 bool fillBuffers(); 00341 00342 // Called from fillBuffers. Return the number of frames written, 00343 // which will be count or fewer. Return in the frame argument the 00344 // new buffered frame position (which may be earlier than the 00345 // frame argument passed in, in the case of looping). 00346 int mixModels(int &frame, int count, float **buffers); 00347 00348 // Called from getSourceSamples. 00349 void applyAuditioningEffect(int count, float **buffers); 00350 00351 // Ranges of current selections, if play selection is active 00352 std::vector<RealTime> m_rangeStarts; 00353 std::vector<RealTime> m_rangeDurations; 00354 void rebuildRangeLists(); 00355 00356 int getCurrentFrame(RealTime outputLatency); 00357 00358 class FillThread : public Thread 00359 { 00360 public: 00361 FillThread(AudioCallbackPlaySource &source) : 00362 Thread(Thread::NonRTThread), 00363 m_source(source) { } 00364 00365 virtual void run(); 00366 00367 protected: 00368 AudioCallbackPlaySource &m_source; 00369 }; 00370 00371 QMutex m_mutex; 00372 QWaitCondition m_condition; 00373 FillThread *m_fillThread; 00374 SRC_STATE *m_converter; 00375 SRC_STATE *m_crapConverter; // for use when playing very fast 00376 int m_resampleQuality; 00377 void initialiseConverter(); 00378 }; 00379 00380 #endif 00381 00382