FMODVoiceAdapter.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <memory.h>
  13. #include "RakPeerInterface.h"
  14. #include "MessageIdentifiers.h"
  15. #include "FMODVoiceAdapter.h"
  16. #include "fmod_errors.h"
  17. /// To test sending to myself
  18. //#define _TEST_LOOPBACK
  19. // Number of RakVoice frames in the fmod sound
  20. #define FRAMES_IN_SOUND 4
  21. using namespace RakNet;
  22. FMODVoiceAdapter FMODVoiceAdapter::instance;
  23. FMODVoiceAdapter::FMODVoiceAdapter(){
  24. rakVoice=0;
  25. fmodSystem = 0;
  26. recSound=0;
  27. sound=0;
  28. channel=0;
  29. mute=false;
  30. }
  31. FMODVoiceAdapter* FMODVoiceAdapter::Instance(){
  32. return &instance;
  33. }
  34. bool FMODVoiceAdapter::SetupAdapter(FMOD::System *fmodSystem, RakVoice *rakVoice)
  35. {
  36. FMOD_RESULT fmodErr;
  37. RakAssert(fmodSystem);
  38. RakAssert(rakVoice);
  39. // Make sure rakVoice was initialized
  40. RakAssert((rakVoice->IsInitialized())&&(rakVoice->GetRakPeerInterface()!=NULL));
  41. this->fmodSystem = fmodSystem;
  42. this->rakVoice = rakVoice;
  43. lastPlayPos = 0;
  44. lastRecordingPos = 0;
  45. //
  46. // Create the FMOD sound used to record
  47. //
  48. FMOD_CREATESOUNDEXINFO exinfo;
  49. memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
  50. exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
  51. exinfo.numchannels = 1;
  52. exinfo.format = FMOD_SOUND_FORMAT_PCM16;
  53. exinfo.defaultfrequency = rakVoice->GetSampleRate();
  54. exinfo.length = rakVoice->GetBufferSizeBytes()*FRAMES_IN_SOUND;
  55. fmodErr = fmodSystem->createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &recSound);
  56. if (fmodErr!=FMOD_OK)
  57. return false;
  58. // Create the FMOD sound used to play incoming sound data
  59. fmodErr = fmodSystem->createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &sound);
  60. if (fmodErr!=FMOD_OK)
  61. return false;
  62. // Start playing the sound used for output
  63. sound->setMode(FMOD_LOOP_NORMAL);
  64. fmodErr= fmodSystem->playSound(FMOD_CHANNEL_REUSE, sound, false, &channel);
  65. if (fmodErr!=FMOD_OK)
  66. return false;
  67. // Start recording
  68. fmodErr=fmodSystem->recordStart(0,recSound, true);
  69. if (fmodErr!=FMOD_OK)
  70. return false;
  71. return true;
  72. }
  73. void FMODVoiceAdapter::Update(void)
  74. {
  75. RakAssert(fmodSystem);
  76. UpdateSound(true);
  77. UpdateSound(false);
  78. }
  79. void FMODVoiceAdapter::Release(void)
  80. {
  81. FMOD_RESULT err;
  82. if (fmodSystem==NULL) return;
  83. // Stop recording
  84. bool recording=false;
  85. err = fmodSystem->isRecording(0,&recording);
  86. RakAssert(err==FMOD_OK);
  87. if (recording){
  88. fmodSystem->recordStop(0);
  89. }
  90. // Stop what we hear
  91. bool playing;
  92. err = channel->isPlaying(&playing);
  93. RakAssert(err==FMOD_OK);
  94. if (playing){
  95. channel->stop();
  96. }
  97. if (recSound!=NULL)
  98. {
  99. recSound->release();
  100. recSound = NULL;
  101. }
  102. if (sound!=NULL)
  103. {
  104. sound->release();
  105. sound = NULL;
  106. }
  107. }
  108. void FMODVoiceAdapter::SetMute(bool mute)
  109. {
  110. this->mute = mute;
  111. }
  112. void FMODVoiceAdapter::UpdateSound(bool isRec)
  113. {
  114. FMOD_RESULT fmodErr;
  115. unsigned int soundLength;
  116. const int sampleSize = 2;
  117. FMOD::Sound *snd = (isRec) ? recSound : sound;
  118. unsigned int& lastPos = (isRec) ? lastRecordingPos : lastPlayPos;
  119. // get current Play or recording position
  120. unsigned int currPos;
  121. if (isRec){
  122. fmodErr=fmodSystem->getRecordPosition(0,&currPos);
  123. RakAssert(fmodErr==FMOD_OK);
  124. } else {
  125. fmodErr=channel->getPosition(&currPos, FMOD_TIMEUNIT_PCM);
  126. RakAssert(fmodErr==FMOD_OK);
  127. }
  128. // Get length of sound in samples
  129. fmodErr=snd->getLength(&soundLength, FMOD_TIMEUNIT_PCM);
  130. RakAssert(fmodErr==FMOD_OK);
  131. // calculate some variables we'll need ahead
  132. int bufferSizeBytes = rakVoice->GetBufferSizeBytes();
  133. // Round down the current position to a multiple of buffer size in samples
  134. currPos -= currPos % (bufferSizeBytes/sampleSize);
  135. if ( ((!isRec)||(isRec && !mute)) && (currPos != lastPos) )
  136. {
  137. void *ptr1, *ptr2;
  138. unsigned int len1, len2;
  139. int blockLength;
  140. blockLength = (int)currPos - (int)lastPos;
  141. // Check for wrap around, and adjust
  142. if (blockLength < 0)
  143. {
  144. blockLength += soundLength;
  145. }
  146. // Lock to get access to the raw data
  147. snd->lock(lastPos * sampleSize, blockLength * sampleSize, &ptr1, &ptr2, &len1, &len2);
  148. // Since the length and current position are both a multiple of bufferSizeBytes
  149. // just treat treat one full buffer at a time
  150. int numFrames = len1 / bufferSizeBytes;
  151. while(numFrames--){
  152. if (isRec) {
  153. BroadcastFrame(ptr1);
  154. } else {
  155. rakVoice->ReceiveFrame(ptr1);
  156. }
  157. ptr1 = (char*)ptr1 + bufferSizeBytes;
  158. }
  159. numFrames = len2 / bufferSizeBytes;
  160. while(numFrames--) {
  161. if (isRec){
  162. BroadcastFrame(ptr2);
  163. } else {
  164. rakVoice->ReceiveFrame(ptr2);
  165. }
  166. ptr2 = (char*)ptr2 + bufferSizeBytes;
  167. }
  168. snd->unlock(ptr1, ptr2, len1, len2);
  169. }
  170. lastPos = currPos;
  171. }
  172. void FMODVoiceAdapter::BroadcastFrame(void *ptr)
  173. {
  174. #ifndef _TEST_LOOPBACK
  175. unsigned i;
  176. unsigned int numPeers = rakVoice->GetRakPeerInterface()->GetMaximumNumberOfPeers();
  177. for (i=0; i < numPeers; i++)
  178. {
  179. rakVoice->SendFrame(rakVoice->GetRakPeerInterface()->GetGUIDFromIndex(i), ptr);
  180. }
  181. #else
  182. rakVoice->SendFrame(RakNet::UNASSIGNED_SYSTEM_ADDRESS, ptr);
  183. #endif
  184. }
粤ICP备19079148号