cannam@0: cannam@0: cannam@0: VampPluginSDK: PluginChannelAdapter.cpp Source File cannam@0: cannam@0: cannam@0: cannam@0: cannam@0: cannam@0: cannam@0:

PluginChannelAdapter.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
cannam@0: 00002 
cannam@0: 00003 /*
cannam@0: 00004     Vamp
cannam@0: 00005 
cannam@0: 00006     An API for audio analysis and feature extraction plugins.
cannam@0: 00007 
cannam@0: 00008     Centre for Digital Music, Queen Mary, University of London.
cannam@0: 00009     Copyright 2006-2007 Chris Cannam and QMUL.
cannam@0: 00010   
cannam@0: 00011     Permission is hereby granted, free of charge, to any person
cannam@0: 00012     obtaining a copy of this software and associated documentation
cannam@0: 00013     files (the "Software"), to deal in the Software without
cannam@0: 00014     restriction, including without limitation the rights to use, copy,
cannam@0: 00015     modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@0: 00016     of the Software, and to permit persons to whom the Software is
cannam@0: 00017     furnished to do so, subject to the following conditions:
cannam@0: 00018 
cannam@0: 00019     The above copyright notice and this permission notice shall be
cannam@0: 00020     included in all copies or substantial portions of the Software.
cannam@0: 00021 
cannam@0: 00022     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@0: 00023     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@0: 00024     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@0: 00025     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@0: 00026     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@0: 00027     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@0: 00028     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@0: 00029 
cannam@0: 00030     Except as contained in this notice, the names of the Centre for
cannam@0: 00031     Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@0: 00032     shall not be used in advertising or otherwise to promote the sale,
cannam@0: 00033     use or other dealings in this Software without prior written
cannam@0: 00034     authorization.
cannam@0: 00035 */
cannam@0: 00036 
cannam@0: 00037 #include "PluginChannelAdapter.h"
cannam@0: 00038 
cannam@0: 00039 namespace Vamp {
cannam@0: 00040 
cannam@0: 00041 namespace HostExt {
cannam@0: 00042 
cannam@0: 00043 class PluginChannelAdapter::Impl
cannam@0: 00044 {
cannam@0: 00045 public:
cannam@0: 00046     Impl(Plugin *plugin);
cannam@0: 00047     ~Impl();
cannam@0: 00048 
cannam@0: 00049     bool initialise(size_t channels, size_t stepSize, size_t blockSize);
cannam@0: 00050 
cannam@0: 00051     FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
cannam@0: 00052 
cannam@0: 00053 protected:
cannam@0: 00054     Plugin *m_plugin;
cannam@0: 00055     size_t m_blockSize;
cannam@0: 00056     size_t m_inputChannels;
cannam@0: 00057     size_t m_pluginChannels;
cannam@0: 00058     float **m_buffer;
cannam@0: 00059     const float **m_forwardPtrs;
cannam@0: 00060 };
cannam@0: 00061 
cannam@0: 00062 PluginChannelAdapter::PluginChannelAdapter(Plugin *plugin) :
cannam@0: 00063     PluginWrapper(plugin)
cannam@0: 00064 {
cannam@0: 00065     m_impl = new Impl(plugin);
cannam@0: 00066 }
cannam@0: 00067 
cannam@0: 00068 PluginChannelAdapter::~PluginChannelAdapter()
cannam@0: 00069 {
cannam@0: 00070     delete m_impl;
cannam@0: 00071 }
cannam@0: 00072 
cannam@0: 00073 bool
cannam@0: 00074 PluginChannelAdapter::initialise(size_t channels, size_t stepSize, size_t blockSize)
cannam@0: 00075 {
cannam@0: 00076     return m_impl->initialise(channels, stepSize, blockSize);
cannam@0: 00077 }
cannam@0: 00078 
cannam@0: 00079 PluginChannelAdapter::FeatureSet
cannam@0: 00080 PluginChannelAdapter::process(const float *const *inputBuffers,
cannam@0: 00081                               RealTime timestamp)
cannam@0: 00082 {
cannam@0: 00083     return m_impl->process(inputBuffers, timestamp);
cannam@0: 00084 }
cannam@0: 00085 
cannam@0: 00086 PluginChannelAdapter::Impl::Impl(Plugin *plugin) :
cannam@0: 00087     m_plugin(plugin),
cannam@0: 00088     m_blockSize(0),
cannam@0: 00089     m_inputChannels(0),
cannam@0: 00090     m_pluginChannels(0),
cannam@0: 00091     m_buffer(0),
cannam@0: 00092     m_forwardPtrs(0)
cannam@0: 00093 {
cannam@0: 00094 }
cannam@0: 00095 
cannam@0: 00096 PluginChannelAdapter::Impl::~Impl()
cannam@0: 00097 {
cannam@0: 00098     // the adapter will delete the plugin
cannam@0: 00099 
cannam@0: 00100     if (m_buffer) {
cannam@0: 00101         if (m_inputChannels > m_pluginChannels) {
cannam@0: 00102             delete[] m_buffer[0];
cannam@0: 00103         } else {
cannam@0: 00104             for (size_t i = 0; i < m_pluginChannels - m_inputChannels; ++i) {
cannam@0: 00105                 delete[] m_buffer[i];
cannam@0: 00106             }
cannam@0: 00107         }
cannam@0: 00108         delete[] m_buffer;
cannam@0: 00109         m_buffer = 0;
cannam@0: 00110     }
cannam@0: 00111 
cannam@0: 00112     if (m_forwardPtrs) {
cannam@0: 00113         delete[] m_forwardPtrs;
cannam@0: 00114         m_forwardPtrs = 0;
cannam@0: 00115     }
cannam@0: 00116 }
cannam@0: 00117 
cannam@0: 00118 bool
cannam@0: 00119 PluginChannelAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize)
cannam@0: 00120 {
cannam@0: 00121     m_blockSize = blockSize;
cannam@0: 00122 
cannam@0: 00123     size_t minch = m_plugin->getMinChannelCount();
cannam@0: 00124     size_t maxch = m_plugin->getMaxChannelCount();
cannam@0: 00125 
cannam@0: 00126     m_inputChannels = channels;
cannam@0: 00127 
cannam@0: 00128     if (m_inputChannels < minch) {
cannam@0: 00129 
cannam@0: 00130         m_forwardPtrs = new const float *[minch];
cannam@0: 00131 
cannam@0: 00132         if (m_inputChannels > 1) {
cannam@0: 00133             // We need a set of zero-valued buffers to add to the
cannam@0: 00134             // forwarded pointers
cannam@0: 00135             m_buffer = new float*[minch - channels];
cannam@0: 00136             for (size_t i = 0; i < minch; ++i) {
cannam@0: 00137                 m_buffer[i] = new float[blockSize];
cannam@0: 00138                 for (size_t j = 0; j < blockSize; ++j) {
cannam@0: 00139                     m_buffer[i][j] = 0.f;
cannam@0: 00140                 }
cannam@0: 00141             }
cannam@0: 00142         }
cannam@0: 00143 
cannam@0: 00144         m_pluginChannels = minch;
cannam@0: 00145 
cannam@0: 00146         std::cerr << "PluginChannelAdapter::initialise: expanding " << m_inputChannels << " to " << m_pluginChannels << " for plugin" << std::endl;
cannam@0: 00147 
cannam@0: 00148     } else if (m_inputChannels > maxch) {
cannam@0: 00149 
cannam@0: 00150         // We only need m_buffer if we are mixing down to a single
cannam@0: 00151         // channel -- otherwise we can just forward the same float* as
cannam@0: 00152         // passed in to process(), expecting the excess to be ignored
cannam@0: 00153 
cannam@0: 00154         if (maxch == 1) {
cannam@0: 00155             m_buffer = new float *[1];
cannam@0: 00156             m_buffer[0] = new float[blockSize];
cannam@0: 00157 
cannam@0: 00158             std::cerr << "PluginChannelAdapter::initialise: mixing " << m_inputChannels << " to mono for plugin" << std::endl;
cannam@0: 00159 
cannam@0: 00160         } else {
cannam@0: 00161             
cannam@0: 00162             std::cerr << "PluginChannelAdapter::initialise: reducing " << m_inputChannels << " to " << m_pluginChannels << " for plugin" << std::endl;
cannam@0: 00163         }
cannam@0: 00164 
cannam@0: 00165         m_pluginChannels = maxch;
cannam@0: 00166 
cannam@0: 00167     } else {
cannam@0: 00168  
cannam@0: 00169         std::cerr << "PluginChannelAdapter::initialise: accepting given number of channels (" << m_inputChannels << ")" << std::endl;
cannam@0: 00170         m_pluginChannels = m_inputChannels;
cannam@0: 00171     }
cannam@0: 00172 
cannam@0: 00173     return m_plugin->initialise(m_pluginChannels, stepSize, blockSize);
cannam@0: 00174 }
cannam@0: 00175 
cannam@0: 00176 PluginChannelAdapter::FeatureSet
cannam@0: 00177 PluginChannelAdapter::Impl::process(const float *const *inputBuffers,
cannam@0: 00178                                     RealTime timestamp)
cannam@0: 00179 {
cannam@0: 00180 //    std::cerr << "PluginChannelAdapter::process: " << m_inputChannels << " -> " << m_pluginChannels << " channels" << std::endl;
cannam@0: 00181 
cannam@0: 00182     if (m_inputChannels < m_pluginChannels) {
cannam@0: 00183 
cannam@0: 00184         if (m_inputChannels == 1) {
cannam@0: 00185             for (size_t i = 0; i < m_pluginChannels; ++i) {
cannam@0: 00186                 m_forwardPtrs[i] = inputBuffers[0];
cannam@0: 00187             }
cannam@0: 00188         } else {
cannam@0: 00189             for (size_t i = 0; i < m_inputChannels; ++i) {
cannam@0: 00190                 m_forwardPtrs[i] = inputBuffers[i];
cannam@0: 00191             }
cannam@0: 00192             for (size_t i = m_inputChannels; i < m_pluginChannels; ++i) {
cannam@0: 00193                 m_forwardPtrs[i] = m_buffer[i - m_inputChannels];
cannam@0: 00194             }
cannam@0: 00195         }
cannam@0: 00196 
cannam@0: 00197         return m_plugin->process(m_forwardPtrs, timestamp);
cannam@0: 00198 
cannam@0: 00199     } else if (m_inputChannels > m_pluginChannels) {
cannam@0: 00200 
cannam@0: 00201         if (m_pluginChannels == 1) {
cannam@0: 00202             for (size_t j = 0; j < m_blockSize; ++j) {
cannam@0: 00203                 m_buffer[0][j] = inputBuffers[0][j];
cannam@0: 00204             }
cannam@0: 00205             for (size_t i = 1; i < m_inputChannels; ++i) {
cannam@0: 00206                 for (size_t j = 0; j < m_blockSize; ++j) {
cannam@0: 00207                     m_buffer[0][j] += inputBuffers[i][j];
cannam@0: 00208                 }
cannam@0: 00209             }
cannam@0: 00210             for (size_t j = 0; j < m_blockSize; ++j) {
cannam@0: 00211                 m_buffer[0][j] /= m_inputChannels;
cannam@0: 00212             }
cannam@0: 00213             return m_plugin->process(m_buffer, timestamp);
cannam@0: 00214         } else {
cannam@0: 00215             return m_plugin->process(inputBuffers, timestamp);
cannam@0: 00216         }
cannam@0: 00217 
cannam@0: 00218     } else {
cannam@0: 00219 
cannam@0: 00220         return m_plugin->process(inputBuffers, timestamp);
cannam@0: 00221     }
cannam@0: 00222 }
cannam@0: 00223 
cannam@0: 00224 }
cannam@0: 00225 
cannam@0: 00226 }
cannam@0: 00227 
cannam@0: 00228 
cannam@0: 
cannam@0:
Generated on Wed Jul 9 11:36:06 2008 for VampPluginSDK by  cannam@0: cannam@0: doxygen 1.5.5
cannam@0: cannam@0: