1 #include "RakVoice.h"
2 #include "speex/speex.h"
3 #include "speex/speex_preprocess.h"
4 #include "BitStream.h"
5 #include "PacketPriority.h"
6 #include "MessageIdentifiers.h"
7 #include "BitStream.h"
8 #include "RakPeerInterface.h"
9 #include <stdlib.h>
10 #include "GetTime.h"
11 
12 #ifdef _DEBUG
13 #include <stdio.h>
14 #endif
15 
16 //#define PRINT_DEBUG_INFO
17 
18 #define SAMPLESIZE 2
19 
20 #ifdef PRINT_DEBUG_INFO
21 #include <stdio.h>
22 #endif
23 
VoiceChannelComp(const RakNetGUID & key,VoiceChannel * const & data)24 int VoiceChannelComp( const RakNetGUID &key, VoiceChannel * const &data )
25 {
26 	if (key < data->guid)
27 		return -1;
28 	if (key == data->guid)
29 		return 0;
30 	return 1;
31 }
32 
RakVoice()33 RakVoice::RakVoice()
34 {
35 	bufferedOutput=0;
36 	defaultEncoderComplexity=2;
37 	defaultVADState=true;
38 	defaultDENOISEState=false;
39 	defaultVBRState=false;
40 	loopbackMode=false;
41 }
~RakVoice()42 RakVoice::~RakVoice()
43 {
44 	Deinit();
45 }
Init(unsigned short sampleRate,unsigned bufferSizeBytes)46 void RakVoice::Init(unsigned short sampleRate, unsigned bufferSizeBytes)
47 {
48 	// Record the parameters
49 	RakAssert(sampleRate==8000 || sampleRate==16000 || sampleRate==32000);
50 	this->sampleRate=sampleRate;
51 	this->bufferSizeBytes=bufferSizeBytes;
52 	bufferedOutputCount=bufferSizeBytes/SAMPLESIZE;
53 	bufferedOutput = (float*) rakMalloc_Ex(sizeof(float)*bufferedOutputCount, __FILE__, __LINE__);
54 	unsigned i;
55 	for (i=0; i < bufferedOutputCount; i++)
56 		bufferedOutput[i]=0.0f;
57 	zeroBufferedOutput=false;
58 
59 }
Deinit(void)60 void RakVoice::Deinit(void)
61 {
62 	// check pointer before free
63 	if (bufferedOutput)
64 	{
65 		rakFree_Ex(bufferedOutput, __FILE__, __LINE__ );
66 		bufferedOutput = 0;
67 		CloseAllChannels();
68 	}
69 }
SetLoopbackMode(bool enabled)70 void RakVoice::SetLoopbackMode(bool enabled)
71 {
72 	if (enabled)
73 	{
74 		Packet p;
75 		RakNet::BitStream out;
76 		out.Write((unsigned char)ID_RAKVOICE_OPEN_CHANNEL_REQUEST);
77 		out.Write((int32_t)sampleRate);
78 		p.data=out.GetData();
79 		p.systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
80 		p.guid=UNASSIGNED_RAKNET_GUID;
81 		p.length=out.GetNumberOfBytesUsed();
82 		OpenChannel(&p);
83 	}
84 	else
85 	{
86 		FreeChannelMemory(UNASSIGNED_RAKNET_GUID);
87 	}
88 	loopbackMode=enabled;
89 }
IsLoopbackMode(void) const90 bool RakVoice::IsLoopbackMode(void) const
91 {
92 	return loopbackMode;
93 }
RequestVoiceChannel(RakNetGUID recipient)94 void RakVoice::RequestVoiceChannel(RakNetGUID recipient)
95 {
96 	// Send a reliable ordered message to the other system to open a voice channel
97 	RakNet::BitStream out;
98 	out.Write((unsigned char)ID_RAKVOICE_OPEN_CHANNEL_REQUEST);
99 	out.Write((int32_t)sampleRate);
100 	SendUnified(&out, HIGH_PRIORITY, RELIABLE_ORDERED,0,recipient,false);
101 }
CloseVoiceChannel(RakNetGUID recipient)102 void RakVoice::CloseVoiceChannel(RakNetGUID recipient)
103 {
104 	FreeChannelMemory(recipient);
105 
106 	// Send a message to the remote system telling them to close the channel
107 	RakNet::BitStream out;
108 	out.Write((unsigned char)ID_RAKVOICE_CLOSE_CHANNEL);
109 	SendUnified(&out, HIGH_PRIORITY, RELIABLE_ORDERED,0,recipient,false);
110 }
CloseAllChannels(void)111 void RakVoice::CloseAllChannels(void)
112 {
113 	RakNet::BitStream out;
114 	out.Write((unsigned char)ID_RAKVOICE_CLOSE_CHANNEL);
115 
116 	// Free the memory for all channels
117 	unsigned index;
118 	for (index=0; index < voiceChannels.Size(); index++)
119 	{
120 		SendUnified(&out, HIGH_PRIORITY, RELIABLE_ORDERED,0,voiceChannels[index]->guid,false);
121 		FreeChannelMemory(index,false);
122 	}
123 
124 	voiceChannels.Clear(false, __FILE__, __LINE__);
125 }
SendFrame(RakNetGUID recipient,void * inputBuffer)126 bool RakVoice::SendFrame(RakNetGUID recipient, void *inputBuffer)
127 {
128 	bool objectExists;
129 	unsigned index;
130 	VoiceChannel *channel;
131 
132 	index = voiceChannels.GetIndexFromKey(recipient, &objectExists);
133 	if (objectExists)
134 	{
135 		unsigned totalBufferSize;
136 		unsigned remainingBufferSize;
137 
138 		channel=voiceChannels[index];
139 
140 		totalBufferSize=bufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT;
141 		if (channel->outgoingWriteIndex >= channel->outgoingReadIndex)
142 			remainingBufferSize=totalBufferSize-(channel->outgoingWriteIndex-channel->outgoingReadIndex);
143 		else
144 			remainingBufferSize=channel->outgoingReadIndex-channel->outgoingWriteIndex;
145 
146 #ifdef _DEBUG
147 		RakAssert(remainingBufferSize>0 && remainingBufferSize <= totalBufferSize);
148 	//	printf("SendFrame: buff=%i writeIndex=%i readIndex=%i\n",remainingBufferSize, channel->outgoingWriteIndex, channel->outgoingReadIndex);
149 
150 		//printf("Writing %i bytes to write offset %i. %i %i.\n", bufferSizeBytes, channel->outgoingWriteIndex, *((char*)inputBuffer+channel->outgoingWriteIndex), *((char*)inputBuffer+channel->outgoingWriteIndex+bufferSizeBytes-1));
151 #endif
152 
153 		// Copy encoded sound to the outgoing buffer for that channel.  This has to be fast, since this function is likely to be called from a locked buffer
154 		// I allocated the buffer to be a size multiple of bufferSizeBytes so don't have to watch for overflow on this line
155 		memcpy(channel->outgoingBuffer + channel->outgoingWriteIndex, inputBuffer, bufferSizeBytes );
156 
157 #ifdef _DEBUG
158 		RakAssert(channel->outgoingWriteIndex+bufferSizeBytes <= totalBufferSize);
159 #endif
160 
161 
162 		// Increment the write index, wrapping if needed.
163 		channel->outgoingWriteIndex+=bufferSizeBytes;
164 #ifdef _DEBUG
165 		// Verify that the write is aligned to the size of outgoingBuffer
166 		RakAssert(channel->outgoingWriteIndex <= totalBufferSize);
167 #endif
168 		if (channel->outgoingWriteIndex==totalBufferSize)
169 			channel->outgoingWriteIndex=0;
170 
171 		if (bufferSizeBytes >= remainingBufferSize) // Would go past the current read position
172 		{
173 #ifdef _DEBUG
174 			// This is actually a warning - it means that FRAME_OUTGOING_BUFFER_COUNT wasn't big enough and old data is being overwritten
175 			RakAssert(0);
176 #endif
177 			// Force the read index up one block
178 			channel->outgoingReadIndex=(channel->outgoingReadIndex+channel->speexOutgoingFrameSampleCount * SAMPLESIZE)%totalBufferSize;
179 		}
180 
181     	return true;
182 	}
183 
184 	return false;
185 }
IsSendingVoiceDataTo(RakNetGUID recipient)186 bool RakVoice::IsSendingVoiceDataTo(RakNetGUID recipient)
187 {
188 	bool objectExists;
189 	unsigned index;
190 	index = voiceChannels.GetIndexFromKey(recipient, &objectExists);
191 
192 	// Free the memory for this channel
193 	if (objectExists)
194 		return voiceChannels[index]->isSendingVoiceData;
195 	return false;
196 }
ReceiveFrame(void * outputBuffer)197 void RakVoice::ReceiveFrame(void *outputBuffer)
198 {
199 	short *out = (short*)outputBuffer;
200 	unsigned i;
201 	// Convert the floats to final 16-bits output
202 	for (i=0; i < bufferSizeBytes / SAMPLESIZE; i++)
203 	{
204 		if (bufferedOutput[i]>32767.0f)
205 			out[i]=32767;
206 		else if (bufferedOutput[i]<-32768.0f)
207 			out[i]=-32768;
208 		else
209 			out[i]=(short)bufferedOutput[i];
210 	}
211 
212 	// Done with this block.  Zero all the values in Update
213 	zeroBufferedOutput=true;
214 }
215 
216 
GetSampleRate(void) const217 int RakVoice::GetSampleRate(void) const
218 {
219 	return sampleRate;
220 }
221 
GetBufferSizeBytes(void) const222 int RakVoice::GetBufferSizeBytes(void) const
223 {
224 	return bufferSizeBytes;
225 }
226 
IsInitialized(void) const227 bool RakVoice::IsInitialized(void) const
228 {
229 	// Use bufferedOutput to tell if the object was not initialized
230 	return (bufferedOutput!=0);
231 }
232 
GetRakPeerInterface(void) const233 RakPeerInterface* RakVoice::GetRakPeerInterface(void) const
234 {
235 	return rakPeerInterface;
236 }
GetBufferedBytesToSend(RakNetGUID guid) const237 unsigned RakVoice::GetBufferedBytesToSend(RakNetGUID guid) const
238 {
239 	bool objectExists;
240 	VoiceChannel *channel;
241 	unsigned totalBufferSize=bufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT;
242 	if (guid!=UNASSIGNED_RAKNET_GUID)
243 	{
244 		unsigned index = voiceChannels.GetIndexFromKey(guid, &objectExists);
245 		channel = voiceChannels[index];
246 		if (objectExists)
247 		{
248 			if (channel->outgoingWriteIndex>=channel->outgoingReadIndex)
249 				return channel->outgoingWriteIndex-channel->outgoingReadIndex;
250 			else
251 				return channel->outgoingWriteIndex + (totalBufferSize-channel->outgoingReadIndex);
252 		}
253 	}
254 	else
255 	{
256 		unsigned total=0;
257 		for (unsigned i=0; i < voiceChannels.Size(); i++)
258 		{
259 			channel=voiceChannels[i];
260 			if (channel->outgoingWriteIndex>=channel->outgoingReadIndex)
261 				total+=channel->outgoingWriteIndex-channel->outgoingReadIndex;
262 			else
263 				total+=channel->outgoingWriteIndex + (totalBufferSize-channel->outgoingReadIndex);
264 		}
265 		return total;
266 	}
267 
268 	return 0;
269 }
GetBufferedBytesToReturn(RakNetGUID guid) const270 unsigned RakVoice::GetBufferedBytesToReturn(RakNetGUID guid) const
271 {
272 	bool objectExists;
273 	VoiceChannel *channel;
274 	unsigned totalBufferSize=bufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT;
275 	if (guid!=UNASSIGNED_RAKNET_GUID)
276 	{
277 		unsigned index = voiceChannels.GetIndexFromKey(guid, &objectExists);
278 		channel = voiceChannels[index];
279 		if (objectExists)
280 		{
281 			if (channel->incomingReadIndex <= channel->incomingWriteIndex)
282 				return channel->incomingWriteIndex-channel->incomingReadIndex;
283 			else
284 				return totalBufferSize-channel->incomingReadIndex+channel->incomingWriteIndex;
285 		}
286 	}
287 	else
288 	{
289 		unsigned total=0;
290 		for (unsigned i=0; i < voiceChannels.Size(); i++)
291 		{
292 			channel=voiceChannels[i];
293 			if (channel->incomingReadIndex <= channel->incomingWriteIndex)
294 				total+=channel->incomingWriteIndex-channel->incomingReadIndex;
295 			else
296 				total+=totalBufferSize-channel->incomingReadIndex+channel->incomingWriteIndex;
297 		}
298 		return total;
299 	}
300 	return 0;
301 }
OnShutdown(void)302 void RakVoice::OnShutdown(void)
303 {
304 	CloseAllChannels();
305 }
306 
Update(void)307 void RakVoice::Update(void)
308 {
309 	unsigned i,j, bytesAvailable, speexFramesAvailable, speexBlockSize;
310 	unsigned bytesWaitingToReturn;
311 	int bytesWritten;
312 	VoiceChannel *channel;
313 	char *inputBuffer;
314 	char tempOutput[2048];
315 	// 1 byte for ID, and 2 bytes(short) for Message number
316 	static const int headerSize=sizeof(unsigned char) + sizeof(unsigned short);
317 	// First byte is ID for RakNet
318 	tempOutput[0]=ID_RAKVOICE_DATA;
319 
320 	RakNetTime currentTime = RakNet::GetTime();
321 
322 	// Size of VoiceChannel::incomingBuffer and VoiceChannel::outgoingBuffer arrays
323 	unsigned totalBufferSize=bufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT;
324 
325 	// Allow all channels to write, and set the output to zero in preparation
326 	if (zeroBufferedOutput)
327 	{
328 		for (i=0; i < bufferedOutputCount; i++)
329 			bufferedOutput[i]=0.0f;
330 		for (i=0; i < voiceChannels.Size(); i++)
331 			voiceChannels[i]->copiedOutgoingBufferToBufferedOutput=false;
332 		zeroBufferedOutput=false;
333 	}
334 
335 	// For each channel
336 	for (i=0; i < voiceChannels.Size(); i++)
337 	{
338 		channel=voiceChannels[i];
339 
340 		if (currentTime - channel->lastSend > 50) // Throttle to 20 sends a second
341 		{
342 			channel->isSendingVoiceData=false;
343 
344 			// Circular buffer so I have to do this to count how many bytes are available
345 			if (channel->outgoingWriteIndex>=channel->outgoingReadIndex)
346 				bytesAvailable=channel->outgoingWriteIndex-channel->outgoingReadIndex;
347 			else
348 				bytesAvailable=channel->outgoingWriteIndex + (totalBufferSize-channel->outgoingReadIndex);
349 
350 			// Speex returns how many frames it encodes per block.  Each frame is of byte length sampleSize.
351 			speexBlockSize = channel->speexOutgoingFrameSampleCount * SAMPLESIZE;
352 
353 #ifdef PRINT_DEBUG_INFO
354 			static int lastPrint=0;
355 			if (i==0 && currentTime-lastPrint > 2000)
356 			{
357 				lastPrint=currentTime;
358 				unsigned bytesWaitingToReturn;
359 				if (channel->incomingReadIndex <= channel->incomingWriteIndex)
360 					bytesWaitingToReturn=channel->incomingWriteIndex-channel->incomingReadIndex;
361 				else
362 					bytesWaitingToReturn=totalBufferSize-channel->incomingReadIndex+channel->incomingWriteIndex;
363 
364 				printf("%i bytes to send. incomingMessageNumber=%i. bytesWaitingToReturn=%i.\n", bytesAvailable, channel->incomingMessageNumber, bytesWaitingToReturn );
365 			}
366 #endif
367 
368 #ifdef _TEST_LOOPBACK
369 			/*
370 			if (bufferSizeBytes<bytesAvailable)
371 			{
372 				printf("Update: bytesAvailable=%i writeIndex=%i readIndex=%i\n",bytesAvailable, channel->outgoingWriteIndex, channel->outgoingReadIndex);
373 				memcpy(channel->incomingBuffer + channel->incomingWriteIndex, channel->outgoingBuffer+channel->outgoingReadIndex, bufferSizeBytes);
374 				channel->incomingWriteIndex=(channel->incomingWriteIndex+bufferSizeBytes) % totalBufferSize;
375 				channel->outgoingReadIndex=(channel->outgoingReadIndex+bufferSizeBytes) % totalBufferSize;
376 			}
377 			return;
378 			*/
379 #endif
380 
381 			// Find out how many frames we can read out of the buffer for speex to encode and send these out.
382 			speexFramesAvailable = bytesAvailable / speexBlockSize;
383 
384 			// Encode all available frames and send them unreliable sequenced
385 			if (speexFramesAvailable > 0)
386 			{
387 				SpeexBits speexBits;
388 				speex_bits_init(&speexBits);
389 				while (speexFramesAvailable-- > 0)
390 				{
391 					speex_bits_reset(&speexBits);
392 
393 					// If the input data would wrap around the buffer, copy it to another buffer first
394 					if (channel->outgoingReadIndex + speexBlockSize >= totalBufferSize)
395 					{
396 #ifdef _DEBUG
397 						RakAssert(speexBlockSize < 2048-1);
398 #endif
399 						unsigned t;
400 						for (t=0; t < speexBlockSize; t++)
401 							tempOutput[t+headerSize]=channel->outgoingBuffer[t%totalBufferSize];
402 						inputBuffer=tempOutput+headerSize;
403 					}
404 					else
405 						inputBuffer=channel->outgoingBuffer+channel->outgoingReadIndex;
406 
407 #ifdef _DEBUG
408 					/*
409 					printf("In: ");
410 					if (shortSampleType)
411 					{
412 						short *blah = (short*) inputBuffer;
413 						for (int p=0; p < 5; p++)
414 						{
415 							printf("%.i ", blah[p]);
416 						}
417 					}
418 					else
419 					{
420 						float *blah = (float*) inputBuffer;
421 						for (int p=0; p < 5; p++)
422 						{
423 							printf("%.3f ", blah[p]);
424 						}
425 					}
426 
427 					printf("\n");
428 */
429 #endif
430 					int is_speech=1;
431 
432 					// Run preprocessor if required
433 					if (defaultDENOISEState||defaultVADState){
434 						is_speech=speex_preprocess((SpeexPreprocessState*)channel->pre_state,(spx_int16_t*) inputBuffer, NULL );
435 					}
436 
437 					if ((is_speech)||(!defaultVADState)){
438 						is_speech = speex_encode_int(channel->enc_state, (spx_int16_t*) inputBuffer, &speexBits);
439 					}
440 
441 					channel->outgoingReadIndex=(channel->outgoingReadIndex+speexBlockSize)%totalBufferSize;
442 
443 					// If no speech detected, don't send this frame
444 					if ((!is_speech)&&(defaultVADState)){
445 						continue;
446 					}
447 
448 					channel->isSendingVoiceData=true;
449 
450 #ifdef _DEBUG
451 //					printf("Update: bytesAvailable=%i writeIndex=%i readIndex=%i\n",bytesAvailable, channel->outgoingWriteIndex, channel->outgoingReadIndex);
452 #endif
453 
454 					bytesWritten = speex_bits_write(&speexBits, tempOutput+headerSize, 2048-headerSize);
455 #ifdef _DEBUG
456 					// If this assert hits then you need to increase the size of the temp buffer, but this is really a bug because
457 					// voice packets should never be bigger than a few hundred bytes.
458 					RakAssert(bytesWritten!=2048-headerSize);
459 #endif
460 
461 //					static int bytesSent=0;
462 //					bytesSent+= bytesWritten+headerSize;
463 //					printf("bytesSent=%i\n", bytesSent);
464 
465 #ifdef PRINT_DEBUG_INFO
466 static int voicePacketsSent=0;
467 printf("%i ", voicePacketsSent++);
468 #endif
469 
470 					// at +1, because the first byte in the buffer has the ID for RakNet.
471 					memcpy(tempOutput+1, &channel->outgoingMessageNumber, sizeof(unsigned short));
472 					channel->outgoingMessageNumber++;
473 					RakNet::BitStream tempOutputBs((unsigned char*) tempOutput,bytesWritten+headerSize,false);
474 					SendUnified(&tempOutputBs, HIGH_PRIORITY, UNRELIABLE,0,channel->guid,false);
475 
476 					if (loopbackMode)
477 					{
478 						Packet p;
479 						p.length=bytesWritten+1;
480 						p.data=(unsigned char*)tempOutput;
481 						p.guid=channel->guid;
482 						p.systemAddress=rakPeerInterface->GetSystemAddressFromGuid(p.guid);
483 						OnVoiceData(&p);
484 					}
485 				}
486 
487 				speex_bits_destroy(&speexBits);
488 				channel->lastSend=currentTime;
489 			}
490 		}
491 
492 		// As sound buffer blocks fill up, I add their values to RakVoice::bufferedOutput .  Then when the user calls ReceiveFrame they get that value, already
493 		// processed.  This is necessary because that function needs to run as fast as possible so I remove all processing there that I can.  Otherwise the sound
494 		// plays back distorted and popping
495 		if (channel->copiedOutgoingBufferToBufferedOutput==false)
496 		{
497 			if (channel->incomingReadIndex <= channel->incomingWriteIndex)
498 				bytesWaitingToReturn=channel->incomingWriteIndex-channel->incomingReadIndex;
499 			else
500 				bytesWaitingToReturn=totalBufferSize-channel->incomingReadIndex+channel->incomingWriteIndex;
501 
502 			if (bytesWaitingToReturn==0)
503 			{
504 				channel->bufferOutput=true;
505 			}
506 			else if (channel->bufferOutput==false || bytesWaitingToReturn > bufferSizeBytes*2)
507 			{
508 				// Block running this again until the user calls ReceiveFrame since every call to ReceiveFrame only gets zero or one output blocks from
509 				// each channel
510 				channel->copiedOutgoingBufferToBufferedOutput=true;
511 
512 				// Stop buffering output.  We won't start buffering again until there isn't enough data to read.
513 				channel->bufferOutput=false;
514 
515 				// Cap to the size of the output buffer.  But we do write less if less is available, with the rest silence
516 				if (bytesWaitingToReturn > bufferSizeBytes)
517 				{
518 					bytesWaitingToReturn=bufferSizeBytes;
519 				}
520 				else
521 				{
522 					// Align the write index so when we increment the partial block read (which is always aligned) it computes out to 0 bytes waiting
523 					channel->incomingWriteIndex=channel->incomingReadIndex+bufferSizeBytes;
524 					if (channel->incomingWriteIndex==totalBufferSize)
525 						channel->incomingWriteIndex=0;
526 				}
527 
528 				short *in = (short *) (channel->incomingBuffer+channel->incomingReadIndex);
529 				for (j=0; j < bytesWaitingToReturn / SAMPLESIZE; j++)
530 				{
531 					// Write short to float so if the range goes over the range of a float we can still add and subtract the correct final value.
532 					// It will be clamped at the end
533 					bufferedOutput[j]+=in[j%(totalBufferSize/SAMPLESIZE)];
534 				}
535 
536 				// Update the read index.  Always update by bufferSizeBytes, not bytesWaitingToReturn.
537 				// if bytesWaitingToReturn < bufferSizeBytes then the rest is silence since this means the buffer ran out or we stopped sending.
538 				channel->incomingReadIndex+=bufferSizeBytes;
539 				if (channel->incomingReadIndex==totalBufferSize)
540 					channel->incomingReadIndex=0;
541 
542 			//	printf("%f %f\n", channel->incomingReadIndex/(float)bufferSizeBytes, channel->incomingWriteIndex/(float)bufferSizeBytes);
543 			}
544 		}
545 	}
546 }
OnReceive(Packet * packet)547 PluginReceiveResult RakVoice::OnReceive(Packet *packet)
548 {
549 	RakAssert(packet);
550 
551 	switch (packet->data[0])
552 	{
553 	case ID_RAKVOICE_OPEN_CHANNEL_REQUEST:
554 		OnOpenChannelRequest(packet);
555 	break;
556 	case ID_RAKVOICE_OPEN_CHANNEL_REPLY:
557 		OnOpenChannelReply(packet);
558 		break;
559 	case ID_RAKVOICE_CLOSE_CHANNEL:
560 		FreeChannelMemory(packet->guid);
561 	break;
562 	case ID_RAKVOICE_DATA:
563 		OnVoiceData(packet);
564 		return RR_STOP_PROCESSING_AND_DEALLOCATE;
565 	}
566 
567 	return RR_CONTINUE_PROCESSING;
568 }
OnClosedConnection(SystemAddress systemAddress,RakNetGUID rakNetGUID,PI2_LostConnectionReason lostConnectionReason)569 void RakVoice::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
570 {
571 	(void)systemAddress;
572 
573 	if (lostConnectionReason==LCR_CLOSED_BY_USER)
574 		CloseVoiceChannel(rakNetGUID);
575 	else
576 		FreeChannelMemory(rakNetGUID);
577 }
578 
OnOpenChannelRequest(Packet * packet)579 void RakVoice::OnOpenChannelRequest(Packet *packet)
580 {
581 	if (voiceChannels.HasData(packet->guid))
582 		return;
583 
584 	// If the system is not initialized, just return
585 	if (bufferedOutput==0)
586 		return;
587 
588 	OpenChannel(packet);
589 
590 	RakNet::BitStream out;
591 	out.Write((unsigned char)ID_RAKVOICE_OPEN_CHANNEL_REPLY);
592 	out.Write((int32_t)sampleRate);
593 	SendUnified(&out, HIGH_PRIORITY, RELIABLE_ORDERED,0,packet->systemAddress,false);
594 }
OnOpenChannelReply(Packet * packet)595 void RakVoice::OnOpenChannelReply(Packet *packet)
596 {
597 	if (voiceChannels.HasData(packet->guid))
598 		return;
599 	OpenChannel(packet);
600 }
OpenChannel(Packet * packet)601 void RakVoice::OpenChannel(Packet *packet)
602 {
603 	RakNet::BitStream in(packet->data, packet->length, false);
604 	in.IgnoreBits(8);
605 
606 	FreeChannelMemory(packet->guid);
607 
608 	VoiceChannel *channel=RakNet::OP_NEW<VoiceChannel>( __FILE__, __LINE__ );
609 	channel->guid=packet->guid;
610 	channel->isSendingVoiceData=false;
611 	int sampleRate;
612 	in.Read(sampleRate);
613 	channel->remoteSampleRate=sampleRate;
614 
615 	if (channel->remoteSampleRate!=8000 && channel->remoteSampleRate!=16000 && channel->remoteSampleRate!=32000)
616 	{
617 #ifdef _DEBUG
618 		RakAssert(0);
619 #endif
620 		RakNet::OP_DELETE(channel, __FILE__, __LINE__);
621 		return;
622 	}
623 
624 	if (sampleRate==8000)
625 		channel->enc_state=speex_encoder_init(&speex_nb_mode);
626 	else if (sampleRate==16000)
627 		channel->enc_state=speex_encoder_init(&speex_wb_mode);
628 	else // 32000
629 		channel->enc_state=speex_encoder_init(&speex_uwb_mode);
630 
631 	if (channel->remoteSampleRate==8000)
632 		channel->dec_state=speex_decoder_init(&speex_nb_mode);
633 	else if (channel->remoteSampleRate==16000)
634 		channel->dec_state=speex_decoder_init(&speex_wb_mode);
635 	else // 32000
636 		channel->dec_state=speex_decoder_init(&speex_uwb_mode);
637 
638 	// make sure encoder and decoder are created
639 	RakAssert((channel->enc_state)&&(channel->dec_state));
640 
641 	int ret;
642 	ret=speex_encoder_ctl(channel->enc_state, SPEEX_GET_FRAME_SIZE, &channel->speexOutgoingFrameSampleCount);
643 	RakAssert(ret==0);
644 	channel->outgoingBuffer = (char*) rakMalloc_Ex(bufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT, __FILE__, __LINE__);
645 	channel->outgoingReadIndex=0;
646 	channel->outgoingWriteIndex=0;
647 	channel->bufferOutput=true;
648 	channel->outgoingMessageNumber=0;
649 	channel->copiedOutgoingBufferToBufferedOutput=false;
650 
651 	ret=speex_decoder_ctl(channel->dec_state, SPEEX_GET_FRAME_SIZE, &channel->speexIncomingFrameSampleCount);
652 	RakAssert(ret==0);
653 	channel->incomingBuffer = (char*) rakMalloc_Ex(bufferSizeBytes * FRAME_INCOMING_BUFFER_COUNT, __FILE__, __LINE__);
654 	channel->incomingReadIndex=0;
655 	channel->incomingWriteIndex=0;
656 	channel->lastSend=0;
657 	channel->incomingMessageNumber=0;
658 
659 	// Initialize preprocessor
660 	channel->pre_state = speex_preprocess_state_init(channel->speexOutgoingFrameSampleCount, sampleRate);
661 	RakAssert(channel->pre_state);
662 
663 	// Set encoder default parameters
664 	SetEncoderParameter(channel->enc_state, SPEEX_SET_VBR, (defaultVBRState) ? 1 : 0 );
665 	SetEncoderParameter(channel->enc_state, SPEEX_SET_COMPLEXITY, defaultEncoderComplexity);
666 	// Set preprocessor default parameters
667 	SetPreprocessorParameter(channel->pre_state, SPEEX_PREPROCESS_SET_DENOISE, (defaultDENOISEState) ? 1 : 2);
668 	SetPreprocessorParameter(channel->pre_state, SPEEX_PREPROCESS_SET_VAD, (defaultVADState) ? 1 : 2);
669 
670 	voiceChannels.Insert(packet->guid, channel, true, __FILE__, __LINE__);
671 }
672 
673 
SetEncoderParameter(void * enc_state,int vartype,int val)674 void RakVoice::SetEncoderParameter(void* enc_state, int vartype, int val)
675 {
676 	if (enc_state){
677 		// Set parameter for just one encoder
678 		int ret = speex_encoder_ctl(enc_state, vartype, &val);
679 		RakAssert(ret==0);
680 	} else {
681 		// Set parameter for all encoders
682 		for (unsigned int index=0; index < voiceChannels.Size(); index++)
683 		{
684 			int ret = speex_encoder_ctl(voiceChannels[index]->enc_state, vartype, &val);
685 			RakAssert(ret==0);
686 		}
687 	}
688 }
689 
SetPreprocessorParameter(void * pre_state,int vartype,int val)690 void RakVoice::SetPreprocessorParameter(void* pre_state, int vartype, int val)
691 {
692 	if (pre_state){
693 		// Set parameter for just one preprocessor
694 		int ret = speex_preprocess_ctl((SpeexPreprocessState*)pre_state, vartype, &val);
695 		RakAssert(ret==0);
696 	} else {
697 		// Set parameter for all decoders
698 		for (unsigned int index=0; index < voiceChannels.Size(); index++)
699 		{
700 			int ret = speex_preprocess_ctl((SpeexPreprocessState*)voiceChannels[index]->pre_state, vartype, &val);
701 			RakAssert(ret==0);
702 		}
703 	}
704 }
705 
SetEncoderComplexity(int complexity)706 void RakVoice::SetEncoderComplexity(int complexity)
707 {
708 	RakAssert((complexity>=0)&&(complexity<=10));
709 	SetEncoderParameter(NULL, SPEEX_SET_COMPLEXITY, complexity);
710 	defaultEncoderComplexity = complexity;
711 }
SetVAD(bool enable)712 void RakVoice::SetVAD(bool enable)
713 {
714 	SetPreprocessorParameter(NULL, SPEEX_PREPROCESS_SET_VAD, (enable)? 1 : 2);
715 	defaultVADState = enable;
716 }
SetNoiseFilter(bool enable)717 void RakVoice::SetNoiseFilter(bool enable)
718 {
719 	SetPreprocessorParameter(NULL, SPEEX_PREPROCESS_SET_DENOISE, (enable) ? 1 : 2);
720 	defaultDENOISEState = enable;
721 }
SetVBR(bool enable)722 void RakVoice::SetVBR(bool enable)
723 {
724 	SetEncoderParameter(NULL, SPEEX_SET_VBR, (enable) ? 1 : 0);
725 	defaultVBRState = enable;
726 }
727 
GetEncoderComplexity(void)728 int RakVoice::GetEncoderComplexity(void)
729 {
730 	return defaultEncoderComplexity;
731 }
IsVADActive(void)732 bool RakVoice::IsVADActive(void)
733 {
734 	return defaultVADState;
735 }
IsNoiseFilterActive()736 bool RakVoice::IsNoiseFilterActive()
737 {
738 	return defaultDENOISEState;
739 }
IsVBRActive()740 bool RakVoice::IsVBRActive()
741 {
742 	return defaultVBRState;
743 }
744 
745 
FreeChannelMemory(RakNetGUID recipient)746 void RakVoice::FreeChannelMemory(RakNetGUID recipient)
747 {
748 	bool objectExists;
749 	unsigned index;
750 	index = voiceChannels.GetIndexFromKey(recipient, &objectExists);
751 
752 	// Free the memory for this channel
753 	if (objectExists)
754 	{
755 		FreeChannelMemory(index, true);
756 	}
757 }
FreeChannelMemory(unsigned index,bool removeIndex)758 void RakVoice::FreeChannelMemory(unsigned index, bool removeIndex)
759 {
760 	VoiceChannel *channel;
761 	channel=voiceChannels[index];
762 	speex_encoder_destroy(channel->enc_state);
763 	speex_decoder_destroy(channel->dec_state);
764 	speex_preprocess_state_destroy((SpeexPreprocessState*)channel->pre_state);
765 	rakFree_Ex(channel->incomingBuffer, __FILE__, __LINE__ );
766 	rakFree_Ex(channel->outgoingBuffer, __FILE__, __LINE__ );
767 	RakNet::OP_DELETE(channel, __FILE__, __LINE__);
768 	if (removeIndex)
769 		voiceChannels.RemoveAtIndex(index);
770 }
OnVoiceData(Packet * packet)771 void RakVoice::OnVoiceData(Packet *packet)
772 {
773 	bool objectExists;
774 	unsigned index;
775 	unsigned short packetMessageNumber, messagesSkipped;
776 	VoiceChannel *channel;
777 	char tempOutput[2048];
778 	unsigned int i;
779 	// 1 byte for ID, 2 bytes(short) for message number
780 	static const int headerSize=sizeof(unsigned char) + sizeof(unsigned short);
781 
782 	index = voiceChannels.GetIndexFromKey(packet->guid, &objectExists);
783 	if (objectExists)
784 	{
785 		SpeexBits speexBits;
786 		speex_bits_init(&speexBits);
787 		channel=voiceChannels[index];
788 		memcpy(&packetMessageNumber, packet->data+1, sizeof(unsigned short));
789 
790 		// Intentional overflow
791 		messagesSkipped=packetMessageNumber-channel->incomingMessageNumber;
792 		if (messagesSkipped > ((unsigned short)-1)/2)
793 		{
794 #ifdef PRINT_DEBUG_INFO
795 			printf("--- UNDERFLOW ---\n");
796 #endif
797 			// Underflow, just ignore it
798 			return;
799 		}
800 #ifdef PRINT_DEBUG_INFO
801 		if (messagesSkipped>0)
802 			printf("%i messages skipped\n", messagesSkipped);
803 #endif
804 		// Don't do more than 100 ms of messages skipped.  Discard the rest.
805 		int maxSkip = (int)(100.0f / (float) sampleRate);
806 		for (i=0; i < (unsigned) messagesSkipped && i < (unsigned) maxSkip; i++)
807 		{
808 			speex_decode_int(channel->dec_state, 0, (spx_int16_t*)tempOutput);
809 
810 			// Write to buffer a 'message skipped' interpolation
811 			WriteOutputToChannel(channel, tempOutput);
812 		}
813 
814 		channel->incomingMessageNumber=packetMessageNumber+1;
815 
816 		// Write to incomingBuffer the decoded data
817 		speex_bits_read_from(&speexBits, (char*)(packet->data+headerSize), packet->length-headerSize);
818 		speex_decode_int(channel->dec_state, &speexBits, (spx_int16_t*)tempOutput);
819 
820 #ifdef _DEBUG
821 		{
822 			/*
823 			printf("Out: ");
824 			if (channel->remoteIsShortSampleType)
825 			{
826 				short *blah = (short*) tempOutput;
827 				for (int p=0; p < 5; p++)
828 				{
829 					printf("%.i ", blah[p]);
830 				}
831 			}
832 			else
833 			{
834 				float *blah = (float*) tempOutput;
835 				for (int p=0; p < 5; p++)
836 				{
837 					printf("%.3f ", blah[p]);
838 				}
839 			}
840 
841 			printf("\n");
842 			*/
843 		}
844 #endif
845 
846 		// Write to buffer
847 		WriteOutputToChannel(channel, tempOutput);
848 
849 		speex_bits_destroy(&speexBits);
850 	}
851 }
WriteOutputToChannel(VoiceChannel * channel,char * dataToWrite)852 void RakVoice::WriteOutputToChannel(VoiceChannel *channel, char *dataToWrite)
853 {
854 	unsigned totalBufferSize;
855 	unsigned remainingBufferSize;
856 	unsigned speexBlockSize;
857 
858 	totalBufferSize=bufferSizeBytes * FRAME_INCOMING_BUFFER_COUNT;
859 	if (channel->incomingWriteIndex >= channel->incomingReadIndex)
860 		remainingBufferSize=totalBufferSize-(channel->incomingWriteIndex-channel->incomingReadIndex);
861 	else
862 		remainingBufferSize=channel->incomingReadIndex-channel->incomingWriteIndex;
863 
864 	// Speex returns how many frames it encodes per block.  Each frame is of byte length sampleSize.
865 	speexBlockSize = channel->speexIncomingFrameSampleCount * SAMPLESIZE;
866 
867 	if (channel->incomingWriteIndex+speexBlockSize <= totalBufferSize)
868 	{
869 		memcpy(channel->incomingBuffer + channel->incomingWriteIndex, dataToWrite, speexBlockSize);
870 	}
871 	else
872 	{
873 		memcpy(channel->incomingBuffer + channel->incomingWriteIndex, dataToWrite, totalBufferSize-channel->incomingWriteIndex);
874 		memcpy(channel->incomingBuffer, dataToWrite, speexBlockSize-(totalBufferSize-channel->incomingWriteIndex));
875 	}
876     channel->incomingWriteIndex=(channel->incomingWriteIndex+speexBlockSize) % totalBufferSize;
877 
878 
879 #ifdef _DEBUG
880 	//printf("WriteOutputToChannel: buff=%i writeIndex=%i readIndex=%i\n",remainingBufferSize, channel->incomingWriteIndex, channel->incomingReadIndex);
881 #endif
882 
883 	if (bufferSizeBytes >= remainingBufferSize) // Would go past the current read position
884 	{
885 #ifdef _DEBUG
886 		// This is actually a warning - it means that FRAME_INCOMING_BUFFER_COUNT wasn't big enough and old data is being overwritten
887 		RakAssert(0);
888 #endif
889 		// Force the read index up one block
890 		channel->incomingReadIndex+=bufferSizeBytes;
891 		if (channel->incomingReadIndex==totalBufferSize)
892 			channel->incomingReadIndex=0;
893 	}
894 }
895