ITANetAudioStreamingClient.cpp 4.98 KB
Newer Older
Dipl.-Ing. Jonas Stienen's avatar
Running  
Dipl.-Ing. Jonas Stienen committed
1 2 3 4
#include <ITANetAudioStreamingClient.h>

#include <ITANetAudioClient.h>
#include <ITANetAudioMessage.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
5
#include <ITANetAudioStream.h>
Anne Heimes's avatar
Anne Heimes committed
6 7
#include <ITADataLog.h>
#include <ITAClock.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
8 9

#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
10
#include <VistaBase/VistaStreamUtils.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
11

Anne Heimes's avatar
Anne Heimes committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
//! Audio streaming log item
struct ITAClientLog : public ITALogDataBase
{
	inline static std::ostream& outputDesc( std::ostream& os )
	{
		os << "BlockId";
		os << "\t" << "WorldTimeStamp";
		os << "\t" << "ProtocolStatus";
		os << "\t" << "FreeSamples";
		os << std::endl;
		return os;
	};

	inline std::ostream& outputData( std::ostream& os ) const
	{
		os << uiBlockId;
		os << "\t" << std::setprecision( 12 ) << dWorldTimeStamp;
		os << "\t" << iProtocolStatus;
		os << "\t" << iFreeSamples;
		os << std::endl;
		return os;
	};

	unsigned int uiBlockId; //!< Block identifier (audio streaming)
	double dWorldTimeStamp;
	int iProtocolStatus; //!< ... usw
	int iFreeSamples;

};

class ITABufferedDataLoggerImplClient : public ITABufferedDataLogger < ITAClientLog > {};


Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
45
CITANetAudioStreamingClient::CITANetAudioStreamingClient( CITANetAudioStream* pParent )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
46 47
	: m_oBlockIncrementEvent( VistaThreadEvent::WAITABLE_EVENT )
	, m_pStream( pParent )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
48 49 50
	, m_pConnection( NULL )
	, m_bStopIndicated( false )
{
Dipl.-Ing. Jonas Stienen's avatar
Running  
Dipl.-Ing. Jonas Stienen committed
51
	m_pClient = new CITANetAudioClient();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
52

Anne's avatar
Anne committed
53 54 55
	m_oParams.iChannels = pParent->GetNumberOfChannels();
	m_oParams.dSampleRate = pParent->GetSampleRate();
	m_oParams.iBlockSize = pParent->GetBlocklength();
Anne Heimes's avatar
Anne Heimes committed
56 57 58
	m_pClientLogger = new ITABufferedDataLoggerImplClient( );
	m_pClientLogger->setOutputFile("NetAudioLogClient.txt");
	iStreamingBlockId = 0;
59
	m_pMessage = new CITANetAudioMessage( VistaSerializingToolset::SWAPS_MULTIBYTE_VALUES );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
60 61 62 63 64 65
}

CITANetAudioStreamingClient::~CITANetAudioStreamingClient()
{
	if( m_pConnection )
	{
Anne's avatar
Anne committed
66 67
		m_pMessage->ResetMessage();
		m_pMessage->SetConnection( m_pConnection );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
68
		m_pMessage->SetMessageType( CITANetAudioProtocol::NP_CLIENT_CLOSE );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
69 70
		m_pMessage->WriteMessage();
		m_pClient->Disconnect();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
71
	}
Anne Heimes's avatar
Anne Heimes committed
72
	delete m_pClientLogger;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
73 74 75 76
}

bool CITANetAudioStreamingClient::Connect( const std::string& sAddress, int iPort )
{
Dipl.-Ing. Jonas Stienen's avatar
Running  
Dipl.-Ing. Jonas Stienen committed
77
	if( GetIsConnected() )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
78 79 80 81 82 83 84
		return false;
	
	if( !m_pClient->Connect( sAddress, iPort ) )
		ITA_EXCEPT1( INVALID_PARAMETER, "Could not connect to " + sAddress );
	
	m_pConnection = m_pClient->GetConnection();

85
	m_pMessage->ResetMessage();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
86 87 88 89
	m_pMessage->SetConnection( m_pConnection );

	// Validate streaming parameters of server and client
	m_pMessage->SetMessageType( CITANetAudioProtocol::NP_CLIENT_OPEN );
Anne's avatar
Anne committed
90
	m_pMessage->WriteStreamingParameters( m_oParams );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
91 92 93
	m_pMessage->WriteMessage();

	m_pMessage->ReadAnswer();
94
	assert( m_pMessage->GetAnswerType() == CITANetAudioProtocol::NP_SERVER_OPEN );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
95
	bool bOK = m_pMessage->ReadBool();
96
	
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
97 98
	if( !bOK )
		ITA_EXCEPT1( INVALID_PARAMETER, "Streaming server declined connection, detected streaming parameter mismatch." );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
99 100 101 102 103 104 105 106

	Run();

	return true;
}

