annotate audio/EffectWrapper.cpp @ 740:846970dbef17 audio-source-refactor

Use shared_ptr for plugin instances throughout
author Chris Cannam
date Fri, 20 Mar 2020 16:31:58 +0000
parents ddfac001b543
children 54393ed09d65
rev   line source
Chris@739 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@739 2
Chris@739 3 /*
Chris@739 4 Sonic Visualiser
Chris@739 5 An audio file viewer and annotation editor.
Chris@739 6 Centre for Digital Music, Queen Mary, University of London.
Chris@739 7
Chris@739 8 This program is free software; you can redistribute it and/or
Chris@739 9 modify it under the terms of the GNU General Public License as
Chris@739 10 published by the Free Software Foundation; either version 2 of the
Chris@739 11 License, or (at your option) any later version. See the file
Chris@739 12 COPYING included with this distribution for more information.
Chris@739 13 */
Chris@739 14
Chris@739 15 #include "EffectWrapper.h"
Chris@739 16
Chris@739 17 #include <rubberband/RubberBandStretcher.h>
Chris@739 18
Chris@739 19 #include "base/Debug.h"
Chris@739 20
Chris@740 21 //#define DEBUG_EFFECT_WRAPPER 1
Chris@740 22
Chris@739 23 using namespace std;
Chris@739 24
Chris@739 25 static const int DEFAULT_RING_BUFFER_SIZE = 131071;
Chris@739 26
Chris@739 27 EffectWrapper::EffectWrapper(ApplicationPlaybackSource *source) :
Chris@739 28 m_source(source),
Chris@739 29 m_bypassed(false),
Chris@739 30 m_failed(false),
Chris@739 31 m_channelCount(0)
Chris@739 32 {
Chris@739 33 }
Chris@739 34
Chris@739 35 EffectWrapper::~EffectWrapper()
Chris@739 36 {
Chris@739 37 }
Chris@739 38
Chris@739 39 void
Chris@739 40 EffectWrapper::setEffect(weak_ptr<RealTimePluginInstance> effect)
Chris@739 41 {
Chris@739 42 lock_guard<mutex> guard(m_mutex);
Chris@739 43
Chris@740 44 #ifdef DEBUG_EFFECT_WRAPPER
Chris@740 45 SVCERR << "EffectWrapper[" << this
Chris@740 46 << "]::setEffect(" << effect.lock() << ")" << endl;
Chris@740 47 #endif
Chris@740 48
Chris@739 49 m_effect = effect;
Chris@739 50 m_failed = false;
Chris@739 51 }
Chris@739 52
Chris@739 53 void
Chris@739 54 EffectWrapper::setBypassed(bool bypassed)
Chris@739 55 {
Chris@739 56 lock_guard<mutex> guard(m_mutex);
Chris@739 57
Chris@740 58 #ifdef DEBUG_EFFECT_WRAPPER
Chris@740 59 SVCERR << "EffectWrapper[" << this
Chris@740 60 << "]::setBypassed(" << bypassed << ")" << endl;
Chris@740 61 #endif
Chris@740 62
Chris@739 63 m_bypassed = bypassed;
Chris@739 64 }
Chris@739 65
Chris@739 66 bool
Chris@739 67 EffectWrapper::isBypassed() const
Chris@739 68 {
Chris@739 69 lock_guard<mutex> guard(m_mutex);
Chris@739 70
Chris@739 71 return m_bypassed;
Chris@739 72 }
Chris@739 73
Chris@739 74 void
Chris@739 75 EffectWrapper::reset()
Chris@739 76 {
Chris@739 77 lock_guard<mutex> guard(m_mutex);
Chris@739 78
Chris@740 79 #ifdef DEBUG_EFFECT_WRAPPER
Chris@740 80 SVCERR << "EffectWrapper[" << this << "]::reset" << endl;
Chris@740 81 #endif
Chris@740 82
Chris@739 83 for (auto &rb: m_effectOutputBuffers) {
Chris@739 84 rb.reset();
Chris@739 85 }
Chris@740 86
Chris@740 87 m_failed = false;
Chris@739 88 }
Chris@739 89
Chris@739 90 int
Chris@739 91 EffectWrapper::getSourceSamples(float *const *samples,
Chris@739 92 int nchannels, int nframes)
Chris@739 93 {
Chris@739 94 lock_guard<mutex> guard(m_mutex);
Chris@739 95
Chris@740 96 #ifdef DEBUG_EFFECT_WRAPPER
Chris@740 97 SVCERR << "EffectWrapper[" << this << "]::getSourceSamples: " << nframes
Chris@740 98 << " frames across " << nchannels << " channels" << endl;
Chris@740 99 #endif
Chris@740 100
Chris@739 101 auto effect(m_effect.lock());
Chris@739 102
Chris@740 103 if (!effect) {
Chris@740 104 #ifdef DEBUG_EFFECT_WRAPPER
Chris@740 105 SVCERR << "EffectWrapper::getSourceSamples: "
Chris@740 106 << "no effect is set" << endl;
Chris@740 107 #endif
Chris@739 108 return m_source->getSourceSamples(samples, nchannels, nframes);
Chris@739 109 }
Chris@739 110
Chris@740 111 if (m_bypassed || m_failed) {
Chris@740 112 #ifdef DEBUG_EFFECT_WRAPPER
Chris@740 113 SVCERR << "EffectWrapper::getSourceSamples: "
Chris@740 114 << "effect is bypassed or has failed" << endl;
Chris@740 115 #endif
Chris@740 116 return m_source->getSourceSamples(samples, nchannels, nframes);
Chris@740 117 }
Chris@740 118
Chris@739 119 static int warnings = 0;
Chris@739 120 if (nchannels != m_channelCount) {
Chris@739 121 if (warnings >= 0) {
Chris@740 122 SVCERR << "WARNING: EffectWrapper::getSourceSamples called for a number of channels different from that set with setSystemPlaybackChannelCount ("
Chris@739 123 << nchannels << " vs " << m_channelCount << ")" << endl;
Chris@739 124 if (++warnings == 6) {
Chris@739 125 SVCERR << "(further warnings will be suppressed)" << endl;
Chris@739 126 warnings = -1;
Chris@739 127 }
Chris@739 128 }
Chris@739 129 return 0;
Chris@739 130 }
Chris@739 131
Chris@739 132 if ((int)effect->getAudioInputCount() != m_channelCount) {
Chris@739 133 if (!m_failed) {
Chris@739 134 SVCERR << "EffectWrapper::getSourceSamples: "
Chris@739 135 << "Can't run plugin: plugin input count "
Chris@739 136 << effect->getAudioInputCount()
Chris@739 137 << " != our channel count " << m_channelCount
Chris@739 138 << " (future errors for this plugin will be suppressed)"
Chris@739 139 << endl;
Chris@739 140 m_failed = true;
Chris@739 141 }
Chris@739 142 }
Chris@739 143 if ((int)effect->getAudioOutputCount() != m_channelCount) {
Chris@739 144 if (!m_failed) {
Chris@739 145 SVCERR << "EffectWrapper::getSourceSamples: "
Chris@739 146 << "Can't run plugin: plugin output count "
Chris@739 147 << effect->getAudioOutputCount()
Chris@739 148 << " != our channel count " << m_channelCount
Chris@739 149 << " (future errors for this plugin will be suppressed)"
Chris@739 150 << endl;
Chris@739 151 m_failed = true;
Chris@739 152 }
Chris@739 153 }
Chris@739 154
Chris@739 155 if (m_failed) {
Chris@739 156 return m_source->getSourceSamples(samples, nchannels, nframes);
Chris@739 157 }
Chris@739 158
Chris@739 159 float **ib = effect->getAudioInputBuffers();
Chris@739 160 float **ob = effect->getAudioOutputBuffers();
Chris@739 161 int blockSize = effect->getBufferSize();
Chris@739 162
Chris@739 163 int got = 0;
Chris@739 164
Chris@739 165 while (got < nframes) {
Chris@739 166
Chris@739 167 int read = 0;
Chris@739 168 for (int c = 0; c < nchannels; ++c) {
Chris@740 169 read = m_effectOutputBuffers[c].read(samples[c] + got,
Chris@740 170 nframes - got);
Chris@739 171 }
Chris@739 172
Chris@739 173 got += read;
Chris@739 174
Chris@739 175 if (got < nframes) {
Chris@739 176
Chris@739 177 int toRun = m_source->getSourceSamples(ib, nchannels, blockSize);
Chris@739 178 if (toRun <= 0) break;
Chris@739 179
Chris@740 180 #ifdef DEBUG_EFFECT_WRAPPER
Chris@740 181 SVCERR << "EffectWrapper::getSourceSamples: Running effect "
Chris@740 182 << "for " << toRun << " frames" << endl;
Chris@740 183 #endif
Chris@739 184 effect->run(Vamp::RealTime::zeroTime, toRun);
Chris@739 185
Chris@739 186 for (int c = 0; c < nchannels; ++c) {
Chris@739 187 m_effectOutputBuffers[c].write(ob[c], toRun);
Chris@739 188 }
Chris@739 189 }
Chris@739 190 }
Chris@739 191
Chris@739 192 return got;
Chris@739 193 }
Chris@739 194
Chris@739 195 void
Chris@739 196 EffectWrapper::setSystemPlaybackChannelCount(int count)
Chris@739 197 {
Chris@739 198 {
Chris@739 199 lock_guard<mutex> guard(m_mutex);
Chris@740 200 #ifdef DEBUG_EFFECT_WRAPPER
Chris@740 201 SVCERR << "EffectWrapper[" << this
Chris@740 202 << "]::setSystemPlaybackChannelCount(" << count << ")" << endl;
Chris@740 203 #endif
Chris@739 204 m_effectOutputBuffers.resize
Chris@739 205 (count, RingBuffer<float>(DEFAULT_RING_BUFFER_SIZE));
Chris@739 206 m_channelCount = count;
Chris@739 207 }
Chris@739 208 m_source->setSystemPlaybackChannelCount(count);
Chris@739 209 }
Chris@739 210
Chris@739 211 void
Chris@739 212 EffectWrapper::setSystemPlaybackSampleRate(int rate)
Chris@739 213 {
Chris@739 214 m_source->setSystemPlaybackSampleRate(rate);
Chris@739 215 }
Chris@739 216
Chris@739 217 std::string
Chris@739 218 EffectWrapper::getClientName() const
Chris@739 219 {
Chris@739 220 return m_source->getClientName();
Chris@739 221 }
Chris@739 222
Chris@739 223 int
Chris@739 224 EffectWrapper::getApplicationSampleRate() const
Chris@739 225 {
Chris@739 226 return m_source->getApplicationSampleRate();
Chris@739 227 }
Chris@739 228
Chris@739 229 int
Chris@739 230 EffectWrapper::getApplicationChannelCount() const
Chris@739 231 {
Chris@739 232 return m_source->getApplicationChannelCount();
Chris@739 233 }
Chris@739 234
Chris@739 235 void
Chris@739 236 EffectWrapper::setSystemPlaybackBlockSize(int sz)
Chris@739 237 {
Chris@739 238 SVDEBUG << "NOTE: EffectWrapper::setSystemPlaybackBlockSize called "
Chris@739 239 << "with size = " << sz << "; not passing to wrapped source, as "
Chris@739 240 << "actual block size will vary" << endl;
Chris@739 241 }
Chris@739 242
Chris@739 243 void
Chris@739 244 EffectWrapper::setSystemPlaybackLatency(int latency)
Chris@739 245 {
Chris@739 246 m_source->setSystemPlaybackLatency(latency);
Chris@739 247 }
Chris@739 248
Chris@739 249 void
Chris@739 250 EffectWrapper::setOutputLevels(float left, float right)
Chris@739 251 {
Chris@739 252 m_source->setOutputLevels(left, right);
Chris@739 253 }
Chris@739 254
Chris@739 255 void
Chris@739 256 EffectWrapper::audioProcessingOverload()
Chris@739 257 {
Chris@739 258 m_source->audioProcessingOverload();
Chris@739 259 }