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