MP3Container.cpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include "MP3Container.h"
  2. #include <cstring> // for memmove
  3. #include "StreamInfo.h" // for BitWidth, BitWidth::BW_16, SampleRate, Sampl...
  4. #include "mp3dec.h" // for MP3FindSyncWord
  5. using namespace bell;
  6. MP3Container::MP3Container(std::istream& istr, const std::byte* headingBytes) : bell::AudioContainer(istr) {
  7. if (headingBytes != nullptr) {
  8. memcpy(buffer.data(), headingBytes, 7);
  9. bytesInBuffer = 7;
  10. }
  11. }
  12. bool MP3Container::fillBuffer() {
  13. if (this->bytesInBuffer < MP3_MAX_FRAME_SIZE * 2) {
  14. this->istr.read((char*)buffer.data() + bytesInBuffer,
  15. buffer.size() - bytesInBuffer);
  16. this->bytesInBuffer += istr.gcount();
  17. }
  18. return this->bytesInBuffer >= MP3_MAX_FRAME_SIZE * 2;
  19. }
  20. void MP3Container::consumeBytes(uint32_t len) {
  21. dataOffset += len;
  22. }
  23. std::byte* MP3Container::readSample(uint32_t& len) {
  24. // Align data if previous read was offseted
  25. if (dataOffset > 0 && bytesInBuffer > 0) {
  26. size_t toConsume = std::min(dataOffset, bytesInBuffer);
  27. memmove(buffer.data(), buffer.data() + toConsume,
  28. buffer.size() - toConsume);
  29. dataOffset -= toConsume;
  30. bytesInBuffer -= toConsume;
  31. }
  32. if (!this->fillBuffer()) {
  33. len = 0;
  34. return nullptr;
  35. }
  36. int startOffset =
  37. MP3FindSyncWord((uint8_t*)this->buffer.data(), bytesInBuffer);
  38. if (startOffset < 0) {
  39. // Discard word
  40. dataOffset = MP3_MAX_FRAME_SIZE;
  41. return nullptr;
  42. }
  43. dataOffset += startOffset;
  44. len = bytesInBuffer - dataOffset;
  45. return this->buffer.data() + dataOffset;
  46. }
  47. void MP3Container::parseSetupData() {
  48. channels = 2;
  49. sampleRate = bell::SampleRate::SR_44100;
  50. bitWidth = bell::BitWidth::BW_16;
  51. }