Commit 20e770c7 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Adding net audio stream classes (moved from VABase) and adding test

parent d5d051b2
/*
* --------------------------------------------------------------------------------------------
*
* VVV VVV A
* VVV VVV AAA Virtual Acoustics (VA)
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA
* VVVVVV AAA (c) Copyright Institute of Technical Acoustics (ITA), 2015-2017
* VVVV AAA RWTH Aachen University (http://www.akustik.rwth-aachen.de)
*
* --------------------------------------------------------------------------------------------
*/
#ifndef IW_VACORE_NETWORK_STREAM_AUDIO_SIGNAL_SOURCE
#define IW_VACORE_NETWORK_STREAM_AUDIO_SIGNAL_SOURCE
#include <VACoreDefinitions.h>
#include <VASamples.h>
#include <VAStruct.h>
class VistaConnectionIP;
class VistaTCPServer;
class VistaTCPSocket;
//! Helper class for server-side network audio signal sources
/**
* Provides network functionality for an audio signal source.
* Transmit method has to be executed by user, status information
* for the queued samples on client side can be received.
*/
class VACORE_API CVANetworkStreamAudioSignalSource
{
public:
//! Create a network signal source (not connected)
CVANetworkStreamAudioSignalSource();
virtual ~CVANetworkStreamAudioSignalSource();
//! Start to listen on server socket
/**
* @param[in] sServerBindAddress Server name or IP
* @param[in] iServerBindPort Server port number
*
* @note This method is blocking
*/
bool Start( const std::string& sServerBindAddress = "localhost", const int iServerBindPort = 12480 );
//! Stop server and close connection
void Stop();
//! Connection status getter
bool GetIsConnected() const;
//! Transmit samples of arbitrary length
/**
* Transmit a frame of samples (buffer for one or more channels) over the network
* connection. The entire length of the buffer(s) will be send and execution is blocked
* until finished.
*
* @param[in] oFrame Vector of samples in a buffer with same length
*
* @note Will raise VAException if problem with connection occurs
*/
int Transmit( const std::vector< CVASampleBuffer >& oFrame );
//! Returns the internal number of queued samples at client side (last known state)
/**
* At client side, a ring buffer with at least the number of samples for one processing block
* is used.
*
* @return Number of queued samples at client side
*
* @note thread-safe
*/
int GetNumQueuedSamples();
private:
int m_iNumQueuedSamples; //!< Client-side number of queued samples
VistaTCPServer* m_pServer; //!< TCP server
VistaTCPSocket* m_pSocket; //!< TCP socket
VistaConnectionIP* m_pConnection; //!< IP connection
};
#endif // IW_VACORE_NETWORK_STREAM_AUDIO_SIGNAL_SOURCE
......@@ -7,6 +7,7 @@ set( DirFiles
VACoreDefinitions.h
#VACoreDumper.h
VACoreFactory.h
VANetworkStreamAudioSignalSource.h
VAObjectPool.h
VAReferenceableObject.h
VAUncopyable.h
......
#include <VANetworkStreamAudioSignalSource.h>
#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
#include <VistaInterProcComm/IPNet/VistaTCPServer.h>
#include <VistaInterProcComm/IPNet/VistaTCPSocket.h>
CVANetworkStreamAudioSignalSource::CVANetworkStreamAudioSignalSource()
: m_pServer( NULL )
, m_pSocket( NULL )
, m_pConnection( NULL )
{
}
bool CVANetworkStreamAudioSignalSource::Start( const std::string& sServerBindAddress /* = "localhost" */, const int iServerBindPort /* = 12480 */ )
{
m_pServer = new VistaTCPServer( sServerBindAddress, iServerBindPort );
m_pSocket = m_pServer->GetNextClient();
if( !m_pSocket )
return false;
if( m_pSocket->GetIsConnected() )
m_pConnection = new VistaConnectionIP( m_pSocket );
if( !m_pConnection )
return false;
return true;
}
void CVANetworkStreamAudioSignalSource::Stop()
{
delete m_pConnection;
m_pConnection = NULL;
m_pSocket = NULL;
delete m_pServer;
m_pServer = NULL;
}
CVANetworkStreamAudioSignalSource::~CVANetworkStreamAudioSignalSource()
{
delete m_pConnection;
delete m_pServer;
}
bool CVANetworkStreamAudioSignalSource::GetIsConnected() const
{
return m_pConnection ? true : false;
}
int CVANetworkStreamAudioSignalSource::GetNumQueuedSamples()
{
return 0;
}
int CVANetworkStreamAudioSignalSource::Transmit( const std::vector<CVASampleBuffer>& oFrame )
{
return 0;
}
\ No newline at end of file
......@@ -18,6 +18,7 @@ set( DirFiles
VANetstreamSignalSource.h
#VAPureDataSignalSource.cpp
#VAPureDataSignalSource.h
VANetworkStreamAudioSignalSource.cpp
VASequencerSignalSource.cpp
VASequencerSignalSource.h
_SourceFiles.cmake
......
......@@ -46,3 +46,13 @@ vista_install( GenericPathRendererTest )
vista_create_default_info_file( GenericPathRendererTest )
set_property( TARGET GenericPathRendererTest PROPERTY FOLDER "VA/Tests/VACore" )
add_executable( NetworkStreamAudioSignalSourceTest NetworkStreamAudioSignalSourceTest.cpp )
target_link_libraries( NetworkStreamAudioSignalSourceTest ${VISTA_USE_PACKAGE_LIBRARIES} )
vista_configure_app( NetworkStreamAudioSignalSourceTest )
vista_install( NetworkStreamAudioSignalSourceTest )
vista_create_default_info_file( NetworkStreamAudioSignalSourceTest )
set_property( TARGET NetworkStreamAudioSignalSourceTest PROPERTY FOLDER "VA/Tests/VABase" )
......@@ -149,7 +149,9 @@ CVAStruct GetCoreConfig()
void CreateAudioSignals()
{
cout << "Connecting to network stream signal source on localhost:12480" << endl;
string sNetStreamID = core->CreateNetworkStreamSignalSource( "localhost", 12480, "CoreTestNetStream" );
string sFileID = core->CreateAudiofileSignalSource( "Audiofiles/Bauer.wav" );
core->SetAudiofileSignalSourcePlaybackAction( sFileID, IVACore::VA_PLAYBACK_ACTION_PLAY );
core->SetAudiofileSignalSourceIsLooping( sFileID, true );
......
#include <VAException.h>
#include <VANetworkStreamAudioSignalSource.h>
#include <VASamples.h>
#include <VistaInterProcComm/Concurrency/VistaTicker.h>
#include <VistaBase/VistaTimeUtils.h>
#include <algorithm>
#include <iostream>
using namespace std;
const static int g_iBlockLength = 128;
const static double g_dSampleRate = 44.1e3;
//! Example for a sample generator class
struct CVATestSampleGenerator
{
inline CVATestSampleGenerator()
{
voBuffer.push_back( CVASampleBuffer( g_iBlockLength ) ); // single channel
dFrequency = 567.8f;
};
//! Generate a sinusoidal signal
inline void CalculateMoreSamples( const int nSamples )
{
if( voBuffer[ 0 ].GetNumSamples() != nSamples )
voBuffer[ 0 ] = CVASampleBuffer( nSamples );
for( int i = 0; i < nSamples; i++ )
{
dVal += ( i + 1 ) / double( nSamples ) * 2.0f * 3.1415f * dFrequency;
voBuffer[ 0 ].GetData()[ i ] = float( sin( dVal ) );
}
dVal = fmod( dVal, 2 * 3.1415f );
};
std::vector< CVASampleBuffer > voBuffer;
double dFrequency;
private:
double dVal;
};
//! Example sample server class that provides a network audio feed based on an own timeout
class CVATestSampleServer : public CVANetworkStreamAudioSignalSource, public VistaTicker::AfterPulseFunctor
{
public:
inline CVATestSampleServer()
: CVANetworkStreamAudioSignalSource()
{
double dBlockRate = g_dSampleRate / double( g_iBlockLength );
int iTimeoutMilliseconds = int( std::round( dBlockRate * 1.0e-3 ) );
m_pTimeoutTicker = new VistaTicker();
m_pTimeoutTicker->AddTrigger( new VistaTicker::TriggerContext( iTimeoutMilliseconds, true ) );
m_pTimeoutTicker->StartTicker();
m_pTimeoutTicker->SetAfterPulseFunctor( this );
};
inline ~CVATestSampleServer()
{
m_pTimeoutTicker->SetAfterPulseFunctor( NULL );
m_pTimeoutTicker->StopTicker();
delete m_pTimeoutTicker;
};
// Overload VistaTicker AfterPulseFunctor callback function
virtual inline bool operator()()
{
if( !CVANetworkStreamAudioSignalSource::GetIsConnected() )
return false;
int nNumSamples = CVANetworkStreamAudioSignalSource::GetNumQueuedSamples();
// Choose your strategy ...
if( nNumSamples > 0 )
{
m_oSampleGenerator.CalculateMoreSamples( nNumSamples );
CVANetworkStreamAudioSignalSource::Transmit( m_oSampleGenerator.voBuffer );
}
return true;
};
private:
VistaTicker* m_pTimeoutTicker;
CVATestSampleGenerator m_oSampleGenerator;
};
int main( int, char** )
{
/*
*
* Use VA and create a network audio stream to connect to this test server.
*
*/
CVATestSampleServer oSampleServer;
cout << "Starting server on default bind address and port" << endl;
bool bSuccess = oSampleServer.Start(); // Waits for connections on default bind socket localhost:12480
if( bSuccess )
cout << "Server started" << endl;
if( oSampleServer.GetIsConnected() )
cout << "Connection established" << endl;
else
cout << "Conection failed" << endl;
cout << "Sleeping for a while ...";
VistaTimeUtils::Sleep( int( 10e3 ) );
return 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment