Aufgrund einer Wartung wird GitLab am 18.01. zwischen 8:00 und 9:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 18.01. between 8:00 and 9:00 am.

ITANetAudioStream.cpp 4.09 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <ITANetAudioStream.h>

// ITA includes
#include <ITAException.h>

// Vista includes
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
#include <VistaInterProcComm/IPNet/VistaTCPServer.h>
#include <VistaInterProcComm/IPNet/VistaTCPSocket.h>
//#include <VistaBase/VistaTimeUtils.h>
#include <VistaInterProcComm/IPNet/VistaIPAddress.h>

// STL
#include <cmath>

class CITANetAudioStreamConnection : public VistaThreadLoop
{
public:
	enum MessageType
	{
		NET_MESSAGE_NONE = 0,
		NET_MESSAGE_OPEN,
		NET_MESSAGE_CLOSE,
		NET_MESSAGE_SAMPLES,
	};

	inline CITANetAudioStreamConnection( CITANetAudioStream* pParent )
		: m_pParent( pParent )
		, m_pConnection( NULL )
		, m_bStopIndicated( false )
	{
	};

	inline bool Connect( const std::string& sAddress, int iPort )
	{
		if( m_pConnection )
			ITA_EXCEPT1( MODAL_EXCEPTION, "This net stream is already connected" );

		// Attempt to connect and check parameters
		m_pConnection = new VistaConnectionIP( VistaConnectionIP::CT_TCP, sAddress, iPort );
		if( !m_pConnection->GetIsConnected() )
		{
			delete m_pConnection;
			m_pConnection = NULL;
			return false;
		}

		int iMessageType = NET_MESSAGE_OPEN;
		m_pConnection->Send( &iMessageType, sizeof( int ) );

		int iNumChannels = ( int ) m_pParent->GetNumberOfChannels();
		m_pConnection->Send( &iNumChannels, sizeof( int ) );
		double dSampleRate = m_pParent->GetSampleRate();
		m_pConnection->Send( &dSampleRate, sizeof( double ) );
		int iBlockLength = ( int ) m_pParent->GetBlocklength();
		m_pConnection->Send( &iBlockLength, sizeof( int ) );
		int iRingBufferSize = ( int ) m_pParent->GetRingBufferSize();
		m_pConnection->Send( &iRingBufferSize, sizeof( int ) );
		m_pConnection->WaitForSendFinish();

		int iServerMessageType;
		m_pConnection->Receive( &iServerMessageType, sizeof( int ) );

		Run();
	};

	inline void Disconnect()
	{
		m_bStopIndicated = true;
		StopGently( true );

		delete m_pConnection;
		m_pConnection = NULL;

		m_bStopIndicated = false;
	};

	inline ~CITANetAudioStreamConnection()
	{
		int iMessageType = NET_MESSAGE_CLOSE;
		m_pConnection->Send( &iMessageType, sizeof( int ) );
	};

	inline bool LoopBody()
	{
		if( m_bStopIndicated )
			return true;

		// Receive messages
		while( true )
		{
			m_pConnection->Receive( NULL, 0 ); // @todo: receive messages and react

			int iNumSamples = 12;
			if( true )
				m_pParent->Transmit( m_sfReceivingBuffer, iNumSamples );
		}
	};

private:
	VistaConnectionIP* m_pConnection;
	CITANetAudioStream* m_pParent;
	ITASampleFrame m_sfReceivingBuffer;	
	bool m_bStopIndicated;
};

CITANetAudioStream::CITANetAudioStream( int iChannels, double dSamplingRate, int iBufferSize, int iRingBufferCapacity )
	: m_sfOutputStreamBuffer( iChannels, iBufferSize, true )
	, m_dSampleRate( dSamplingRate )
	, m_sfRingBuffer( iChannels, iRingBufferCapacity, true )
	
{
	m_pNetAudioProducer = new CITANetAudioStreamConnection( this );
}

bool CITANetAudioStream::Connect( const std::string& sAddress, int iPort )
{
	return m_pNetAudioProducer->Connect( sAddress, iPort );
}

CITANetAudioStream::~CITANetAudioStream()
{
	delete m_pNetAudioProducer;
}

int CITANetAudioStream::GetRingBufferSize() const
{
	return m_sfRingBuffer.GetLength();
}

unsigned int CITANetAudioStream::GetBlocklength() const
{
	return  ( unsigned int ) m_sfOutputStreamBuffer.GetLength();
}

unsigned int CITANetAudioStream::GetNumberOfChannels() const
{
	return ( unsigned int ) m_sfOutputStreamBuffer.channels();
}

double CITANetAudioStream::GetSampleRate() const
{
	return m_dSampleRate;
}

const float* CITANetAudioStream::GetBlockPointer( unsigned int uiChannel, const ITAStreamInfo* )
{
	// @todo: implement cyclic read from ring buffer
	
	return m_sfOutputStreamBuffer[ uiChannel ].GetData();
}

void CITANetAudioStream::IncrementBlockPointer()
{
	// Increment read cursor by one audio block and wrap around if exceeding ring buffer
	m_iReadCursor = ( m_iReadCursor + m_sfOutputStreamBuffer.GetLength() ) % m_sfRingBuffer.GetLength();
}

int CITANetAudioStream::Transmit( const ITASampleFrame& sfNewSamples, int iNumSamples )
{
	ITA_EXCEPT0( NOT_IMPLEMENTED );
}