ITANetAudioMessage.cpp 11.2 KB
Newer Older
Anne's avatar
Anne committed
1
#include <ITANetAudioMessage.h>
Anne's avatar
Anne committed
2
3
4
5
6
7
8
9
10
#include <ITAStringUtils.h>

#include <VistaInterProcComm/Connections/VistaConnectionIP.h>
#include <VistaBase/VistaExceptionBase.h>

#include <cassert>

static int S_nMessageIds = 0;

11
12
13
14
CITANetAudioMessage::CITANetAudioMessage(VistaSerializingToolset::ByteOrderSwapBehavior bSwapBuffers)
: m_vecIncomingBuffer(2048)
, m_oOutgoing(2048)
, m_pConnection(NULL)
Anne's avatar
Anne committed
15
{
16
17
	m_oOutgoing.SetByteorderSwapFlag(bSwapBuffers);
	m_oIncoming.SetByteorderSwapFlag(bSwapBuffers);
Anne's avatar
Anne committed
18
19
20
21
22
	ResetMessage();
}

void CITANetAudioMessage::ResetMessage()
{
23
	if (m_oIncoming.GetTailSize() > 0)
Anne's avatar
Anne committed
24
25
26
27
28
29
30
	{
		std::cerr << "CITANetAudioMessage::ResetMessage() called before message was fully processed!" << std::endl;
	}

	// wait till sending is complete -> this prevents us
	// from deleting the buffer while it is still being read
	// by the connection
31
	if (m_pConnection)
Anne's avatar
Anne committed
32
33
34
35
36
		m_pConnection->WaitForSendFinish();

	m_nMessageId = S_nMessageIds++;

	m_oOutgoing.ClearBuffer();
37
38
39
	m_oOutgoing.WriteInt32(0); // size dummy
	m_oOutgoing.WriteInt32(0); // type dummy
	m_oOutgoing.WriteInt32(0); // ID
Anne's avatar
Anne committed
40

41
	m_oIncoming.SetBuffer(NULL, 0);
Anne's avatar
Anne committed
42
43
44
45
46
47
48

	m_nMessageType = CITANetAudioProtocol::NP_INVALID;
	m_nAnswerType = CITANetAudioProtocol::NP_INVALID;

	m_pConnection = NULL;
}

49
void CITANetAudioMessage::SetConnection(VistaConnectionIP* pConn)
Anne's avatar
Anne committed
50
51
52
53
54
55
{
	m_pConnection = pConn;
}

void CITANetAudioMessage::WriteMessage()
{
56
	VistaType::byte* pBuffer = (VistaType::byte*) m_oOutgoing.GetBuffer();
Anne's avatar
Anne committed
57
58
59
	VistaType::sint32 iSwapDummy;

	// rewrite size dummy
60
61
62
63
	iSwapDummy = m_oOutgoing.GetBufferSize() - sizeof(VistaType::sint32);
	if (m_oOutgoing.GetByteorderSwapFlag())
		VistaSerializingToolset::Swap4(&iSwapDummy);
	memcpy(pBuffer, &iSwapDummy, sizeof(VistaType::sint32));
Anne's avatar
Anne committed
64

65
	pBuffer += sizeof(VistaType::sint32);
Anne's avatar
Anne committed
66
67
68

	// rewrite type dummy
	iSwapDummy = m_nMessageType;
69
70
71
72
73
	if (m_oOutgoing.GetByteorderSwapFlag())
		VistaSerializingToolset::Swap4(&iSwapDummy);
	memcpy(pBuffer, &iSwapDummy, sizeof(VistaType::sint32));

	pBuffer += sizeof(VistaType::sint32);
Anne's avatar
Anne committed
74
75
76

	// rewrite messageid dummy
	iSwapDummy = m_nMessageId;
77
78
79
	if (m_oOutgoing.GetByteorderSwapFlag())
		VistaSerializingToolset::Swap4(&iSwapDummy);
	memcpy(pBuffer, &iSwapDummy, sizeof(VistaType::sint32));
Anne's avatar
Anne committed
80
81
82
83

	try
	{
		int iRawBufferSize = m_oOutgoing.GetBufferSize();
84
		int nRet = m_pConnection->WriteRawBuffer(m_oOutgoing.GetBuffer(), iRawBufferSize);
Anne's avatar
Anne committed
85
		m_pConnection->WaitForSendFinish();
86
87
		if (nRet != m_oOutgoing.GetBufferSize())
			ITA_EXCEPT1(NETWORK_ERROR, "Could not write the expected number of bytes");
Anne's avatar
Anne committed
88
	}
89
	catch (VistaExceptionBase& ex)
Anne's avatar
Anne committed
90
	{
91
		ITA_EXCEPT1(NETWORK_ERROR, ex.GetExceptionText());
Anne's avatar
Anne committed
92
93
94
95
96
97
98
99
100
	}
}


