00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "RealTimeEffectModelTransformer.h"
00017
00018 #include "plugin/RealTimePluginFactory.h"
00019 #include "plugin/RealTimePluginInstance.h"
00020 #include "plugin/PluginXml.h"
00021
00022 #include "data/model/Model.h"
00023 #include "data/model/SparseTimeValueModel.h"
00024 #include "data/model/DenseTimeValueModel.h"
00025 #include "data/model/WritableWaveFileModel.h"
00026 #include "data/model/WaveFileModel.h"
00027
00028 #include "TransformFactory.h"
00029
00030 #include <iostream>
00031
00032 RealTimeEffectModelTransformer::RealTimeEffectModelTransformer(Input in,
00033 const Transform &transform) :
00034 ModelTransformer(in, transform),
00035 m_plugin(0)
00036 {
00037 m_units = TransformFactory::getInstance()->getTransformUnits
00038 (transform.getIdentifier());
00039 m_outputNo =
00040 (transform.getOutput() == "A") ? -1 : transform.getOutput().toInt();
00041
00042 QString pluginId = transform.getPluginIdentifier();
00043
00044 if (!m_transform.getBlockSize()) m_transform.setBlockSize(1024);
00045
00046
00047
00048 RealTimePluginFactory *factory =
00049 RealTimePluginFactory::instanceFor(pluginId);
00050
00051 if (!factory) {
00052 std::cerr << "RealTimeEffectModelTransformer: No factory available for plugin id \""
00053 << pluginId.toStdString() << "\"" << std::endl;
00054 return;
00055 }
00056
00057 DenseTimeValueModel *input = getConformingInput();
00058 if (!input) return;
00059
00060 m_plugin = factory->instantiatePlugin(pluginId, 0, 0,
00061 input->getSampleRate(),
00062 m_transform.getBlockSize(),
00063 input->getChannelCount());
00064
00065 if (!m_plugin) {
00066 std::cerr << "RealTimeEffectModelTransformer: Failed to instantiate plugin \""
00067 << pluginId.toStdString() << "\"" << std::endl;
00068 return;
00069 }
00070
00071 TransformFactory::getInstance()->setPluginParameters(m_transform, m_plugin);
00072
00073 if (m_outputNo >= 0 &&
00074 m_outputNo >= int(m_plugin->getControlOutputCount())) {
00075 std::cerr << "RealTimeEffectModelTransformer: Plugin has fewer than desired " << m_outputNo << " control outputs" << std::endl;
00076 return;
00077 }
00078
00079 if (m_outputNo == -1) {
00080
00081 size_t outputChannels = m_plugin->getAudioOutputCount();
00082 if (outputChannels > input->getChannelCount()) {
00083 outputChannels = input->getChannelCount();
00084 }
00085
00086 WritableWaveFileModel *model = new WritableWaveFileModel
00087 (input->getSampleRate(), outputChannels);
00088
00089 m_output = model;
00090
00091 } else {
00092
00093 SparseTimeValueModel *model = new SparseTimeValueModel
00094 (input->getSampleRate(), m_transform.getBlockSize(), 0.0, 0.0, false);
00095
00096 if (m_units != "") model->setScaleUnits(m_units);
00097
00098 m_output = model;
00099 }
00100 }
00101
00102 RealTimeEffectModelTransformer::~RealTimeEffectModelTransformer()
00103 {
00104 delete m_plugin;
00105 }
00106
00107 DenseTimeValueModel *
00108 RealTimeEffectModelTransformer::getConformingInput()
00109 {
00110 DenseTimeValueModel *dtvm =
00111 dynamic_cast<DenseTimeValueModel *>(getInputModel());
00112 if (!dtvm) {
00113 std::cerr << "RealTimeEffectModelTransformer::getConformingInput: WARNING: Input model is not conformable to DenseTimeValueModel" << std::endl;
00114 }
00115 return dtvm;
00116 }
00117
00118 void
00119 RealTimeEffectModelTransformer::run()
00120 {
00121 DenseTimeValueModel *input = getConformingInput();
00122 if (!input) return;
00123
00124 while (!input->isReady()) {
00125 if (dynamic_cast<WaveFileModel *>(input)) break;
00126 std::cerr << "RealTimeEffectModelTransformer::run: Waiting for input model to be ready..." << std::endl;
00127 sleep(1);
00128 }
00129
00130 SparseTimeValueModel *stvm = dynamic_cast<SparseTimeValueModel *>(m_output);
00131 WritableWaveFileModel *wwfm = dynamic_cast<WritableWaveFileModel *>(m_output);
00132 if (!stvm && !wwfm) return;
00133
00134 if (stvm && (m_outputNo >= int(m_plugin->getControlOutputCount()))) return;
00135
00136 size_t sampleRate = input->getSampleRate();
00137 size_t channelCount = input->getChannelCount();
00138 if (!wwfm && m_input.getChannel() != -1) channelCount = 1;
00139
00140 long blockSize = m_plugin->getBufferSize();
00141
00142 float **inbufs = m_plugin->getAudioInputBuffers();
00143
00144 long startFrame = m_input.getModel()->getStartFrame();
00145 long endFrame = m_input.getModel()->getEndFrame();
00146
00147 RealTime contextStartRT = m_transform.getStartTime();
00148 RealTime contextDurationRT = m_transform.getDuration();
00149
00150 long contextStart =
00151 RealTime::realTime2Frame(contextStartRT, sampleRate);
00152
00153 long contextDuration =
00154 RealTime::realTime2Frame(contextDurationRT, sampleRate);
00155
00156 if (contextStart == 0 || contextStart < startFrame) {
00157 contextStart = startFrame;
00158 }
00159
00160 if (contextDuration == 0) {
00161 contextDuration = endFrame - contextStart;
00162 }
00163 if (contextStart + contextDuration > endFrame) {
00164 contextDuration = endFrame - contextStart;
00165 }
00166
00167 wwfm->setStartFrame(contextStart);
00168
00169 long blockFrame = contextStart;
00170
00171 long prevCompletion = 0;
00172
00173 long latency = m_plugin->getLatency();
00174
00175 while (blockFrame < contextStart + contextDuration + latency &&
00176 !m_abandoned) {
00177
00178 long completion =
00179 (((blockFrame - contextStart) / blockSize) * 99) /
00180 ((contextDuration) / blockSize);
00181
00182 long got = 0;
00183
00184 if (channelCount == 1) {
00185 if (inbufs && inbufs[0]) {
00186 got = input->getData
00187 (m_input.getChannel(), blockFrame, blockSize, inbufs[0]);
00188 while (got < blockSize) {
00189 inbufs[0][got++] = 0.0;
00190 }
00191 }
00192 for (size_t ch = 1; ch < m_plugin->getAudioInputCount(); ++ch) {
00193 for (long i = 0; i < blockSize; ++i) {
00194 inbufs[ch][i] = inbufs[0][i];
00195 }
00196 }
00197 } else {
00198 got = input->getData(0, channelCount - 1,
00199 blockFrame, blockSize,
00200 inbufs);
00201 while (got < blockSize) {
00202 for (size_t ch = 0; ch < channelCount; ++ch) {
00203 inbufs[ch][got] = 0.0;
00204 }
00205 ++got;
00206 }
00207 for (size_t ch = channelCount; ch < m_plugin->getAudioInputCount(); ++ch) {
00208 for (long i = 0; i < blockSize; ++i) {
00209 inbufs[ch][i] = inbufs[ch % channelCount][i];
00210 }
00211 }
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 m_plugin->run(Vamp::RealTime::frame2RealTime(blockFrame, sampleRate));
00229
00230 if (stvm) {
00231
00232 float value = m_plugin->getControlOutputValue(m_outputNo);
00233
00234 long pointFrame = blockFrame;
00235 if (pointFrame > latency) pointFrame -= latency;
00236 else pointFrame = 0;
00237
00238 stvm->addPoint(SparseTimeValueModel::Point
00239 (pointFrame, value, ""));
00240
00241 } else if (wwfm) {
00242
00243 float **outbufs = m_plugin->getAudioOutputBuffers();
00244
00245 if (outbufs) {
00246
00247 if (blockFrame >= latency) {
00248 long writeSize = std::min
00249 (blockSize,
00250 contextStart + contextDuration + latency - blockFrame);
00251 wwfm->addSamples(outbufs, writeSize);
00252 } else if (blockFrame + blockSize >= latency) {
00253 long offset = latency - blockFrame;
00254 long count = blockSize - offset;
00255 float **tmp = new float *[channelCount];
00256 for (size_t c = 0; c < channelCount; ++c) {
00257 tmp[c] = outbufs[c] + offset;
00258 }
00259 wwfm->addSamples(tmp, count);
00260 delete[] tmp;
00261 }
00262 }
00263 }
00264
00265 if (blockFrame == contextStart || completion > prevCompletion) {
00266 if (stvm) stvm->setCompletion(completion);
00267 if (wwfm) wwfm->setCompletion(completion);
00268 prevCompletion = completion;
00269 }
00270
00271 blockFrame += blockSize;
00272 }
00273
00274 if (m_abandoned) return;
00275
00276 if (stvm) stvm->setCompletion(100);
00277 if (wwfm) wwfm->setCompletion(100);
00278 }
00279