| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 | #include "ADTSContainer.h"#include <cstring>  // for memmove#include <iostream>#include "StreamInfo.h"  // for BitWidth, BitWidth::BW_16, SampleRate, Sampl...// #include "aacdec.h"      // for AACFindSyncWordusing namespace bell;#define SYNC_WORLD_LEN 4#define SYNCWORDH 0xff#define SYNCWORDL 0xf0// AAC ADTS frame header len#define AAC_ADTS_FRAME_HEADER_LEN 9// AAC ADTS frame sync verify#define AAC_ADTS_SYNC_VERIFY(buf) \  ((buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0))// AAC ADTS Frame size value stores in 13 bits started at the 31th bit from header#define AAC_ADTS_FRAME_GETSIZE(buf) \  ((buf[3] & 0x03) << 11 | buf[4] << 3 | buf[5] >> 5)ADTSContainer::ADTSContainer(std::istream& istr, const std::byte* headingBytes)    : bell::AudioContainer(istr) {  if (headingBytes != nullptr) {    memcpy(buffer.data(), headingBytes, 7);    bytesInBuffer = 7;  }}bool ADTSContainer::fillBuffer() {  if (this->bytesInBuffer < AAC_MAX_FRAME_SIZE * 2) {    this->istr.read((char*)buffer.data() + bytesInBuffer,                    buffer.size() - bytesInBuffer);    this->bytesInBuffer += istr.gcount();  }  return this->bytesInBuffer >= AAC_MAX_FRAME_SIZE;}bool ADTSContainer::resyncADTS() {  int resyncOffset = 0;  bool resyncValid = false;  size_t validBytes = bytesInBuffer - dataOffset;  while (!resyncValid && resyncOffset < validBytes) {    uint8_t* buf = (uint8_t*)this->buffer.data() + dataOffset + resyncOffset;    if (AAC_ADTS_SYNC_VERIFY(buf)) {      // Read frame size, and check if a consecutive frame is available      uint32_t frameSize = AAC_ADTS_FRAME_GETSIZE(buf);      if (frameSize + resyncOffset > validBytes) {        // Not enough data, discard this frame        resyncOffset++;        continue;      }      buf =          (uint8_t*)this->buffer.data() + dataOffset + resyncOffset + frameSize;      if (AAC_ADTS_SYNC_VERIFY(buf)) {        buf += AAC_ADTS_FRAME_GETSIZE(buf);        if (AAC_ADTS_SYNC_VERIFY(buf)) {          protectionAbsent = (buf[1] & 1);          // Found 3 consecutive frames, resynced          resyncValid = true;        }      }    } else {      resyncOffset++;    }  }  dataOffset += resyncOffset;  return resyncValid;}void ADTSContainer::consumeBytes(uint32_t len) {  dataOffset += len;}std::byte* ADTSContainer::readSample(uint32_t& len) {  // Align data if previous read was offseted  if (dataOffset > 0 && bytesInBuffer > 0) {    size_t toConsume = std::min(dataOffset, bytesInBuffer);    memmove(buffer.data(), buffer.data() + toConsume,            buffer.size() - toConsume);    dataOffset -= toConsume;    bytesInBuffer -= toConsume;  }  if (!this->fillBuffer()) {    len = 0;    return nullptr;  }  uint8_t* buf = (uint8_t*)buffer.data() + dataOffset;  if (!AAC_ADTS_SYNC_VERIFY(buf)) {    if (!resyncADTS()) {      len = 0;      return nullptr;    }  } else {    protectionAbsent = (buf[1] & 1);  }  len = AAC_ADTS_FRAME_GETSIZE(buf);  if (len > bytesInBuffer - dataOffset) {    if (!resyncADTS()) {      len = 0;      return nullptr;    }  }  return buffer.data() + dataOffset;}void ADTSContainer::parseSetupData() {  channels = 2;  sampleRate = bell::SampleRate::SR_44100;  bitWidth = bell::BitWidth::BW_16;}
 |