Mercurial > hg > svcore
comparison transform/RealTimePluginTransform.cpp @ 60:3086ff194ea0
* More structural work on feature extraction plugin C <-> C++ adapter
* Allow use of LADSPA/DSSI plugins with control outputs as feature extraction
plugins (DSSI with MIDI output still to come)
* Reorder labels on spectrogram status box
* Minor tweaks in doc etc.
author | Chris Cannam |
---|---|
date | Mon, 27 Mar 2006 15:03:02 +0000 |
parents | |
children | 749b5521e082 |
comparison
equal
deleted
inserted
replaced
59:9705a1978ecc | 60:3086ff194ea0 |
---|---|
1 | |
2 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
3 | |
4 /* | |
5 Sonic Visualiser | |
6 An audio file viewer and annotation editor. | |
7 Centre for Digital Music, Queen Mary, University of London. | |
8 This file copyright 2006 Chris Cannam. | |
9 | |
10 This program is free software; you can redistribute it and/or | |
11 modify it under the terms of the GNU General Public License as | |
12 published by the Free Software Foundation; either version 2 of the | |
13 License, or (at your option) any later version. See the file | |
14 COPYING included with this distribution for more information. | |
15 */ | |
16 | |
17 #include "RealTimePluginTransform.h" | |
18 | |
19 #include "plugin/RealTimePluginFactory.h" | |
20 #include "plugin/RealTimePluginInstance.h" | |
21 | |
22 #include "base/Model.h" | |
23 #include "model/SparseTimeValueModel.h" | |
24 #include "model/DenseTimeValueModel.h" | |
25 | |
26 #include <iostream> | |
27 | |
28 RealTimePluginTransform::RealTimePluginTransform(Model *inputModel, | |
29 QString pluginId, | |
30 QString configurationXml, | |
31 int output) : | |
32 Transform(inputModel), | |
33 m_plugin(0), | |
34 m_outputNo(output) | |
35 { | |
36 std::cerr << "RealTimePluginTransform::RealTimePluginTransform: plugin " << pluginId.toStdString() << ", output " << output << std::endl; | |
37 | |
38 RealTimePluginFactory *factory = | |
39 RealTimePluginFactory::instanceFor(pluginId); | |
40 | |
41 if (!factory) { | |
42 std::cerr << "RealTimePluginTransform: No factory available for plugin id \"" | |
43 << pluginId.toStdString() << "\"" << std::endl; | |
44 return; | |
45 } | |
46 | |
47 DenseTimeValueModel *input = getInput(); | |
48 if (!input) return; | |
49 | |
50 m_plugin = factory->instantiatePlugin(pluginId, 0, 0, m_input->getSampleRate(), | |
51 1024, //!!! wants to be configurable | |
52 input->getChannelCount()); | |
53 | |
54 if (!m_plugin) { | |
55 std::cerr << "RealTimePluginTransform: Failed to instantiate plugin \"" | |
56 << pluginId.toStdString() << "\"" << std::endl; | |
57 return; | |
58 } | |
59 | |
60 if (configurationXml != "") { | |
61 m_plugin->setParametersFromXml(configurationXml); | |
62 } | |
63 | |
64 if (m_outputNo >= m_plugin->getControlOutputCount()) { | |
65 std::cerr << "RealTimePluginTransform: Plugin has fewer than desired " << m_outputNo << " control outputs" << std::endl; | |
66 return; | |
67 } | |
68 | |
69 m_output = new SparseTimeValueModel(input->getSampleRate(), | |
70 1024, //!!! | |
71 0.0, 0.0, false); | |
72 } | |
73 | |
74 RealTimePluginTransform::~RealTimePluginTransform() | |
75 { | |
76 delete m_plugin; | |
77 } | |
78 | |
79 DenseTimeValueModel * | |
80 RealTimePluginTransform::getInput() | |
81 { | |
82 DenseTimeValueModel *dtvm = | |
83 dynamic_cast<DenseTimeValueModel *>(getInputModel()); | |
84 if (!dtvm) { | |
85 std::cerr << "RealTimePluginTransform::getInput: WARNING: Input model is not conformable to DenseTimeValueModel" << std::endl; | |
86 } | |
87 return dtvm; | |
88 } | |
89 | |
90 void | |
91 RealTimePluginTransform::run() | |
92 { | |
93 DenseTimeValueModel *input = getInput(); | |
94 if (!input) return; | |
95 | |
96 SparseTimeValueModel *model = dynamic_cast<SparseTimeValueModel *>(m_output); | |
97 if (!model) return; | |
98 | |
99 if (m_outputNo >= m_plugin->getControlOutputCount()) return; | |
100 | |
101 size_t sampleRate = input->getSampleRate(); | |
102 int channelCount = input->getChannelCount(); | |
103 size_t blockSize = m_plugin->getBufferSize(); | |
104 | |
105 float **buffers = m_plugin->getAudioInputBuffers(); | |
106 | |
107 size_t startFrame = m_input->getStartFrame(); | |
108 size_t endFrame = m_input->getEndFrame(); | |
109 size_t blockFrame = startFrame; | |
110 | |
111 size_t prevCompletion = 0; | |
112 | |
113 int i = 0; | |
114 | |
115 while (blockFrame < endFrame) { | |
116 | |
117 std::cout << "RealTimePluginTransform::run: blockFrame " | |
118 << blockFrame; | |
119 | |
120 size_t completion = | |
121 (((blockFrame - startFrame) / blockSize) * 99) / | |
122 ( (endFrame - startFrame) / blockSize); | |
123 | |
124 size_t got = 0; | |
125 | |
126 if (channelCount == 1) { | |
127 got = input->getValues | |
128 (-1, blockFrame, blockFrame + blockSize, buffers[0]); | |
129 while (got < blockSize) { | |
130 buffers[0][got++] = 0.0; | |
131 } | |
132 } else { | |
133 for (size_t ch = 0; ch < channelCount; ++ch) { | |
134 got = input->getValues | |
135 (ch, blockFrame, blockFrame + blockSize, buffers[ch]); | |
136 while (got < blockSize) { | |
137 buffers[ch][got++] = 0.0; | |
138 } | |
139 } | |
140 } | |
141 | |
142 m_plugin->run(RealTime::frame2RealTime(blockFrame, sampleRate)); | |
143 | |
144 float value = m_plugin->getControlOutputValue(m_outputNo); | |
145 | |
146 std::cout << " value " << value << std::endl; | |
147 | |
148 model->addPoint(SparseTimeValueModel::Point(blockFrame, value, "")); | |
149 | |
150 if (blockFrame == startFrame || completion > prevCompletion) { | |
151 model->setCompletion(completion); | |
152 prevCompletion = completion; | |
153 } | |
154 | |
155 blockFrame += blockSize; | |
156 } | |
157 | |
158 model->setCompletion(100); | |
159 } | |
160 |