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 }