Commit 8c33c69d authored by Anne Heimes's avatar Anne Heimes

Merge branch 'ba_2016_heimes' of https://git.rwth-aachen.de/ita/ITADataSources into ba_2016_heimes

parents b28e2b15 e09426c6
...@@ -111,6 +111,7 @@ endif( ) ...@@ -111,6 +111,7 @@ endif( )
if( ITA_DATA_SOURCES_WITH_NET_AUDIO ) if( ITA_DATA_SOURCES_WITH_NET_AUDIO )
list( APPEND ITADataSourcesHeader list( APPEND ITADataSourcesHeader
"include/ITANetAudioStream.h" "include/ITANetAudioStream.h"
"include/ITANetAudioSampleServer.h"
"include/ITANetAudioStreamingServer.h" "include/ITANetAudioStreamingServer.h"
) )
list( APPEND ITADataSourcesSources list( APPEND ITADataSourcesSources
......
/*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_NET_AUDIO_SAMPLE_SERVER
#define INCLUDE_WATCHER_ITA_NET_AUDIO_SAMPLE_SERVER
#include <ITADataSourcesDefinitions.h>
#include <ITANetAudioStreamingServer.h>
#include <ITADataSourceRealization.h>
//! Sample-generation class with abstract method for providing samples
/*
* This ready-to-use class helps to provide samples for a NetAudio streaming server with
* a single method for processing that has to be implemented ...
* ... just derive and implement Process() method. Have a look at Zero() method
* for exemplary usage of sample buffer.
*/
class ITA_DATA_SOURCES_API CITASampleProcessor : public ITADatasourceRealization
{
public:
//! Create a sample processor with streaming parameters
/*
* @param[in] iNumChannels Channels provided
* @param[in] dSampleRate Audio processing sampling rate
* @param[in] iBlockLength Audio processing block length / buffer size
*/
inline CITASampleProcessor( const int iNumChannels, const double dSampleRate, const int iBlockLength )
: ITADatasourceRealization( ( unsigned int ) ( iNumChannels ), dSampleRate, ( unsigned int ) ( iBlockLength ) )
{
m_vvfSampleBuffer.resize( iNumChannels );
for( size_t c = 0; c < iNumChannels; c++ )
m_vvfSampleBuffer[ c ].resize( iBlockLength );
Zero();
};
//! Sets all channels and samples to zero
inline void Zero()
{
/*
* Use this as an example how to work with the buffer structure.
*/
// Iterate over channels
for( size_t c = 0; c < m_vvfSampleBuffer.size(); c++ )
{
std::vector< float >& vfSingleChannelSampleBuffer( m_vvfSampleBuffer[ c ] ); // One channel
// Iterate over samples of channel
for( size_t n = 0; n < vfSingleChannelSampleBuffer.size(); n++ )
{
float& fSample( vfSingleChannelSampleBuffer[ n ] ); // One sample
fSample = 0.0f; // -> Manipulation
}
}
};
//! Process samples (overwrite this virtual method)
/**
* Method that is called in audio streaming context and requests
* to produce or copy audio samples into the internal buffer m_vvfSampleBuffer
*
* @param[in] pStreamInfo Information over streaming status, i.e. sample count and time stamp
*
*/
virtual void Process( const ITAStreamInfo* pStreamInfo ) =0;
protected:
std::vector< std::vector< float > > m_vvfSampleBuffer; //!< Multi-channel sample buffer to be filled
private:
//! Delegate internal buffer to audio stream (ITADatasource)
inline void ProcessStream( const ITAStreamInfo* pInfo )
{
Process( pInfo );
for( size_t c = 0; c < m_vvfSampleBuffer.size(); c++ )
{
float* pfData = GetWritePointer( ( unsigned int ) ( c ) );
for( size_t n = 0; n < m_vvfSampleBuffer[ c ].size(); n++ )
pfData[ n ] = m_vvfSampleBuffer[ c ][ n ];
}
IncrementWritePointer();
};
};
//! Network audio sample server (for providing samples via derived generator class)
/**
* Audio sample transmitter for a networked sample callback function that can connect via TCP/IP.
*
* @sa CITANetAudioStream CITANetAudioStreamingServer CITASampleProcessor
* @note not thread-safe
*/
class ITA_DATA_SOURCES_API CITANetAudioSampleServer : public CITANetAudioStreamingServer
{
public:
inline CITANetAudioSampleServer( CITASampleProcessor* pProcessor )
: m_pSampleProcessor( pProcessor )
{
SetInputStream( m_pSampleProcessor );
};
inline ~CITANetAudioSampleServer()
{};
private:
//! Prohibit public access to streaming context and delegate
inline void SetInputStream( ITADatasource* pDataSource )
{
CITANetAudioStreamingServer::SetInputStream( pDataSource );
};
//! Prohibit public access to streaming context and delegate
inline ITADatasource* GetInputStream() const
{
return CITANetAudioStreamingServer::GetInputStream();
};
CITASampleProcessor* m_pSampleProcessor; //!< Callback / sample processor
};
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_SAMPLE_SERVER
...@@ -44,7 +44,7 @@ class VistaConnectionIP; ...@@ -44,7 +44,7 @@ class VistaConnectionIP;
/** /**
* Audio sample transmitter for a networked signal source that can connect via TCP/IP. * Audio sample transmitter for a networked signal source that can connect via TCP/IP.
* *
* @sa CITANetAudioStream, CITANetAudioSampleServer * @sa CITANetAudioStream
* @note not thread-safe * @note not thread-safe
*/ */
class ITA_DATA_SOURCES_API CITANetAudioStreamingServer : public VistaThreadLoop class ITA_DATA_SOURCES_API CITANetAudioStreamingServer : public VistaThreadLoop
...@@ -115,6 +115,9 @@ private: ...@@ -115,6 +115,9 @@ private:
int m_iSendingBlockLength; int m_iSendingBlockLength;
int m_iMaxSendBlocks; int m_iMaxSendBlocks;
double m_dStreamTimeStart; //!< Stream time start
long unsigned int m_nStreamSampleCounts; //!< Samples that has been streamed
friend class CITANetAudioServer; friend class CITANetAudioServer;
}; };
......
// $Id: $ /*
* ----------------------------------------------------------------
*
* ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef __ITA_STREAM_INFO_H__ #ifndef INCLUDE_WATCHER_ITA_STREAM_INFO
#define __ITA_STREAM_INFO_H__ #define INCLUDE_WATCHER_ITA_STREAM_INFO
#include <ITATypes.h> #include <ITATypes.h>
// Diese Datenklasse beschreibt den Zustand eines Audiostreams //! Time code information for audio streams
class ITAStreamInfo { class ITAStreamInfo
{
public: public:
// Anzahl der abgespielten Samples seit Beginn des Streamings uint64_t nSamples; //!< Number of samples processed
uint64_t nSamples; double dTimecode; //!< Time code
// TODO: Beschreiben inline ITAStreamInfo()
double dTimecode; : nSamples( 0 )
, dTimecode( 0 )
{};
//! Standard-Konstruktor (setzt alle Werte 0)
ITAStreamInfo() : nSamples(0), dTimecode(0) {}
//! Destruktor
virtual ~ITAStreamInfo() {}; virtual ~ITAStreamInfo() {};
}; };
#endif // __ITA_STREAM_INFO_H__ #endif // INCLUDE_WATCHER_ITA_STREAM_INFO
#include "ITADataSourceRealization.h" #include "ITADataSourceRealization.h"
#include <cassert>
#include <ITAFastMath.h> #include <ITAFastMath.h>
#include <cassert>
/* ITADatasourceRealization::ITADatasourceRealization( unsigned int uiChannels, double dSamplerate, unsigned int uiBlocklength, unsigned int uiCapacity )
ITADatasourceRealization::ITADatasourceRealization(unsigned int uiChannels,
unsigned int uiBlocklength,
unsigned int uiCapacity)
{
Init(uiChannels, uiBlocklength, uiCapacity);
}
*/
ITADatasourceRealization::ITADatasourceRealization(unsigned int uiChannels,
double dSamplerate,
unsigned int uiBlocklength,
unsigned int uiCapacity)
{ {
assert( dSamplerate > 0 ); assert( dSamplerate > 0 );
m_dSampleRate = dSamplerate; m_dSampleRate = dSamplerate;
m_oStreamProps.dSamplerate = dSamplerate; m_oStreamProps.dSamplerate = dSamplerate;
Init(uiChannels, uiBlocklength, uiCapacity); Init( uiChannels, uiBlocklength, uiCapacity );
} }
void ITADatasourceRealization::Init(unsigned int uiChannels, void ITADatasourceRealization::Init( unsigned int uiChannels, unsigned int uiBlocklength, unsigned int uiCapacity )
unsigned int uiBlocklength,
unsigned int uiCapacity)
{ {
assert( uiChannels > 0 ); assert( uiChannels > 0 );
assert( uiBlocklength > 0 ); assert( uiBlocklength > 0 );
...@@ -49,7 +33,7 @@ void ITADatasourceRealization::Init(unsigned int uiChannels, ...@@ -49,7 +33,7 @@ void ITADatasourceRealization::Init(unsigned int uiChannels,
m_oStreamProps.uiChannels = m_uiChannels; m_oStreamProps.uiChannels = m_uiChannels;
m_oStreamProps.uiBlocklength = m_uiBlocklength; m_oStreamProps.uiBlocklength = m_uiBlocklength;
m_uiBufferSize = uiBlocklength * (uiCapacity+1); m_uiBufferSize = uiBlocklength * ( uiCapacity + 1 );
m_pEventHandler = NULL; m_pEventHandler = NULL;
...@@ -72,16 +56,18 @@ void ITADatasourceRealization::Init(unsigned int uiChannels, ...@@ -72,16 +56,18 @@ void ITADatasourceRealization::Init(unsigned int uiChannels,
2005-2-14 2005-2-14
*/ */
m_pfBuffer = fm_falloc(m_uiBufferSize * m_uiChannels + /* >>> */ 1024 /* <<< */, false); m_pfBuffer = fm_falloc( m_uiBufferSize * m_uiChannels + /* >>> */ 1024 /* <<< */, false );
Reset(); Reset();
} }
ITADatasourceRealization::~ITADatasourceRealization() { ITADatasourceRealization::~ITADatasourceRealization()
fm_free(m_pfBuffer); {
fm_free( m_pfBuffer );
} }
void ITADatasourceRealization::Reset() { void ITADatasourceRealization::Reset()
{
m_uiReadCursor = 0; m_uiReadCursor = 0;
m_uiWriteCursor = 0; m_uiWriteCursor = 0;
...@@ -93,22 +79,26 @@ void ITADatasourceRealization::Reset() { ...@@ -93,22 +79,26 @@ void ITADatasourceRealization::Reset() {
m_iGBPEntrances = 0; m_iGBPEntrances = 0;
m_bGBPFirst = true; m_bGBPFirst = true;
fm_zero(m_pfBuffer, m_uiBufferSize * m_uiChannels + /* >>> */ 1024 /* <<< */); fm_zero( m_pfBuffer, m_uiBufferSize * m_uiChannels + /* >>> */ 1024 /* <<< */ );
} }
bool ITADatasourceRealization::HasStreamErrors() const { bool ITADatasourceRealization::HasStreamErrors() const
return (m_iBufferUnderflows > 0) || (m_iBufferOverflows > 0) || (m_iGBPReentrances > 0); {
return ( m_iBufferUnderflows > 0 ) || ( m_iBufferOverflows > 0 ) || ( m_iGBPReentrances > 0 );
} }
ITADatasourceRealizationEventHandler* ITADatasourceRealization::GetStreamEventHandler() const { ITADatasourceRealizationEventHandler* ITADatasourceRealization::GetStreamEventHandler() const
{
return m_pEventHandler; return m_pEventHandler;
} }
void ITADatasourceRealization::SetStreamEventHandler(ITADatasourceRealizationEventHandler* pHandler) { void ITADatasourceRealization::SetStreamEventHandler( ITADatasourceRealizationEventHandler* pHandler )
{
m_pEventHandler = pHandler; m_pEventHandler = pHandler;
} }
const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, const ITAStreamInfo* pStreamInfo) { const float* ITADatasourceRealization::GetBlockPointer( unsigned int uiChannel, const ITAStreamInfo* pStreamInfo )
{
assert( uiChannel < m_uiChannels ); assert( uiChannel < m_uiChannels );
/* /*
...@@ -117,7 +107,8 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c ...@@ -117,7 +107,8 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c
* *
* WICHTIG: Dies sollte nicht passieren. Fehler beim anwendenden Programmierer! * WICHTIG: Dies sollte nicht passieren. Fehler beim anwendenden Programmierer!
*/ */
if (++m_iGBPEntrances > 1) { if( ++m_iGBPEntrances > 1 )
{
--m_iGBPEntrances; --m_iGBPEntrances;
++m_iGBPReentrances; ++m_iGBPReentrances;
return NULL; return NULL;
...@@ -125,12 +116,16 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c ...@@ -125,12 +116,16 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c
// Hook/Handler aufrufen // Hook/Handler aufrufen
PreGetBlockPointer(); PreGetBlockPointer();
if (m_pEventHandler) m_pEventHandler->HandlePreGetBlockPointer(this, uiChannel); if( m_pEventHandler )
m_pEventHandler->HandlePreGetBlockPointer( this, uiChannel );
if (m_bGBPFirst) { if( m_bGBPFirst )
{
// Erster Eintritt in GBP seit letztem IBP => Daten produzieren // Erster Eintritt in GBP seit letztem IBP => Daten produzieren
ProcessStream(pStreamInfo); ProcessStream( pStreamInfo );
if (m_pEventHandler) m_pEventHandler->HandleProcessStream(this, pStreamInfo);
if( m_pEventHandler )
m_pEventHandler->HandleProcessStream( this, pStreamInfo );
m_bGBPFirst = false; m_bGBPFirst = false;
} }
...@@ -145,45 +140,51 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c ...@@ -145,45 +140,51 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c
*/ */
unsigned int uiLocalReadCursor = m_uiReadCursor; unsigned int uiLocalReadCursor = m_uiReadCursor;
if (uiLocalReadCursor == m_uiWriteCursor) { if( uiLocalReadCursor == m_uiWriteCursor )
{
++m_iBufferUnderflows; ++m_iBufferUnderflows;
--m_iGBPEntrances; --m_iGBPEntrances;
return NULL; return NULL;
} }
--m_iGBPEntrances; --m_iGBPEntrances;
return m_pfBuffer + (uiChannel * m_uiBufferSize) + uiLocalReadCursor; return m_pfBuffer + ( uiChannel * m_uiBufferSize ) + uiLocalReadCursor;
} }
void ITADatasourceRealization::IncrementBlockPointer() { void ITADatasourceRealization::IncrementBlockPointer()
{
unsigned int uiLocalReadCursor = m_uiReadCursor; unsigned int uiLocalReadCursor = m_uiReadCursor;
if (uiLocalReadCursor == m_uiWriteCursor) if( uiLocalReadCursor == m_uiWriteCursor )
// Keine Daten im Ausgabepuffer? Kein Inkrement mglich! (Fehlerfall) // Keine Daten im Ausgabepuffer? Kein Inkrement mglich! (Fehlerfall)
++m_iBufferUnderflows; ++m_iBufferUnderflows;
else else
// Lesezeiger inkrementieren // Lesezeiger inkrementieren
m_uiReadCursor = (uiLocalReadCursor + m_uiBlocklength) % m_uiBufferSize; m_uiReadCursor = ( uiLocalReadCursor + m_uiBlocklength ) % m_uiBufferSize;
m_bGBPFirst = true; m_bGBPFirst = true;
PostIncrementBlockPointer(); PostIncrementBlockPointer();
if (m_pEventHandler) m_pEventHandler->HandlePostIncrementBlockPointer(this);
if( m_pEventHandler )
m_pEventHandler->HandlePostIncrementBlockPointer( this );
} }
float* ITADatasourceRealization::GetWritePointer(unsigned int uiChannel) { float* ITADatasourceRealization::GetWritePointer( unsigned int uiChannel )
{
assert( uiChannel < m_uiChannels ); assert( uiChannel < m_uiChannels );
return m_pfBuffer + (uiChannel * m_uiBufferSize) + m_uiWriteCursor; return m_pfBuffer + ( uiChannel * m_uiBufferSize ) + m_uiWriteCursor;
} }
void ITADatasourceRealization::IncrementWritePointer() { void ITADatasourceRealization::IncrementWritePointer()
{
// Lokaler Schreibcursor // Lokaler Schreibcursor
unsigned int uiLocalWriteCursor = m_uiWriteCursor; unsigned int uiLocalWriteCursor = m_uiWriteCursor;
unsigned int uiNewWriteCursor = (uiLocalWriteCursor + m_uiBlocklength) % m_uiBufferSize; unsigned int uiNewWriteCursor = ( uiLocalWriteCursor + m_uiBlocklength ) % m_uiBufferSize;
// Pufferberlauf // Pufferberlauf
if (uiNewWriteCursor == m_uiReadCursor) { if( uiNewWriteCursor == m_uiReadCursor )
{
++m_iBufferOverflows; ++m_iBufferOverflows;
return; return;
} }
...@@ -192,6 +193,6 @@ void ITADatasourceRealization::IncrementWritePointer() { ...@@ -192,6 +193,6 @@ void ITADatasourceRealization::IncrementWritePointer() {
m_uiWriteCursor = uiNewWriteCursor; m_uiWriteCursor = uiNewWriteCursor;
} }
void ITADatasourceRealizationEventHandler::HandlePreGetBlockPointer(ITADatasourceRealization* pSender, unsigned int uiChannel) {} void ITADatasourceRealizationEventHandler::HandlePreGetBlockPointer( ITADatasourceRealization*, unsigned int ) {}
void ITADatasourceRealizationEventHandler::HandlePostIncrementBlockPointer(ITADatasourceRealization* pSender) {} void ITADatasourceRealizationEventHandler::HandlePostIncrementBlockPointer( ITADatasourceRealization* ) {}
void ITADatasourceRealizationEventHandler::HandleProcessStream(ITADatasourceRealization* pSender, const ITAStreamInfo* pStreamInfo) {} void ITADatasourceRealizationEventHandler::HandleProcessStream( ITADatasourceRealization*, const ITAStreamInfo* ) {}
...@@ -71,6 +71,8 @@ CITANetAudioStreamingServer::CITANetAudioStreamingServer() ...@@ -71,6 +71,8 @@ CITANetAudioStreamingServer::CITANetAudioStreamingServer()
, m_iEstimatedClientRingBufferFreeSamples( 0 ) , m_iEstimatedClientRingBufferFreeSamples( 0 )
, m_iClientRingBufferSize( 0 ) , m_iClientRingBufferSize( 0 )
, m_dEstimatedCorrFactor( 1 ) , m_dEstimatedCorrFactor( 1 )
, m_dStreamTimeStart( 0.0f )
, m_nStreamSampleCounts( 0 )
{ {
// Careful with this: // Careful with this:
//SetPriority( VistaPriority::VISTA_MID_PRIORITY ); //SetPriority( VistaPriority::VISTA_MID_PRIORITY );
...@@ -160,6 +162,9 @@ bool CITANetAudioStreamingServer::LoopBody() ...@@ -160,6 +162,9 @@ bool CITANetAudioStreamingServer::LoopBody()
{ {
const double dNow = ITAClock::getDefaultClock()->getTime(); const double dNow = ITAClock::getDefaultClock()->getTime();
if( m_dStreamTimeStart == 0.0f )
m_dStreamTimeStart = dNow;
CITAServerLog oLog; CITAServerLog oLog;
oLog.dWorldTimeStamp = dNow; oLog.dWorldTimeStamp = dNow;
oLog.uiBlockId = ++m_iServerBlockId; oLog.uiBlockId = ++m_iServerBlockId;
...@@ -182,10 +187,11 @@ bool CITANetAudioStreamingServer::LoopBody() ...@@ -182,10 +187,11 @@ bool CITANetAudioStreamingServer::LoopBody()
for( int i = 0; i < int( m_pInputStream->GetNumberOfChannels() ); i++ ) for( int i = 0; i < int( m_pInputStream->GetNumberOfChannels() ); i++ )
{ {
ITAStreamInfo oStreamInfo; ITAStreamInfo oStreamInfo;
oStreamInfo.nSamples = m_iSendingBlockLength; oStreamInfo.nSamples = ( m_nStreamSampleCounts += m_iSendingBlockLength );
oStreamInfo.dTimecode = dNow - m_dStreamTimeStart;
const float* pfData = m_pInputStream->GetBlockPointer( i, &oStreamInfo ); const float* pfData = m_pInputStream->GetBlockPointer( i, &oStreamInfo );
if( pfData != 0 ) if( pfData != nullptr )
m_sfTempTransmitBuffer[ i ].write( pfData, m_iSendingBlockLength, 0 ); m_sfTempTransmitBuffer[ i ].write( pfData, m_iSendingBlockLength, 0 );
} }
......
#include <ITANetAudioStreamingServer.h> #include <ITANetAudioStreamingServer.h>
#include <ITANetAudioSampleServer.h>
#include <ITANetAudioStream.h> #include <ITANetAudioStream.h>
#include <ITAPortaudioInterface.h> #include <ITAPortaudioInterface.h>
#include <ITAStreamFunctionGenerator.h> #include <ITAStreamFunctionGenerator.h>
...@@ -8,6 +9,7 @@ ...@@ -8,6 +9,7 @@
#include <ITAStreamProbe.h> #include <ITAStreamProbe.h>
#include <ITAStreamPatchBay.h> #include <ITAStreamPatchBay.h>
#include <ITAAsioInterface.h> #include <ITAAsioInterface.h>
#include <ITAStreamInfo.h>
#include <VistaBase/VistaStreamUtils.h> #include <VistaBase/VistaStreamUtils.h>
#include <VistaBase/VistaTimeUtils.h> #include <VistaBase/VistaTimeUtils.h>
...@@ -24,7 +26,7 @@ const static string g_sInputFilePath = "gershwin-mono.wav"; ...@@ -24,7 +26,7 @@ const static string g_sInputFilePath = "gershwin-mono.wav";
const static int g_iServerPort = 12480; const static int g_iServerPort = 12480;
const static double g_dSampleRate = 44100; const static double g_dSampleRate = 44100;
const static int g_iBlockLength = 512; const static int g_iBlockLength = 512;
const static int g_iChannels = 160; const static int g_iChannels = 2;
const static int g_iTargetLatencySamples = g_iBlockLength * 2; const static int g_iTargetLatencySamples = g_iBlockLength * 2;
const static int g_iRingerBufferCapacity = g_iBlockLength * 10; const static int g_iRingerBufferCapacity = g_iBlockLength * 10;
const static double g_dDuration = 10.0f; const static double g_dDuration = 10.0f;
...@@ -34,53 +36,103 @@ const static string g_sAudioInterface = "ASIO4ALL v2"; ...@@ -34,53 +36,103 @@ const static string g_sAudioInterface = "ASIO4ALL v2";
//const static string g_sAudioInterface = "ASIO Hammerfall DSP"; //const static string g_sAudioInterface = "ASIO Hammerfall DSP";
const static bool g_bUseUDP = false; const static bool g_bUseUDP = false;
class CServer : public VistaThread class CSampleGenerator : public CITASampleProcessor
{ {
public: public:
inline CServer( const string& sInputFilePath ) inline CSampleGenerator()
: CITASampleProcessor( g_dSampleRate, g_iChannels, g_iBlockLength )
{};
inline void Process( const ITAStreamInfo* pStreamInfo )
{
for( size_t c = 0; c < m_vvfSampleBuffer.size(); c++ )
{