annotate audio/AudioGenerator.h @ 570:6f54789f3127 3.0-integration

Fix race condition in first-time recording, where adding the recording wave model would prompt the audio play source to note that its channel count had increased (from 0 to, say, 2) and thus to cause the audio device to be reopened, stopping recording. Fix is to make this only happen if channel count increases beyond that of the device, which shouldn't happen in the recording case
author Chris Cannam
date Wed, 04 Jan 2017 11:48:03 +0000
parents 56acd9368532
children b23bebfdfaba
rev   line source
Chris@43 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@43 2
Chris@43 3 /*
Chris@43 4 Sonic Visualiser
Chris@43 5 An audio file viewer and annotation editor.
Chris@43 6 Centre for Digital Music, Queen Mary, University of London.
Chris@43 7 This file copyright 2006 Chris Cannam.
Chris@43 8
Chris@43 9 This program is free software; you can redistribute it and/or
Chris@43 10 modify it under the terms of the GNU General Public License as
Chris@43 11 published by the Free Software Foundation; either version 2 of the
Chris@43 12 License, or (at your option) any later version. See the file
Chris@43 13 COPYING included with this distribution for more information.
Chris@43 14 */
Chris@43 15
Chris@43 16 #ifndef _AUDIO_GENERATOR_H_
Chris@43 17 #define _AUDIO_GENERATOR_H_
Chris@43 18
Chris@43 19 class Model;
Chris@43 20 class NoteModel;
matthiasm@281 21 class FlexiNoteModel;
Chris@43 22 class DenseTimeValueModel;
Chris@43 23 class SparseOneDimensionalModel;
Chris@108 24 class Playable;
Chris@307 25 class ClipMixer;
Chris@313 26 class ContinuousSynth;
Chris@43 27
Chris@43 28 #include <QObject>
Chris@43 29 #include <QMutex>
Chris@43 30
Chris@43 31 #include <set>
Chris@43 32 #include <map>
Chris@275 33 #include <vector>
Chris@43 34
Chris@436 35 #include "base/BaseTypes.h"
Chris@436 36
Chris@43 37 class AudioGenerator : public QObject
Chris@43 38 {
Chris@43 39 Q_OBJECT
Chris@43 40
Chris@43 41 public:
Chris@43 42 AudioGenerator();
Chris@43 43 virtual ~AudioGenerator();
Chris@43 44
Chris@43 45 /**
Chris@43 46 * Add a data model to be played from and initialise any necessary
Chris@43 47 * audio generation code. Returns true if the model will be
Chris@108 48 * played. The model will be added regardless of the return
Chris@108 49 * value.
Chris@43 50 */
Chris@43 51 virtual bool addModel(Model *model);
Chris@43 52
Chris@43 53 /**
Chris@43 54 * Remove a model.
Chris@43 55 */
Chris@43 56 virtual void removeModel(Model *model);
Chris@43 57
Chris@43 58 /**
Chris@43 59 * Remove all models.
Chris@43 60 */
Chris@43 61 virtual void clearModels();
Chris@43 62
Chris@43 63 /**
Chris@305 64 * Reset playback, clearing buffers and the like.
Chris@43 65 */
Chris@43 66 virtual void reset();
Chris@43 67
Chris@43 68 /**
Chris@43 69 * Set the target channel count. The buffer parameter to mixModel
Chris@43 70 * must always point to at least this number of arrays.
Chris@43 71 */
Chris@366 72 virtual void setTargetChannelCount(int channelCount);
Chris@43 73
Chris@43 74 /**
Chris@43 75 * Return the internal processing block size. The frameCount
Chris@43 76 * argument to all mixModel calls must be a multiple of this
Chris@43 77 * value.
Chris@43 78 */
Chris@436 79 virtual sv_frame_t getBlockSize() const;
Chris@43 80
Chris@43 81 /**
Chris@43 82 * Mix a single model into an output buffer.
Chris@43 83 */
Chris@436 84 virtual sv_frame_t mixModel(Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
Chris@436 85 float **buffer, sv_frame_t fadeIn = 0, sv_frame_t fadeOut = 0);
Chris@43 86
Chris@43 87 /**
Chris@43 88 * Specify that only the given set of models should be played.
Chris@43 89 */
Chris@43 90 virtual void setSoloModelSet(std::set<Model *>s);
Chris@43 91
Chris@43 92 /**
Chris@43 93 * Specify that all models should be played as normal (if not
Chris@43 94 * muted).
Chris@43 95 */
Chris@43 96 virtual void clearSoloModelSet();
Chris@43 97
Chris@43 98 protected slots:
Chris@309 99 void playClipIdChanged(const Playable *, QString);
Chris@43 100
Chris@43 101 protected:
Chris@436 102 sv_samplerate_t m_sourceSampleRate;
Chris@366 103 int m_targetChannelCount;
Chris@366 104 int m_waveType;
Chris@43 105
Chris@43 106 bool m_soloing;
Chris@43 107 std::set<Model *> m_soloModelSet;
Chris@43 108
Chris@43 109 struct NoteOff {
Chris@43 110
Chris@436 111 NoteOff(float _freq, sv_frame_t _frame) : frequency(_freq), frame(_frame) { }
Chris@275 112
Chris@308 113 float frequency;
Chris@436 114 sv_frame_t frame;
Chris@43 115
Chris@43 116 struct Comparator {
Chris@43 117 bool operator()(const NoteOff &n1, const NoteOff &n2) const {
Chris@43 118 return n1.frame < n2.frame;
Chris@43 119 }
Chris@43 120 };
Chris@43 121 };
Chris@43 122
Chris@307 123
Chris@307 124 typedef std::map<const Model *, ClipMixer *> ClipMixerMap;
Chris@43 125
Chris@178 126 typedef std::multiset<NoteOff, NoteOff::Comparator> NoteOffSet;
Chris@43 127 typedef std::map<const Model *, NoteOffSet> NoteOffMap;
Chris@43 128
Chris@313 129 typedef std::map<const Model *, ContinuousSynth *> ContinuousSynthMap;
Chris@313 130
Chris@43 131 QMutex m_mutex;
Chris@313 132
Chris@307 133 ClipMixerMap m_clipMixerMap;
Chris@43 134 NoteOffMap m_noteOffs;
Chris@43 135 static QString m_sampleDir;
Chris@43 136
Chris@313 137 ContinuousSynthMap m_continuousSynthMap;
Chris@313 138
Chris@313 139 bool usesClipMixer(const Model *);
Chris@349 140 bool wantsQuieterClips(const Model *);
Chris@313 141 bool usesContinuousSynth(const Model *);
Chris@313 142
Chris@307 143 ClipMixer *makeClipMixerFor(const Model *model);
Chris@313 144 ContinuousSynth *makeSynthFor(const Model *model);
Chris@307 145
Chris@108 146 static void initialiseSampleDir();
Chris@43 147
Chris@436 148 virtual sv_frame_t mixDenseTimeValueModel
Chris@436 149 (DenseTimeValueModel *model, sv_frame_t startFrame, sv_frame_t frameCount,
Chris@436 150 float **buffer, float gain, float pan, sv_frame_t fadeIn, sv_frame_t fadeOut);
Chris@43 151
Chris@436 152 virtual sv_frame_t mixClipModel
Chris@436 153 (Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
Chris@313 154 float **buffer, float gain, float pan);
Chris@313 155
Chris@436 156 virtual sv_frame_t mixContinuousSynthModel
Chris@436 157 (Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
Chris@313 158 float **buffer, float gain, float pan);
Chris@275 159
Chris@436 160 static const sv_frame_t m_processingBlockSize;
Chris@382 161
Chris@382 162 float **m_channelBuffer;
Chris@436 163 sv_frame_t m_channelBufSiz;
Chris@382 164 int m_channelBufCount;
Chris@43 165 };
Chris@43 166
Chris@43 167 #endif
Chris@43 168