ITANetAudioStreamingServer.cpp 5.8 KB
Newer Older
Anne's avatar
Anne committed
1 2
#include <ITANetAudioStreamingServer.h>
#include <ITANetAudioServer.h>
3
#include <ITANetAudioMessage.h>
Anne's avatar
Anne committed
4 5

// ITA includes
Anne's avatar
Anne committed
6
#include <ITADataSource.h>
7
#include <ITANetAudioMessage.h>
Anne's avatar
Anne committed
8 9 10 11 12 13 14 15 16
#include <ITAException.h>
#include <ITAStreamInfo.h>

// Vista includes
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
#include <VistaInterProcComm/IPNet/VistaTCPSocket.h>
#include <VistaBase/VistaTimeUtils.h>
#include <VistaInterProcComm/IPNet/VistaIPAddress.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
17
#include <VistaBase/VistaStreamUtils.h>
Anne's avatar
Anne committed
18 19 20 21 22

// STL
#include <cmath>
#include <cassert>

Anne's avatar
Anne committed
23 24 25 26 27
CITANetAudioStreamingServer::CITANetAudioStreamingServer( )
: m_pInputStream( NULL )
, m_iUpdateStrategy( AUTO )
, m_pConnection( NULL )
, m_pNetAudioServer( new CITANetAudioServer( ) )
Anne's avatar
Anne committed
28 29 30
{
}

31
bool CITANetAudioStreamingServer::Start( const std::string& sAddress, int iPort )
Anne's avatar
Anne committed
32
{
Anne's avatar
Anne committed
33
	if ( !m_pInputStream )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
34 35
		ITA_EXCEPT1( MODAL_EXCEPTION, "Can not start server without a valid input stream" );

Anne's avatar
Anne committed
36
	if ( !m_pNetAudioServer->Start( sAddress, iPort ) ) // blocking
37 38
		return false;

Anne's avatar
Anne committed
39
	m_pConnection = m_pNetAudioServer->GetConnection( );
40

Anne's avatar
Anne committed
41 42
	m_pMessage = new CITANetAudioMessage( m_pConnection->GetByteorderSwapFlag( ) );
	m_pMessage->ResetMessage( );
43
	m_pMessage->SetConnection( m_pConnection );
Anne's avatar
Anne committed
44
	while ( !m_pMessage->ReadMessage( 0 ) ); //blocking
45

Anne's avatar
Anne committed
46 47
	assert( m_pMessage->GetMessageType( ) == CITANetAudioProtocol::NP_CLIENT_OPEN );
	CITANetAudioProtocol::StreamingParameters oClientParams = m_pMessage->ReadStreamingParameters( );
48

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
49
	bool bOK = false;
Anne's avatar
Anne committed
50
	m_oServerParams.iRingBufferSize = oClientParams.iRingBufferSize;
Anne's avatar
Anne committed
51
	if ( m_oServerParams == oClientParams )
Anne's avatar
Anne committed
52
	{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
53
		bOK = true;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
54
#ifdef NET_AUDIO_SHOW_TRAFFIC
55
		vstr::out() << "[ITANetAudioStreamingServer] Server and client parameters matched. Will resume with streaming" << std::endl;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
56 57 58
	}
	else
	{
59
		vstr::out() << "[ITANetAudioStreamingServer] Server and client parameters mismatch detected. Will notify client and stop." << std::endl;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
60
#endif
Anne's avatar
Anne committed
61
	}
Anne's avatar
Anne committed
62

Anne's avatar
Anne committed
63
	m_pMessage->SetMessageType( CITANetAudioProtocol::NP_SERVER_OPEN );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
64
	m_pMessage->WriteBool( bOK );
Anne's avatar
Anne committed
65
	m_pMessage->WriteMessage( );
66

Anne's avatar
Anne committed
67 68
	if ( bOK )
		Run( );
69

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
70
	return bOK;
Anne's avatar
Anne committed
71 72
}

