...
 
Commits (119)
......@@ -110,23 +110,22 @@ endif( )
if( ITA_DATA_SOURCES_WITH_NET_AUDIO )
list( APPEND ITADataSourcesHeader
"include/ITANetAudioClient.h"
"include/ITANetAudioMessage.h"
"include/ITANetAudioProtocol.h"
"include/ITANetAudioServer.h"
"include/ITANetAudioStream.h"
"include/ITANetAudioStreamingClient.h"
"include/ITANetAudioSampleServer.h"
"include/ITANetAudioStreamingServer.h"
"include/ITANetAudioStreamingClient.h"
)
list( APPEND ITADataSourcesSources
"src/ITANetAudioClient.cpp"
"src/ITANetAudioClient.h"
"src/ITANetAudioMessage.cpp"
"src/ITANetAudioProtocol.cpp"
"src/ITANetAudioMessage.h"
"src/ITANetAudioProtocol.h"
"src/ITANetAudioServer.cpp"
"src/ITANetAudioServer.h"
"src/ITANetAudioStream.cpp"
"src/ITANetAudioStreamingClient.cpp"
"src/ITANetAudioStreamingClient.h"
"src/ITANetAudioStreamingServer.cpp"
"src/ITANetAudioServer.cpp"
)
endif( )
......
/*
* ----------------------------------------------------------------
*
* 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 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();
};
inline ~CITASampleProcessor()
{
};
//! 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 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
......@@ -26,9 +26,6 @@
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;
class CITANetAudioStreamingClient;
......@@ -38,7 +35,7 @@ class ITABufferedDataLoggerImplAudio;
//! Network audio stream
/**
* Audio streaming for a signal source that is connected via TCP/IP.
* Audio streaming for a signal source that is connected via TCP/IP or UDP.
* The network audio stream behaves like a client and receives samples
* from a network audio stream server, CITANetAudioStreamingSearver.
*
......@@ -46,11 +43,13 @@ class ITABufferedDataLoggerImplAudio;
* block the streaming processing, because it is decoupled from the
* network connection and forwards samples from an internal ring buffer.
* If the buffer runs out of samples, zeros will be return. If the buffer
* overruns, the sample server will be suspendeb by blocking the network
* overruns, the sample server will be suspended by blocking the network
* data flow.
*
* Latency can be managed by either providing a small ring buffer or
* oversizing the ring buffer and requesting a target latency.
* Latency can be managed by either providing a small ring buffer and
* constantly filling it uo, or by oversizing the internal ring buffer
* only pushing samples to meet a target latency. This has to be
* implemented by the server.
*
* \note not thread-safe
*/
......@@ -58,7 +57,21 @@ class ITA_DATA_SOURCES_API CITANetAudioStream : public ITADatasource
{
public:
//! Constructor of a network audio stream
CITANetAudioStream( int iChannels, double dSamplingRate, int iBufferSize, int iRingBufferCapacity = 2048 );
/**
* @param[in] iChannels Number of channels
* @param[in] dSamplingRate Sampling rate
* @param[in] iBufferSize Size of audio streaming buffer
* @param[in] iRingBufferCapacity Internal ring buffer
*
* The ring buffer capacity should be roughly 6-10 buffer sizes long for short audio streaming buffers,
* and can go down to one block in case of higher audio buffer sizes.
*
* The streaming parameters have to match with the server settings (yes also buffer size, that of the audio streaming context)
*
* @note Accept for more memory usage, oversizing the buffer does not require more CPU.
*/
CITANetAudioStream( const int iChannels, const double dSamplingRate, const int iBufferSize, const int iRingBufferCapacity = 2048 );
virtual ~CITANetAudioStream();
//! Network streaming status of client
......@@ -68,16 +81,20 @@ public:
STOPPED, //!< Client not connected to a server and streaming stopped, i.e. not receiving samples by choice
CONNECTED, //!< Client is connected to a sample server (and potentially receives samples)
STREAMING, //!<
BUFFER_UNDERRUN,
BUFFER_OVERRUN,
BUFFER_UNDERRUN, //!< Client internal audio buffer ran out of samples
BUFFER_OVERRUN, //!< Client internal audio ring buffer is full
};
//! Connect a streaming server
/**
* @sAddress[in] Server address IP, i.e. 127.0.0.1
* @sAddress[in] Server address IP (127.0.0.1, localhost, etc.)
* @iPort[in] Server socket port, defaults to 12480
* @return True, if connection could be established and streaming parameters match
*/
bool Connect( const std::string& sAddress, int iPort = 12480 );
bool Connect( const std::string& sAddress, const int iPort = 12480, const bool bUseUDP = false );
//! Disconnct safely from server
void Disconnect();
//! Returns the connection status
/**
......@@ -85,43 +102,47 @@ public:
*/
bool GetIsConnected() const;
//! Set allowed latency (s)
//! Returns the minimal latency possible (single block)
/**
* Sets the latency that will be used for reading and writing from ring buffer.
* New samples will be requested and send if the latency / ring buffer samples
* is lower than the target latency.
*/
void SetAllowedLatencySeconds( float fLatencySeconds );
void SetAllowedLatencySamples( int iLatencySamples );
float GetAllowedLatencySeconds() const;
int GetAllowedLatencySamples() const;
//! Sets the minimal latency possible
/**
* Real-time network audio is considered to process at lowest latency possible.
* However, this implementation requires at least one block. Hence latency is
* depending on sampling rate and block length.
*
* @sa GetMinimumLatencySamples()
* @sa GetMinimumLatencySamples()
* @return Minimum latency in seconds
*/
float GetMinimumLatencySeconds() const;
//! Returns the maximum latency possible (entire ring buffer used)
/**
* @return Maximum latency in seconds
*/
float GetMaximumLatencySeconds() const;
//! Returns the minimum latency possible (single block)
/**
* @return Minimum latency in samples
*/
int GetMinimumLatencySamples() const;
//! Returns the maximum latency possible (entire ring buffer used)
/**
* @return Maximum latency in samples
*/
int GetMaximumLatencySamples() const;
//! Sets the latency for real-time processing
//! Returns the NetAudio streaming logger base name
std::string GetNetAudioStreamLoggerBaseName() const;
//! Sets the NetAudio streaming logger base name
/**
* Real-time network audio is considered to process at lowest latency possible.
* However, this implementation requires at least one block. Hence latency is
* depending on sampling rate and block length. This method basically
* sets the minimum allowed latency to this value.
*
* @sa GetMinimumLatencySeconds()
* @sa SetAllowedLatencySeconds()
* If debugging is enabled, all debugging files will be named
* with this suffix.
* @param[in] sBaseName Base name string
*
*/
void SetLatencyForRealtime();
void SetNetAudioStreamingLoggerBaseName( const std::string& sBaseName );
//! Enabled/disables export of loggers
void SetDebuggingEnabled( bool bEnabled );
//! Logging export flag getter
bool GetIsDebuggingEnabled() const;
//! Returns (static) size of ring buffer
/**
......@@ -167,6 +188,7 @@ public:
*/
void IncrementBlockPointer();
protected:
//! This method is called by the networkg client and pushes samples into the ring buffer
/**
......@@ -180,7 +202,7 @@ protected:
*
* @note This method is not called out of the audio streaming context but out of the network context.
*/
int Transmit( const ITASampleFrame& sfNewSamples, int iNumSamples );
int Transmit( const ITASampleFrame& sfNewSamples, const int iNumSamples );
//! Returns samples that can be read from ring buffer
/**
......@@ -194,6 +216,9 @@ protected:
*/
int GetRingBufferFreeSamples() const;
//! Returns a string for the streaming status identifier
static std::string GetStreamingStatusString( const int iStreamingStatus );
private:
CITANetAudioStreamingClient* m_pNetAudioStreamingClient; //!< Audio streaming network client
......@@ -204,16 +229,17 @@ private:
int m_iWriteCursor; //!< Cursor where samples will be fed into ring buffer from net audio producer (always ahead)
bool m_bRingBufferFull; //!< Indicator if ring buffer is full (and read cursor equals write cursor)
ITASampleFrame m_sfRingBuffer; //!< Ring buffer
int m_iTargetSampleLatency; //!< Maximum allowed samples / target sample latency
int m_iStreamingStatus; //!< Current streaming status
double m_dLastStreamingTimeCode;
ITABufferedDataLoggerImplAudio* m_pAudioLogger; //!< Logging for the audio stream
ITABufferedDataLoggerImplStream* m_pStreamLogger; //!< Logging for the audio stream
ITABufferedDataLoggerImplNet* m_pNetLogger; //!< Logging for the network stream
int iAudioStreamingBlockID; //!< Audio streaming block id
int iNetStreamingBlockID; //!< Network streaming block id
ITABufferedDataLoggerImplStream* m_pAudioStreamLogger; //!< Logging for the audio stream
ITABufferedDataLoggerImplNet* m_pNetworkStreamLogger; //!< Logging for the network stream
std::string m_sNetAudioStreamLoggerBaseName;
bool m_bDebuggingEnabled;
int m_iAudioStreamingBlockID; //!< Audio streaming block id
int m_iNetStreamingBlockID; //!< Network streaming block id
friend class CITANetAudioStreamingClient;
};
......
......@@ -21,60 +21,72 @@
#include <ITADataSourcesDefinitions.h>
#include <ITANetAudioProtocol.h>
#include <ITASampleFrame.h>
#include <ITAStopWatch.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <ITANetAudioProtocol.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <ITASampleFrame.h>
#include <iostream>
class ITADatasource;
class CITANetAudioMessage;
class CITANetAudioProtocol;
class CITANetAudioServer;
class CITANetAudioMessage;
class VistaTCPSocket;
class CITABufferedDataLoggerImplServer;
class VistaConnectionIP;
//! Network audio sample server (for connecting a net audio stream)
//! Network audio streaming server (for connecting a net audio stream) with an ITADataSource connection
/**
* Audio sample transmitter for a networked signal source that can connect via TCP/IP.
*
* \sa CITANetAudioStream
* \note not thread-safe
*/
* Audio sample transmitter for a networked signal source that can connect via TCP/IP.
*
* @sa CITANetAudioStream
* @note not thread-safe
*/
class ITA_DATA_SOURCES_API CITANetAudioStreamingServer : public VistaThreadLoop
{
public:
enum UpdateStrategy
{
AUTO = 1, //!< Automatic update rate based on sample rate and block length of client (default)
ADAPTIVE, //!< Adaptive update rate, adjusts for drifting clocks
CONSTANT, //!< Set a user-defined update rate (may cause forced pausing of sample feeding or dropouts on client side)
};
CITANetAudioStreamingServer();
virtual ~CITANetAudioStreamingServer() {};
~CITANetAudioStreamingServer();
bool Start( const std::string& sAddress, int iPort );
//! Start to listen on a socket (blocking)
bool Start( const std::string& sAddress, const int iPort, const double dTimeIntervalCientSendStatus, const bool bUseUDP = false );
bool IsClientConnected() const;
std::string GetNetworkAddress() const;
int GetNetworkPort() const;
bool LoopBody();
void Stop();
void SetInputStream( ITADatasource* pInStream );
int GetNetStreamBlocklength() const;
int GetNetStreamNumberOfChannels() const;
double GetNetStreamSampleRate() const;
int GetNetStreamNumberOfChannels( ) const;
double GetNetStreamSampleRate( ) const;
double GetEstimatedCorrFactor( ) const;
void SetEstimatedCorrFactor( double dcorrFactor );
//! Enabled/disables export of loggers
void SetDebuggingEnabled( bool bEnabled );
//! Logging export flag getter
bool GetIsDebuggingEnabled() const;
int GetSendingBlockLength() const;
void SetSendingBlockLength( const int iSendingBlockLength );
void SetAutomaticUpdateRate();
void SetTargetLatencySamples( const int iTargetLatency );
int GetTargetLatencySamples() const;
void SetServerLogBaseName( const std::string& sBaseName );
std::string GetServerLogBaseName() const;
bool LoopBody();
protected:
ITADatasource* GetInputStream() const;
......@@ -85,12 +97,25 @@ private:
ITADatasource* m_pInputStream;
VistaConnectionIP* m_pConnection;
CITANetAudioProtocol::StreamingParameters m_oServerParams;
CITANetAudioMessage* m_pIncomingMessage;
CITANetAudioMessage* m_pOutgoingMessage;
CITANetAudioMessage* m_pMessage;
CITABufferedDataLoggerImplServer* m_pServerLogger;
std::string m_sServerLogBaseName;
ITAStopWatch m_swTryReadBlockStats, m_swTryReadAccessStats;
bool m_bDebuggingEnabled;
int m_iServerBlockId;
double m_dLastTimeStamp;
double m_dEstimatedCorrFactor;
int m_iTargetLatencySamples;
int m_iEstimatedClientRingBufferFreeSamples;
int m_iClientRingBufferSize;
int m_iSendingBlockLength;
int m_iMaxSendBlocks;
int m_iUpdateStrategy;
int m_iClientRingBufferFreeSamples;
double m_dStreamTimeStart; //!< Stream time start
long unsigned int m_nStreamSampleCounts; //!< Samples that has been streamed
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__
#define __ITA_STREAM_INFO_H__
#ifndef INCLUDE_WATCHER_ITA_STREAM_INFO
#define INCLUDE_WATCHER_ITA_STREAM_INFO
#include <ITATypes.h>
// Diese Datenklasse beschreibt den Zustand eines Audiostreams
class ITAStreamInfo {
//! Time code information for audio streams
class ITAStreamInfo
{
public:
// Anzahl der abgespielten Samples seit Beginn des Streamings
uint64_t nSamples;
uint64_t nSamples; //!< Number of samples processed
double dStreamTimeCode; //!< Stream time code (starts with zero)
double dSysTimeCode; //!< System time stamp code (begings with current time stamp of system)
// TODO: Beschreiben
double dTimecode;
inline ITAStreamInfo()
: nSamples( 0 )
, dStreamTimeCode( 0.0f )
, dSysTimeCode( 0.0f )
{};
//! Standard-Konstruktor (setzt alle Werte 0)
ITAStreamInfo() : nSamples(0), dTimecode(0) {}
//! Destruktor
virtual ~ITAStreamInfo() {};
inline virtual ~ITAStreamInfo() {};
};
#endif // __ITA_STREAM_INFO_H__
#endif // INCLUDE_WATCHER_ITA_STREAM_INFO
......@@ -220,7 +220,7 @@ private:
ITADatasource* pDatasource; //!< Datasource assigned to the input
std::vector< const float* > vpfInputData; //!< Pointers to the next stream blocks
inline InputDesc( const int iChannels, const int iBlockLength )
inline InputDesc( const int iChannels, const int )
: vpfInputData( iChannels, nullptr )
, iChannels( iChannels )
, fCurrentGain( 1.0f )
......
This diff is collapsed.
......@@ -6,6 +6,7 @@
#include <ITAException.h>
#include <ITAFunctors.h>
#include <ITANumericUtils.h>
#include <ITAClock.h>
#ifndef WIN32
#include <memory.h>
......@@ -98,7 +99,8 @@ void ITABufferDataSink::Transfer( unsigned int uiSamples )
m_uiWriteCursor += m;
m_siState.nSamples += m_pdsSource->GetBlocklength();
m_siState.dTimecode = ( double ) ( m_siState.nSamples ) / m_pdsSource->GetSampleRate();
m_siState.dStreamTimeCode = ( double ) ( m_siState.nSamples ) / m_pdsSource->GetSampleRate();
m_siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
m_pdsSource->IncrementBlockPointer();
}
......
#include "ITADataSourceRealization.h"
#include <cassert>
#include <ITAFastMath.h>
#include <cassert>
/*
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)
ITADatasourceRealization::ITADatasourceRealization( unsigned int uiChannels, double dSamplerate, unsigned int uiBlocklength, unsigned int uiCapacity )
{
assert( dSamplerate > 0 );
m_dSampleRate = dSamplerate;
m_oStreamProps.dSamplerate = dSamplerate;
Init(uiChannels, uiBlocklength, uiCapacity);
}
Init( uiChannels, uiBlocklength, uiCapacity );
}
void ITADatasourceRealization::Init(unsigned int uiChannels,
unsigned int uiBlocklength,
unsigned int uiCapacity)
void ITADatasourceRealization::Init( unsigned int uiChannels, unsigned int uiBlocklength, unsigned int uiCapacity )
{
assert( uiChannels > 0 );
assert( uiBlocklength > 0 );
......@@ -49,7 +33,7 @@ void ITADatasourceRealization::Init(unsigned int uiChannels,
m_oStreamProps.uiChannels = m_uiChannels;
m_oStreamProps.uiBlocklength = m_uiBlocklength;
m_uiBufferSize = uiBlocklength * (uiCapacity+1);
m_uiBufferSize = uiBlocklength * ( uiCapacity + 1 );
m_pEventHandler = NULL;
......@@ -57,31 +41,33 @@ void ITADatasourceRealization::Init(unsigned int uiChannels,
Organisation des Puffers: Damit die Blcke der einzelnen Kanle
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
// TODO: Fehlerbehandlung beim Speicherallozieren
/* Bugfix zu Bug #001:
Hier wurde der Puffer einfach um 1024 Felder verlngert.
Damit Funktioniert Wuschels ASIO4ALL jetzt. Ungeklrt aber
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() {
fm_free(m_pfBuffer);
ITADatasourceRealization::~ITADatasourceRealization()
{
fm_free( m_pfBuffer );
}
void ITADatasourceRealization::Reset() {
void ITADatasourceRealization::Reset()
{
m_uiReadCursor = 0;
m_uiWriteCursor = 0;
......@@ -93,22 +79,26 @@ void ITADatasourceRealization::Reset() {
m_iGBPEntrances = 0;
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 {
return (m_iBufferUnderflows > 0) || (m_iBufferOverflows > 0) || (m_iGBPReentrances > 0);
bool ITADatasourceRealization::HasStreamErrors() const
{
return ( m_iBufferUnderflows > 0 ) || ( m_iBufferOverflows > 0 ) || ( m_iGBPReentrances > 0 );
}
ITADatasourceRealizationEventHandler* ITADatasourceRealization::GetStreamEventHandler() const {
ITADatasourceRealizationEventHandler* ITADatasourceRealization::GetStreamEventHandler() const
{
return m_pEventHandler;
}
void ITADatasourceRealization::SetStreamEventHandler(ITADatasourceRealizationEventHandler* pHandler) {
void ITADatasourceRealization::SetStreamEventHandler( ITADatasourceRealizationEventHandler* 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 );
/*
......@@ -117,7 +107,8 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c
*
* WICHTIG: Dies sollte nicht passieren. Fehler beim anwendenden Programmierer!
*/
if (++m_iGBPEntrances > 1) {
if( ++m_iGBPEntrances > 1 )
{
--m_iGBPEntrances;
++m_iGBPReentrances;
return NULL;
......@@ -125,12 +116,16 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c
// Hook/Handler aufrufen
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
ProcessStream(pStreamInfo);
if (m_pEventHandler) m_pEventHandler->HandleProcessStream(this, pStreamInfo);
ProcessStream( pStreamInfo );
if( m_pEventHandler )
m_pEventHandler->HandleProcessStream( this, pStreamInfo );
m_bGBPFirst = false;
}
......@@ -145,45 +140,51 @@ const float* ITADatasourceRealization::GetBlockPointer(unsigned int uiChannel, c
*/
unsigned int uiLocalReadCursor = m_uiReadCursor;
if (uiLocalReadCursor == m_uiWriteCursor) {
if( uiLocalReadCursor == m_uiWriteCursor )
{
++m_iBufferUnderflows;
--m_iGBPEntrances;
return NULL;
}
--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;
if (uiLocalReadCursor == m_uiWriteCursor)
if( uiLocalReadCursor == m_uiWriteCursor )
// Keine Daten im Ausgabepuffer? Kein Inkrement mglich! (Fehlerfall)
++m_iBufferUnderflows;
else
// Lesezeiger inkrementieren
m_uiReadCursor = (uiLocalReadCursor + m_uiBlocklength) % m_uiBufferSize;
m_uiReadCursor = ( uiLocalReadCursor + m_uiBlocklength ) % m_uiBufferSize;
m_bGBPFirst = true;
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 );
return m_pfBuffer + (uiChannel * m_uiBufferSize) + m_uiWriteCursor;
return m_pfBuffer + ( uiChannel * m_uiBufferSize ) + m_uiWriteCursor;
}
void ITADatasourceRealization::IncrementWritePointer() {
void ITADatasourceRealization::IncrementWritePointer()
{
// Lokaler Schreibcursor
unsigned int uiLocalWriteCursor = m_uiWriteCursor;
unsigned int uiNewWriteCursor = (uiLocalWriteCursor + m_uiBlocklength) % m_uiBufferSize;
unsigned int uiNewWriteCursor = ( uiLocalWriteCursor + m_uiBlocklength ) % m_uiBufferSize;
// Pufferberlauf
if (uiNewWriteCursor == m_uiReadCursor) {
if( uiNewWriteCursor == m_uiReadCursor )
{
++m_iBufferOverflows;
return;
}
......@@ -192,6 +193,6 @@ void ITADatasourceRealization::IncrementWritePointer() {
m_uiWriteCursor = uiNewWriteCursor;
}
void ITADatasourceRealizationEventHandler::HandlePreGetBlockPointer(ITADatasourceRealization* pSender, unsigned int uiChannel) {}
void ITADatasourceRealizationEventHandler::HandlePostIncrementBlockPointer(ITADatasourceRealization* pSender) {}
void ITADatasourceRealizationEventHandler::HandleProcessStream(ITADatasourceRealization* pSender, const ITAStreamInfo* pStreamInfo) {}
void ITADatasourceRealizationEventHandler::HandlePreGetBlockPointer( ITADatasourceRealization*, unsigned int ) {}
void ITADatasourceRealizationEventHandler::HandlePostIncrementBlockPointer( ITADatasourceRealization* ) {}
void ITADatasourceRealizationEventHandler::HandleProcessStream( ITADatasourceRealization*, const ITAStreamInfo* ) {}
......@@ -8,6 +8,8 @@
#include <ITAStreamInfo.h>
#include <ITAAudiofileWriter.h>
#include <ITAException.h>
#include <ITAClock.h>
#include <cmath>
#include <string>
#include <vector>
......@@ -90,7 +92,8 @@ void WriteFromDatasourceToBuffer(ITADatasource* pSource,
n += uiBlocklength;
siState.nSamples += uiBlocklength;
siState.dTimecode = (double) (siState.nSamples) / dSamplerate;
siState.dStreamTimeCode = (double) (siState.nSamples) / dSamplerate;
siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
if (bDisplayProgress)
{
......@@ -193,7 +196,8 @@ void WriteFromDatasourceToFile(ITADatasource* pSource,
pSource->IncrementBlockPointer();
siState.nSamples += uiBlocklength;
siState.dTimecode = (double) (siState.nSamples) / dSamplerate;
siState.dStreamTimeCode = (double) (siState.nSamples) / dSamplerate;
siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
// Daten schreiben
writer->write((std::min)(uiBlocklength, (uiNumberOfSamples - n)), vpfData);
......
......@@ -4,13 +4,16 @@
#include <ITADataSource.h>
#include <ITAAudiofileWriter.h>
#include <ITANumericUtils.h>
#include <ITAClock.h>
ITAFileDatasink::ITAFileDatasink( std::string sFilename, ITADatasource* pdsSource, ITAQuantization eQuantization )
: m_pfSilence( NULL ) {
: m_pfSilence( NULL )
{
m_pdsSource = pdsSource;
m_pFileWriter = NULL;
if( pdsSource ) {
if( pdsSource )
{
m_vpfData.resize( pdsSource->GetNumberOfChannels() );
ITAAudiofileProperties props;
......@@ -24,19 +27,23 @@ ITAFileDatasink::ITAFileDatasink( std::string sFilename, ITADatasource* pdsSourc
}
}
ITAFileDatasink::~ITAFileDatasink() {
ITAFileDatasink::~ITAFileDatasink()
{
delete m_pFileWriter;
fm_free( m_pfSilence );
}
void ITAFileDatasink::Transfer( unsigned int uiSamples ) {
if( m_pdsSource ) {
void ITAFileDatasink::Transfer( unsigned int uiSamples )
{
if( m_pdsSource )
{
// Anzahl der zu transferrierenden Blcke bestimmen
unsigned int b = m_pdsSource->GetBlocklength();
unsigned int n = uprdivu( uiSamples, b );
for( unsigned int i = 0; i < n; i++ ) {
for( unsigned int j = 0; j < m_pdsSource->GetNumberOfChannels(); j++ ) {
for( unsigned int j = 0; j < m_pdsSource->GetNumberOfChannels(); j++ )
{
const float* pfSrc = m_pdsSource->GetBlockPointer( j, &m_siState );
if( pfSrc )
m_vpfData[ j ] = ( float* ) pfSrc;
......@@ -45,7 +52,8 @@ void ITAFileDatasink::Transfer( unsigned int uiSamples ) {
}
m_pdsSource->IncrementBlockPointer();
m_siState.nSamples += b;
m_siState.dTimecode = ( double ) ( m_siState.nSamples ) / m_pdsSource->GetSampleRate();
m_siState.dStreamTimeCode = ( double ) ( m_siState.nSamples ) / m_pdsSource->GetSampleRate();
m_siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
m_pFileWriter->write( b, m_vpfData );
}
......
#include <ITANetAudioClient.h>
#include "ITANetAudioClient.h"
#include <ITANetAudioMessage.h>
#include <ITANetAudioProtocol.h>
#include <ITANetAudioStream.h>
#include <ITAException.h>
#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
......@@ -16,13 +15,15 @@ CITANetAudioClient::~CITANetAudioClient()
delete m_pConnection;
}
bool CITANetAudioClient::Connect( const std::string& sAddress, int iPort )
bool CITANetAudioClient::Connect( const std::string& sAddress, const int iPort, const bool bUseUDP /* = false */ )
{
if( GetIsConnected() )
ITA_EXCEPT1( MODAL_EXCEPTION, "This net stream is already connected" );
// Attempt to connect and check parameters
m_pConnection = new VistaConnectionIP( VistaConnectionIP::CT_TCP, sAddress, iPort );
const VistaConnectionIP::VistaProtocol iCTProtocol = bUseUDP ? VistaConnectionIP::CT_UDP : VistaConnectionIP::CT_TCP;
m_pConnection = new VistaConnectionIP( iCTProtocol, sAddress, iPort );
if( !GetIsConnected() )
{
delete m_pConnection;
......@@ -46,5 +47,8 @@ void CITANetAudioClient::Disconnect()
bool CITANetAudioClient::GetIsConnected() const
{
return m_pConnection ? true : false;
if( m_pConnection )
return m_pConnection->GetIsOpen();
else
return false;
}
......@@ -28,7 +28,7 @@ class VistaConnectionIP;
//! A network audio client that connects to a network audio server
/**
* Use CITANetAudioStreamingClient to start an audio stream with the connection of this client.
* This class is basically a helper around Vista TCP/IP network functionality.
* This class is basically a helper around Vista TCP/IP or UDP network functionality.
*
*/
class CITANetAudioClient
......@@ -42,7 +42,7 @@ public:
CITANetAudioClient();
~CITANetAudioClient();
bool Connect( const std::string& sAddress, int iPort );
bool Connect( const std::string& sAddress, const int iPort, const bool bUseUDP );
void Disconnect();
bool GetIsConnected() const;
......
This diff is collapsed.
......@@ -21,11 +21,12 @@
#include <ITADataSourcesDefinitions.h>
#include "ITANetAudioProtocol.h"
// ITA includes
#include <ITAException.h>
#include <ITASampleBuffer.h>
#include <ITASampleFrame.h>
#include <ITANetAudioProtocol.h>
// Vista includes
#include <VistaInterProcComm/Connections/VistaByteBufferSerializer.h>
......@@ -36,6 +37,7 @@
#include <vector>
class VistaConnectionIP;
class ITABufferedDataLoggerImplProtocol;
//! Network audio messages
/**
......@@ -48,13 +50,17 @@ class VistaConnectionIP;
class ITA_DATA_SOURCES_API CITANetAudioMessage
{
public:
CITANetAudioMessage( VistaConnectionIP* );
CITANetAudioMessage( VistaSerializingToolset::ByteOrderSwapBehavior bSwapBuffers );
void SetConnection( VistaConnectionIP* );
VistaConnectionIP* GetConnection() const;
void ClearConnection();
//! Will always block processing until data is completely send
void WriteMessage();
bool TryReadMessage();
//! Returns false if no incomming data during timeout
bool ReadMessage( const int iTimeoutMilliseconds );
void ResetMessage();
......@@ -65,6 +71,7 @@ public:
void SetMessageType( int nType );
int GetMessageType() const;
void WriteInt( const int );
void WriteBool( const bool );
void WriteDouble( const double );
......@@ -91,15 +98,25 @@ public:
int ReadRingBufferFree();
void ReadSampleFrame(ITASampleFrame* pSampleFrame);
void SetMessageLoggerBaseName( const std::string& );
std::string GetMessageLoggerBaseName() const;
void SetDebuggingEnabled( bool bEnabled );
bool GetIsDebuggingEnabled() const;
private:
int m_nMessageType;
int m_nMessageId;
unsigned long m_iBytesReceivedTotal;
VistaByteBufferSerializer m_oOutgoing; //!< Serialization buffer for messages
VistaByteBufferDeSerializer m_oIncoming; //!< Deserialization buffer for messages
std::vector< VistaType::byte > m_vecIncomingBuffer; // Net IO buffer
int m_nTimeoutMilliseconds; //!< Timeout for try-read message
VistaConnectionIP* m_pConnection;
ITABufferedDataLoggerImplProtocol* m_pMessageLogger;
std::string m_sMessageLoggerBaseName;
bool m_bDebuggingEnabled;
};
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_MESSAGE
#include <ITANetAudioProtocol.h>
#include "ITANetAudioProtocol.h"
// @todo remove (all inline implemented)
\ No newline at end of file
......@@ -47,40 +47,58 @@ class CITANetAudioStream;
class ITA_DATA_SOURCES_API CITANetAudioProtocol
{
public:
static const int NET_AUDIO_VERSION = 1;
static const int NP_INVALID = -1;
static const int NP_GET_VERSION_INFO = 1;
static const int NP_CLIENT_IDLE = 0;
static const int NP_CLIENT_OPEN = 100;
static const int NP_CLIENT_CLOSE = 101;
static const int NP_CLIENT_WAITING_FOR_SAMPLES = 111;
static const int NP_CLIENT_SENDING_RINGBUFFER_FREE_SAMPLES = 111;
static const int NP_SERVER_CLOSE = 200;
static const int NP_SERVER_OPEN = 201;
static const int NP_SERVER_GET_RINGBUFFER_SIZE = 210;
static const int NP_SERVER_GET_RINGBUFFER_FREE = 211;
static const int NP_SERVER_SEND_SAMPLES = 222;
static const int NP_SERVER_OPEN = 200;
static const int NP_SERVER_CLOSE = 201;
static const int NP_SERVER_REFUSED_INVALID_PARAMETERS = 202;
static const int NP_SERVER_GET_RINGBUFFER_FREE_SAMPLES = 211;
static const int NP_SERVER_SENDING_SAMPLES = 222;
inline CITANetAudioProtocol() {};
inline ~CITANetAudioProtocol() {};
inline static std::string GetNPMessageID( const int iMessageType )
{
switch( iMessageType )
{
case NP_CLIENT_IDLE: return "CLIENT_IDLE";
case NP_CLIENT_OPEN: return "CLIENT_OPEN";
case NP_CLIENT_CLOSE: return "CLIENT_CLOSE";
case NP_CLIENT_SENDING_RINGBUFFER_FREE_SAMPLES: return "CLIENT_SENDING_RINGBUFFER_FREE_SAMPLES";
case NP_SERVER_OPEN: return "SERVER_OPEN";
case NP_SERVER_REFUSED_INVALID_PARAMETERS: return "NP_SERVER_REFUSED_INVALID_PARAMETERS";
case NP_SERVER_CLOSE: return "SERVER_CLOSE";
case NP_SERVER_GET_RINGBUFFER_FREE_SAMPLES: return "SERVER_GET_RINGBUFFER_FREE_SAMPLES";
case NP_SERVER_SENDING_SAMPLES: return "SERVER_SENDING_SAMPLES";
default: return "INVALID";
}
};
struct StreamingParameters
{
int iChannels;
double dSampleRate;
int iBlockSize;
int iRingBufferSize;
inline StreamingParameters()
{
iChannels = 0;
dSampleRate = 0.0f;
iBlockSize = 0;
iRingBufferSize = 0;
};
inline bool operator==( const StreamingParameters& rhs )
{
if( ( iChannels == rhs.iChannels ) && ( dSampleRate == rhs.dSampleRate ) && ( iBlockSize == rhs.iBlockSize ) )
if ( ( iChannels == rhs.iChannels )
&& ( dSampleRate == rhs.dSampleRate )
&& (iBlockSize == rhs.iBlockSize)
&& (iRingBufferSize == rhs.iRingBufferSize))
return true;
else
return false;
......
#include <ITANetAudioServer.h>
#include "ITANetAudioServer.h"
#include "ITANetAudioProtocol.h"
#include <ITANetAudioStreamingServer.h>
#include <ITANetAudioProtocol.h>
// ITA includes
#include <ITADataSource.h>
......@@ -12,6 +13,8 @@
#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
#include <VistaInterProcComm/IPNet/VistaTCPServer.h>
#include <VistaInterProcComm/IPNet/VistaTCPSocket.h>
#include <VistaInterProcComm/IPNet/VistaSocketAddress.h>
#include <VistaInterProcComm/IPNet/VistaUDPSocket.h>
#include <VistaBase/VistaTimeUtils.h>
#include <VistaInterProcComm/IPNet/VistaIPAddress.h>
......@@ -20,8 +23,9 @@
#include <cassert>
CITANetAudioServer::CITANetAudioServer()
: m_pServer( NULL )
, m_pSocket( NULL )
: m_pTCPServer( NULL )
, m_pTCPSocket( NULL )
, m_pUDPSocket( NULL )
, m_pConnection( NULL )
, m_iServerPort( -1 )
{
......@@ -29,9 +33,13 @@ CITANetAudioServer::CITANetAudioServer()
CITANetAudioServer::~CITANetAudioServer()
{
m_pTCPSocket = NULL;
delete m_pUDPSocket;
m_pUDPSocket = NULL;
delete m_pConnection;
delete m_pServer;
delete m_pSocket;
delete m_pTCPServer;
}
std::string CITANetAudioServer::GetServerAddress() const
......@@ -44,21 +52,37 @@ int CITANetAudioServer::GetNetworkPort() const
return m_iServerPort;
}
bool CITANetAudioServer::Start(const std::string& sAddress, int iPort)
bool CITANetAudioServer::Start( const std::string& sAddress, const int iPort, const bool bUseUDP )
{
if( m_pServer )
ITA_EXCEPT1( MODAL_EXCEPTION, "This net sample server is already started" );
if( m_pTCPServer || m_pUDPSocket )
ITA_EXCEPT1( MODAL_EXCEPTION, "This NetAudio server is already started" );
m_pServer = new VistaTCPServer( sAddress, iPort, 1 );
m_sServerAddress = sAddress;
m_iServerPort = iPort;
// blocking wait for connection
m_pSocket = m_pServer->GetNextClient();
if( !m_pSocket )
return false;
if( m_pSocket->GetIsConnected() )
m_pConnection = new VistaConnectionIP( m_pSocket );
if( bUseUDP )
{
VistaSocketAddress oAddress( sAddress, iPort );
VistaUDPSocket* pUDPSocket = new VistaUDPSocket();
// blocking wait for connection
pUDPSocket->ConnectToAddress( oAddress );
if( pUDPSocket->GetIsConnected() )
m_pConnection = new VistaConnectionIP( pUDPSocket );
}
else
{
m_pTCPServer = new VistaTCPServer( sAddress, iPort, 1 );
// blocking wait for connection
m_pTCPSocket = m_pTCPServer->GetNextClient();
if( !m_pTCPSocket )
return false;
if( m_pTCPSocket->GetIsConnected() )
m_pConnection = new VistaConnectionIP( m_pTCPSocket );
}
if( !m_pConnection )
return false;
......@@ -77,10 +101,13 @@ void CITANetAudioServer::Stop()
delete m_pConnection;
m_pConnection = NULL;
m_pSocket = NULL;
m_pTCPSocket = NULL;
delete m_pTCPServer;
m_pTCPServer = NULL;
delete m_pServer;
m_pServer = NULL;
delete m_pUDPSocket;
m_pUDPSocket = NULL;
}
bool CITANetAudioServer::IsConnected() const
......
......@@ -21,8 +21,6 @@
#include <ITADataSourcesDefinitions.h>
#include <ITANetAudioProtocol.h>
#include <ITASampleFrame.h>
#include <string>
......@@ -32,6 +30,7 @@ class CITANetAudioStreamingServer;
class VistaConnectionIP;
class VistaTCPServer;
class VistaTCPSocket;
class VistaUDPSocket;
//! Realizes server functionality for network audio streaming
/**
......@@ -49,7 +48,7 @@ public:
std::string GetServerAddress() const;
int GetNetworkPort() const;
bool Start( const std::string& sAddress, int iPort );
bool Start( const std::string& sAddress, const int iPort, const bool bUseUDP );
void Stop();
VistaConnectionIP* GetConnection() const;
......@@ -57,12 +56,14 @@ public:
private:
VistaTCPServer* m_pServer;
VistaTCPSocket* m_pSocket;
VistaTCPServer* m_pTCPServer;
VistaTCPSocket* m_pTCPSocket;
VistaUDPSocket* m_pUDPSocket;
VistaConnectionIP* m_pConnection;
int m_iServerPort;
std::string m_sServerAddress;
};
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_SERVER
This diff is collapsed.
This diff is collapsed.
......@@ -21,10 +21,9 @@
#include <ITADataSourcesDefinitions.h>
#include <ITANetAudioProtocol.h>
#include <ITASampleFrame.h>
#include <ITAStreamProbe.h>
#include <ITAStopWatch.h>
#include <VistaInterProcComm/Concurrency/VistaThreadEvent.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
......@@ -37,10 +36,11 @@ class CITANetAudioMessage;
class CITANetAudioProtocol;
class CITANetAudioStream;
class ITABufferedDataLoggerImplClient;
class VistaConnectionIP;
//! Network audio streaming client
/**
* Audio streaming for a signal source that is connected via TCP/IP.
* Audio streaming for a signal source that is connected via TCP/IP or UDP.
* Implements the ITA network protocol for audio streaming on client side.
*
* @todo: move to src folder
......@@ -53,12 +53,18 @@ public:
CITANetAudioStreamingClient( CITANetAudioStream* pParent );
virtual ~CITANetAudioStreamingClient();
bool Connect( const std::string& sAddress, int iPort );
bool Connect( const std::string& sAddress, const int iPort, const bool bUseUDP );
bool GetIsConnected() const;
void Disconnect();
bool LoopBody();
std::string GetClientLoggerBaseName() const;
void SetClientLoggerBaseName( const std::string& );
void SetDebuggingEnabled( const bool bEnabled );
bool GetIsDebuggingEnabled() const;
protected:
void TriggerBlockIncrement();
......@@ -67,20 +73,23 @@ private:
CITANetAudioStream* m_pStream;
CITANetAudioProtocol* m_pProtocol;
CITANetAudioMessage* m_pIncomingMessage;
CITANetAudioMessage* m_pOutgoingMessage;
CITANetAudioMessage* m_pMessage;
VistaConnectionIP* m_pConnection;
VistaThreadEvent m_oBlockIncrementEvent;
ITASampleFrame m_sfReceivingBuffer; //!< Buffer incoming data
bool m_bStopIndicated;
bool m_bStopped;
CITANetAudioProtocol::StreamingParameters m_oParams;
int m_iStreamingBlockId;
double m_dServerClockSyncRequestTimeInterval;
double m_dServerClockSyncLastSyncTime;
bool m_bStopIndicated;
int iStreamingBlockId;
ITABufferedDataLoggerImplClient* m_pClientLogger;
std::string m_sClientLoggerBaseName;
ITAStopWatch m_swTryReadBlockStats, m_swTryReadAccessStats;
bool m_bDebuggingEnabled;
friend class CITANetAudioStream;
};
......
This diff is collapsed.
#include <ITAStreamPump.h>
#include <ITADataSource.h>
#include <ITAClock.h>
ITAStreamPump::ITAStreamPump(ITADatasource* pDatasource) : m_pDatasource(pDatasource), m_pTimer(NULL) {
m_pTimer = new ITATimer( (double) pDatasource->GetBlocklength() / pDatasource->GetSampleRate(), true);
m_pTimer->attach(this);
ITAStreamPump::ITAStreamPump( ITADatasource* pDatasource )
: m_pDatasource( pDatasource )
, m_pTimer( NULL )
{
m_pTimer = new ITATimer( ( double ) pDatasource->GetBlocklength() / pDatasource->GetSampleRate(), true );
m_pTimer->attach( this );
m_uiChannels = pDatasource->GetNumberOfChannels();
}
ITAStreamPump::~ITAStreamPump() {
ITAStreamPump::~ITAStreamPump()
{
delete m_pTimer;
}
}
void ITAStreamPump::StartStreaming() {
void ITAStreamPump::StartStreaming()
{
m_pTimer->start();
}
void ITAStreamPump::StopStreaming() {
void ITAStreamPump::StopStreaming()
{
m_pTimer->stop();
}
void ITAStreamPump::handleTimerEvent(const ITATimer& tSource) {
if (&tSource == m_pTimer) {
for (unsigned int i=0; i<m_uiChannels; i++) m_pDatasource->GetBlockPointer(i, &m_siState);
void ITAStreamPump::handleTimerEvent( const ITATimer& tSource )
{
if( &tSource == m_pTimer )
{
for( unsigned int i = 0; i < m_uiChannels; i++ ) m_pDatasource->GetBlockPointer( i, &m_siState );
m_pDatasource->IncrementBlockPointer();
m_siState.nSamples += m_pDatasource->GetBlocklength();
m_siState.dTimecode = (double) (m_siState.nSamples) / m_pDatasource->GetSampleRate();
}
m_siState.dStreamTimeCode = ( double ) ( m_siState.nSamples ) / m_pDatasource->GetSampleRate();
m_siState.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
}
}
#!/bin/bash
# Auto-generated file that sets the environment variables for the project
export LD_LIBRARY_PATH=/home/jst/dev/ITACoreLibs/build/lib:/home/jst/dev/ViSTA/build/lib:/home/jst/dev/ViSTA/build/lib/DriverPlugins:/usr/bin:$LD_LIBRARY_PATH
export VISTACORELIBS_DRIVER_PLUGIN_DIRS=/home/jst/dev/ViSTA/build/lib/DriverPlugins
#!/bin/bash
# Auto-generated file that sets the environment variables for the project
export LD_LIBRARY_PATH=/home/jst/dev/ITACoreLibs/build/lib:/home/jst/dev/ViSTA/build/lib:/home/jst/dev/ViSTA/build/lib/DriverPlugins:/usr/bin:$LD_LIBRARY_PATH
export VISTACORELIBS_DRIVER_PLUGIN_DIRS=/home/jst/dev/ViSTA/build/lib/DriverPlugins
#!/bin/bash
# Auto-generated file that sets the environment variables for the project
export LD_LIBRARY_PATH=/home/jst/dev/ITACoreLibs/build/lib:/home/jst/dev/ViSTA/build/lib:/home/jst/dev/ViSTA/build/lib/DriverPlugins:/usr/bin:$LD_LIBRARY_PATH
export VISTACORELIBS_DRIVER_PLUGIN_DIRS=/home/jst/dev/ViSTA/build/lib/DriverPlugins