ITANetAudioStreamingClient.cpp 3.95 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 6 7
#include <ITANetAudioStream.h>

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

CITANetAudioStreamingClient::CITANetAudioStreamingClient( CITANetAudioStream* pParent )
12
	: m_pStream( pParent )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
13 14
	, m_pConnection( NULL )
	, m_bStopIndicated( false )
15
	, m_bStopped( false )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
16
{
Dipl.-Ing. Jonas Stienen's avatar
Running  
Dipl.-Ing. Jonas Stienen committed
17
	m_pClient = new CITANetAudioClient();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
18

Anne's avatar
Anne committed
19 20 21
	m_oParams.iChannels = pParent->GetNumberOfChannels();
	m_oParams.dSampleRate = pParent->GetSampleRate();
	m_oParams.iBlockSize = pParent->GetBlocklength();
22 23

	m_pMessage = new CITANetAudioMessage( VistaSerializingToolset::SWAPS_MULTIBYTE_VALUES );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
24 25 26 27
}

CITANetAudioStreamingClient::~CITANetAudioStreamingClient()
{
28 29 30 31 32 33 34 35
	if( GetIsConnected() )
		Disconnect();

	StopGently( true );

	delete m_pClientLogger;
	delete m_pClient;
	delete m_pMessage;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
36 37 38 39
}

bool CITANetAudioStreamingClient::Connect( const std::string& sAddress, int iPort )
{
Dipl.-Ing. Jonas Stienen's avatar
Running  
Dipl.-Ing. Jonas Stienen committed
40
	if( GetIsConnected() )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
41 42 43 44 45 46 47
		return false;
	
	if( !m_pClient->Connect( sAddress, iPort ) )
		ITA_EXCEPT1( INVALID_PARAMETER, "Could not connect to " + sAddress );
	
	m_pConnection = m_pClient->GetConnection();

48
	m_pMessage->ResetMessage();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
49 50 51 52
	m_pMessage->SetConnection( m_pConnection );

	// Validate streaming parameters of server and client
	m_pMessage->SetMessageType( CITANetAudioProtocol::NP_CLIENT_OPEN );
Anne's avatar
Anne committed
53
	m_pMessage->WriteStreamingParameters( m_oParams );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
54 55 56
	m_pMessage->WriteMessage();

	m_pMessage->ReadAnswer();
57
	assert( m_pMessage->GetAnswerType() == CITANetAudioProtocol::NP_SERVER_OPEN );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
58
	bool bOK = m_pMessage->ReadBool();
59
	
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
60 61
	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
62 63 64 65 66 67 68 69

	Run();

	return true;
}

bool CITANetAudioStreamingClient::LoopBody()
{
70
	if( !GetIsConnected() )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
71 72
		return true;

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
	ITAClientLog oLog;
	oLog.uiBlockId = ++iStreamingBlockId;

	if( m_bStopIndicated && !m_bStopped )
	{
		m_pMessage->ResetMessage();
		m_pMessage->SetMessageType( CITANetAudioProtocol::NP_CLIENT_CLOSE );
		m_pMessage->WriteMessage();
		m_bStopped = true;
		
		m_pMessage->SetConnection( NULL );

		while( GetIsConnected() )
			VistaTimeUtils::Sleep( 100 );

		return true;
	}
	
Anne's avatar
Anne committed
91
	m_pMessage->ResetMessage();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
92 93
	m_pMessage->SetConnection( m_pConnection );
	m_pMessage->SetMessageType( CITANetAudioProtocol::NP_CLIENT_WAITING_FOR_SAMPLES );
94 95 96 97
	int iFreeSamplesUntilAllowedReached = m_pStream->GetAllowedLatencySamples() - m_pStream->GetRingBufferAvailableSamples();
	if( iFreeSamplesUntilAllowedReached < 0 )
		iFreeSamplesUntilAllowedReached = 0;
	m_pMessage->WriteInt( iFreeSamplesUntilAllowedReached );
Anne's avatar
Anne committed
98 99
	m_pMessage->WriteMessage();

100 101 102
	// Read answer (blocking)
	m_pMessage->ResetMessage( );
	if ( m_pMessage->ReadMessage( 0 ) )
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
103
	{
104
		int iMsgType = m_pMessage->GetMessageType( );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
105

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
106
	case CITANetAudioProtocol::NP_INVALID:
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
107
		// Something went wrong
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
108
		vstr::err() << "Received invalid message type" << std::endl;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
109 110 111 112 113
		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
114
		break;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
115

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

Anne's avatar
Anne committed
119
		m_pMessage->ReadSampleFrame( &m_sfReceivingBuffer );
120
		if ( m_pStream->GetRingBufferFreeSamples( ) >= m_sfReceivingBuffer.GetLength( ) )
Anne's avatar
Anne committed
121
			m_pStream->Transmit( m_sfReceivingBuffer, m_sfReceivingBuffer.GetLength( ) );
Anne's avatar
Anne committed
122 123
		//else 
			// Fehler
124
		
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
125
		break;
Anne's avatar
Anne committed
126 127
	case CITANetAudioProtocol::NP_SERVER_GET_RINGBUFFER_FREE :
		break;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
128
	}
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
129 130 131 132

	return true;
}

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
133 134 135 136
bool CITANetAudioStreamingClient::GetIsConnected() const
{
	return m_pClient->GetIsConnected();
}
137 138 139 140 141

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

142 143 144
	while( !m_bStopped )
		VistaTimeUtils::Sleep( 100 );
	
145
	m_pConnection = NULL;
146
	m_pClient->Disconnect();
147
	m_bStopIndicated = false;
148
	m_bStopped = false;
149
}