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