void CITANetAudioMessage::ReadMessage()
{
	try
	{
		VistaType::sint32 nMessageSize;
101
102
		int nReturn = m_pConnection->ReadInt32(nMessageSize);

Anne's avatar
Anne committed
103
		// we need at least the two protocol ints
104
		assert(nMessageSize >= 2 * sizeof(VistaType::sint32));
Anne's avatar
Anne committed
105

106
107
		if (nMessageSize > (int)m_vecIncomingBuffer.size())
			m_vecIncomingBuffer.resize(nMessageSize);
Anne's avatar
Anne committed
108

109
110
111
		nReturn = m_pConnection->ReadRawBuffer(&m_vecIncomingBuffer[0], nMessageSize);
		if (nReturn != nMessageSize)
			ITA_EXCEPT1(NETWORK_ERROR, "Protokoll error, Received less bytes than expected");
Anne's avatar
Anne committed
112

113
		m_oIncoming.SetBuffer(&m_vecIncomingBuffer[0], nReturn);
Anne's avatar
Anne committed
114
115
116

		// DEBUG: std::cout << "Remainign Size after Mesage Read: " << m_pConnection->PendingDataSize() << std::endl;
	}
117
	catch (VistaExceptionBase& ex)
Anne's avatar
Anne committed
118
	{
119
		ITA_EXCEPT1(UNKNOWN, ex.GetExceptionText());
Anne's avatar
Anne committed
120
	}
121
	catch (ITAException& ex)
Anne's avatar
Anne committed
122
123
124
125
126
127
128
129
130
131
132
	{
		ex;
	}

	m_nMessageType = ReadInt();
	m_nMessageId = ReadInt();
}


void CITANetAudioMessage::WriteAnswer()
{
133
	VistaType::byte* pBuffer = (VistaType::byte*)m_oOutgoing.GetBuffer();
Anne's avatar
Anne committed
134
135
136
	VistaType::sint32 iSwapDummy;

	// rewrite size dummy
137
138
139
140
	iSwapDummy = m_oOutgoing.GetBufferSize() - sizeof(VistaType::sint32);
	if (m_oOutgoing.GetByteorderSwapFlag())
		VistaSerializingToolset::Swap4(&iSwapDummy);
	memcpy(pBuffer, &iSwapDummy, sizeof(VistaType::sint32));
Anne's avatar
Anne committed
141

142
	pBuffer += sizeof(VistaType::sint32);
Anne's avatar
Anne committed
143
144
145

	// rewrite type dummy
	iSwapDummy = m_nAnswerType;
146
147
148
149
150
	if (m_oOutgoing.GetByteorderSwapFlag())
		VistaSerializingToolset::Swap4(&iSwapDummy);
	memcpy(pBuffer, &iSwapDummy, sizeof(VistaType::sint32));

	pBuffer += sizeof(VistaType::sint32);
Anne's avatar
Anne committed
151
152
153

	// rewrite message dummy
	iSwapDummy = m_nMessageId;
154
155
156
	if (m_oOutgoing.GetByteorderSwapFlag())
		VistaSerializingToolset::Swap4(&iSwapDummy);
	memcpy(pBuffer, &iSwapDummy, sizeof(VistaType::sint32));
Anne's avatar
Anne committed
157
158
159

	try
	{
160
		int nRet = m_pConnection->WriteRawBuffer(m_oOutgoing.GetBuffer(), m_oOutgoing.GetBufferSize());
Anne's avatar
Anne committed
161
		m_pConnection->WaitForSendFinish();
162
163
		if (nRet != m_oOutgoing.GetBufferSize())
			ITA_EXCEPT1(UNKNOWN, "Could not write the expected number of bytes");
Anne's avatar
Anne committed
164
	}
165
	catch (VistaExceptionBase& ex)
Anne's avatar
Anne committed
166
	{
167
		ITA_EXCEPT1(UNKNOWN, ex.GetExceptionText());
Anne's avatar
Anne committed
168
169
170
171
172
173
174
175
176
177
178
	}
}

