EncodedAudioStream.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include "EncodedAudioStream.h"
  2. #include <string.h> // for memcpy, memmove
  3. #include <stdexcept> // for runtime_error
  4. #include <type_traits> // for remove_extent_t
  5. #include <utility> // for move
  6. #include "BellLogger.h" // for AbstractLogger, BELL_LOG, bell
  7. #include "ByteStream.h" // for ByteStream
  8. #include "DecoderGlobals.h" // for DecodersInstance, decodersInstance, AAC_...
  9. using namespace bell;
  10. EncodedAudioStream::EncodedAudioStream() {
  11. bell::decodersInstance->ensureAAC();
  12. bell::decodersInstance->ensureMP3();
  13. inputBuffer = std::vector<uint8_t>(AAC_READBUF_SIZE * 4);
  14. outputBuffer = std::vector<short>(AAC_MAX_NCHANS * AAC_MAX_NSAMPS * 4 * 4);
  15. decodePtr = inputBuffer.data();
  16. }
  17. EncodedAudioStream::~EncodedAudioStream() {
  18. this->innerStream->close();
  19. }
  20. void EncodedAudioStream::openWithStream(
  21. std::unique_ptr<bell::ByteStream> byteStream) {
  22. if (this->innerStream) {
  23. this->innerStream->close();
  24. }
  25. this->innerStream = std::move(byteStream);
  26. this->guessDataFormat();
  27. }
  28. bool EncodedAudioStream::vectorStartsWith(std::vector<uint8_t>& vec,
  29. std::vector<uint8_t>& start) {
  30. if (vec.size() < start.size()) {
  31. return false;
  32. }
  33. for (int i = 0; i < start.size(); i++) {
  34. if (vec[i] != start[i]) {
  35. return false;
  36. }
  37. }
  38. return true;
  39. }
  40. size_t EncodedAudioStream::decodeFrame(uint8_t* dst) {
  41. if (innerStream->size() != 0 &&
  42. innerStream->position() >= innerStream->size()) {
  43. return 0;
  44. }
  45. switch (this->codec) {
  46. case AudioCodec::AAC:
  47. return decodeFrameAAC(dst);
  48. break;
  49. case AudioCodec::MP3:
  50. return decodeFrameMp3(dst);
  51. break;
  52. default:
  53. break;
  54. }
  55. return 0;
  56. }
  57. size_t EncodedAudioStream::decodeFrameMp3(uint8_t* dst) {
  58. size_t writtenBytes = 0;
  59. int bufSize = MP3_READBUF_SIZE;
  60. int readBytes = innerStream->read(inputBuffer.data() + bytesInBuffer,
  61. bufSize - bytesInBuffer);
  62. if (readBytes > 0) {
  63. bytesInBuffer += readBytes;
  64. decodePtr = inputBuffer.data();
  65. offset = MP3FindSyncWord(inputBuffer.data(), bytesInBuffer);
  66. if (offset != -1) {
  67. bytesInBuffer -= offset;
  68. decodePtr += offset;
  69. int decodeStatus =
  70. MP3Decode(bell::decodersInstance->mp3Decoder, &decodePtr,
  71. &bytesInBuffer, outputBuffer.data(), 0);
  72. MP3GetLastFrameInfo(bell::decodersInstance->mp3Decoder, &mp3FrameInfo);
  73. if (decodeStatus == ERR_MP3_NONE) {
  74. decodedSampleRate = mp3FrameInfo.samprate;
  75. writtenBytes =
  76. (mp3FrameInfo.bitsPerSample / 8) * mp3FrameInfo.outputSamps;
  77. memcpy(dst, outputBuffer.data(), writtenBytes);
  78. } else {
  79. BELL_LOG(info, TAG, "Error in frame, moving two bytes %d",
  80. decodeStatus);
  81. decodePtr += 1;
  82. bytesInBuffer -= 1;
  83. }
  84. } else {
  85. BELL_LOG(info, TAG, "Unexpected error in data, skipping a word");
  86. decodePtr += 3800;
  87. bytesInBuffer -= 3800;
  88. }
  89. memmove(inputBuffer.data(), decodePtr, bytesInBuffer);
  90. }
  91. return writtenBytes;
  92. }
  93. bool EncodedAudioStream::isReadable() {
  94. return this->codec != AudioCodec::NONE;
  95. }
  96. size_t EncodedAudioStream::decodeFrameAAC(uint8_t* dst) {
  97. size_t writtenBytes = 0;
  98. auto bufSize = AAC_READBUF_SIZE;
  99. int readBytes = innerStream->read(inputBuffer.data() + bytesInBuffer,
  100. bufSize - bytesInBuffer);
  101. if (readBytes > 0) {
  102. bytesInBuffer += readBytes;
  103. decodePtr = inputBuffer.data();
  104. offset = AACFindSyncWord(inputBuffer.data(), bytesInBuffer);
  105. if (offset != -1) {
  106. bytesInBuffer -= offset;
  107. decodePtr += offset;
  108. int decodeStatus =
  109. AACDecode(bell::decodersInstance->aacDecoder, &decodePtr,
  110. &bytesInBuffer, outputBuffer.data());
  111. AACGetLastFrameInfo(bell::decodersInstance->aacDecoder, &aacFrameInfo);
  112. if (decodeStatus == ERR_AAC_NONE) {
  113. decodedSampleRate = aacFrameInfo.sampRateOut;
  114. writtenBytes =
  115. (aacFrameInfo.bitsPerSample / 8) * aacFrameInfo.outputSamps;
  116. memcpy(dst, outputBuffer.data(), writtenBytes);
  117. } else {
  118. BELL_LOG(info, TAG, "Error in frame, moving two bytes %d",
  119. decodeStatus);
  120. decodePtr += 1;
  121. bytesInBuffer -= 1;
  122. }
  123. } else {
  124. BELL_LOG(info, TAG, "Unexpected error in data, skipping a word");
  125. decodePtr += 3800;
  126. bytesInBuffer -= 3800;
  127. }
  128. memmove(inputBuffer.data(), decodePtr, bytesInBuffer);
  129. }
  130. return writtenBytes;
  131. }
  132. void EncodedAudioStream::guessDataFormat() {
  133. // Read 14 bytes from the stream
  134. this->innerStream->read(inputBuffer.data(), 14);
  135. bytesInBuffer = 14;
  136. BELL_LOG(info, TAG, "No codec set, reading secret bytes");
  137. if (vectorStartsWith(inputBuffer, this->mp3MagicBytesIdc) ||
  138. vectorStartsWith(inputBuffer, this->mp3MagicBytesUntagged)) {
  139. BELL_LOG(info, TAG, "Detected MP3");
  140. codec = AudioCodec::MP3;
  141. } else if (vectorStartsWith(inputBuffer, this->aacMagicBytes) ||
  142. vectorStartsWith(inputBuffer, this->aacMagicBytes4)) {
  143. BELL_LOG(info, TAG, "Detected AAC");
  144. codec = AudioCodec::AAC;
  145. }
  146. if (codec == AudioCodec::NONE) {
  147. throw std::runtime_error("Codec not supported");
  148. }
  149. }
  150. void EncodedAudioStream::readFully(uint8_t* dst, size_t nbytes) {}