annotate transform/RealTimePluginTransform.cpp @ 76:af2725b5d6fe

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