void CITANetAudioMessage::ReadAnswer()
{
	try
	{
		VistaType::sint32 nMessageSize;
		int nReturn;
		try
		{
179
			nReturn = m_pConnection->ReadInt32(nMessageSize);
Anne's avatar
Anne committed
180
		}
181
		catch (...)
Anne's avatar
Anne committed
182
183
184
185
		{
			nReturn = -1; // Network connection error
		}

186
		if (nReturn != sizeof(VistaType::sint32))
Anne's avatar
Anne committed
187
		{
188
			ITA_EXCEPT1(UNKNOWN, "Protokoll error, Received less bytes than expected");
Anne's avatar
Anne committed
189
190
191
		}

		// we need at least the two protocol types
192
		assert(nMessageSize >= 2 * sizeof(VistaType::sint32));
Anne's avatar
Anne committed
193

194
195
		if (nMessageSize > (int)m_vecIncomingBuffer.size())
			m_vecIncomingBuffer.resize(nMessageSize);
Anne's avatar
Anne committed
196
197

		// jst: hier nicht while( nReturn < nMessageSize) ReadRawBuffer??
198
199
200
		nReturn = m_pConnection->ReadRawBuffer(&m_vecIncomingBuffer[0], nMessageSize);
		if (nReturn != nMessageSize)
			ITA_EXCEPT1(UNKNOWN, "Protokoll error, Received less bytes than expected");
Anne's avatar
Anne committed
201

202
		m_oIncoming.SetBuffer(&m_vecIncomingBuffer[0], nReturn);
Anne's avatar
Anne committed
203
	}
204
	catch (VistaExceptionBase& ex)
Anne's avatar
Anne committed
205
206
207
	{
		// Probable connection loss
		return;
208
		ITA_EXCEPT1(UNKNOWN, ex.GetExceptionText());
Anne's avatar
Anne committed
209
	}
210
	catch (ITAException& ex)
Anne's avatar
Anne committed
211
212
213
214
215
216
217
218
	{
		std::string sErrorText = ex.ToString();
	}

	try
	{
		m_nAnswerType = ReadInt(); // TODO: assert weg, daf�r Kontrolle falls Server crasht<
		int nMessageID = ReadInt();
219
		assert(nMessageID == m_nMessageId);
Anne's avatar
Anne committed
220
221
		m_nMessageId = nMessageID;
	}
222
	catch (ITAException& ex)
Anne's avatar
Anne committed
223
224
225
226
227
228
229
230
231
232
233
	{
		std::cerr << "ITANetAudioMessage: Protocol error: " << ex << std::endl;
	}
}


int CITANetAudioMessage::GetMessageType() const
{
	return m_nMessageType;
}

234
void CITANetAudioMessage::SetMessageType(int nType)
Anne's avatar
Anne committed
235
{
236
	assert(m_nMessageType == CITANetAudioProtocol::NP_INVALID); // should only be set once
Anne's avatar
Anne committed
237
238
239
	m_nMessageType = nType;
}

