2008-06-02 21:41:35 +00:00
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
/*
Vamp
An API for audio analysis and feature extraction plugins .
Centre for Digital Music , Queen Mary , University of London .
2011-03-02 12:38:17 +00:00
Copyright 2006 - 2009 Chris Cannam and QMUL .
This file by Mark Levy and Chris Cannam , Copyright 2007 - 2009 QMUL .
2008-06-02 21:41:35 +00:00
Permission is hereby granted , free of charge , to any person
obtaining a copy of this software and associated documentation
files ( the " Software " ) , to deal in the Software without
restriction , including without limitation the rights to use , copy ,
modify , merge , publish , distribute , sublicense , and / or sell copies
of the Software , and to permit persons to whom the Software is
furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND ,
EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF
CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
Except as contained in this notice , the names of the Centre for
Digital Music ; Queen Mary , University of London ; and Chris Cannam
shall not be used in advertising or otherwise to promote the sale ,
use or other dealings in this Software without prior written
authorization .
*/
# include <vector>
# include <map>
2009-04-16 16:02:25 +00:00
# include "vamp-hostsdk/PluginBufferingAdapter.h"
2011-03-02 12:38:17 +00:00
# include "vamp-hostsdk/PluginInputDomainAdapter.h"
2008-06-02 21:41:35 +00:00
using std : : vector ;
using std : : map ;
2009-04-16 12:32:55 +00:00
_VAMP_SDK_HOSTSPACE_BEGIN ( PluginBufferingAdapter . cpp )
2008-06-02 21:41:35 +00:00
namespace Vamp {
namespace HostExt {
class PluginBufferingAdapter : : Impl
{
public :
Impl ( Plugin * plugin , float inputSampleRate ) ;
~ Impl ( ) ;
2009-04-16 12:32:55 +00:00
void setPluginStepSize ( size_t stepSize ) ;
void setPluginBlockSize ( size_t blockSize ) ;
2008-06-02 21:41:35 +00:00
bool initialise ( size_t channels , size_t stepSize , size_t blockSize ) ;
2009-04-16 12:32:55 +00:00
void getActualStepAndBlockSizes ( size_t & stepSize , size_t & blockSize ) ;
2008-06-02 21:41:35 +00:00
OutputList getOutputDescriptors ( ) const ;
2009-04-16 12:32:55 +00:00
void setParameter ( std : : string , float ) ;
void selectProgram ( std : : string ) ;
2008-06-02 21:41:35 +00:00
void reset ( ) ;
FeatureSet process ( const float * const * inputBuffers , RealTime timestamp ) ;
FeatureSet getRemainingFeatures ( ) ;
protected :
class RingBuffer
{
public :
RingBuffer ( int n ) :
m_buffer ( new float [ n + 1 ] ) , m_writer ( 0 ) , m_reader ( 0 ) , m_size ( n + 1 ) { }
virtual ~ RingBuffer ( ) { delete [ ] m_buffer ; }
int getSize ( ) const { return m_size - 1 ; }
void reset ( ) { m_writer = 0 ; m_reader = 0 ; }
int getReadSpace ( ) const {
int writer = m_writer , reader = m_reader , space ;
if ( writer > reader ) space = writer - reader ;
else if ( writer < reader ) space = ( writer + m_size ) - reader ;
else space = 0 ;
return space ;
}
int getWriteSpace ( ) const {
int writer = m_writer ;
int reader = m_reader ;
int space = ( reader + m_size - writer - 1 ) ;
if ( space > = m_size ) space - = m_size ;
return space ;
}
int peek ( float * destination , int n ) const {
int available = getReadSpace ( ) ;
if ( n > available ) {
for ( int i = available ; i < n ; + + i ) {
destination [ i ] = 0.f ;
}
n = available ;
}
if ( n = = 0 ) return n ;
int reader = m_reader ;
int here = m_size - reader ;
const float * const bufbase = m_buffer + reader ;
if ( here > = n ) {
for ( int i = 0 ; i < n ; + + i ) {
destination [ i ] = bufbase [ i ] ;
}
} else {
for ( int i = 0 ; i < here ; + + i ) {
destination [ i ] = bufbase [ i ] ;
}
float * const destbase = destination + here ;
const int nh = n - here ;
for ( int i = 0 ; i < nh ; + + i ) {
destbase [ i ] = m_buffer [ i ] ;
}
}
return n ;
}
int skip ( int n ) {
int available = getReadSpace ( ) ;
if ( n > available ) {
n = available ;
}
if ( n = = 0 ) return n ;
int reader = m_reader ;
reader + = n ;
while ( reader > = m_size ) reader - = m_size ;
m_reader = reader ;
return n ;
}
int write ( const float * source , int n ) {
int available = getWriteSpace ( ) ;
if ( n > available ) {
n = available ;
}
if ( n = = 0 ) return n ;
int writer = m_writer ;
int here = m_size - writer ;
float * const bufbase = m_buffer + writer ;
if ( here > = n ) {
for ( int i = 0 ; i < n ; + + i ) {
bufbase [ i ] = source [ i ] ;
}
} else {
for ( int i = 0 ; i < here ; + + i ) {
bufbase [ i ] = source [ i ] ;
}
const int nh = n - here ;
const float * const srcbase = source + here ;
float * const buf = m_buffer ;
for ( int i = 0 ; i < nh ; + + i ) {
buf [ i ] = srcbase [ i ] ;
}
}
writer + = n ;
while ( writer > = m_size ) writer - = m_size ;
m_writer = writer ;
return n ;
}
int zero ( int n ) {
int available = getWriteSpace ( ) ;
if ( n > available ) {
n = available ;
}
if ( n = = 0 ) return n ;
int writer = m_writer ;
int here = m_size - writer ;
float * const bufbase = m_buffer + writer ;
if ( here > = n ) {
for ( int i = 0 ; i < n ; + + i ) {
bufbase [ i ] = 0.f ;
}
} else {
for ( int i = 0 ; i < here ; + + i ) {
bufbase [ i ] = 0.f ;
}
const int nh = n - here ;
for ( int i = 0 ; i < nh ; + + i ) {
m_buffer [ i ] = 0.f ;
}
}
writer + = n ;
while ( writer > = m_size ) writer - = m_size ;
m_writer = writer ;
return n ;
}
protected :
float * m_buffer ;
int m_writer ;
int m_reader ;
int m_size ;
private :
RingBuffer ( const RingBuffer & ) ; // not provided
RingBuffer & operator = ( const RingBuffer & ) ; // not provided
} ;
Plugin * m_plugin ;
2009-04-16 12:32:55 +00:00
size_t m_inputStepSize ; // value passed to wrapper initialise()
size_t m_inputBlockSize ; // value passed to wrapper initialise()
size_t m_setStepSize ; // value passed to setPluginStepSize()
size_t m_setBlockSize ; // value passed to setPluginBlockSize()
size_t m_stepSize ; // value actually used to initialise plugin
size_t m_blockSize ; // value actually used to initialise plugin
2008-06-02 21:41:35 +00:00
size_t m_channels ;
vector < RingBuffer * > m_queue ;
float * * m_buffers ;
float m_inputSampleRate ;
2009-04-16 12:32:55 +00:00
long m_frame ;
2008-06-02 21:41:35 +00:00
bool m_unrun ;
2009-04-16 12:32:55 +00:00
mutable OutputList m_outputs ;
mutable std : : map < int , bool > m_rewriteOutputTimes ;
2008-06-02 21:41:35 +00:00
2009-04-16 12:32:55 +00:00
void processBlock ( FeatureSet & allFeatureSets ) ;
2008-06-02 21:41:35 +00:00
} ;
PluginBufferingAdapter : : PluginBufferingAdapter ( Plugin * plugin ) :
PluginWrapper ( plugin )
{
m_impl = new Impl ( plugin , m_inputSampleRate ) ;
}
PluginBufferingAdapter : : ~ PluginBufferingAdapter ( )
{
delete m_impl ;
}
2009-04-16 12:32:55 +00:00
size_t
PluginBufferingAdapter : : getPreferredStepSize ( ) const
{
return getPreferredBlockSize ( ) ;
}
size_t
PluginBufferingAdapter : : getPreferredBlockSize ( ) const
{
return PluginWrapper : : getPreferredBlockSize ( ) ;
}
size_t
PluginBufferingAdapter : : getPluginPreferredStepSize ( ) const
{
return PluginWrapper : : getPreferredStepSize ( ) ;
}
size_t
PluginBufferingAdapter : : getPluginPreferredBlockSize ( ) const
{
return PluginWrapper : : getPreferredBlockSize ( ) ;
}
void
PluginBufferingAdapter : : setPluginStepSize ( size_t stepSize )
{
m_impl - > setPluginStepSize ( stepSize ) ;
}
void
PluginBufferingAdapter : : setPluginBlockSize ( size_t blockSize )
{
m_impl - > setPluginBlockSize ( blockSize ) ;
}
void
PluginBufferingAdapter : : getActualStepAndBlockSizes ( size_t & stepSize ,
size_t & blockSize )
{
m_impl - > getActualStepAndBlockSizes ( stepSize , blockSize ) ;
}
2008-06-02 21:41:35 +00:00
bool
PluginBufferingAdapter : : initialise ( size_t channels , size_t stepSize , size_t blockSize )
{
return m_impl - > initialise ( channels , stepSize , blockSize ) ;
}
PluginBufferingAdapter : : OutputList
PluginBufferingAdapter : : getOutputDescriptors ( ) const
{
return m_impl - > getOutputDescriptors ( ) ;
}
2009-04-16 12:32:55 +00:00
void
PluginBufferingAdapter : : setParameter ( std : : string name , float value )
{
m_impl - > setParameter ( name , value ) ;
}
void
PluginBufferingAdapter : : selectProgram ( std : : string name )
{
m_impl - > selectProgram ( name ) ;
}
2008-06-02 21:41:35 +00:00
void
PluginBufferingAdapter : : reset ( )
{
m_impl - > reset ( ) ;
}
PluginBufferingAdapter : : FeatureSet
PluginBufferingAdapter : : process ( const float * const * inputBuffers ,
RealTime timestamp )
{
return m_impl - > process ( inputBuffers , timestamp ) ;
}
PluginBufferingAdapter : : FeatureSet
PluginBufferingAdapter : : getRemainingFeatures ( )
{
return m_impl - > getRemainingFeatures ( ) ;
}
PluginBufferingAdapter : : Impl : : Impl ( Plugin * plugin , float inputSampleRate ) :
m_plugin ( plugin ) ,
m_inputStepSize ( 0 ) ,
m_inputBlockSize ( 0 ) ,
2009-04-16 12:32:55 +00:00
m_setStepSize ( 0 ) ,
m_setBlockSize ( 0 ) ,
2008-06-02 21:41:35 +00:00
m_stepSize ( 0 ) ,
m_blockSize ( 0 ) ,
m_channels ( 0 ) ,
m_queue ( 0 ) ,
m_buffers ( 0 ) ,
m_inputSampleRate ( inputSampleRate ) ,
2009-04-16 12:32:55 +00:00
m_frame ( 0 ) ,
2008-06-02 21:41:35 +00:00
m_unrun ( true )
{
2009-04-16 12:32:55 +00:00
( void ) getOutputDescriptors ( ) ; // set up m_outputs and m_rewriteOutputTimes
2008-06-02 21:41:35 +00:00
}
PluginBufferingAdapter : : Impl : : ~ Impl ( )
{
// the adapter will delete the plugin
for ( size_t i = 0 ; i < m_channels ; + + i ) {
delete m_queue [ i ] ;
delete [ ] m_buffers [ i ] ;
}
delete [ ] m_buffers ;
}
2009-04-16 12:32:55 +00:00
void
PluginBufferingAdapter : : Impl : : setPluginStepSize ( size_t stepSize )
2008-06-02 21:41:35 +00:00
{
2009-04-16 12:32:55 +00:00
if ( m_inputStepSize ! = 0 ) {
std : : cerr < < " PluginBufferingAdapter::setPluginStepSize: ERROR: Cannot be called after initialise() " < < std : : endl ;
return ;
}
m_setStepSize = stepSize ;
2008-06-02 21:41:35 +00:00
}
2009-04-16 12:32:55 +00:00
void
PluginBufferingAdapter : : Impl : : setPluginBlockSize ( size_t blockSize )
{
if ( m_inputBlockSize ! = 0 ) {
std : : cerr < < " PluginBufferingAdapter::setPluginBlockSize: ERROR: Cannot be called after initialise() " < < std : : endl ;
return ;
}
m_setBlockSize = blockSize ;
}
void
PluginBufferingAdapter : : Impl : : getActualStepAndBlockSizes ( size_t & stepSize ,
size_t & blockSize )
{
stepSize = m_stepSize ;
blockSize = m_blockSize ;
}
2008-06-02 21:41:35 +00:00
bool
PluginBufferingAdapter : : Impl : : initialise ( size_t channels , size_t stepSize , size_t blockSize )
{
if ( stepSize ! = blockSize ) {
std : : cerr < < " PluginBufferingAdapter::initialise: input stepSize must be equal to blockSize for this adapter (stepSize = " < < stepSize < < " , blockSize = " < < blockSize < < " ) " < < std : : endl ;
return false ;
}
m_channels = channels ;
m_inputStepSize = stepSize ;
m_inputBlockSize = blockSize ;
2009-04-16 12:32:55 +00:00
// if the user has requested particular step or block sizes, use
// those; otherwise use the step and block sizes which the plugin
// prefers
m_stepSize = 0 ;
m_blockSize = 0 ;
if ( m_setStepSize > 0 ) {
m_stepSize = m_setStepSize ;
}
if ( m_setBlockSize > 0 ) {
m_blockSize = m_setBlockSize ;
}
if ( m_stepSize = = 0 & & m_blockSize = = 0 ) {
m_stepSize = m_plugin - > getPreferredStepSize ( ) ;
m_blockSize = m_plugin - > getPreferredBlockSize ( ) ;
}
2008-06-02 21:41:35 +00:00
2009-04-16 12:32:55 +00:00
bool freq = ( m_plugin - > getInputDomain ( ) = = Vamp : : Plugin : : FrequencyDomain ) ;
2008-06-02 21:41:35 +00:00
// or sensible defaults if it has no preference
if ( m_blockSize = = 0 ) {
2009-04-16 12:32:55 +00:00
if ( m_stepSize = = 0 ) {
m_blockSize = 1024 ;
if ( freq ) {
m_stepSize = m_blockSize / 2 ;
} else {
m_stepSize = m_blockSize ;
}
} else if ( freq ) {
2008-06-02 21:41:35 +00:00
m_blockSize = m_stepSize * 2 ;
} else {
m_blockSize = m_stepSize ;
}
2009-04-16 12:32:55 +00:00
} else if ( m_stepSize = = 0 ) { // m_blockSize != 0 (that was handled above)
if ( freq ) {
m_stepSize = m_blockSize / 2 ;
} else {
m_stepSize = m_blockSize ;
}
2008-06-02 21:41:35 +00:00
}
// current implementation breaks if step is greater than block
if ( m_stepSize > m_blockSize ) {
2009-04-16 12:32:55 +00:00
size_t newBlockSize ;
if ( freq ) {
newBlockSize = m_stepSize * 2 ;
} else {
newBlockSize = m_stepSize ;
}
std : : cerr < < " PluginBufferingAdapter::initialise: WARNING: step size " < < m_stepSize < < " is greater than block size " < < m_blockSize < < " : cannot handle this in adapter; adjusting block size to " < < newBlockSize < < std : : endl ;
m_blockSize = newBlockSize ;
2008-06-02 21:41:35 +00:00
}
2009-04-16 12:32:55 +00:00
// std::cerr << "PluginBufferingAdapter::initialise: NOTE: stepSize " << m_inputStepSize << " -> " << m_stepSize
// << ", blockSize " << m_inputBlockSize << " -> " << m_blockSize << std::endl;
2008-06-02 21:41:35 +00:00
m_buffers = new float * [ m_channels ] ;
for ( size_t i = 0 ; i < m_channels ; + + i ) {
m_queue . push_back ( new RingBuffer ( m_blockSize + m_inputBlockSize ) ) ;
m_buffers [ i ] = new float [ m_blockSize ] ;
}
2009-04-16 12:32:55 +00:00
bool success = m_plugin - > initialise ( m_channels , m_stepSize , m_blockSize ) ;
// std::cerr << "PluginBufferingAdapter::initialise: success = " << success << std::endl;
if ( success ) {
// Re-query outputs; properties such as bin count may have
// changed on initialise
m_outputs . clear ( ) ;
( void ) getOutputDescriptors ( ) ;
}
return success ;
2008-06-02 21:41:35 +00:00
}
PluginBufferingAdapter : : OutputList
PluginBufferingAdapter : : Impl : : getOutputDescriptors ( ) const
{
2009-04-16 12:32:55 +00:00
if ( m_outputs . empty ( ) ) {
// std::cerr << "PluginBufferingAdapter::getOutputDescriptors: querying anew" << std::endl;
m_outputs = m_plugin - > getOutputDescriptors ( ) ;
}
PluginBufferingAdapter : : OutputList outs = m_outputs ;
2008-06-02 21:41:35 +00:00
for ( size_t i = 0 ; i < outs . size ( ) ; + + i ) {
2009-04-16 12:32:55 +00:00
switch ( outs [ i ] . sampleType ) {
case OutputDescriptor : : OneSamplePerStep :
outs [ i ] . sampleType = OutputDescriptor : : FixedSampleRate ;
outs [ i ] . sampleRate = ( 1.f / m_inputSampleRate ) * m_stepSize ;
m_rewriteOutputTimes [ i ] = true ;
break ;
case OutputDescriptor : : FixedSampleRate :
if ( outs [ i ] . sampleRate = = 0.f ) {
outs [ i ] . sampleRate = ( 1.f / m_inputSampleRate ) * m_stepSize ;
}
// We actually only need to rewrite output times for
// features that don't have timestamps already, but we
// can't tell from here whether our features will have
// timestamps or not
m_rewriteOutputTimes [ i ] = true ;
break ;
case OutputDescriptor : : VariableSampleRate :
m_rewriteOutputTimes [ i ] = false ;
break ;
2008-06-02 21:41:35 +00:00
}
}
2009-04-16 12:32:55 +00:00
2008-06-02 21:41:35 +00:00
return outs ;
}
2009-04-16 12:32:55 +00:00
void
PluginBufferingAdapter : : Impl : : setParameter ( std : : string name , float value )
{
m_plugin - > setParameter ( name , value ) ;
// Re-query outputs; properties such as bin count may have changed
m_outputs . clear ( ) ;
( void ) getOutputDescriptors ( ) ;
}
void
PluginBufferingAdapter : : Impl : : selectProgram ( std : : string name )
{
m_plugin - > selectProgram ( name ) ;
// Re-query outputs; properties such as bin count may have changed
m_outputs . clear ( ) ;
( void ) getOutputDescriptors ( ) ;
}
2008-06-02 21:41:35 +00:00
void
PluginBufferingAdapter : : Impl : : reset ( )
{
2009-04-16 12:32:55 +00:00
m_frame = 0 ;
2008-06-02 21:41:35 +00:00
m_unrun = true ;
for ( size_t i = 0 ; i < m_queue . size ( ) ; + + i ) {
m_queue [ i ] - > reset ( ) ;
}
2009-04-16 12:32:55 +00:00
m_plugin - > reset ( ) ;
2008-06-02 21:41:35 +00:00
}
PluginBufferingAdapter : : FeatureSet
PluginBufferingAdapter : : Impl : : process ( const float * const * inputBuffers ,
RealTime timestamp )
{
2009-04-16 12:32:55 +00:00
if ( m_inputStepSize = = 0 ) {
std : : cerr < < " PluginBufferingAdapter::process: ERROR: Plugin has not been initialised " < < std : : endl ;
return FeatureSet ( ) ;
}
2008-06-02 21:41:35 +00:00
FeatureSet allFeatureSets ;
if ( m_unrun ) {
2009-04-16 12:32:55 +00:00
m_frame = RealTime : : realTime2Frame ( timestamp ,
int ( m_inputSampleRate + 0.5 ) ) ;
2008-06-02 21:41:35 +00:00
m_unrun = false ;
}
// queue the new input
for ( size_t i = 0 ; i < m_channels ; + + i ) {
int written = m_queue [ i ] - > write ( inputBuffers [ i ] , m_inputBlockSize ) ;
if ( written < int ( m_inputBlockSize ) & & i = = 0 ) {
std : : cerr < < " WARNING: PluginBufferingAdapter::Impl::process: "
< < " Buffer overflow: wrote " < < written
< < " of " < < m_inputBlockSize
< < " input samples (for plugin step size "
< < m_stepSize < < " , block size " < < m_blockSize < < " ) "
< < std : : endl ;
}
}
// process as much as we can
while ( m_queue [ 0 ] - > getReadSpace ( ) > = int ( m_blockSize ) ) {
2009-04-16 12:32:55 +00:00
processBlock ( allFeatureSets ) ;
2008-06-02 21:41:35 +00:00
}
return allFeatureSets ;
}
PluginBufferingAdapter : : FeatureSet
PluginBufferingAdapter : : Impl : : getRemainingFeatures ( )
{
FeatureSet allFeatureSets ;
// process remaining samples in queue
while ( m_queue [ 0 ] - > getReadSpace ( ) > = int ( m_blockSize ) ) {
2009-04-16 12:32:55 +00:00
processBlock ( allFeatureSets ) ;
2008-06-02 21:41:35 +00:00
}
// pad any last samples remaining and process
if ( m_queue [ 0 ] - > getReadSpace ( ) > 0 ) {
for ( size_t i = 0 ; i < m_channels ; + + i ) {
m_queue [ i ] - > zero ( m_blockSize - m_queue [ i ] - > getReadSpace ( ) ) ;
}
2009-04-16 12:32:55 +00:00
processBlock ( allFeatureSets ) ;
2008-06-02 21:41:35 +00:00
}
// get remaining features
FeatureSet featureSet = m_plugin - > getRemainingFeatures ( ) ;
for ( map < int , FeatureList > : : iterator iter = featureSet . begin ( ) ;
iter ! = featureSet . end ( ) ; + + iter ) {
FeatureList featureList = iter - > second ;
for ( size_t i = 0 ; i < featureList . size ( ) ; + + i ) {
allFeatureSets [ iter - > first ] . push_back ( featureList [ i ] ) ;
}
}
return allFeatureSets ;
}
void
2009-04-16 12:32:55 +00:00
PluginBufferingAdapter : : Impl : : processBlock ( FeatureSet & allFeatureSets )
2008-06-02 21:41:35 +00:00
{
for ( size_t i = 0 ; i < m_channels ; + + i ) {
m_queue [ i ] - > peek ( m_buffers [ i ] , m_blockSize ) ;
}
2009-04-16 12:32:55 +00:00
long frame = m_frame ;
RealTime timestamp = RealTime : : frame2RealTime
( frame , int ( m_inputSampleRate + 0.5 ) ) ;
FeatureSet featureSet = m_plugin - > process ( m_buffers , timestamp ) ;
2008-06-02 21:41:35 +00:00
2011-03-02 12:38:17 +00:00
PluginWrapper * wrapper = dynamic_cast < PluginWrapper * > ( m_plugin ) ;
RealTime adjustment ;
if ( wrapper ) {
PluginInputDomainAdapter * ida =
wrapper - > getWrapper < PluginInputDomainAdapter > ( ) ;
if ( ida ) adjustment = ida - > getTimestampAdjustment ( ) ;
}
2009-04-16 12:32:55 +00:00
for ( FeatureSet : : iterator iter = featureSet . begin ( ) ;
2008-06-02 21:41:35 +00:00
iter ! = featureSet . end ( ) ; + + iter ) {
2009-04-16 12:32:55 +00:00
2008-06-02 21:41:35 +00:00
int outputNo = iter - > first ;
2009-04-16 12:32:55 +00:00
if ( m_rewriteOutputTimes [ outputNo ] ) {
2008-06-02 21:41:35 +00:00
2009-04-16 12:32:55 +00:00
FeatureList featureList = iter - > second ;
for ( size_t i = 0 ; i < featureList . size ( ) ; + + i ) {
2008-06-02 21:41:35 +00:00
2009-04-16 12:32:55 +00:00
switch ( m_outputs [ outputNo ] . sampleType ) {
2008-06-02 21:41:35 +00:00
2009-04-16 12:32:55 +00:00
case OutputDescriptor : : OneSamplePerStep :
// use our internal timestamp, always
2011-03-02 12:38:17 +00:00
featureList [ i ] . timestamp = timestamp + adjustment ;
2009-04-16 12:32:55 +00:00
featureList [ i ] . hasTimestamp = true ;
break ;
2008-06-02 21:41:35 +00:00
2009-04-16 12:32:55 +00:00
case OutputDescriptor : : FixedSampleRate :
// use our internal timestamp if feature lacks one
if ( ! featureList [ i ] . hasTimestamp ) {
2011-03-02 12:38:17 +00:00
featureList [ i ] . timestamp = timestamp + adjustment ;
2009-04-16 12:32:55 +00:00
featureList [ i ] . hasTimestamp = true ;
}
break ;
2008-06-02 21:41:35 +00:00
2009-04-16 12:32:55 +00:00
case OutputDescriptor : : VariableSampleRate :
break ; // plugin must set timestamp
default :
break ;
}
2008-06-02 21:41:35 +00:00
2009-04-16 12:32:55 +00:00
allFeatureSets [ outputNo ] . push_back ( featureList [ i ] ) ;
}
} else {
for ( size_t i = 0 ; i < iter - > second . size ( ) ; + + i ) {
allFeatureSets [ outputNo ] . push_back ( iter - > second [ i ] ) ;
}
2008-06-02 21:41:35 +00:00
}
}
// step forward
for ( size_t i = 0 ; i < m_channels ; + + i ) {
m_queue [ i ] - > skip ( m_stepSize ) ;
}
2009-04-16 12:32:55 +00:00
// increment internal frame counter each time we step forward
m_frame + = m_stepSize ;
2008-06-02 21:41:35 +00:00
}
}
}
2009-04-16 12:32:55 +00:00
_VAMP_SDK_HOSTSPACE_END ( PluginBufferingAdapter . cpp )