Audio.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. #include "mumlib/Audio.hpp"
  2. #include <boost/format.hpp>
  3. static boost::posix_time::seconds RESET_SEQUENCE_NUMBER_INTERVAL(5);
  4. mumlib::Audio::Audio(int sampleRate, int bitrate, int channels)
  5. : logger(log4cpp::Category::getInstance("mumlib.Audio")),
  6. opusDecoder(nullptr),
  7. opusEncoder(nullptr),
  8. outgoingSequenceNumber(0),
  9. iSampleRate(sampleRate),
  10. iChannels(channels) {
  11. int error, ret;
  12. iFrameSize = sampleRate / 100;
  13. iAudioBufferSize = iFrameSize;
  14. iAudioBufferSize *= 12;
  15. opusDecoder = opus_decoder_create(sampleRate, channels, &error);
  16. if (error != OPUS_OK) {
  17. throw AudioException((boost::format("failed to initialize OPUS decoder: %s") % opus_strerror(error)).str());
  18. }
  19. opusEncoder = opus_encoder_create(sampleRate, channels, OPUS_APPLICATION_VOIP, &error);
  20. if (error != OPUS_OK) {
  21. throw AudioException((boost::format("failed to initialize OPUS encoder: %s") % opus_strerror(error)).str());
  22. }
  23. ret = opus_encoder_ctl(opusEncoder, OPUS_SET_BITRATE(bitrate));
  24. if (ret != OPUS_OK) {
  25. throw AudioException((boost::format("failed to initialize transmission bitrate to %d B/s: %s")
  26. % bitrate % opus_strerror(ret)).str());
  27. }
  28. ret = opus_encoder_ctl(opusEncoder, OPUS_SET_VBR(0));
  29. if (ret != OPUS_OK) {
  30. throw AudioException((boost::format("failed to initialize variable bitrate: %s")
  31. % opus_strerror(ret)).str());
  32. }
  33. ret = opus_encoder_ctl(opusEncoder, OPUS_SET_VBR_CONSTRAINT(0));
  34. if (ret != OPUS_OK) {
  35. throw AudioException((boost::format("failed to initialize variable bitrate constraint: %s")
  36. % opus_strerror(ret)).str());
  37. }
  38. ret = opus_encoder_ctl(opusEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
  39. if (ret != OPUS_OK) {
  40. throw AudioException((boost::format("failed to initialize bandwidth narrow: %s")
  41. % opus_strerror(ret)).str());
  42. }
  43. ret = opus_encoder_ctl(opusEncoder, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
  44. if (ret != OPUS_OK) {
  45. throw AudioException((boost::format("failed to initialize maximum bandwidth narrow: %s")
  46. % opus_strerror(ret)).str());
  47. }
  48. resetEncoder();
  49. jbBuffer = jitter_buffer_init(iFrameSize);
  50. int margin = 10 * iFrameSize;
  51. jitter_buffer_ctl(jbBuffer, JITTER_BUFFER_SET_MARGIN, &margin);
  52. fFadeIn = new float[iFrameSize];
  53. fFadeOut = new float[iFrameSize];
  54. // Sine function to represent fade in/out. Period is FRAME_SIZE.
  55. float mul = static_cast<float>(M_PI / 2.0 * static_cast<double>(iFrameSize));
  56. for(unsigned int i = 0; i < iFrameSize; i++) {
  57. fFadeIn[i] = fFadeOut[iFrameSize - 1 - 1] = sinf(static_cast<float>(i) * mul);
  58. }
  59. }
  60. mumlib::Audio::~Audio() {
  61. if (opusDecoder) {
  62. opus_decoder_destroy(opusDecoder);
  63. }
  64. if (opusEncoder) {
  65. opus_encoder_destroy(opusEncoder);
  66. }
  67. jitter_buffer_destroy(jbBuffer);
  68. delete[] fFadeIn;
  69. delete[] fFadeOut;
  70. }
  71. void mumlib::Audio::setOpusEncoderBitrate(int bitrate) {
  72. int error = opus_encoder_ctl(opusEncoder, OPUS_SET_BITRATE(bitrate));
  73. if (error != OPUS_OK) {
  74. throw AudioException((boost::format("failed to initialize transmission bitrate to %d B/s: %s")
  75. % bitrate % opus_strerror(error)).str());
  76. }
  77. }
  78. int mumlib::Audio::getOpusEncoderBitrate() {
  79. opus_int32 bitrate;
  80. int error = opus_encoder_ctl(opusEncoder, OPUS_GET_BITRATE(&bitrate));
  81. if (error != OPUS_OK) {
  82. throw AudioException((boost::format("failed to read Opus bitrate: %s") % opus_strerror(error)).str());
  83. }
  84. return bitrate;
  85. }
  86. void mumlib::Audio::addFrameToBuffer(uint8_t *inputBuffer, int inputLength, int sequence) {
  87. int dataPointer = 0;
  88. VarInt varInt(inputBuffer);
  89. int opusDataLength = varInt.getValue();
  90. dataPointer += varInt.getEncoded().size();
  91. bool lastPacket = (opusDataLength & 0x2000) != 0;
  92. opusDataLength &= 0x1fff;
  93. auto *packet = reinterpret_cast<const unsigned char *>(&inputBuffer[dataPointer]);
  94. int frame = opus_packet_get_nb_frames(packet, opusDataLength);
  95. int samples = frame * opus_packet_get_samples_per_frame(packet, iSampleRate);
  96. int channel = opus_packet_get_nb_channels(packet);
  97. if(not sequence) {
  98. resetJitterBuffer();
  99. }
  100. logger.info("Opus packet, frame: %d, samples: %d, channel: %d", frame, samples, channel);
  101. JitterBufferPacket jbPacket;
  102. jbPacket.data = reinterpret_cast<char *>(&inputBuffer[dataPointer]);
  103. jbPacket.len = opusDataLength;
  104. jbPacket.span = samples;
  105. jbPacket.timestamp = iFrameSize * sequence;
  106. jbPacket.user_data = lastPacket;
  107. jitter_buffer_put(jbBuffer, &jbPacket);
  108. }
  109. std::pair<int, bool> mumlib::Audio::decodeOpusPayload(int16_t *pcmBuffer, int pcmBufferSize) {
  110. int avail = 0;
  111. spx_uint32_t remaining = 0;
  112. jitter_buffer_ctl(jbBuffer, JITTER_BUFFER_GET_AVAILABLE_COUNT, &avail);
  113. jitter_buffer_remaining_span(jbBuffer, remaining);
  114. int timestamp = jitter_buffer_get_pointer_timestamp(jbBuffer);
  115. logger.warn("jbBufer, avail: %d, remain: %d, timestamp: %d", avail, remaining, timestamp);
  116. char data[4096];
  117. JitterBufferPacket jbPacket;
  118. jbPacket.data = data;
  119. jbPacket.len = 4096;
  120. spx_int32_t startofs = 0;
  121. int opusDataLength;
  122. int outputSize;
  123. spx_uint32_t lastPacket;
  124. if(jitter_buffer_get(jbBuffer, &jbPacket, iFrameSize, &startofs) == JITTER_BUFFER_OK) {
  125. opusDataLength = jbPacket.len;
  126. lastPacket = jbPacket.user_data;
  127. } else {
  128. jitter_buffer_update_delay(jbBuffer, &jbPacket, NULL);
  129. }
  130. if(opusDataLength) {
  131. outputSize = opus_decode(opusDecoder,
  132. reinterpret_cast<const unsigned char *>(jbPacket.data),
  133. jbPacket.len,
  134. pcmBuffer,
  135. pcmBufferSize, 0);
  136. } else {
  137. outputSize = opus_decode(opusDecoder,
  138. NULL, 0, pcmBuffer, pcmBufferSize, 0);
  139. }
  140. if(outputSize < 0) {
  141. outputSize = iFrameSize;
  142. memset(pcmBuffer, 0, iFrameSize * sizeof(float));
  143. }
  144. if(lastPacket) {
  145. for(unsigned int i = 0; i < iFrameSize; i++)
  146. pcmBuffer[i] *= fFadeOut[i];
  147. }
  148. for (int i = outputSize / iFrameSize; i > 0; --i) {
  149. jitter_buffer_tick(jbBuffer);
  150. }
  151. logger.debug("%d B of Opus data decoded to %d PCM samples, last packet: %d.",
  152. opusDataLength, outputSize, lastPacket);
  153. return std::make_pair(outputSize, lastPacket);
  154. }
  155. void mumlib::Audio::mixAudio(uint8_t *dest, uint8_t *src, int bufferOffset, int inputLength) {
  156. for(int i = 0; i < inputLength; i++) {
  157. float mix = 0;
  158. // Clip to [-1,1]
  159. if(mix > 1)
  160. mix = 1;
  161. else if(mix < -1)
  162. mix = -1;
  163. dest[i + bufferOffset] = mix;
  164. }
  165. }
  166. std::pair<int, bool> mumlib::Audio::decodeOpusPayload(uint8_t *inputBuffer,
  167. int inputLength,
  168. int16_t *pcmBuffer,
  169. int pcmBufferSize) {
  170. int64_t opusDataLength;
  171. int dataPointer = 0;
  172. VarInt varInt(inputBuffer);
  173. opusDataLength = varInt.getValue();
  174. dataPointer += varInt.getEncoded().size();
  175. bool lastPacket = (opusDataLength & 0x2000) != 0;
  176. opusDataLength = opusDataLength & 0x1fff;
  177. if (inputLength < opusDataLength + dataPointer) {
  178. throw AudioException((boost::format("invalid Opus payload (%d B): header %d B, expected Opus data length %d B")
  179. % inputLength % dataPointer % opusDataLength).str());
  180. }
  181. // Issue #3 (Users speaking simultaneously)
  182. // https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__decoder.html
  183. // Opus is a stateful codec with overlapping blocks and as a result Opus packets are not coded independently of each other.
  184. // Packets must be passed into the decoder serially and in the correct order for a correct decode.
  185. // Lost packets can be replaced with loss concealment by calling the decoder with a null pointer and zero length for the missing packet.
  186. // A single codec state may only be accessed from a single thread at a time and any required locking must be performed by the caller.
  187. // Separate streams must be decoded with separate decoder states and can be decoded in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK defined.
  188. auto *packet = reinterpret_cast<const unsigned char *>(&inputBuffer[dataPointer]);
  189. int frame = opus_packet_get_nb_frames(packet, opusDataLength);
  190. int samples = frame * opus_packet_get_samples_per_frame(packet, iSampleRate);
  191. int outputSize = opus_decode(opusDecoder,
  192. packet,
  193. opusDataLength,
  194. pcmBuffer,
  195. pcmBufferSize,
  196. 0);
  197. if (outputSize <= 0) {
  198. throw AudioException((boost::format("failed to decode %d B of OPUS data: %s") % inputLength %
  199. opus_strerror(outputSize)).str());
  200. }
  201. logger.debug("%d B of Opus data decoded to %d PCM samples, last packet: %d.",
  202. opusDataLength, outputSize, lastPacket);
  203. return std::make_pair(outputSize, lastPacket);
  204. }
  205. int mumlib::Audio::encodeAudioPacket(int target, int16_t *inputPcmBuffer, int inputLength, uint8_t *outputBuffer,
  206. int outputBufferSize) {
  207. using namespace std::chrono;
  208. const int lastAudioPacketSentInterval = duration_cast<milliseconds>(
  209. system_clock::now() - lastEncodedAudioPacketTimestamp).count();
  210. if (lastAudioPacketSentInterval > RESET_SEQUENCE_NUMBER_INTERVAL.total_milliseconds() + 1000) {
  211. logger.debug("Last audio packet was sent %d ms ago, resetting encoder.", lastAudioPacketSentInterval);
  212. resetEncoder();
  213. }
  214. std::vector<uint8_t> header;
  215. header.push_back(static_cast<unsigned char &&>(0x80 | target));
  216. auto sequenceNumberEnc = VarInt(outgoingSequenceNumber).getEncoded();
  217. header.insert(header.end(), sequenceNumberEnc.begin(), sequenceNumberEnc.end());
  218. uint8_t tmpOpusBuffer[1024];
  219. const int outputSize = opus_encode(opusEncoder,
  220. inputPcmBuffer,
  221. inputLength,
  222. tmpOpusBuffer,
  223. min(outputBufferSize, 1024)
  224. );
  225. if (outputSize <= 0) {
  226. throw AudioException((boost::format("failed to encode %d B of PCM data: %s") % inputLength %
  227. opus_strerror(outputSize)).str());
  228. }
  229. auto outputSizeEnc = VarInt(outputSize).getEncoded();
  230. header.insert(header.end(), outputSizeEnc.begin(), outputSizeEnc.end());
  231. memcpy(outputBuffer, &header[0], header.size());
  232. memcpy(outputBuffer + header.size(), tmpOpusBuffer, (size_t) outputSize);
  233. int incrementNumber = 100 * inputLength / iSampleRate;
  234. outgoingSequenceNumber += incrementNumber;
  235. lastEncodedAudioPacketTimestamp = std::chrono::system_clock::now();
  236. return static_cast<int>(outputSize + header.size());
  237. }
  238. void mumlib::Audio::resetEncoder() {
  239. int status = opus_encoder_ctl(opusEncoder, OPUS_RESET_STATE, nullptr);
  240. if (status != OPUS_OK) {
  241. throw AudioException((boost::format("failed to reset encoder: %s") % opus_strerror(status)).str());
  242. }
  243. outgoingSequenceNumber = 0;
  244. }
  245. void mumlib::Audio::resetJitterBuffer() {
  246. logger.debug("Last audio packet, resetting jitter buffer");
  247. jitter_buffer_reset(jbBuffer);
  248. }
  249. mumlib::IncomingAudioPacket mumlib::Audio::decodeIncomingAudioPacket(uint8_t *inputBuffer, int inputBufferLength) {
  250. mumlib::IncomingAudioPacket incomingAudioPacket{};
  251. incomingAudioPacket.type = static_cast<AudioPacketType >((inputBuffer[0] & 0xE0) >> 5);
  252. incomingAudioPacket.target = inputBuffer[0] & 0x1F;
  253. std::array<int64_t *, 2> varInts = {&incomingAudioPacket.sessionId, &incomingAudioPacket.sequenceNumber};
  254. int dataPointer = 1;
  255. for (int64_t *val : varInts) {
  256. VarInt varInt(&inputBuffer[dataPointer]);
  257. *val = varInt.getValue();
  258. dataPointer += varInt.getEncoded().size();
  259. }
  260. incomingAudioPacket.audioPayload = &inputBuffer[dataPointer];
  261. incomingAudioPacket.audioPayloadLength = inputBufferLength - dataPointer;
  262. if (dataPointer >= inputBufferLength) {
  263. throw AudioException((boost::format("invalid incoming audio packet (%d B): header %d B") % inputBufferLength %
  264. dataPointer).str());
  265. }
  266. logger.debug(
  267. "Received %d B of audio packet, %d B header, %d B payload (target: %d, sessionID: %ld, seq num: %ld).",
  268. inputBufferLength,
  269. dataPointer,
  270. incomingAudioPacket.audioPayloadLength,
  271. incomingAudioPacket.target,
  272. incomingAudioPacket.sessionId,
  273. incomingAudioPacket.sequenceNumber);
  274. return incomingAudioPacket;
  275. }