annotate transform/RealTimePluginTransform.cpp @ 35:06787742542a

* Add a bit of resistance to pane dragging so as to make it harder to inadvertently drag in the other axis from the one you intended
author Chris Cannam
date Fri, 22 Sep 2006 16:46:10 +0000
parents 8ad306d8a568
children f18093617b78
rev   line source
Chris@0 1
Chris@0 2 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 3
Chris@0 4 /*
Chris@0 5 Sonic Visualiser
Chris@0 6 An audio file viewer and annotation editor.
Chris@0 7 Centre for Digital Music, Queen Mary, University of London.
Chris@0 8 This file copyright 2006 Chris Cannam.
Chris@0 9
Chris@0 10 This program is free software; you can redistribute it and/or
Chris@0 11 modify it under the terms of the GNU General Public License as
Chris@0 12 published by the Free Software Foundation; either version 2 of the
Chris@0 13 License, or (at your option) any later version. See the file
Chris@0 14 COPYING included with this distribution for more information.
Chris@0 15 */
Chris@0 16
Chris@0 17 #include "RealTimePluginTransform.h"
Chris@0 18
Chris@0 19 #include "plugin/RealTimePluginFactory.h"
Chris@0 20 #include "plugin/RealTimePluginInstance.h"
Chris@0 21 #include "plugin/PluginXml.h"
Chris@0 22
Chris@1 23 #include "data/model/Model.h"
Chris@1 24 #include "data/model/SparseTimeValueModel.h"
Chris@1 25 #include "data/model/DenseTimeValueModel.h"
Chris@0 26
Chris@0 27 #include <iostream>
Chris@0 28
Chris@0 29 RealTimePluginTransform::RealTimePluginTransform(Model *inputModel,
Chris@0 30 QString pluginId,
Chris@27 31 const ExecutionContext &context,
Chris@0 32 QString configurationXml,
Chris@0 33 QString units,
Chris@27 34 int output) :
Chris@27 35 PluginTransform(inputModel, context),
Chris@0 36 m_plugin(0),
Chris@27 37 m_outputNo(output)
Chris@0 38 {
Chris@27 39 if (!m_context.blockSize) m_context.blockSize = 1024;
Chris@26 40
Chris@0 41 std::cerr << "RealTimePluginTransform::RealTimePluginTransform: plugin " << pluginId.toStdString() << ", output " << output << std::endl;
Chris@0 42
Chris@0 43 RealTimePluginFactory *factory =
Chris@0 44 RealTimePluginFactory::instanceFor(pluginId);
Chris@0 45
Chris@0 46 if (!factory) {
Chris@0 47 std::cerr << "RealTimePluginTransform: No factory available for plugin id \""
Chris@0 48 << pluginId.toStdString() << "\"" << std::endl;
Chris@0 49 return;
Chris@0 50 }
Chris@0 51
Chris@0 52 DenseTimeValueModel *input = getInput();
Chris@0 53 if (!input) return;
Chris@0 54
Chris@0 55 m_plugin = factory->instantiatePlugin(pluginId, 0, 0, m_input->getSampleRate(),
Chris@27 56 m_context.blockSize,
Chris@0 57 input->getChannelCount());
Chris@0 58
Chris@0 59 if (!m_plugin) {
Chris@0 60 std::cerr << "RealTimePluginTransform: Failed to instantiate plugin \""
Chris@0 61 << pluginId.toStdString() << "\"" << std::endl;
Chris@0 62 return;
Chris@0 63 }
Chris@0 64
Chris@0 65 if (configurationXml != "") {
Chris@0 66 PluginXml(m_plugin).setParametersFromXml(configurationXml);
Chris@0 67 }
Chris@0 68
Chris@34 69 if (m_outputNo >= 0 && m_outputNo >= m_plugin->getControlOutputCount()) {
Chris@0 70 std::cerr << "RealTimePluginTransform: Plugin has fewer than desired " << m_outputNo << " control outputs" << std::endl;
Chris@0 71 return;
Chris@0 72 }
Chris@34 73
Chris@34 74 if (m_outputNo == -1) {
Chris@34 75
Chris@34 76 //!!! process audio!
Chris@34 77
Chris@34 78 } else {
Chris@0 79
Chris@34 80 SparseTimeValueModel *model = new SparseTimeValueModel
Chris@34 81 (input->getSampleRate(), m_context.blockSize, 0.0, 0.0, false);
Chris@0 82
Chris@34 83 if (units != "") model->setScaleUnits(units);
Chris@0 84
Chris@34 85 m_output = model;
Chris@34 86 }
Chris@0 87 }
Chris@0 88
Chris@0 89 RealTimePluginTransform::~RealTimePluginTransform()
Chris@0 90 {
Chris@0 91 delete m_plugin;
Chris@0 92 }
Chris@0 93
Chris@0 94 DenseTimeValueModel *
Chris@0 95 RealTimePluginTransform::getInput()
Chris@0 96 {
Chris@0 97 DenseTimeValueModel *dtvm =
Chris@0 98 dynamic_cast<DenseTimeValueModel *>(getInputModel());
Chris@0 99 if (!dtvm) {
Chris@0 100 std::cerr << "RealTimePluginTransform::getInput: WARNING: Input model is not conformable to DenseTimeValueModel" << std::endl;
Chris@0 101 }
Chris@0 102 return dtvm;
Chris@0 103 }
Chris@0 104
Chris@0 105 void
Chris@0 106 RealTimePluginTransform::run()
Chris@0 107 {
Chris@0 108 DenseTimeValueModel *input = getInput();
Chris@0 109 if (!input) return;
Chris@0 110
Chris@0 111 SparseTimeValueModel *model = dynamic_cast<SparseTimeValueModel *>(m_output);
Chris@0 112 if (!model) return;
Chris@0 113
Chris@0 114 if (m_outputNo >= m_plugin->getControlOutputCount()) return;
Chris@0 115
Chris@0 116 size_t sampleRate = input->getSampleRate();
Chris@0 117 int channelCount = input->getChannelCount();
Chris@27 118 if (m_context.channel != -1) channelCount = 1;
Chris@0 119
Chris@0 120 size_t blockSize = m_plugin->getBufferSize();
Chris@0 121
Chris@0 122 float **buffers = m_plugin->getAudioInputBuffers();
Chris@0 123
Chris@0 124 size_t startFrame = m_input->getStartFrame();
Chris@0 125 size_t endFrame = m_input->getEndFrame();
Chris@0 126 size_t blockFrame = startFrame;
Chris@0 127
Chris@0 128 size_t prevCompletion = 0;
Chris@0 129
Chris@0 130 int i = 0;
Chris@0 131
Chris@0 132 while (blockFrame < endFrame) {
Chris@0 133
Chris@0 134 size_t completion =
Chris@0 135 (((blockFrame - startFrame) / blockSize) * 99) /
Chris@0 136 ( (endFrame - startFrame) / blockSize);
Chris@0 137
Chris@0 138 size_t got = 0;
Chris@0 139
Chris@0 140 if (channelCount == 1) {
Chris@0 141 got = input->getValues
Chris@27 142 (m_context.channel, blockFrame, blockFrame + blockSize, buffers[0]);
Chris@0 143 while (got < blockSize) {
Chris@0 144 buffers[0][got++] = 0.0;
Chris@0 145 }
Chris@27 146 if (m_context.channel == -1 && channelCount > 1) {
Chris@0 147 // use mean instead of sum, as plugin input
Chris@0 148 for (size_t i = 0; i < got; ++i) {
Chris@0 149 buffers[0][i] /= channelCount;
Chris@0 150 }
Chris@0 151 }
Chris@0 152 } else {
Chris@0 153 for (size_t ch = 0; ch < channelCount; ++ch) {
Chris@0 154 got = input->getValues
Chris@0 155 (ch, blockFrame, blockFrame + blockSize, buffers[ch]);
Chris@0 156 while (got < blockSize) {
Chris@0 157 buffers[ch][got++] = 0.0;
Chris@0 158 }
Chris@0 159 }
Chris@0 160 }
Chris@0 161
Chris@0 162 m_plugin->run(Vamp::RealTime::frame2RealTime(blockFrame, sampleRate));
Chris@0 163
Chris@0 164 float value = m_plugin->getControlOutputValue(m_outputNo);
Chris@0 165
Chris@0 166 model->addPoint(SparseTimeValueModel::Point
Chris@0 167 (blockFrame - m_plugin->getLatency(), value, ""));
Chris@0 168
Chris@0 169 if (blockFrame == startFrame || completion > prevCompletion) {
Chris@0 170 model->setCompletion(completion);
Chris@0 171 prevCompletion = completion;
Chris@0 172 }
Chris@0 173
Chris@0 174 blockFrame += blockSize;
Chris@0 175 }
Chris@0 176
Chris@0 177 model->setCompletion(100);
Chris@0 178 }
Chris@0 179