...
 
Commits (32)
......@@ -25,3 +25,5 @@ Thumbs.db
svnaccess
*.lib
*.exp
*.log
*.txt
......@@ -14,16 +14,29 @@ vista_use_package( Portaudio QUIET )
vista_use_package( JACK QUIET )
if( NOT DEFINED ITA_DATA_SOURCE_WITH_INTEGRATED_ASIO )
set( ITA_DATA_SOURCE_WITH_INTEGRATED_ASIO ${VASIO_FOUND} CACHE BOOL "Build with ASIO support" )
if( NOT DEFINED ITA_DATA_SOURCES_WITH_INTEGRATED_ASIO )
set( ITA_DATA_SOURCES_WITH_INTEGRATED_ASIO ${VASIO_FOUND} CACHE BOOL "Build with ASIO support" )
endif( )
if( NOT DEFINED ITA_DATA_SOURCE_WITH_INTEGRATED_PORTAUDIO )
set( ITA_DATA_SOURCE_WITH_INTEGRATED_PORTAUDIO ${VPORTAUDIO_FOUND} CACHE BOOL "Build with Portaudio support" )
if( NOT DEFINED ITA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO )
set( ITA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO ${VPORTAUDIO_FOUND} CACHE BOOL "Build with Portaudio support" )
endif( )
if( NOT DEFINED ITA_DATA_SOURCE_WITH_INTEGRATED_JACK )
set( ITA_DATA_SOURCE_WITH_INTEGRATED_JACK ${VJACK_FOUND} CACHE BOOL "Build with JACK2 support" )
if( NOT DEFINED ITA_DATA_SOURCES_WITH_INTEGRATED_JACK )
set( ITA_DATA_SOURCES_WITH_INTEGRATED_JACK ${VJACK_FOUND} CACHE BOOL "Build with JACK2 support" )
endif( )
if( NOT DEFINED ITA_DATA_SOURCES_WITH_NET_AUDIO )
set( ITA_DATA_SOURCES_WITH_NET_AUDIO ON CACHE BOOL "Build with NetAudio support" )
endif( )
if( NOT DEFINED ITA_DATA_SOURCES_NET_AUDIO_SHOW_TRAFFIC )
set( ITA_DATA_SOURCES_NET_AUDIO_SHOW_TRAFFIC OFF CACHE BOOL "Show a lot of traffic information with NetAudio (debugging only)" )
mark_as_advanced( ITA_DATA_SOURCES_NET_AUDIO_SHOW_TRAFFIC )
endif( )
if( ITA_DATA_SOURCES_NET_AUDIO_SHOW_TRAFFIC )
add_definitions( -DNET_AUDIO_SHOW_TRAFFIC )
endif( )
......@@ -40,14 +53,6 @@ set( ITADataSourcesHeader
"include/ITADataSourcesDefinitions.h"
"include/ITAFileDataSink.h"
"include/ITAFileDataSource.h"
"include/ITANetAudioClient.h"
"include/ITANetAudioMessage.h"
"include/ITANetAudioProtocol.h"
"include/ITANetAudioServer.h"
"include/ITANetAudioStream.h"
"include/ITANetAudioStreamingClient.h"
"include/ITANetAudioStreamingServer.h"
"include/ITANetAudioStreamingClient.h"
"include/ITAPeakDetector.h"
"include/ITARMSDetector.h"
"include/ITAStreamAmplifier.h"
......@@ -67,13 +72,6 @@ set( ITADataSourcesSources
"src/ITADataSourceRealization.cpp"
"src/ITAFileDataSink.cpp"
"src/ITAFileDataSource.cpp"
"src/ITANetAudioClient.cpp"
"src/ITANetAudioMessage.cpp"
"src/ITANetAudioProtocol.cpp"
"src/ITANetAudioStream.cpp"
"src/ITANetAudioStreamingClient.cpp"
"src/ITANetAudioStreamingServer.cpp"
"src/ITANetAudioServer.cpp"
"src/ITAPeakDetector.cpp"
"src/ITARMSDetector.cpp"
"src/ITAStreamAmplifier.cpp"
......@@ -94,27 +92,49 @@ if( WIN32 )
list( APPEND ITADataSourcesSources "src/ITAStreamPump.cpp" "src/ITADataSourceUtils.cpp" )
endif( )
if( VASIO_FOUND AND ITA_DATA_SOURCE_WITH_INTEGRATED_ASIO )
if( VASIO_FOUND AND ITA_DATA_SOURCES_WITH_INTEGRATED_ASIO )
list( APPEND ITADataSourcesHeader "include/ITAAsioInterface.h" )
list( APPEND ITADataSourcesSources "src/ITAAsioInterface.cpp" )
add_definitions( -DIEEE754_64FLOAT=1 )
endif( )
if( VPORTAUDIO_FOUND AND ITA_DATA_SOURCE_WITH_INTEGRATED_PORTAUDIO )
if( VPORTAUDIO_FOUND AND ITA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO )
list( APPEND ITADataSourcesHeader "include/ITAPortaudioInterface.h" )
list( APPEND ITADataSourcesSources "src/ITAPortaudioInterface.cpp" )
endif( )
if( VJACK_FOUND AND ITA_DATA_SOURCE_WITH_INTEGRATED_JACK )
if( VJACK_FOUND AND ITA_DATA_SOURCES_WITH_INTEGRATED_JACK )
list( APPEND ITADataSourcesHeader "include/ITAJACKInterface.h" )
list( APPEND ITADataSourcesSources "src/ITAJACKInterface.cpp" )
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/ITANetAudioStreamingServer.h"
"include/ITANetAudioStreamingClient.h"
)
list( APPEND ITADataSourcesSources
"src/ITANetAudioClient.cpp"
"src/ITANetAudioMessage.cpp"
"src/ITANetAudioProtocol.cpp"
"src/ITANetAudioStream.cpp"
"src/ITANetAudioStreamingClient.cpp"
"src/ITANetAudioStreamingServer.cpp"
"src/ITANetAudioServer.cpp"
)
endif( )
# compiler settings
if( ITA_VISTA_BUILD_STATIC )
add_definitions( -DVISTABASE_STATIC -DVISTAMATH_STATIC -DVISTAASPECTS_STATIC -DVISTATOOLS_STATIC -DVISTAINTERPROCCOMM_STATIC )
endif( )
if( BUILD_SHARED_LIBS )
add_definitions( -DITA_DATA_SOURCES_EXPORT )
else( )
......
Copyright 2015-2017 Institute of Technical Acoustics, RWTH Aachen University. Any usage and distribution is prohibited, unless explicitly granted by the authors.
\ No newline at end of file
Copyright 2015-2017 Institute of Technical Acoustics, RWTH Aachen University
Licensed under the Apache License, Version 2.0 (the "License");
you may not use files of this project except in compliance with the License.
You may obtain a copy of the License at
<http://www.apache.org/licenses/LICENSE-2.0>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
\ No newline at end of file
## ITADataSources
ITADataSources is a C++ library for component-oriented audio streaming providing basic modules to manipulate samples in a block-based audio processing.
It is marked deprecated because it will be substituted by the module-base [ITAStreaming](https://git.rwth-aachen.de/ita/ITAStreaming) project in the future, but is still heavily used and updated.
ITADataSources is a component from [ITACoreLibs](https://git.rwth-aachen.de/ita/ITACoreLibs), a collection of C++ libraries for virtual acoustics.
### License
See [LICENSE](LICENSE.md) file.
### Quick build guide
Follow instructions from Wiki pages of [ITABase](https://git.rwth-aachen.de/ita/ITABase/wikis/home) project.
......@@ -6,13 +6,13 @@ include( VistaCommon )
vista_use_package( ITADataSources REQUIRED FIND_DEPENDENCIES )
if( ITA_DATA_SOURCE_WITH_INTEGRATED_ASIO )
if( TA_DATA_SOURCES_WITH_INTEGRATED_ASIO )
add_definitions( "-DITA_WHAD_WITH_ASIO" )
endif( ITA_DATA_SOURCE_WITH_INTEGRATED_ASIO )
endif( TA_DATA_SOURCES_WITH_INTEGRATED_ASIO )
if( ITA_DATA_SOURCE_WITH_INTEGRATED_PORTAUDIO )
if( TA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO )
add_definitions( "-DITA_WHAD_WITH_PORTAUDIO" )
endif( ITA_DATA_SOURCE_WITH_INTEGRATED_PORTAUDIO )
endif( TA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO )
add_executable( ita_whad main.cpp )
target_link_libraries( ita_whad ${VISTA_USE_PACKAGE_LIBRARIES} )
......
......@@ -25,6 +25,8 @@
//#include <asiosys.h>
#include <common/asio.h>
#include <string>
#define ITASIO_API ITA_DATA_SOURCES_API
/*
......@@ -201,7 +203,11 @@ ITASIO_API ASIOError ITAsioInitializeDriver(long lDriverNr);
*
* \return ASE_OK wenn kein Fehler auftrat
*/
ITASIO_API ASIOError ITAsioInitializeDriver(const char* pszDriverName);
ITASIO_API ASIOError ITAsioInitializeDriver( const char* pszDriverName );
inline ASIOError ITAsioInitializeDriver( const std::string& sDriverName )
{
return ITAsioInitializeDriver( sDriverName.c_str() );
};
//! ASIO-Treiber freigeben
/**
......
......@@ -16,8 +16,8 @@
*
*/
#ifndef INCLUDE_WATCHER_ITA_DATA_SOURCE_REALIZATION
#define INCLUDE_WATCHER_ITA_DATA_SOURCE_REALIZATION
#ifndef INCLUDE_WATCHER_ITA_DATA_SOURCES_REALIZATION
#define INCLUDE_WATCHER_ITA_DATA_SOURCES_REALIZATION
#include <ITADataSourcesDefinitions.h>
......@@ -200,4 +200,4 @@ public:
virtual void HandleProcessStream(ITADatasourceRealization* pSender, const ITAStreamInfo* pStreamInfo);
};
#endif // INCLUDE_WATCHER_ITA_DATA_SOURCE_REALIZATION
#endif // INCLUDE_WATCHER_ITA_DATA_SOURCES_REALIZATION
......@@ -16,8 +16,8 @@
*
*/
#ifndef INCLUDE_WATCHER_ITA_DATA_SOURCE_UTILS
#define INCLUDE_WATCHER_ITA_DATA_SOURCE_UTILS
#ifndef INCLUDE_WATCHER_ITA_DATA_SOURCES_UTILS
#define INCLUDE_WATCHER_ITA_DATA_SOURCES_UTILS
#include <ITADataSourcesDefinitions.h>
......@@ -82,4 +82,4 @@ ITA_DATA_SOURCES_API void WriteFromDatasourceToFile(ITADatasource* pSource,
bool bDisplayProgress=false);
#endif // INCLUDE_WATCHER_ITA_DATA_SOURCE_UTILS
#endif // INCLUDE_WATCHER_ITA_DATA_SOURCES_UTILS
......@@ -28,6 +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.
*
*/
class CITANetAudioClient
......
......@@ -40,8 +40,10 @@ class VistaConnectionIP;
//! Network audio messages
/*
* Messages consist of a message part and an answer part, each read or written
* separately. Messages have a two-int-header (SIZE, MSGTYPE), and
* answers have a two-int header (SIZE; ANSWERTYPE)
* separately. Messages have a three-int-header (SIZE, MSGTYPE, ID), and
* answers have a three-int header (SIZE, ANSWERTYPE, ID)
*
* @todo move to src folder
*/
class ITA_DATA_SOURCES_API CITANetAudioMessage
{
......@@ -101,9 +103,9 @@ private:
int m_nMessageType;
int m_nMessageId;
int m_nAnswerType;
VistaByteBufferSerializer m_oOutgoing;
VistaByteBufferDeSerializer m_oIncoming;
std::vector< VistaType::byte > m_vecIncomingBuffer;
VistaByteBufferSerializer m_oOutgoing; //!< Serialization buffer for messages
VistaByteBufferDeSerializer m_oIncoming; //!< Deserialization buffer for messages
std::vector< VistaType::byte > m_vecIncomingBuffer; // Net IO buffer
VistaConnectionIP* m_pConnection;
};
......
......@@ -54,7 +54,7 @@ public:
static const int NP_CLIENT_OPEN = 100;
static const int NP_CLIENT_CLOSE = 101;
static const int NP_CLIENT_WAITING_FOR_SAMPLES = 102;
static const int NP_CLIENT_WAITING_FOR_SAMPLES = 111;
static const int NP_SERVER_CLOSE = 200;
static const int NP_SERVER_OPEN = 201;
......
......@@ -37,6 +37,8 @@ class VistaTCPSocket;
/**
* Can be connected to an ITADataSource as a streaming source
* or to a user-implemented sample producer, i.e. an audio sythesizer.
*
* @todo: move to src folder
*/
class ITA_DATA_SOURCES_API CITANetAudioServer
{
......
......@@ -32,74 +32,166 @@ using namespace std;
class CITANetAudioStreamingClient;
class ITABufferedDataLoggerImplStream;
class ITABufferedDataLoggerImplNet;
//! Network audio stream
/**
* Audio streaming for a signal source that is connected via TCP/IP.
*
* \note not thread-safe
*/
* Audio streaming for a signal source that is connected via TCP/IP.
* The network audio stream behaves like a client and receives samples
* from a network audio stream server, CITANetAudioStreamingSearver.
*
* The stream will always work within a streaming context and will never
* 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
* data flow.
*
* Latency can be managed by either providing a small ring buffer or
* oversizing the ring buffer and requesting a target latency.
*
* \note not thread-safe
*/
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 );
virtual ~CITANetAudioStream();
//! Network streaming status of client
enum StreamingStatus
{
INVALID = -1,
STOPPED,
CONNECTED,
STREAMING,
INVALID = -1, //!< Invalid status, for exception detection
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,
};
bool Connect( const std::string& sAddress, int iPort );
//! Connect a streaming server
/**
* @sAddress[in] Server address IP, i.e. 127.0.0.1
* @iPort[in] Server socket port, defaults to 12480
*/
bool Connect( const std::string& sAddress, int iPort = 12480 );
//! Returns the connection status
/**
* @return True, if connected
*/
bool GetIsConnected() const;
//! Set allowed latency (s)
/**
* 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;
float GetMinimumLatencySeconds() const;
float GetMaximumLatencySeconds() const;
int GetMinimumLatencySamples() const;
int GetMaximumLatencySamples() const;
//! Returns (static) size of ring buffer
/**
* @return Number of maximum samples that can be hold by internal ring buffer
*/
int GetRingBufferSize() const;
//! Returns true if ring buffer is full
/**
* @return True, if ring buffer full (down to the last sample, not smaller that block size)
*/
bool GetIsRingBufferFull() const;
//! Returns true if ring buffer is empty
/**
* @return True, if ring buffer empty (down to the last sample, not smaller that block size)
*/
bool GetIsRingBufferEmpty() const;
//! Returns block size
unsigned int GetBlocklength() const;
//! Returns number of channels
unsigned int GetNumberOfChannels() const;
//! Returns sampling rate
double GetSampleRate() const;
//! Audio streaming block read for a given channel
/**
* This method is called by the streaming context for each channel, also providing stream infos.
* It copies samples out of the ring buffer, but does not touch the read/write cursors.
*/
const float* GetBlockPointer( unsigned int uiChannel, const ITAStreamInfo* );
//! Audio streaming block increment
/**
* This method updates the read curser and forwards it by one block. This operations
* frees samples out of the ring buffer. It also triggersan event
* to indicate that the ring buffer readable sample number has been decreased.
* Depending on the network streaming settings, the trigger will be forwarded
* to the server to inform about the number of free samples, that can be re-filled.
*/
void IncrementBlockPointer();
protected:
//! This method is called by the streaming client and pushes sampes into the ring buffer
//! This method is called by the networkg client and pushes samples into the ring buffer
/**
* \param sfNewSamples Sample buffer (multi channel) with sample data
* If samples fit ring buffer, the rite curser will be increased by iNumSamples, hence
* the number of free (writable) samples decreases.
*
* @param[in] sfNewSamples Sample frame with new samples to be appended to the ring buffer
* \param iNumSamples samples to be read from the sample frame (must be smaller or equal length)
*
* \return Number of free samples in ring buffer
* @return Number of free samples in ring buffer
*
* @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 );
//! Returns samples that can be read from ring buffer
/**
* @return Readable samples between read and write cursor.
*/
int GetRingBufferAvailableSamples() const;
//! Returns free samples between write and read cursor
/**
* @return Free samples between write and read cursor.
*/
int GetRingBufferFreeSamples() const;
private:
CITANetAudioStreamingClient* m_pNetAudioStreamingClient;
CITANetAudioStreamingClient* m_pNetAudioStreamingClient; //!< Audio streaming network client
double m_dSampleRate;
ITASampleFrame m_sfOutputStreamBuffer;
double m_dSampleRate; //!< Sampling rate
ITASampleFrame m_sfOutputStreamBuffer; //!< Output samples temp buffer (audio context)
int m_iReadCursor; //!< Cursor where samples will be consumed from ring buffer on next block
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; //!< Buffer incoming data
ITASampleFrame m_sfRingBuffer; //!< Ring buffer
int m_iTargetSampleLatency; //!< Maximum allowed samples / target sample latency
int m_iStreamingStatus; //!< Current streaming status
friend class CITANetAudioStreamingClient;
ofstream outputFile;
double m_dLastStreamingTimeCode;
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
friend class CITANetAudioStreamingClient;
};
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_STREAM
......@@ -40,7 +40,9 @@ class CITANetAudioStream;
//! Network audio streaming client
/**
* Audio streaming for a signal source that is connected via TCP/IP.
* Implements the ITA network protocol for audio streaming in client side.
* Implements the ITA network protocol for audio streaming on client side.
*
* @todo: move to src folder
*
* \note not thread-safe
*/
......
......@@ -25,11 +25,15 @@
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <ITANetAudioProtocol.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <ITASampleFrame.h>
using namespace std;
class ITADatasource;
class CITANetAudioMessage;
......@@ -91,6 +95,8 @@ private:
int m_iClientRingBufferFreeSamples;
friend class CITANetAudioServer;
ofstream outputFile;
};
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_STREAMING_SERVER
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -31,7 +31,6 @@ CITANetAudioStreamingClient::~CITANetAudioStreamingClient()
m_pMessage->SetConnection( m_pConnection );
m_pMessage->SetMessageType( CITANetAudioProtocol::NP_CLIENT_CLOSE );
m_pMessage->WriteMessage();
m_pMessage->ReadAnswer();
m_pClient->Disconnect();
}
}
......@@ -80,7 +79,10 @@ bool CITANetAudioStreamingClient::LoopBody()
m_pMessage->ResetMessage();
m_pMessage->SetConnection( m_pConnection );
m_pMessage->SetMessageType( CITANetAudioProtocol::NP_CLIENT_WAITING_FOR_SAMPLES );
m_pMessage->WriteInt( m_pStream->GetRingBufferFreeSamples() );
int iFreeSamplesUntilAllowedReached = m_pStream->GetAllowedLatencySamples() - m_pStream->GetRingBufferAvailableSamples();
if( iFreeSamplesUntilAllowedReached < 0 )
iFreeSamplesUntilAllowedReached = 0;
m_pMessage->WriteInt( iFreeSamplesUntilAllowedReached );
m_pMessage->WriteMessage();
// Wait for answer of server
......@@ -96,7 +98,6 @@ bool CITANetAudioStreamingClient::LoopBody()
case CITANetAudioProtocol::NP_SERVER_WAITING_FOR_TRIGGER:
// Wait until block increment is triggered by audio context (more free samples in ring buffer)
//std::cout << "Will wait for block increment" << std::endl;
m_oBlockIncrementEvent.WaitForEvent( true );
break;
......@@ -104,7 +105,6 @@ bool CITANetAudioStreamingClient::LoopBody()
// Receive samples from net message and forward them to the stream ring buffer
m_pMessage->ReadSampleFrame( &m_sfReceivingBuffer );
//std::cout << "Receiving " << m_sfReceivingBuffer.GetLength() << " samples from streaming server" << std::endl;
if ( m_pStream->GetRingBufferFreeSamples( ) >= m_sfReceivingBuffer.GetLength( ) )
m_pStream->Transmit( m_sfReceivingBuffer, m_sfReceivingBuffer.GetLength( ) );
//else
......
......@@ -24,7 +24,7 @@ CITANetAudioStreamingServer::CITANetAudioStreamingServer()
, m_iUpdateStrategy( AUTO )
, m_pConnection( NULL )
{
m_pNetAudioServer = new CITANetAudioServer();
m_pNetAudioServer = new CITANetAudioServer( );
}
bool CITANetAudioStreamingServer::Start( const std::string& sAddress, int iPort )
......@@ -128,6 +128,7 @@ bool CITANetAudioStreamingServer::LoopBody()
case CITANetAudioProtocol::NP_CLIENT_WAITING_FOR_SAMPLES:
{
int iFreeSamples = m_pMessage->ReadInt();
if( iFreeSamples >= m_pInputStream->GetBlocklength() )
{
// Send Samples
......@@ -143,26 +144,20 @@ bool CITANetAudioStreamingServer::LoopBody()
m_pMessage->SetAnswerType( CITANetAudioProtocol::NP_SERVER_SEND_SAMPLES );
m_pMessage->WriteSampleFrame( &m_sfTempTransmitBuffer );
m_pMessage->WriteAnswer();
//std::cout << "Transmitted " << m_pInputStream->GetBlocklength() << " samples, because there where " << iFreeSamples << " free samples on client side" << std::endl;
}
else
{
//std::cout << "Could not transmitt, because there where only " << iFreeSamples << " free samples on client side" << std::endl;
// Waiting for Trigger
m_pMessage->SetAnswerType( CITANetAudioProtocol::NP_SERVER_WAITING_FOR_TRIGGER );
m_pMessage->WriteAnswer();
break;
}
float fTimeOut = m_pInputStream->GetBlocklength() / m_pInputStream->GetSampleRate();
//VistaTimeUtils::Sleep( (int) ( 1 * 100 ) );
break;
}
case CITANetAudioProtocol::NP_CLIENT_CLOSE:
{
m_pMessage->WriteAnswer();
m_pConnection = NULL;
StopGently( true );
Stop();
......
This diff is collapsed.
......@@ -115,17 +115,17 @@ set_property( TARGET StreamProbeTest PROPERTY FOLDER "ITACoreLibs/Tests/ITADataS
# tests
if( ITA_DATA_SOURCE_WITH_INTEGRATED_ASIO )
if( ITA_DATA_SOURCES_WITH_INTEGRATED_ASIO )
add_subdirectory( ITAAsioTests )
endif( ITA_DATA_SOURCE_WITH_INTEGRATED_ASIO )
endif( ITA_DATA_SOURCES_WITH_INTEGRATED_ASIO )
if( ITA_DATA_SOURCE_WITH_INTEGRATED_PORTAUDIO )
if( ITA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO )
add_subdirectory( "ITAPortaudioTests" )
endif( ITA_DATA_SOURCE_WITH_INTEGRATED_PORTAUDIO )
endif( ITA_DATA_SOURCES_WITH_INTEGRATED_PORTAUDIO )
if( VJACK_FOUND AND ITA_DATA_SOURCE_WITH_INTEGRATED_JACK )
if( VJACK_FOUND AND ITA_DATA_SOURCES_WITH_INTEGRATED_JACK )
add_subdirectory( "ITAJACKTests" )
endif( VJACK_FOUND AND ITA_DATA_SOURCE_WITH_INTEGRATED_JACK )
endif( VJACK_FOUND AND ITA_DATA_SOURCES_WITH_INTEGRATED_JACK )
add_subdirectory( "NetAudio" )
add_subdirectory( "VistaNetTest" )
......@@ -7,8 +7,6 @@ include( VistaCommon )
vista_use_package( ITADataSources REQUIRED FIND_DEPENDENCIES )
add_definitions( -DITA_DATA_SOURCES_DLL )
add_executable( ListDevices ListDevices.cpp )
target_link_libraries( ListDevices ${VISTA_USE_PACKAGE_LIBRARIES} )
......
......@@ -7,23 +7,45 @@
#include <ITAException.h>
#include <ITAFileDatasource.h>
#include <ITAStreamProbe.h>
#include <ITAStreamPatchbay.h>
using namespace std;
//static string g_sServerName = "137.226.61.163";
static string g_sServerName = "localhost";
static int g_iServerPort = 12480;
static double g_dSampleRate = 44100;
static int g_iBufferSize = 256;
static int g_iBufferSize = 1024;
static int g_iChannels = 20;
int main( int , char** )
{
CITANetAudioStream oNetAudioStream( 2, g_dSampleRate, g_iBufferSize, 100 * g_iBufferSize );
ITAStreamProbe oProbe( &oNetAudioStream, "out_gutentag.wav" );
//ITAStreamMultiplier1N oMultiplier( &oProbe, 2 );
CITANetAudioStream oNetAudioStream( g_iChannels, g_dSampleRate, g_iBufferSize, 100 * g_iBufferSize );
ITAStreamPatchbay oPatchbay( g_dSampleRate, g_iBufferSize );
oPatchbay.AddInput( &oNetAudioStream );
ITADatasource* pOutput;
oPatchbay.AddOutput( 1 );
/*
for ( int i = 0; i < oNetAudioStream.GetNumberOfChannels( ); i++ )
{
if ( i % 2 == 0 )
oPatchbay.ConnectChannels( 0, i, 0, 0 );
else
oPatchbay.ConnectChannels( 0, i, 0, 1 );
*/
oPatchbay.ConnectChannels( 0, 0, 0, 0, 1.0f );
pOutput = oPatchbay.GetOutputDatasource( 0 );
oPatchbay.SetOutputMuted( 0, true );
ITAStreamProbe oProbe( pOutput, "output.wav" );
ITAStreamMultiplier1N oMultiplier( &oProbe, 2 );
ITAPortaudioInterface ITAPA( g_dSampleRate, g_iBufferSize );
ITAPA.Initialize();
ITAPA.SetPlaybackDatasource( &oProbe );
ITAPA.SetPlaybackDatasource( &oMultiplier );
ITAPA.Open();
ITAPA.Start();
......@@ -59,7 +81,5 @@ int main( int , char** )
ITAPA.Close();
ITAPA.Finalize();
return 0;
}
......@@ -4,6 +4,7 @@
#include <ITANetAudioStreamingServer.h>
#include <ITANetAudioServer.h>
#include <ITAStreamFunctionGenerator.h>
#include <ITAStreamMultiplier1N.h>
#include <ITAFileDatasource.h>
using namespace std;
......@@ -11,14 +12,16 @@ using namespace std;
static string g_sServerName = "localhost";
static int g_iServerPort = 12480;
static double g_dSampleRate = 44100;
static int g_iBlockLength = 256;
static int g_iBlockLength = 1024;
static int g_iChannels = 20;
int main( int , char** )
{
ITAStreamFunctionGenerator oGenerator( 2, g_dSampleRate, g_iBlockLength, ITAStreamFunctionGenerator::SINE, 456.78f, 0.81f, true );
ITAFileDatasource oDatei("01_Empfang_Guten_Tag.wav", g_iBlockLength);
//ITAStreamFunctionGenerator oGenerator( 2, g_dSampleRate, g_iBlockLength, ITAStreamFunctionGenerator::SINE, 456.78f, 0.81f, true );
ITAFileDatasource oFile("gershwin-mono.wav", g_iBlockLength);
ITAStreamMultiplier1N oMuliplier( &oFile, g_iChannels );
CITANetAudioStreamingServer oStreamingServer;
oStreamingServer.SetInputStream(&oDatei);
oStreamingServer.SetInputStream( &oMuliplier );
cout << "Starting server and waiting for connections on '" << g_sServerName << "' on port " << g_iServerPort << endl;
oStreamingServer.Start( g_sServerName, g_iServerPort );
......
NetAudioLogNet = readtable( 'NetAudioLogNet.txt' );
NetAudioLogStream = readtable( 'NetAudioLogStream.txt' );
plot( NetAudioLogNet.WorldTimeStamp, NetAudioLogNet.FreeSamples/NetAudioLogNet.NumSamplesTransmitted )
hold on
plot( NetAudioLogStream.WorldTimeStamp, NetAudioLogStream.FreeSamples/NetAudioLogNet.NumSamplesTransmitted )
\ No newline at end of file
......@@ -17,7 +17,6 @@ vista_create_default_info_file( ITAVistaNetTest )
set_property( TARGET ITAVistaNetTest PROPERTY FOLDER "ITACoreLibs/Tests/ITADataSources/VistaNet" )
add_executable( ITAVistaNetClient VistaNetClient.cpp )
target_link_libraries( ITAVistaNetClient ${VISTA_USE_PACKAGE_LIBRARIES} )
......@@ -39,5 +38,4 @@ vista_configure_app( ITAVistaNetServer )
vista_install( ITAVistaNetServer )
vista_create_default_info_file( ITAVistaNetServer )
set_property( TARGET ITAVistaNetServer PROPERTY FOLDER "ITACoreLibs/Tests/ITADataSources/VistaNet" )
set_property( TARGET ITAVistaNetServer PROPERTY FOLDER "ITACoreLibs/Tests/ITADataSources/VistaNet" )
\ No newline at end of file
#include <cassert>
#include <iostream>
#include <string>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <VistaInterProcComm/Concurrency/VistaThread.h>
#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
#include <VistaInterProcComm/IPNet/VistaTCPServer.h>
#include <VistaInterProcComm/IPNet/VistaTCPSocket.h>
#include <VistaBase/VistaTimeUtils.h>
#include <VistaBase/VistaStreamUtils.h>
using namespace std;
static string g_sServerName = "localhost";
static int g_iServerPort = 12480;
static const string g_sServerName = "localhost";
static const int g_iServerPort = 12480;
static const int g_iRepetitions = 5;
static const size_t g_lDataSize = 152733239;
class CServer : public VistaThreadLoop
class CServer : public VistaThread
{
public:
CServer()
{
m_pServer = new VistaTCPServer( g_sServerName, g_iServerPort, 1 );
Run();
}
};
~CServer()
{
delete m_pServer;
}
};
bool LoopBody()
void ThreadBody()
{
cout << "[ Server ] Waiting for connections" << endl;
VistaTCPSocket* pSocket = m_pServer->GetNextClient();
VistaTimeUtils::Sleep( 100 ); // Sync couts
vstr::out() << "[ Server ] Connected." << endl;
size_t nGetReceiveBufferSize = pSocket->GetReceiveBufferSize();
vstr::out() << "[ Server ] " << nGetReceiveBufferSize << " receive buffer size" << endl;
long nIncomingBytes = pSocket->WaitForIncomingData( 0 );
cout << "Server incoming bytes: " << nIncomingBytes << " bytes" << endl;
vector< char > vdIncomingData;
if( nGetReceiveBufferSize == nIncomingBytes )
cout << "Warning: payload as long as receiver buffer size ... problem will occur!" << endl;
char* buf = new char[ nIncomingBytes ];
bool bRepeat = true;
while( bRepeat )
{
long nIncomingBytes = pSocket->WaitForIncomingData( 0 );
vstr::out() << "[ Server ] " << nIncomingBytes << " incoming bytes" << endl;
long nIncomingBytes2 = pSocket->WaitForIncomingData( 0 );
int iBytesReceived = pSocket->ReceiveRaw( buf, nIncomingBytes );
vector< char > vdIncomingData( iBytesReceived );
for( size_t i=0; i < vdIncomingData.size(); i++ )
vdIncomingData[i] = buf[ i ];
// Two-step receiving
int iPayloadDataSize;
int iBytesRead = pSocket->ReceiveRaw( &iPayloadDataSize, sizeof( int ) );
assert( iBytesRead == sizeof( int ) );
vstr::out() << "[ Server ] Expecting " << iPayloadDataSize << " bytes to come." << endl;
delete[] buf;
if( iPayloadDataSize > vdIncomingData.size() )
vdIncomingData.resize( iPayloadDataSize );
assert( vdIncomingData[0] == 1 );
assert( vdIncomingData[ vdIncomingData.size() -2 ] == -1 );
int iBytesReceivedTotal = 0;
while( iPayloadDataSize != iBytesReceivedTotal )
{
long nIncomingBytes = pSocket->WaitForIncomingData( 0 );
int iBytesReceived = pSocket->ReceiveRaw( &vdIncomingData[ iBytesReceivedTotal ], nIncomingBytes );
iBytesReceivedTotal += iBytesReceived;
vstr::out() << "[ Server ] " << setw( 3 ) << std::floor( iBytesReceivedTotal / float( iPayloadDataSize ) * 100.0f ) << "% transmitted" << endl;
}
VistaTimeUtils::Sleep( 200 );
assert( vdIncomingData[ 0 ] == 1 );
assert( vdIncomingData[ vdIncomingData.size() - 2 ] == -1 );
cout << "Server sending acknowledge flag" << endl;
bool bAck = false;
pSocket->SendRaw( &bAck, 1 );
vstr::out() << "[ Server ] Received all data and content appears valid!" << endl;
return false;
}
vstr::out() << "[ Server ] Sending acknowledge flag" << endl;
bool bTransmissionDone = true;
pSocket->SendRaw( &bTransmissionDone, sizeof( bool ) );
iBytesRead = pSocket->ReceiveRaw( &bRepeat, sizeof( bool ) );
if( bRepeat )
vstr::out() << "[ Server ] Repeating" << endl;
}
vstr::out() << "[ Server ] Closing." << endl;
};
private:
VistaTCPServer* m_pServer;
......@@ -72,37 +87,43 @@ private:
int main( int , char** )
{
CServer oServer;
VistaConnectionIP oConnection( VistaConnectionIP::CT_TCP, g_sServerName, g_iServerPort);
if( oConnection.GetIsConnected() )
if( !oConnection.GetIsConnected() )
{
cout << "Connection established" << endl;
VistaTimeUtils::Sleep( 500 );
cout << "Client sending data" << endl;
VistaTimeUtils::Sleep( 500 );
vstr::out() << "[ Client ] Connection failed" << endl;
return 255;
}
cout << "Connection is buffering: " << ( oConnection.GetIsBuffering() ? "yes" : "no" ) << endl;
vstr::out() << "[ Client ] Connection established" << endl;
vstr::out() << "[ Client ] Connection is buffering: " << ( oConnection.GetIsBuffering() ? "yes" : "no" ) << endl;
size_t l = 10000; // > MTU?
vector< char > vdData( l );
vdData[ 0 ] = 1; // First entry one
vdData[ vdData.size() - 2 ] = -1; // Last entry -1
void* pData = (void*) &vdData[0];
oConnection.Send( pData, int( vdData.size() ) ); // SendRaw?
int i = 0;
while( i++ <= g_iRepetitions )
{
vstr::out() << "[ Client ] Client sending data now." << endl;
vector< char > vdData( g_lDataSize + 4 );
int* piDataSize = ( int* ) &vdData[ 0 ];
*piDataSize = unsigned int( g_lDataSize ); // Send data size as first block
vdData[ 1 * sizeof( int ) + 0 ] = 1; // First entry one (just for fun)
vdData[ vdData.size() - 2 ] = -1; // Second last entry -1 (just for fun)
void* pData = ( void* ) &vdData[ 0 ];
oConnection.Send( pData, int( vdData.size() ) );
bool bAck;
oConnection.ReadBool( bAck );
cout << "Client received acknowledge flag '" << bAck << "'" << endl;
oConnection.Close( false );
}
else
{
cerr << "Connection failed" << endl;
return 255;
if( !bAck )
vstr::out() << "[ Client ] Received negative acknowledge flag" << endl;
else
vstr::out() << "[ Client ] Received positive acknowledge flag" << endl;
bool bRepeat = ( i <= g_iRepetitions );
oConnection.Send( &bRepeat, sizeof( bool ) );
}
oConnection.Close( false );
return 0;
}