Anne's avatar
Anne committed
73
bool CITANetAudioStreamingServer::LoopBody( )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
74
{
Anne's avatar
Anne committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
	// Sending Samples 
	if ( m_iClientRingBufferFreeSamples >= int( m_pInputStream->GetBlocklength( ) ) )
	{
		// Send Samples
		for ( int i = 0; i < int( m_pInputStream->GetNumberOfChannels( ) ); i++ )
		{
			ITAStreamInfo oStreamInfo;
			oStreamInfo.nSamples = m_sfTempTransmitBuffer.GetLength( );
			const float* pfData = m_pInputStream->GetBlockPointer( i, &oStreamInfo );
			if ( pfData != 0 )
				m_sfTempTransmitBuffer[ i ].write( pfData, m_sfTempTransmitBuffer.GetLength( ) );
		}
		m_pInputStream->IncrementBlockPointer( );
		m_pMessage->SetMessageType( CITANetAudioProtocol::NP_SERVER_SENDING_SAMPLES );
		m_pMessage->WriteSampleFrame( &m_sfTempTransmitBuffer );
		m_pMessage->WriteMessage( ); 
		m_iClientRingBufferFreeSamples -= m_sfTempTransmitBuffer.GetLength( );
#ifdef NET_AUDIO_SHOW_TRAFFIC
			vstr::out( ) << "[ITANetAudioStreamingServer] Transmitted " << m_sfTempTransmitBuffer.GetLength( ) << " samples for "
			<< m_pInputStream->GetNumberOfChannels( ) << " channels" << std::endl;
#endif
	}
	else
	{
		// Waiting for Trigger
		m_pMessage->SetMessageType( CITANetAudioProtocol::NP_SERVER_GET_RINGBUFFER_FREE_SAMPLES );
		m_pMessage->WriteMessage( );

#ifdef NET_AUDIO_SHOW_TRAFFIC
		vstr::out( ) << "[ITANetAudioStreamingServer] Not enough free samples in client buffer, requesting a trigger when more free samples available" << std::endl;
#endif
	}


	// Try to Empfange Daten
Anne's avatar
Anne committed
110
	//m_pMessage->SetConnection( m_pConnection );
Anne's avatar
Anne committed
111
	m_pMessage->ResetMessage( );
112

Anne's avatar
Anne committed
113
	if ( m_pMessage->ReadMessage( 1 ) )
114
	{
Anne's avatar
Anne committed
115 116
		int iMsgType = m_pMessage->GetMessageType( );
		switch ( iMsgType )
117
		{
Anne's avatar
Anne committed
118
			case CITANetAudioProtocol::NP_CLIENT_SENDING_RINGBUFFER_FREE_SAMPLES:
119
			{
Anne's avatar
Anne committed
120
				m_iClientRingBufferFreeSamples = m_pMessage->ReadInt( );	
Anne's avatar
Anne committed
121 122 123 124 125 126 127
				break;
			}
			case CITANetAudioProtocol::NP_CLIENT_CLOSE:
			{
				//m_pMessage->SetAnswerType( CITANetAudioProtocol::NP_SERVER_CLOSE );
				//m_pMessage->WriteAnswer();
				StopGently( false );
Anne's avatar
Anne committed
128
				m_pConnection = NULL;
Anne's avatar
Anne committed
129 130 131 132 133 134 135 136
				Stop( );
				return false;
			}
			default:
			{
				vstr::out( ) << "[ITANetAudioStreamingServer] Unkown protocol type : " << iMsgType << std::endl;
				break;
			}
137 138
		}

139
	}
140

Anne's avatar
Anne committed
141
	return false;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
142 143
}

144 145
void CITANetAudioStreamingServer::SetInputStream( ITADatasource* pInStream )
{
Anne's avatar
Anne committed
146
	if ( VistaThreadLoop::IsRunning( ) )
147 148 149
		ITA_EXCEPT1( MODAL_EXCEPTION, "Streaming loop already running, can not change input stream" );

	m_pInputStream = pInStream;
Anne's avatar
Anne committed
150 151 152 153
	m_sfTempTransmitBuffer.init( m_pInputStream->GetNumberOfChannels( ), m_pInputStream->GetBlocklength( ), true );
	m_oServerParams.dSampleRate = m_pInputStream->GetSampleRate( );
	m_oServerParams.iBlockSize = m_pInputStream->GetBlocklength( );
	m_oServerParams.iChannels = m_pInputStream->GetNumberOfChannels( );
154 155
}

Anne's avatar
Anne committed
156
ITADatasource* CITANetAudioStreamingServer::GetInputStream( ) const
Anne's avatar
Anne committed
157 158 159 160
{
	return m_pInputStream;
}

Anne's avatar
Anne committed
161
int CITANetAudioStreamingServer::GetNetStreamBlocklength( ) const
162
{
Anne's avatar
Anne committed
163
	return m_sfTempTransmitBuffer.GetLength( );
164 165
}

Anne's avatar
Anne committed
166
int CITANetAudioStreamingServer::GetNetStreamNumberOfChannels( ) const
167
{
Anne's avatar
Anne committed
168
	return m_sfTempTransmitBuffer.channels( );
169 170
}

Anne's avatar
Anne committed
171
void CITANetAudioStreamingServer::SetAutomaticUpdateRate( )
172 173 174 175
{
	m_iUpdateStrategy = AUTO;
}

Anne's avatar
Anne committed
176
bool CITANetAudioStreamingServer::IsClientConnected( ) const
177
{
Anne's avatar
Anne committed
178
	return m_pNetAudioServer->IsConnected( );
179 180
}

Anne's avatar
Anne committed
181
std::string CITANetAudioStreamingServer::GetNetworkAddress( ) const
182
{
Anne's avatar
Anne committed
183
	return m_pNetAudioServer->GetServerAddress( );
184 185
}

Anne's avatar
Anne committed
186
int CITANetAudioStreamingServer::GetNetworkPort( ) const
187
{
Anne's avatar
Anne committed
188
	return m_pNetAudioServer->GetNetworkPort( );
189 190
}

Anne's avatar
Anne committed
191
void CITANetAudioStreamingServer::Stop( )
Anne's avatar
Anne committed
192
{
Anne's avatar
Anne committed
193
	m_pNetAudioServer->Stop( );
Anne's avatar
Anne committed
194
}