ITANetAudioStreamingServer.cpp 5.69 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( ) ); //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;
50
	m_oServerParams.iBufferSize = oClientParams.iBufferSize;
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
	
	//m_pMessage->SetConnection( m_pConnection );
Anne's avatar
Anne committed
77
	m_pMessage->ResetMessage( );
78

Anne's avatar
Anne committed
79
	if ( m_pMessage->ReadMessage( ) )
80
	{
Anne's avatar
Anne committed
81 82
		int iMsgType = m_pMessage->GetMessageType( );
		switch ( iMsgType )
83
		{
Anne's avatar
Anne committed
84
			case CITANetAudioProtocol::NP_CLIENT_WAITING_FOR_SAMPLES:
85
			{
Anne's avatar
Anne committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
					int iFreeSamples = m_pMessage->ReadInt( );
					if ( iFreeSamples >= 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_SEND_SAMPLES );
					m_pMessage->WriteSampleFrame( &m_sfTempTransmitBuffer );
					m_pMessage->WriteMessage( );
102 103

#ifdef NET_AUDIO_SHOW_TRAFFIC
Anne's avatar
Anne committed
104 105
					vstr::out() << "[ITANetAudioStreamingServer] Transmitted "<< m_sfTempTransmitBuffer.GetLength() << " samples for " 
					<< m_pInputStream->GetNumberOfChannels() << " channels" << std::endl;
106
#endif
Anne's avatar
Anne committed
107 108 109 110 111 112
				}
				else
				{
					// Waiting for Trigger
					m_pMessage->SetMessageType( CITANetAudioProtocol::NP_SERVER_WAITING_FOR_TRIGGER );
					m_pMessage->WriteMessage( );
113 114

#ifdef NET_AUDIO_SHOW_TRAFFIC
Anne's avatar
Anne committed
115
					vstr::out() << "[ITANetAudioStreamingServer] Not enough free samples in client buffer, requesting a trigger when more free samples available" << std::endl;
116
#endif
Anne's avatar
Anne committed
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
				}
				break;
			}
			case CITANetAudioProtocol::NP_CLIENT_CLOSE:
			{
				//m_pMessage->SetAnswerType( CITANetAudioProtocol::NP_SERVER_CLOSE );
				//m_pMessage->WriteAnswer();
				StopGently( false );
				//m_pConnection = NULL;
				Stop( );
				return false;
			}
			default:
			{
				vstr::out( ) << "[ITANetAudioStreamingServer] Unkown protocol type : " << iMsgType << std::endl;
				break;
			}
134 135
		}

136
	}
137

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
138 139 140
	return true;
}

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

	m_pInputStream = pInStream;
Anne's avatar
Anne committed
147 148 149 150
	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( );
151 152
}

Anne's avatar
Anne committed
153
ITADatasource* CITANetAudioStreamingServer::GetInputStream( ) const
Anne's avatar
Anne committed
154 155 156 157
{
	return m_pInputStream;
}

Anne's avatar
Anne committed
158
int CITANetAudioStreamingServer::GetNetStreamBlocklength( ) const
159
{
Anne's avatar
Anne committed
160
	return m_sfTempTransmitBuffer.GetLength( );
161 162
}

Anne's avatar
Anne committed
163
int CITANetAudioStreamingServer::GetNetStreamNumberOfChannels( ) const
164
{
Anne's avatar
Anne committed
165
	return m_sfTempTransmitBuffer.channels( );
166 167
}

Anne's avatar
Anne committed
168
void CITANetAudioStreamingServer::SetAutomaticUpdateRate( )
169 170 171 172
{
	m_iUpdateStrategy = AUTO;
}

Anne's avatar
Anne committed
173
bool CITANetAudioStreamingServer::IsClientConnected( ) const
174
{
Anne's avatar
Anne committed
175
	return m_pNetAudioServer->IsConnected( );
176 177
}

Anne's avatar
Anne committed
178
std::string CITANetAudioStreamingServer::GetNetworkAddress( ) const
179
{
Anne's avatar
Anne committed
180
	return m_pNetAudioServer->GetServerAddress( );
181 182
}

Anne's avatar
Anne committed
183
int CITANetAudioStreamingServer::GetNetworkPort( ) const
184
{
Anne's avatar
Anne committed
185
	return m_pNetAudioServer->GetNetworkPort( );
186 187
}

Anne's avatar
Anne committed
188
void CITANetAudioStreamingServer::Stop( )
Anne's avatar
Anne committed
189
{
Anne's avatar
Anne committed
190
	m_pNetAudioServer->Stop( );
Anne's avatar
Anne committed
191
}