Mercurial > hg > sonic-visualiser
comparison transform/RealTimePluginTransform.cpp @ 110:d25ea0c2af5c
* Fix real-time plugin corruption when getLatency is called for some plugins
* Other minor changes
author | Chris Cannam |
---|---|
date | Thu, 01 Mar 2007 15:35:27 +0000 |
parents | bedc7517b6e8 |
children | b4110b17bca8 |
comparison
equal
deleted
inserted
replaced
109:e6c4b27cba2c | 110:d25ea0c2af5c |
---|---|
32 const ExecutionContext &context, | 32 const ExecutionContext &context, |
33 QString configurationXml, | 33 QString configurationXml, |
34 QString units, | 34 QString units, |
35 int output) : | 35 int output) : |
36 PluginTransform(inputModel, context), | 36 PluginTransform(inputModel, context), |
37 m_pluginId(pluginId), | |
38 m_configurationXml(configurationXml), | |
39 m_units(units), | |
37 m_plugin(0), | 40 m_plugin(0), |
38 m_outputNo(output) | 41 m_outputNo(output) |
39 { | 42 { |
40 if (!m_context.blockSize) m_context.blockSize = 1024; | 43 if (!m_context.blockSize) m_context.blockSize = 1024; |
41 | 44 |
118 DenseTimeValueModel *input = getInput(); | 121 DenseTimeValueModel *input = getInput(); |
119 if (!input) return; | 122 if (!input) return; |
120 | 123 |
121 while (!input->isReady()) { | 124 while (!input->isReady()) { |
122 if (dynamic_cast<WaveFileModel *>(input)) break; // no need to wait | 125 if (dynamic_cast<WaveFileModel *>(input)) break; // no need to wait |
123 std::cerr << "FeatureExtractionPluginTransform::run: Waiting for input model to be ready..." << std::endl; | 126 std::cerr << "RealTimePluginTransform::run: Waiting for input model to be ready..." << std::endl; |
124 sleep(1); | 127 sleep(1); |
125 } | 128 } |
126 | 129 |
127 SparseTimeValueModel *stvm = dynamic_cast<SparseTimeValueModel *>(m_output); | 130 SparseTimeValueModel *stvm = dynamic_cast<SparseTimeValueModel *>(m_output); |
128 WritableWaveFileModel *wwfm = dynamic_cast<WritableWaveFileModel *>(m_output); | 131 WritableWaveFileModel *wwfm = dynamic_cast<WritableWaveFileModel *>(m_output); |
134 int channelCount = input->getChannelCount(); | 137 int channelCount = input->getChannelCount(); |
135 if (!wwfm && m_context.channel != -1) channelCount = 1; | 138 if (!wwfm && m_context.channel != -1) channelCount = 1; |
136 | 139 |
137 size_t blockSize = m_plugin->getBufferSize(); | 140 size_t blockSize = m_plugin->getBufferSize(); |
138 | 141 |
139 float **buffers = m_plugin->getAudioInputBuffers(); | 142 float **inbufs = m_plugin->getAudioInputBuffers(); |
140 | 143 |
141 size_t startFrame = m_input->getStartFrame(); | 144 size_t startFrame = m_input->getStartFrame(); |
142 size_t endFrame = m_input->getEndFrame(); | 145 size_t endFrame = m_input->getEndFrame(); |
143 size_t blockFrame = startFrame; | 146 size_t blockFrame = startFrame; |
144 | 147 |
155 ( (endFrame - startFrame) / blockSize); | 158 ( (endFrame - startFrame) / blockSize); |
156 | 159 |
157 size_t got = 0; | 160 size_t got = 0; |
158 | 161 |
159 if (channelCount == 1) { | 162 if (channelCount == 1) { |
160 if (buffers && buffers[0]) { | 163 if (inbufs && inbufs[0]) { |
161 got = input->getValues | 164 got = input->getValues |
162 (m_context.channel, blockFrame, blockFrame + blockSize, buffers[0]); | 165 (m_context.channel, blockFrame, blockFrame + blockSize, inbufs[0]); |
163 while (got < blockSize) { | 166 while (got < blockSize) { |
164 buffers[0][got++] = 0.0; | 167 inbufs[0][got++] = 0.0; |
165 } | 168 } |
166 if (m_context.channel == -1 && channelCount > 1) { | 169 } |
167 // use mean instead of sum, as plugin input | 170 for (size_t ch = 1; ch < m_plugin->getAudioInputCount(); ++ch) { |
168 for (size_t i = 0; i < got; ++i) { | 171 for (size_t i = 0; i < blockSize; ++i) { |
169 buffers[0][i] /= channelCount; | 172 inbufs[ch][i] = inbufs[0][i]; |
170 } | 173 } |
171 } | |
172 } | 174 } |
173 } else { | 175 } else { |
174 for (size_t ch = 0; ch < channelCount; ++ch) { | 176 for (size_t ch = 0; ch < channelCount; ++ch) { |
175 if (buffers && buffers[ch]) { | 177 if (inbufs && inbufs[ch]) { |
176 got = input->getValues | 178 got = input->getValues |
177 (ch, blockFrame, blockFrame + blockSize, buffers[ch]); | 179 (ch, blockFrame, blockFrame + blockSize, inbufs[ch]); |
178 while (got < blockSize) { | 180 while (got < blockSize) { |
179 buffers[ch][got++] = 0.0; | 181 inbufs[ch][got++] = 0.0; |
180 } | 182 } |
181 } | 183 } |
182 } | 184 } |
185 for (size_t ch = channelCount; ch < m_plugin->getAudioInputCount(); ++ch) { | |
186 for (size_t i = 0; i < blockSize; ++i) { | |
187 inbufs[ch][i] = inbufs[ch % channelCount][i]; | |
188 } | |
189 } | |
183 } | 190 } |
191 | |
192 /* | |
193 std::cerr << "Input for plugin: " << m_plugin->getAudioInputCount() << " channels "<< std::endl; | |
194 | |
195 for (size_t ch = 0; ch < m_plugin->getAudioInputCount(); ++ch) { | |
196 std::cerr << "Input channel " << ch << std::endl; | |
197 for (size_t i = 0; i < 100; ++i) { | |
198 std::cerr << inbufs[ch][i] << " "; | |
199 if (isnan(inbufs[ch][i])) { | |
200 std::cerr << "\n\nWARNING: NaN in audio input" << std::endl; | |
201 } | |
202 } | |
203 } | |
204 */ | |
184 | 205 |
185 m_plugin->run(Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); | 206 m_plugin->run(Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); |
186 | 207 |
187 if (stvm) { | 208 if (stvm) { |
188 | 209 |
195 stvm->addPoint(SparseTimeValueModel::Point | 216 stvm->addPoint(SparseTimeValueModel::Point |
196 (pointFrame, value, "")); | 217 (pointFrame, value, "")); |
197 | 218 |
198 } else if (wwfm) { | 219 } else if (wwfm) { |
199 | 220 |
200 float **buffers = m_plugin->getAudioOutputBuffers(); | 221 float **outbufs = m_plugin->getAudioOutputBuffers(); |
201 | 222 |
202 if (buffers) { | 223 if (outbufs) { |
203 | 224 |
204 if (blockFrame >= latency) { | 225 if (blockFrame >= latency) { |
205 wwfm->addSamples(buffers, blockSize); | 226 wwfm->addSamples(outbufs, blockSize); |
206 } else if (blockFrame + blockSize >= latency) { | 227 } else if (blockFrame + blockSize >= latency) { |
207 size_t offset = latency - blockFrame; | 228 size_t offset = latency - blockFrame; |
208 size_t count = blockSize - offset; | 229 size_t count = blockSize - offset; |
209 float **tmp = new float *[channelCount]; | 230 float **tmp = new float *[channelCount]; |
210 for (size_t c = 0; c < channelCount; ++c) { | 231 for (size_t c = 0; c < channelCount; ++c) { |
211 tmp[c] = buffers[c] + offset; | 232 tmp[c] = outbufs[c] + offset; |
212 } | 233 } |
213 wwfm->addSamples(tmp, count); | 234 wwfm->addSamples(tmp, count); |
214 delete[] tmp; | 235 delete[] tmp; |
215 } | 236 } |
216 } | 237 } |