240
void CITANetAudioMessage::SetAnswerType(int nType)
Anne's avatar
Anne committed
241
{
242
	assert(m_nAnswerType == CITANetAudioProtocol::NP_INVALID); // should only be set once
Anne's avatar
Anne committed
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
	m_nAnswerType = nType;
}

int CITANetAudioMessage::GetAnswerType() const
{
	return m_nAnswerType;
}

int CITANetAudioMessage::GetIncomingMessageSize() const
{
	return m_oIncoming.GetTailSize();
}

int CITANetAudioMessage::GetOutgoingMessageSize() const
{
	return m_oOutgoing.GetBufferSize();
}

bool CITANetAudioMessage::GetOutgoingMessageHasData() const
{
263
	return (m_oOutgoing.GetBufferSize() > 4 * sizeof(VistaType::sint32));
Anne's avatar
Anne committed
264
265
}

266
void CITANetAudioMessage::WriteString(const std::string& sValue)
Anne's avatar
Anne committed
267
{
268
269
	m_oOutgoing.WriteInt32((VistaType::sint32)sValue.size());
	if (!sValue.empty()) m_oOutgoing.WriteString(sValue);
Anne's avatar
Anne committed
270
271
}

272
void CITANetAudioMessage::WriteInt(const int iValue)
Anne's avatar
Anne committed
273
{
274
	m_oOutgoing.WriteInt32((VistaType::sint32)iValue);
Anne's avatar
Anne committed
275
276
}

277
void CITANetAudioMessage::WriteBool(const bool bValue)
Anne's avatar
Anne committed
278
{
279
	m_oOutgoing.WriteBool(bValue);
Anne's avatar
Anne committed
280
281
}

282
void CITANetAudioMessage::WriteFloat(const float fValue)
Anne's avatar
Anne committed
283
{
284
	m_oOutgoing.WriteFloat32(fValue);
Anne's avatar
Anne committed
285
286
}

287
void CITANetAudioMessage::WriteDouble(const double dValue)
Anne's avatar
Anne committed
288
{
289
	m_oOutgoing.WriteFloat64(dValue);
Anne's avatar
Anne committed
290
291
292
293
294
}

std::string CITANetAudioMessage::ReadString()
{
	VistaType::sint32 nSize;
295
296
	int nReturn = m_oIncoming.ReadInt32(nSize);
	assert(nReturn == sizeof(VistaType::sint32));
Anne's avatar
Anne committed
297
298

	// Empty string?
299
	if (nSize == 0) return "";
Anne's avatar
Anne committed
300
301

	std::string sValue;
302
303
	nReturn = m_oIncoming.ReadString(sValue, nSize);
	assert(nReturn == nSize);
Anne's avatar
Anne committed
304
305
306
307
308
309
	return sValue;
}

int CITANetAudioMessage::ReadInt()
{
	VistaType::sint32 nValue;
310
311
312
313
	int nReturn = m_oIncoming.ReadInt32(nValue);
	if (nReturn == -1)
		ITA_EXCEPT1(UNKNOWN, "Could not read integer value from incoming message");
	assert(nReturn == sizeof(VistaType::sint32));
Anne's avatar
Anne committed
314
315
316
317
318
319
	return nValue;
}

bool CITANetAudioMessage::ReadBool()
{
	bool bValue;
320
321
	int nReturn = m_oIncoming.ReadBool(bValue);
	assert(nReturn == sizeof(bool));
Anne's avatar
Anne committed
322
323
324
325
326
	return bValue;
}
float CITANetAudioMessage::ReadFloat()
{
	float fValue;
327
328
	int nReturn = m_oIncoming.ReadFloat32(fValue);
	assert(nReturn == sizeof(float));
Anne's avatar
Anne committed
329
330
331
332
333
	return fValue;
}
double CITANetAudioMessage::ReadDouble()
{
	double dValue;
334
335
	int nReturn = m_oIncoming.ReadFloat64(dValue);
	assert(nReturn == sizeof(double));
Anne's avatar
Anne committed
336
337
338
339
	return dValue;
}


