123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #include "EncodedAudioStream.h"
- #include <string.h> // for memcpy, memmove
- #include <stdexcept> // for runtime_error
- #include <type_traits> // for remove_extent_t
- #include <utility> // for move
- #include "BellLogger.h" // for AbstractLogger, BELL_LOG, bell
- #include "ByteStream.h" // for ByteStream
- #include "DecoderGlobals.h" // for DecodersInstance, decodersInstance, AAC_...
- using namespace bell;
- EncodedAudioStream::EncodedAudioStream() {
- bell::decodersInstance->ensureAAC();
- bell::decodersInstance->ensureMP3();
- inputBuffer = std::vector<uint8_t>(AAC_READBUF_SIZE * 4);
- outputBuffer = std::vector<short>(AAC_MAX_NCHANS * AAC_MAX_NSAMPS * 4 * 4);
- decodePtr = inputBuffer.data();
- }
- EncodedAudioStream::~EncodedAudioStream() {
- this->innerStream->close();
- }
- void EncodedAudioStream::openWithStream(
- std::unique_ptr<bell::ByteStream> byteStream) {
- if (this->innerStream) {
- this->innerStream->close();
- }
- this->innerStream = std::move(byteStream);
- this->guessDataFormat();
- }
- bool EncodedAudioStream::vectorStartsWith(std::vector<uint8_t>& vec,
- std::vector<uint8_t>& start) {
- if (vec.size() < start.size()) {
- return false;
- }
- for (int i = 0; i < start.size(); i++) {
- if (vec[i] != start[i]) {
- return false;
- }
- }
- return true;
- }
- size_t EncodedAudioStream::decodeFrame(uint8_t* dst) {
- if (innerStream->size() != 0 &&
- innerStream->position() >= innerStream->size()) {
- return 0;
- }
- switch (this->codec) {
- case AudioCodec::AAC:
- return decodeFrameAAC(dst);
- break;
- case AudioCodec::MP3:
- return decodeFrameMp3(dst);
- break;
- default:
- break;
- }
- return 0;
- }
- size_t EncodedAudioStream::decodeFrameMp3(uint8_t* dst) {
- size_t writtenBytes = 0;
- int bufSize = MP3_READBUF_SIZE;
- int readBytes = innerStream->read(inputBuffer.data() + bytesInBuffer,
- bufSize - bytesInBuffer);
- if (readBytes > 0) {
- bytesInBuffer += readBytes;
- decodePtr = inputBuffer.data();
- offset = MP3FindSyncWord(inputBuffer.data(), bytesInBuffer);
- if (offset != -1) {
- bytesInBuffer -= offset;
- decodePtr += offset;
- int decodeStatus =
- MP3Decode(bell::decodersInstance->mp3Decoder, &decodePtr,
- &bytesInBuffer, outputBuffer.data(), 0);
- MP3GetLastFrameInfo(bell::decodersInstance->mp3Decoder, &mp3FrameInfo);
- if (decodeStatus == ERR_MP3_NONE) {
- decodedSampleRate = mp3FrameInfo.samprate;
- writtenBytes =
- (mp3FrameInfo.bitsPerSample / 8) * mp3FrameInfo.outputSamps;
- memcpy(dst, outputBuffer.data(), writtenBytes);
- } else {
- BELL_LOG(info, TAG, "Error in frame, moving two bytes %d",
- decodeStatus);
- decodePtr += 1;
- bytesInBuffer -= 1;
- }
- } else {
- BELL_LOG(info, TAG, "Unexpected error in data, skipping a word");
- decodePtr += 3800;
- bytesInBuffer -= 3800;
- }
- memmove(inputBuffer.data(), decodePtr, bytesInBuffer);
- }
- return writtenBytes;
- }
- bool EncodedAudioStream::isReadable() {
- return this->codec != AudioCodec::NONE;
- }
- size_t EncodedAudioStream::decodeFrameAAC(uint8_t* dst) {
- size_t writtenBytes = 0;
- auto bufSize = AAC_READBUF_SIZE;
- int readBytes = innerStream->read(inputBuffer.data() + bytesInBuffer,
- bufSize - bytesInBuffer);
- if (readBytes > 0) {
- bytesInBuffer += readBytes;
- decodePtr = inputBuffer.data();
- offset = AACFindSyncWord(inputBuffer.data(), bytesInBuffer);
- if (offset != -1) {
- bytesInBuffer -= offset;
- decodePtr += offset;
- int decodeStatus =
- AACDecode(bell::decodersInstance->aacDecoder, &decodePtr,
- &bytesInBuffer, outputBuffer.data());
- AACGetLastFrameInfo(bell::decodersInstance->aacDecoder, &aacFrameInfo);
- if (decodeStatus == ERR_AAC_NONE) {
- decodedSampleRate = aacFrameInfo.sampRateOut;
- writtenBytes =
- (aacFrameInfo.bitsPerSample / 8) * aacFrameInfo.outputSamps;
- memcpy(dst, outputBuffer.data(), writtenBytes);
- } else {
- BELL_LOG(info, TAG, "Error in frame, moving two bytes %d",
- decodeStatus);
- decodePtr += 1;
- bytesInBuffer -= 1;
- }
- } else {
- BELL_LOG(info, TAG, "Unexpected error in data, skipping a word");
- decodePtr += 3800;
- bytesInBuffer -= 3800;
- }
- memmove(inputBuffer.data(), decodePtr, bytesInBuffer);
- }
- return writtenBytes;
- }
- void EncodedAudioStream::guessDataFormat() {
- // Read 14 bytes from the stream
- this->innerStream->read(inputBuffer.data(), 14);
- bytesInBuffer = 14;
- BELL_LOG(info, TAG, "No codec set, reading secret bytes");
- if (vectorStartsWith(inputBuffer, this->mp3MagicBytesIdc) ||
- vectorStartsWith(inputBuffer, this->mp3MagicBytesUntagged)) {
- BELL_LOG(info, TAG, "Detected MP3");
- codec = AudioCodec::MP3;
- } else if (vectorStartsWith(inputBuffer, this->aacMagicBytes) ||
- vectorStartsWith(inputBuffer, this->aacMagicBytes4)) {
- BELL_LOG(info, TAG, "Detected AAC");
- codec = AudioCodec::AAC;
- }
- if (codec == AudioCodec::NONE) {
- throw std::runtime_error("Codec not supported");
- }
- }
- void EncodedAudioStream::readFully(uint8_t* dst, size_t nbytes) {}
|