AudioCallbackPlaySource.h

Go to the documentation of this file.
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 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     // Called from fill thread, m_playing true, mutex held
00332     // Return true if work done
00333     bool fillBuffers();
00334     
00335     // Called from fillBuffers.  Return the number of frames written,
00336     // which will be count or fewer.  Return in the frame argument the
00337     // new buffered frame position (which may be earlier than the
00338     // frame argument passed in, in the case of looping).
00339     size_t mixModels(size_t &frame, size_t count, float **buffers);
00340 
00341     // Called from getSourceSamples.
00342     void applyAuditioningEffect(size_t count, float **buffers);
00343 
00344     // Ranges of current selections, if play selection is active
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; // for use when playing very fast
00369     int m_resampleQuality;
00370     void initialiseConverter();
00371 };
00372 
00373 #endif
00374 
00375 

Generated on Wed Feb 20 15:45:24 2008 for SonicVisualiser by  doxygen 1.5.1