340
void CITANetAudioMessage::WriteException(const ITAException& oException)
Anne's avatar
Anne committed
341
{
342
343
344
	WriteInt(oException.iErrorCode);
	WriteString(oException.sModule);
	WriteString(oException.sReason);
Anne's avatar
Anne committed
345
346
347
348
349
350
351
}

ITAException CITANetAudioMessage::ReadException()
{
	int iErrorCode = ReadInt();
	std::string sModule = ReadString();
	std::string sReason = ReadString();
352
	return ITAException(iErrorCode, sModule, sReason);
Anne's avatar
Anne committed
353
354
355
356
357
358
359
360
361
362
363
}

VistaConnectionIP* CITANetAudioMessage::GetConnection() const
{
	return m_pConnection;
}

void CITANetAudioMessage::ClearConnection() {
	m_pConnection = NULL;
}

364
void CITANetAudioMessage::WriteIntVector(const std::vector<int> viData)
Anne's avatar
Anne committed
365
{
366
367
368
369
	int iSize = (int)viData.size();
	WriteInt(iSize);
	for (int i = 0; i < iSize; i++)
		WriteInt(viData[i]);
Anne's avatar
Anne committed
370
371
372
373
374
375
}

std::vector<int> CITANetAudioMessage::ReadIntVector()
{
	std::vector<int> viData;
	int iSize = ReadInt();
376
377
	for (int i = 0; i < iSize; i++)
		viData.push_back(ReadInt());
Anne's avatar
Anne committed
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

	return viData;
}

CITANetAudioProtocol::StreamingParameters CITANetAudioMessage::ReadStreamingParameters()
{
	CITANetAudioProtocol::StreamingParameters oParams;

	oParams.iChannels = ReadInt();
	oParams.dSampleRate = ReadDouble();
	oParams.iBlockSize = ReadInt();

	return oParams;
}

393
void CITANetAudioMessage::WriteStreamingParameters(const CITANetAudioProtocol::StreamingParameters & oParams)
Anne's avatar
Anne committed
394
{
395
396
397
	WriteInt(oParams.iChannels);
	WriteDouble(oParams.dSampleRate);
	WriteInt(oParams.iBlockSize);
Anne's avatar
Anne committed
398
}
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440

int CITANetAudioMessage::ReadRingBufferSize()
{
	return ReadInt();
}

void CITANetAudioMessage::WriteRingBufferSize(const int iBufferSize)
{
	WriteInt(iBufferSize);
}

int CITANetAudioMessage::ReadRingBufferFree()
{
	return ReadInt();
}

void CITANetAudioMessage::WriteRingBufferFree(const int iBufferFree)
{
	WriteInt(iBufferFree);
}

void CITANetAudioMessage::ReadSampleFrame(ITASampleFrame* pSampleFrame)
{
	int iChannels = ReadInt();
	int iSamples = ReadInt();

	if (pSampleFrame->channels() != iChannels || pSampleFrame->GetLength() != iSamples)
		pSampleFrame->init(iChannels, iSamples, false);

	for (int i = 0; i < iChannels; i++)
	{
		for (int j = 0; j < iSamples; j++)
		{
			(*pSampleFrame)[i][j] = ReadFloat();
		}
	}
}

void CITANetAudioMessage::WriteSampleFrame(ITASampleFrame* pSamples)
{
	WriteInt(pSamples->channels());
	WriteInt(pSamples->GetLength());

	for (int i = 0; i < pSamples->channels(); i++)
	{
		for (int j = 0; j < pSamples->GetLength(); j++)
		{
			WriteFloat((*pSamples)[i][j]);
		}
	}
}