ITANetAudioStreamingServer.cpp 5.07 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 23 24 25

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

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

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

36
	if( !m_pNetAudioServer->Start( sAddress, iPort ) ) // blocking
37 38
		return false;

39
	m_pConnection = m_pNetAudioServer->GetConnection();
40

41 42
	m_pMessage = new CITANetAudioMessage( m_pConnection->GetByteorderSwapFlag() );
	m_pMessage->ResetMessage();
43
	m_pMessage->SetConnection( m_pConnection );
44
	m_pMessage->ReadMessage(); // blocking
45

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

62
	m_pMessage->SetAnswerType( CITANetAudioProtocol::NP_SERVER_OPEN );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
63
	m_pMessage->WriteBool( bOK );
64
	m_pMessage->WriteAnswer();
65

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
66 67
	if( bOK )
		Run();
68

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
69
	return bOK;
Anne's avatar
Anne committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
}

bool CITANetAudioStreamingServer::IsClientConnected() const
{
	return m_pNetAudioServer->IsConnected();
}

std::string CITANetAudioStreamingServer::GetNetworkAddress() const
{
	return m_pNetAudioServer->GetServerAddress();
}

int CITANetAudioStreamingServer::GetNetworkPort() const
{
	return m_pNetAudioServer->GetNetworkPort();
}

void CITANetAudioStreamingServer::Stop() 
{
89
	m_pNetAudioServer->Stop();
Anne's avatar
Anne committed
90 91 92 93
}

void CITANetAudioStreamingServer::SetInputStream( ITADatasource* pInStream )
{
94 95 96
	if( VistaThreadLoop::IsRunning() )
		ITA_EXCEPT1( MODAL_EXCEPTION, "Streaming loop already running, can not change input stream" );

Anne's avatar
Anne committed
97
	m_pInputStream = pInStream;
98
	m_sfTempTransmitBuffer.init( m_pInputStream->GetNumberOfChannels(), m_pInputStream->GetBlocklength(), true );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
99 100 101
	m_oServerParams.dSampleRate = m_pInputStream->GetSampleRate();
	m_oServerParams.iBlockSize = m_pInputStream->GetBlocklength();
	m_oServerParams.iChannels = m_pInputStream->GetNumberOfChannels();
Anne's avatar
Anne committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
}

int CITANetAudioStreamingServer::GetNetStreamBlocklength() const
{
	return m_sfTempTransmitBuffer.GetLength();
}

int CITANetAudioStreamingServer::GetNetStreamNumberOfChannels() const
{
	return m_sfTempTransmitBuffer.channels();
}

void CITANetAudioStreamingServer::SetAutomaticUpdateRate()
{
	m_iUpdateStrategy = AUTO;
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
119 120
bool CITANetAudioStreamingServer::LoopBody()
{
121 122 123 124
	m_pMessage->ResetMessage();
	m_pMessage->SetConnection( m_pConnection );
	m_pMessage->ReadMessage(); // blocking

125 126
	int iMsgType = m_pMessage->GetMessageType();
	switch( iMsgType )
127 128
	{
	case CITANetAudioProtocol::NP_CLIENT_WAITING_FOR_SAMPLES:
129 130
	{
		int iFreeSamples = m_pMessage->ReadInt();
131

132
		if( iFreeSamples >= m_pInputStream->GetBlocklength() )
133
		{
134
			// Send Samples
135 136 137
			for( int i = 0; i < m_pInputStream->GetNumberOfChannels(); i++ )
			{
				ITAStreamInfo oStreamInfo;
Anne's avatar
Anne committed
138
				oStreamInfo.nSamples = m_sfTempTransmitBuffer.GetLength();
139
				const float* pfData = m_pInputStream->GetBlockPointer( i, &oStreamInfo );
140 141
				if( pfData != 0 )
					m_sfTempTransmitBuffer[ i ].write( pfData, m_sfTempTransmitBuffer.GetLength() );
142
			}
Anne's avatar
Anne committed
143
			m_pInputStream->IncrementBlockPointer();
144
			m_pMessage->SetAnswerType( CITANetAudioProtocol::NP_SERVER_SEND_SAMPLES );
Anne's avatar
Anne committed
145
			m_pMessage->WriteSampleFrame( &m_sfTempTransmitBuffer );
Anne's avatar
Anne committed
146
			m_pMessage->WriteAnswer();
147 148
		}
		else
149
		{
Anne's avatar
Anne committed
150
			// Waiting for Trigger
151
			m_pMessage->SetAnswerType( CITANetAudioProtocol::NP_SERVER_WAITING_FOR_TRIGGER );
Anne's avatar
Anne committed
152 153
			m_pMessage->WriteAnswer();
			break;
154 155
		}

Anne's avatar
Anne committed
156
		float fTimeOut = m_pInputStream->GetBlocklength() / m_pInputStream->GetSampleRate();
157 158
		break;
	}
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
159
	case CITANetAudioProtocol::NP_CLIENT_CLOSE:
160
	{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
161 162 163 164 165
		m_pConnection = NULL;
		StopGently( true );
		Stop();

		return false;
166
	}
167 168 169 170 171 172
	default:
	{
		std::cout << "Unkown protocol type: " << iMsgType << std::endl;
		break;
	}
	}
173

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
174 175 176
	return true;
}

Anne's avatar
Anne committed
177 178 179 180 181 182 183
ITADatasource* CITANetAudioStreamingServer::GetInputStream() const
{
	return m_pInputStream;
}

int CITANetAudioStreamingServer::Transmit(const ITASampleFrame& sfNewSamples, int iNumSamples)
{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
184
	assert( false );
Anne's avatar
Anne committed
185 186
	return 0;
}