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 } |