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