annotate audio/AudioGenerator.h @ 736:4b58b8f44be7

If a file that looks like audio can't be opened as audio, fail immediately - don't go trying to open .wav files or whatever as sessions or annotations. That only means the error shown to the user is less helpful.
author Chris Cannam
date Wed, 05 Feb 2020 10:45:03 +0000
parents 161063152ddd
children
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@616 16 #ifndef SV_AUDIO_GENERATOR_H
Chris@616 17 #define SV_AUDIO_GENERATOR_H
Chris@43 18
Chris@43 19 class NoteModel;
matthiasm@281 20 class FlexiNoteModel;
Chris@43 21 class DenseTimeValueModel;
Chris@43 22 class SparseOneDimensionalModel;
Chris@108 23 class Playable;
Chris@307 24 class ClipMixer;
Chris@313 25 class ContinuousSynth;
Chris@43 26
Chris@43 27 #include <QObject>
Chris@43 28 #include <QMutex>
Chris@43 29
Chris@43 30 #include <set>
Chris@43 31 #include <map>
Chris@275 32 #include <vector>
Chris@43 33
Chris@436 34 #include "base/BaseTypes.h"
Chris@616 35 #include "data/model/Model.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@682 51 virtual bool addModel(ModelId model);
Chris@43 52
Chris@43 53 /**
Chris@43 54 * Remove a model.
Chris@43 55 */
Chris@682 56 virtual void removeModel(ModelId 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@682 84 virtual sv_frame_t mixModel(ModelId model,
Chris@613 85 sv_frame_t startFrame,
Chris@613 86 sv_frame_t frameCount,
Chris@613 87 float **buffer,
Chris@613 88 sv_frame_t fadeIn = 0,
Chris@613 89 sv_frame_t fadeOut = 0);
Chris@43 90
Chris@43 91 /**
Chris@43 92 * Specify that only the given set of models should be played.
Chris@43 93 */
Chris@682 94 virtual void setSoloModelSet(std::set<ModelId>s);
Chris@43 95
Chris@43 96 /**
Chris@43 97 * Specify that all models should be played as normal (if not
Chris@43 98 * muted).
Chris@43 99 */
Chris@43 100 virtual void clearSoloModelSet();
Chris@43 101
Chris@43 102 protected slots:
Chris@682 103 void playClipIdChanged(int playableId, QString);
Chris@43 104
Chris@43 105 protected:
Chris@436 106 sv_samplerate_t m_sourceSampleRate;
Chris@366 107 int m_targetChannelCount;
Chris@366 108 int m_waveType;
Chris@43 109
Chris@43 110 bool m_soloing;
Chris@682 111 std::set<ModelId> m_soloModelSet;
Chris@43 112
Chris@43 113 struct NoteOff {
Chris@43 114
Chris@615 115 NoteOff(float _freq, sv_frame_t _offFrame, sv_frame_t _onFrame) :
Chris@615 116 frequency(_freq), offFrame(_offFrame), onFrame(_onFrame) { }
Chris@275 117
Chris@308 118 float frequency;
Chris@615 119 sv_frame_t offFrame;
Chris@615 120
Chris@615 121 // This is the frame at which the note whose note-off appears
Chris@615 122 // here began. It is used to determine when we should silence
Chris@615 123 // a note because the playhead has jumped back in time - if
Chris@615 124 // the current frame for rendering is earlier than this one,
Chris@615 125 // then we should end and discard the note
Chris@615 126 //
Chris@615 127 sv_frame_t onFrame;
Chris@43 128
Chris@595 129 struct Comparator {
Chris@595 130 bool operator()(const NoteOff &n1, const NoteOff &n2) const {
Chris@615 131 if (n1.offFrame != n2.offFrame) {
Chris@615 132 return n1.offFrame < n2.offFrame;
Chris@615 133 } else if (n1.onFrame != n2.onFrame) {
Chris@615 134 return n1.onFrame < n2.onFrame;
Chris@615 135 } else {
Chris@615 136 return n1.frequency < n2.frequency;
Chris@615 137 }
Chris@595 138 }
Chris@595 139 };
Chris@43 140 };
Chris@43 141
Chris@307 142
Chris@682 143 typedef std::map<ModelId, ClipMixer *> ClipMixerMap;
Chris@43 144
Chris@178 145 typedef std::multiset<NoteOff, NoteOff::Comparator> NoteOffSet;
Chris@682 146 typedef std::map<ModelId, NoteOffSet> NoteOffMap;
Chris@43 147
Chris@682 148 typedef std::map<ModelId, ContinuousSynth *> ContinuousSynthMap;
Chris@313 149
Chris@43 150 QMutex m_mutex;
Chris@313 151
Chris@307 152 ClipMixerMap m_clipMixerMap;
Chris@43 153 NoteOffMap m_noteOffs;
Chris@43 154 static QString m_sampleDir;
Chris@43 155
Chris@313 156 ContinuousSynthMap m_continuousSynthMap;
Chris@313 157
Chris@682 158 bool usesClipMixer(ModelId);
Chris@682 159 bool wantsQuieterClips(ModelId);
Chris@682 160 bool usesContinuousSynth(ModelId);
Chris@313 161
Chris@682 162 ClipMixer *makeClipMixerFor(ModelId model);
Chris@682 163 ContinuousSynth *makeSynthFor(ModelId model);
Chris@307 164
Chris@108 165 static void initialiseSampleDir();
Chris@43 166
Chris@436 167 virtual sv_frame_t mixDenseTimeValueModel
Chris@682 168 (ModelId model, sv_frame_t startFrame, sv_frame_t frameCount,
Chris@436 169 float **buffer, float gain, float pan, sv_frame_t fadeIn, sv_frame_t fadeOut);
Chris@43 170
Chris@436 171 virtual sv_frame_t mixClipModel
Chris@682 172 (ModelId model, sv_frame_t startFrame, sv_frame_t frameCount,
Chris@313 173 float **buffer, float gain, float pan);
Chris@313 174
Chris@436 175 virtual sv_frame_t mixContinuousSynthModel
Chris@682 176 (ModelId model, sv_frame_t startFrame, sv_frame_t frameCount,
Chris@313 177 float **buffer, float gain, float pan);
Chris@275 178
Chris@436 179 static const sv_frame_t m_processingBlockSize;
Chris@382 180
Chris@382 181 float **m_channelBuffer;
Chris@436 182 sv_frame_t m_channelBufSiz;
Chris@382 183 int m_channelBufCount;
Chris@43 184 };
Chris@43 185
Chris@43 186 #endif
Chris@43 187