bool CITANetAudioStreamingClient::LoopBody()
{
Anne Heimes's avatar
Anne Heimes committed
107 108 109
	ITAClientLog oLog;
	oLog.uiBlockId = ++iStreamingBlockId;

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
110 111 112
	if( m_bStopIndicated )
		return true;

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
113
	// Send message to server that samples can be received
Anne's avatar
Anne committed
114
	m_pMessage->ResetMessage();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
115 116
	m_pMessage->SetConnection( m_pConnection );
	m_pMessage->SetMessageType( CITANetAudioProtocol::NP_CLIENT_WAITING_FOR_SAMPLES );
117
	int iFreeSamplesUntilAllowedReached = m_pStream->GetAllowedLatencySamples() - m_pStream->GetRingBufferAvailableSamples();
Anne Heimes's avatar
Anne Heimes committed
118
	oLog.iFreeSamples = iFreeSamplesUntilAllowedReached;
119 120 121
	if( iFreeSamplesUntilAllowedReached < 0 )
		iFreeSamplesUntilAllowedReached = 0;
	m_pMessage->WriteInt( iFreeSamplesUntilAllowedReached );
Anne's avatar
Anne committed
122 123
	m_pMessage->WriteMessage();

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
124 125
	// Wait for answer of server
	m_pMessage->ReadAnswer();
126 127
	int iAnswerType = m_pMessage->GetAnswerType();
	switch( iAnswerType )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
128
	{
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
129

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
130
	case CITANetAudioProtocol::NP_INVALID:
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
131
		// Something went wrong
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
132
		vstr::err() << "Received invalid message type" << std::endl;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
133 134 135 136 137
		break;

	case CITANetAudioProtocol::NP_SERVER_WAITING_FOR_TRIGGER:
		// Wait until block increment is triggered by audio context (more free samples in ring buffer)
		m_oBlockIncrementEvent.WaitForEvent( true );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
138
		break;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
139

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
140
	case CITANetAudioProtocol::NP_SERVER_SEND_SAMPLES:
141
		// Receive samples from net message and forward them to the stream ring buffer
142

Anne's avatar
Anne committed
143
		m_pMessage->ReadSampleFrame( &m_sfReceivingBuffer );
144
		if ( m_pStream->GetRingBufferFreeSamples( ) >= m_sfReceivingBuffer.GetLength( ) )
Anne's avatar
Anne committed
145
			m_pStream->Transmit( m_sfReceivingBuffer, m_sfReceivingBuffer.GetLength( ) );
Anne's avatar
Anne committed
146 147
		//else 
			// Fehler
148
		
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
149
		break;
Anne's avatar
Anne committed
150 151
	case CITANetAudioProtocol::NP_SERVER_GET_RINGBUFFER_FREE :
		break;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
152
	}
Anne Heimes's avatar
Anne Heimes committed
153 154 155
	oLog.iProtocolStatus = iAnswerType;
	oLog.dWorldTimeStamp = ITAClock::getDefaultClock( )->getTime( );
	m_pClientLogger->log( oLog );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
156 157 158 159 160 161
	return true;
}

void CITANetAudioStreamingClient::TriggerBlockIncrement()
{
	m_oBlockIncrementEvent.SignalEvent();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
162 163 164 165 166 167
}

bool CITANetAudioStreamingClient::GetIsConnected() const
{
	return m_pClient->GetIsConnected();
}
168 169 170 171 172 173 174 175 176 177 178

void CITANetAudioStreamingClient::Disconnect()
{
	m_bStopIndicated = true;
	StopGently( true );

	delete m_pConnection;
	m_pConnection = NULL;

	m_bStopIndicated = false;
}