annotate vamp-sdk/hostext/PluginChannelAdapter.cpp @ 64:9d3272c7db60

* Merge from host-factory-stuff branch: this adds several helper classes in the hostext directory that should make a host's life much easier. This will become version 1.1 of the SDK, eventually.
author cannam
date Fri, 01 Jun 2007 15:10:17 +0000
parents
children a712ed15d158
rev   line source
cannam@64 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@64 2
cannam@64 3 /*
cannam@64 4 Vamp
cannam@64 5
cannam@64 6 An API for audio analysis and feature extraction plugins.
cannam@64 7
cannam@64 8 Centre for Digital Music, Queen Mary, University of London.
cannam@64 9 Copyright 2006 Chris Cannam.
cannam@64 10
cannam@64 11 Permission is hereby granted, free of charge, to any person
cannam@64 12 obtaining a copy of this software and associated documentation
cannam@64 13 files (the "Software"), to deal in the Software without
cannam@64 14 restriction, including without limitation the rights to use, copy,
cannam@64 15 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@64 16 of the Software, and to permit persons to whom the Software is
cannam@64 17 furnished to do so, subject to the following conditions:
cannam@64 18
cannam@64 19 The above copyright notice and this permission notice shall be
cannam@64 20 included in all copies or substantial portions of the Software.
cannam@64 21
cannam@64 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@64 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@64 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@64 25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@64 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@64 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@64 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@64 29
cannam@64 30 Except as contained in this notice, the names of the Centre for
cannam@64 31 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@64 32 shall not be used in advertising or otherwise to promote the sale,
cannam@64 33 use or other dealings in this Software without prior written
cannam@64 34 authorization.
cannam@64 35 */
cannam@64 36
cannam@64 37 #include "PluginChannelAdapter.h"
cannam@64 38
cannam@64 39 namespace Vamp {
cannam@64 40
cannam@64 41 namespace HostExt {
cannam@64 42
cannam@64 43 PluginChannelAdapter::PluginChannelAdapter(Plugin *plugin) :
cannam@64 44 PluginWrapper(plugin),
cannam@64 45 m_blockSize(0),
cannam@64 46 m_inputChannels(0),
cannam@64 47 m_pluginChannels(0),
cannam@64 48 m_buffer(0),
cannam@64 49 m_forwardPtrs(0)
cannam@64 50 {
cannam@64 51 }
cannam@64 52
cannam@64 53 PluginChannelAdapter::~PluginChannelAdapter()
cannam@64 54 {
cannam@64 55 if (m_buffer) {
cannam@64 56 if (m_inputChannels > m_pluginChannels) {
cannam@64 57 delete[] m_buffer[0];
cannam@64 58 } else {
cannam@64 59 for (size_t i = 0; i < m_pluginChannels - m_inputChannels; ++i) {
cannam@64 60 delete[] m_buffer[i];
cannam@64 61 }
cannam@64 62 }
cannam@64 63 delete[] m_buffer;
cannam@64 64 m_buffer = 0;
cannam@64 65 }
cannam@64 66
cannam@64 67 if (m_forwardPtrs) {
cannam@64 68 delete[] m_forwardPtrs;
cannam@64 69 m_forwardPtrs = 0;
cannam@64 70 }
cannam@64 71 }
cannam@64 72
cannam@64 73 bool
cannam@64 74 PluginChannelAdapter::initialise(size_t channels, size_t stepSize, size_t blockSize)
cannam@64 75 {
cannam@64 76 m_blockSize = blockSize;
cannam@64 77
cannam@64 78 size_t minch = m_plugin->getMinChannelCount();
cannam@64 79 size_t maxch = m_plugin->getMaxChannelCount();
cannam@64 80
cannam@64 81 m_inputChannels = channels;
cannam@64 82
cannam@64 83 if (m_inputChannels < minch) {
cannam@64 84
cannam@64 85 m_forwardPtrs = new const float *[minch];
cannam@64 86
cannam@64 87 if (m_inputChannels > 1) {
cannam@64 88 // We need a set of zero-valued buffers to add to the
cannam@64 89 // forwarded pointers
cannam@64 90 m_buffer = new float*[minch - channels];
cannam@64 91 for (size_t i = 0; i < minch; ++i) {
cannam@64 92 m_buffer[i] = new float[blockSize];
cannam@64 93 for (size_t j = 0; j < blockSize; ++j) {
cannam@64 94 m_buffer[i][j] = 0.f;
cannam@64 95 }
cannam@64 96 }
cannam@64 97 }
cannam@64 98
cannam@64 99 m_pluginChannels = minch;
cannam@64 100
cannam@64 101 std::cerr << "PluginChannelAdapter::initialise: expanding " << m_inputChannels << " to " << m_pluginChannels << " for plugin" << std::endl;
cannam@64 102
cannam@64 103 } else if (m_inputChannels > maxch) {
cannam@64 104
cannam@64 105 // We only need m_buffer if we are mixing down to a single
cannam@64 106 // channel -- otherwise we can just forward the same float* as
cannam@64 107 // passed in to process(), expecting the excess to be ignored
cannam@64 108
cannam@64 109 if (maxch == 1) {
cannam@64 110 m_buffer = new float *[1];
cannam@64 111 m_buffer[0] = new float[blockSize];
cannam@64 112
cannam@64 113 std::cerr << "PluginChannelAdapter::initialise: mixing " << m_inputChannels << " to mono for plugin" << std::endl;
cannam@64 114
cannam@64 115 } else {
cannam@64 116
cannam@64 117 std::cerr << "PluginChannelAdapter::initialise: reducing " << m_inputChannels << " to " << m_pluginChannels << " for plugin" << std::endl;
cannam@64 118 }
cannam@64 119
cannam@64 120 m_pluginChannels = maxch;
cannam@64 121
cannam@64 122 } else {
cannam@64 123
cannam@64 124 std::cerr << "PluginChannelAdapter::initialise: accepting given number of channels (" << m_inputChannels << ")" << std::endl;
cannam@64 125 m_pluginChannels = m_inputChannels;
cannam@64 126 }
cannam@64 127
cannam@64 128 return m_plugin->initialise(m_pluginChannels, stepSize, blockSize);
cannam@64 129 }
cannam@64 130
cannam@64 131 PluginChannelAdapter::FeatureSet
cannam@64 132 PluginChannelAdapter::process(const float *const *inputBuffers,
cannam@64 133 RealTime timestamp)
cannam@64 134 {
cannam@64 135 std::cerr << "PluginChannelAdapter::process: " << m_inputChannels << " -> " << m_pluginChannels << " channels" << std::endl;
cannam@64 136
cannam@64 137 if (m_inputChannels < m_pluginChannels) {
cannam@64 138
cannam@64 139 if (m_inputChannels == 1) {
cannam@64 140 for (size_t i = 0; i < m_pluginChannels; ++i) {
cannam@64 141 m_forwardPtrs[i] = inputBuffers[0];
cannam@64 142 }
cannam@64 143 } else {
cannam@64 144 for (size_t i = 0; i < m_inputChannels; ++i) {
cannam@64 145 m_forwardPtrs[i] = inputBuffers[i];
cannam@64 146 }
cannam@64 147 for (size_t i = m_inputChannels; i < m_pluginChannels; ++i) {
cannam@64 148 m_forwardPtrs[i] = m_buffer[i - m_inputChannels];
cannam@64 149 }
cannam@64 150 }
cannam@64 151
cannam@64 152 return m_plugin->process(m_forwardPtrs, timestamp);
cannam@64 153
cannam@64 154 } else if (m_inputChannels > m_pluginChannels) {
cannam@64 155
cannam@64 156 if (m_pluginChannels == 1) {
cannam@64 157 for (size_t j = 0; j < m_blockSize; ++j) {
cannam@64 158 m_buffer[0][j] = inputBuffers[0][j];
cannam@64 159 }
cannam@64 160 for (size_t i = 1; i < m_inputChannels; ++i) {
cannam@64 161 for (size_t j = 0; j < m_blockSize; ++j) {
cannam@64 162 m_buffer[0][j] += inputBuffers[i][j];
cannam@64 163 }
cannam@64 164 }
cannam@64 165 for (size_t j = 0; j < m_blockSize; ++j) {
cannam@64 166 m_buffer[0][j] /= m_inputChannels;
cannam@64 167 }
cannam@64 168 return m_plugin->process(m_buffer, timestamp);
cannam@64 169 } else {
cannam@64 170 return m_plugin->process(inputBuffers, timestamp);
cannam@64 171 }
cannam@64 172
cannam@64 173 } else {
cannam@64 174
cannam@64 175 return m_plugin->process(inputBuffers, timestamp);
cannam@64 176 }
cannam@64 177 }
cannam@64 178
cannam@64 179 }
cannam@64 180
cannam@64 181 }
cannam@64 182
cannam@64 183