Commit 6c4f4aa7 authored by Jonas Stienen's avatar Jonas Stienen

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

# Conflicts:
#	include/ITANetAudioStreamingClient.h
#	src/ITANetAudioStreamingClient.cpp
parents 0d9073a6 1bfecbc7
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project( ITADataSources ) project( ITADataSources )
......
...@@ -6,13 +6,13 @@ include( VistaCommon ) ...@@ -6,13 +6,13 @@ include( VistaCommon )
vista_use_package( ITADataSources REQUIRED FIND_DEPENDENCIES ) vista_use_package( ITADataSources REQUIRED FIND_DEPENDENCIES )
if( TA_DATA_SOURCES_WITH_INTEGRATED_ASIO ) if( ITA_DATA_SOURCES_WITH_INTEGRATED_ASIO )
add_definitions( "-DITA_WHAD_WITH_ASIO" ) add_definitions( "-DITA_WHAD_WITH_ASIO" )
endif( TA_DATA_SOURCES_WITH_INTEGRATED_ASIO ) endif( )
if( TA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO ) if( ITA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO )
add_definitions( "-DITA_WHAD_WITH_PORTAUDIO" ) add_definitions( "-DITA_WHAD_WITH_PORTAUDIO" )
endif( TA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO ) endif( )
add_executable( ita_whad main.cpp ) add_executable( ita_whad main.cpp )
target_link_libraries( ita_whad ${VISTA_USE_PACKAGE_LIBRARIES} ) target_link_libraries( ita_whad ${VISTA_USE_PACKAGE_LIBRARIES} )
......
...@@ -31,26 +31,55 @@ int main( int, char** ) ...@@ -31,26 +31,55 @@ int main( int, char** )
#ifdef ITA_WHAD_WITH_ASIO #ifdef ITA_WHAD_WITH_ASIO
string sFileName = "ita_whad_asio.txt"; string sASIOFileName = "ita_whad_asio.txt";
FILE* file = fopen( sFileName.c_str(), "w" ); FILE* PASIOFile = fopen( sASIOFileName.c_str(), "w" );
ITAsioInitializeLibrary(); ITAsioInitializeLibrary();
long lDrivers = ITAsioGetNumDrivers(); long lASIODrivers = ITAsioGetNumDrivers();
if( lDrivers == 0 ) if( lASIODrivers == 0 )
cerr << "Warning: no ASIO drivers found." << endl; cerr << "Warning: no ASIO drivers found." << endl;
for( long i = 0; i < lDrivers; i++ ) cout << " ### ASIO ### " << endl;
for( long i = 0; i < lASIODrivers; i++ )
{ {
cout << "[" << i+1 << "] \"" << ITAsioGetDriverName(i) << "\"" << endl; cout << "[" << i + 1 << "] \"" << ITAsioGetDriverName( i ) << "\"" << endl;
} }
cout << endl;
ITAsioFinalizeLibrary(); ITAsioFinalizeLibrary();
fclose( file ); fclose( PASIOFile );
#endif // ITA_WHAD_WITH_ASIO #endif // ITA_WHAD_WITH_ASIO
#ifdef ITA_WHAD_WITH_PORTAUDIO
string sPAFileName = "ita_whad_portaudio.txt";
FILE* pPAFile = fopen( sPAFileName.c_str(), "w" );
ITAPortaudioInterface oITAPA( 44.1e3, 1024 );
oITAPA.Initialize();
int iPANumDevices = oITAPA.GetNumDevices();
int iPADefaultIn = oITAPA.GetDefaultInputDevice();
int iPADefaultOut = oITAPA.GetDefaultOutputDevice();
cout << " ### Portaudio ### " << endl;
for( int i = 0; i < iPANumDevices; i++ )
{
string sExtra = "";
if( i == iPADefaultIn || i == iPADefaultOut )
sExtra = " *";
cout << "[" << i + 1 << "] \"" << oITAPA.GetDeviceName( i ) << "\"" << sExtra << endl;
}
cout << endl;
oITAPA.Finalize();
fclose( pPAFile );
#endif // ITA_WHAD_WITH:PORTAUDIO
return 0; return 0;
} }
...@@ -151,6 +151,18 @@ public: ...@@ -151,6 +151,18 @@ public:
//! Wiederholung Ein-/Ausschalten //! Wiederholung Ein-/Ausschalten
void SetLoopMode(bool bLoopMode); void SetLoopMode(bool bLoopMode);
//! Sets the looping mode
/**
* @param[in] bLoopingEnabled True means looping, false will play until EOF
*/
void SetIsLooping( bool bLoopingEnabled );
//! Looping mode getter
/**
* @return True means looping, false will play until EOF
*/
bool GetIsLooping();
//! Arbeitsbereich (region of interest) festlegen //! Arbeitsbereich (region of interest) festlegen
/** /**
* Legt den Arbeitsbereich fest, d.h. das Interval in den Quellendaten, aus dem die * Legt den Arbeitsbereich fest, d.h. das Interval in den Quellendaten, aus dem die
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#ifndef _ITADATASOURCEDELEGATOR_H_ #ifndef _ITADATASOURCEDELEGATOR_H_
#define _ITADATASOURCEDELEGATOR_H_ #define _ITADATASOURCEDELEGATOR_H_
#include <ITADatasource.h> #include <ITADataSource.h>
/** /**
* Diese Klasse implementiert die Schnittstelle der ITADatasource, stellt die * Diese Klasse implementiert die Schnittstelle der ITADatasource, stellt die
...@@ -74,4 +74,4 @@ private: ...@@ -74,4 +74,4 @@ private:
ITADatasource* m_pDatasourceDelegatorTarget; ITADatasource* m_pDatasourceDelegatorTarget;
}; };
#endif // _ITADATASOURCEDELEGATOR_H_ #endif // _ITADATASOURCEDELEGATOR_H_
\ No newline at end of file
...@@ -49,7 +49,8 @@ ...@@ -49,7 +49,8 @@
* *
* \ingroup datasources * \ingroup datasources
*/ */
class ITA_DATA_SOURCES_API ITAFileDatasource : public ITABufferDatasource { class ITA_DATA_SOURCES_API ITAFileDatasource : public ITABufferDatasource
{
public: public:
//! Konstruktor //! Konstruktor
/** /**
......
...@@ -55,9 +55,8 @@ public: ...@@ -55,9 +55,8 @@ public:
void ClearConnection(); void ClearConnection();
void WriteMessage(); void WriteMessage();
void ReadMessage(); // Returns false if no incomming data
void WriteAnswer(); bool ReadMessage( int timeout );
void ReadAnswer();
void ResetMessage(); void ResetMessage();
...@@ -66,9 +65,7 @@ public: ...@@ -66,9 +65,7 @@ public:
bool GetOutgoingMessageHasData() const; bool GetOutgoingMessageHasData() const;
void SetMessageType( int nType ); void SetMessageType( int nType );
void SetAnswerType( int nType );
int GetMessageType() const; int GetMessageType() const;
int GetAnswerType() const;
void WriteInt( const int ); void WriteInt( const int );
...@@ -100,12 +97,16 @@ public: ...@@ -100,12 +97,16 @@ public:
private: private:
int m_nMessageType; int m_nMessageType;
int m_nMessageId; int m_nMessageId;
int m_nAnswerType; unsigned long m_iBytesReceivedTotal;
VistaByteBufferSerializer m_oOutgoing; //!< Serialization buffer for messages VistaByteBufferSerializer m_oOutgoing; //!< Serialization buffer for messages
VistaByteBufferDeSerializer m_oIncoming; //!< Deserialization buffer for messages VistaByteBufferDeSerializer m_oIncoming; //!< Deserialization buffer for messages
std::vector< VistaType::byte > m_vecIncomingBuffer; // Net IO buffer std::vector< VistaType::byte > m_vecIncomingBuffer; // Net IO buffer
VistaConnectionIP* m_pConnection; VistaConnectionIP* m_pConnection;
//DEBUG
int i;
}; };
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_MESSAGE #endif // INCLUDE_WATCHER_ITA_NET_AUDIO_MESSAGE
...@@ -47,21 +47,14 @@ class CITANetAudioStream; ...@@ -47,21 +47,14 @@ class CITANetAudioStream;
class ITA_DATA_SOURCES_API CITANetAudioProtocol class ITA_DATA_SOURCES_API CITANetAudioProtocol
{ {
public: 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_OPEN = 100; static const int NP_CLIENT_OPEN = 100;
static const int NP_CLIENT_CLOSE = 101; 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 = 200;
static const int NP_SERVER_OPEN = 201; static const int NP_SERVER_CLOSE = 201;
static const int NP_SERVER_GET_RINGBUFFER_SIZE = 210; static const int NP_SERVER_GET_RINGBUFFER_FREE_SAMPLES = 211;
static const int NP_SERVER_GET_RINGBUFFER_FREE = 211; static const int NP_SERVER_SENDING_SAMPLES = 222;
static const int NP_SERVER_WAITING_FOR_TRIGGER = 221;
static const int NP_SERVER_SEND_SAMPLES = 222;
inline CITANetAudioProtocol() {}; inline CITANetAudioProtocol() {};
inline ~CITANetAudioProtocol() {}; inline ~CITANetAudioProtocol() {};
...@@ -71,17 +64,25 @@ public: ...@@ -71,17 +64,25 @@ public:
int iChannels; int iChannels;
double dSampleRate; double dSampleRate;
int iBlockSize; int iBlockSize;
int iRingBufferSize;
int iTargetSampleLatency;
inline StreamingParameters() inline StreamingParameters()
{ {
iChannels = 0; iChannels = 0;
dSampleRate = 0.0f; dSampleRate = 0.0f;
iBlockSize = 0; iBlockSize = 0;
iRingBufferSize = 0;
iTargetSampleLatency = 0;
}; };
inline bool operator==( const StreamingParameters& rhs ) 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)
&& (iTargetSampleLatency == rhs.iTargetSampleLatency))
return true; return true;
else else
return false; return false;
......
...@@ -34,6 +34,7 @@ using namespace std; ...@@ -34,6 +34,7 @@ using namespace std;
class CITANetAudioStreamingClient; class CITANetAudioStreamingClient;
class ITABufferedDataLoggerImplStream; class ITABufferedDataLoggerImplStream;
class ITABufferedDataLoggerImplNet; class ITABufferedDataLoggerImplNet;
class ITABufferedDataLoggerImplAudio;
//! Network audio stream //! Network audio stream
/** /**
...@@ -96,12 +97,34 @@ public: ...@@ -96,12 +97,34 @@ public:
void SetAllowedLatencySamples( int iLatencySamples ); void SetAllowedLatencySamples( int iLatencySamples );
float GetAllowedLatencySeconds() const; float GetAllowedLatencySeconds() const;
int GetAllowedLatencySamples() 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()
*/
float GetMinimumLatencySeconds() const; float GetMinimumLatencySeconds() const;
float GetMaximumLatencySeconds() const; float GetMaximumLatencySeconds() const;
int GetMinimumLatencySamples() const; int GetMinimumLatencySamples() const;
int GetMaximumLatencySamples() const; int GetMaximumLatencySamples() const;
//! Sets the latency for real-time processing
/**
* 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()
*/
void SetLatencyForRealtime();
//! Returns (static) size of ring buffer //! Returns (static) size of ring buffer
/** /**
* @return Number of maximum samples that can be hold by internal ring buffer * @return Number of maximum samples that can be hold by internal ring buffer
...@@ -183,11 +206,12 @@ private: ...@@ -183,11 +206,12 @@ private:
int m_iWriteCursor; //!< Cursor where samples will be fed into ring buffer from net audio producer (always ahead) 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) bool m_bRingBufferFull; //!< Indicator if ring buffer is full (and read cursor equals write cursor)
ITASampleFrame m_sfRingBuffer; //!< Ring buffer ITASampleFrame m_sfRingBuffer; //!< Ring buffer
int m_iTargetSampleLatency; //!< Maximum allowed samples / target sample latency int m_iTargetSampleLatencyServer; //!< Maximum allowed samples / target sample latency
int m_iStreamingStatus; //!< Current streaming status int m_iStreamingStatus; //!< Current streaming status
double m_dLastStreamingTimeCode; double m_dLastStreamingTimeCode;
ITABufferedDataLoggerImplAudio* m_pAudioLogger; //!< Logging for the audio stream
ITABufferedDataLoggerImplStream* m_pStreamLogger; //!< Logging for the audio stream ITABufferedDataLoggerImplStream* m_pStreamLogger; //!< Logging for the audio stream
ITABufferedDataLoggerImplNet* m_pNetLogger; //!< Logging for the network stream ITABufferedDataLoggerImplNet* m_pNetLogger; //!< Logging for the network stream
int iAudioStreamingBlockID; //!< Audio streaming block id int iAudioStreamingBlockID; //!< Audio streaming block id
......
...@@ -36,6 +36,7 @@ class CITANetAudioClient; ...@@ -36,6 +36,7 @@ class CITANetAudioClient;
class CITANetAudioMessage; class CITANetAudioMessage;
class CITANetAudioProtocol; class CITANetAudioProtocol;
class CITANetAudioStream; class CITANetAudioStream;
class ITABufferedDataLoggerImplClient;
//! Network audio streaming client //! Network audio streaming client
/** /**
......
/* /*
* ---------------------------------------------------------------- * ----------------------------------------------------------------
* *
* ITA core libs * ITA core libs
* (c) Copyright Institute of Technical Acoustics (ITA) * (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2017 * RWTH Aachen University, Germany, 2015-2017
* *
* ---------------------------------------------------------------- * ----------------------------------------------------------------
* ____ __________ _______ * ____ __________ _______
* // / //__ ___/ // _ | * // / //__ ___/ // _ |
* // / // / // /_| | * // / // / // /_| |
* // / // / // ___ | * // / // / // ___ |
* //__/ //__/ //__/ |__| * //__/ //__/ //__/ |__|
* *
* ---------------------------------------------------------------- * ----------------------------------------------------------------
* *
*/ */
#ifndef INCLUDE_WATCHER_ITA_NET_AUDIO_STREAMING_SERVER #ifndef INCLUDE_WATCHER_ITA_NET_AUDIO_STREAMING_SERVER
#define INCLUDE_WATCHER_ITA_NET_AUDIO_STREAMING_SERVER #define INCLUDE_WATCHER_ITA_NET_AUDIO_STREAMING_SERVER
#include <ITADataSourcesDefinitions.h> #include <ITADataSourcesDefinitions.h>
#include <ITANetAudioProtocol.h> #include <ITANetAudioProtocol.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <ITANetAudioProtocol.h> #include <ITANetAudioProtocol.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h> #include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <ITASampleFrame.h> #include <ITASampleFrame.h>
class ITADatasource; class ITADatasource;
class CITANetAudioMessage; class CITANetAudioMessage;
class CITANetAudioProtocol; class CITANetAudioProtocol;
class CITANetAudioServer; class CITANetAudioServer;
class CITANetAudioMessage; class CITANetAudioMessage;
class VistaTCPSocket; class VistaTCPSocket;
class ITABufferedDataLoggerImplServer;
//! Network audio sample server (for connecting a net audio stream)
/**
* Audio sample transmitter for a networked signal source that can connect via TCP/IP. //! Network audio sample server (for connecting a net audio stream)
* /**
* \sa CITANetAudioStream * Audio sample transmitter for a networked signal source that can connect via TCP/IP.
* \note not thread-safe *
*/ * \sa CITANetAudioStream
class ITA_DATA_SOURCES_API CITANetAudioStreamingServer : public VistaThreadLoop * \note not thread-safe
{ */
public: class ITA_DATA_SOURCES_API CITANetAudioStreamingServer : public VistaThreadLoop
{
enum UpdateStrategy public:
{
AUTO = 1, //!< Automatic update rate based on sample rate and block length of client (default) enum UpdateStrategy
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) 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 ); virtual ~CITANetAudioStreamingServer() {};
bool IsClientConnected() const;
std::string GetNetworkAddress() const; bool Start( const std::string& sAddress, int iPort );
int GetNetworkPort() const; bool IsClientConnected() const;
bool LoopBody(); std::string GetNetworkAddress() const;
void Stop(); int GetNetworkPort() const;
bool LoopBody();
void SetInputStream( ITADatasource* pInStream ); void Stop();
int GetNetStreamBlocklength() const; void SetInputStream( ITADatasource* pInStream );
int GetNetStreamNumberOfChannels() const;
double GetNetStreamSampleRate() const; int GetNetStreamBlocklength() const;
int GetNetStreamNumberOfChannels() const;
void SetAutomaticUpdateRate(); double GetNetStreamSampleRate() const;
protected: void SetAutomaticUpdateRate();
ITADatasource* GetInputStream() const;
protected:
private: ITADatasource* GetInputStream() const;
CITANetAudioServer* m_pNetAudioServer;
ITASampleFrame m_sfTempTransmitBuffer; private:
ITADatasource* m_pInputStream; CITANetAudioServer* m_pNetAudioServer;
VistaConnectionIP* m_pConnection; ITASampleFrame m_sfTempTransmitBuffer;
ITADatasource* m_pInputStream;
CITANetAudioProtocol::StreamingParameters m_oServerParams; VistaConnectionIP* m_pConnection;
CITANetAudioMessage* m_pMessage;
CITANetAudioProtocol::StreamingParameters m_oServerParams;
int m_iUpdateStrategy; CITANetAudioMessage* m_pMessage;
int m_iClientRingBufferFreeSamples;
int iServerBlockId;
friend class CITANetAudioServer; ITABufferedDataLoggerImplServer* m_pServerLogger;
};
int m_iUpdateStrategy;
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_STREAMING_SERVER int m_iClientRingBufferFreeSamples;
int m_iMaxSendBlocks;
friend class CITANetAudioServer;
};
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_STREAMING_SERVER
...@@ -40,7 +40,7 @@ class ITA_DATA_SOURCES_API ITAPortaudioInterface ...@@ -40,7 +40,7 @@ class ITA_DATA_SOURCES_API ITAPortaudioInterface
{ {
public: public:
//! ITAPortaudio error code table //! ITAPortaudio error code table
typedef enum ITA_PA_ERRORCODE enum ITA_PA_ERRORCODE
{ {
//! Portaudio/ITAPortaudio no error //! Portaudio/ITAPortaudio no error
ITA_PA_NO_ERROR=0, ITA_PA_NO_ERROR=0,
...@@ -161,7 +161,7 @@ public: ...@@ -161,7 +161,7 @@ public:
}; };
//! Portaudio available host APIs //! Portaudio available host APIs
typedef enum ITA_PA_HOST_APIS enum ITA_PA_HOST_APIS
{ {