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;
...@@ -57,31 +41,33 @@ void ITADatasourceRealization::Init(unsigned int uiChannels, ...@@ -57,31 +41,33 @@ void ITADatasourceRealization::Init(unsigned int uiChannels,
Organisation des Puffers: Damit die Blcke der einzelnen Kanle Organisation des Puffers: Damit die Blcke der einzelnen Kanle
im Speicher ortlich nher liegen ist das Array wiefolgt indiziert: im Speicher ortlich nher liegen ist das Array wiefolgt indiziert:
[1. Block Kanal 1], ..., [1. Block Kanal k], [2. Block Kanal 1], ... [1. Block Kanal 1], ..., [1. Block Kanal k], [2. Block Kanal 1], ...
*/ */
// Puffer erzeugen und mit Nullen initialiseren // Puffer erzeugen und mit Nullen initialiseren
// TODO: Fehlerbehandlung beim Speicherallozieren // TODO: Fehlerbehandlung beim Speicherallozieren
/* Bugfix zu Bug #001: /* Bugfix zu Bug #001:
Hier wurde der Puffer einfach um 1024 Felder verlngert. Hier wurde der Puffer einfach um 1024 Felder verlngert.
Damit Funktioniert Wuschels ASIO4ALL jetzt. Ungeklrt aber Damit Funktioniert Wuschels ASIO4ALL jetzt. Ungeklrt aber
warum der Fehler auftrat? warum der Fehler auftrat?
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 )
{};