VorbisDecoder.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "VorbisDecoder.h"
  2. #include <stdlib.h> // for free, malloc
  3. #include "CodecType.h" // for bell
  4. #include "config_types.h" // for ogg_int16_t
  5. namespace bell {
  6. class AudioContainer;
  7. } // namespace bell
  8. using namespace bell;
  9. extern "C" {
  10. extern vorbis_dsp_state* vorbis_dsp_create(vorbis_info* vi);
  11. extern void vorbis_dsp_destroy(vorbis_dsp_state* v);
  12. extern int vorbis_dsp_restart(vorbis_dsp_state* v);
  13. extern int vorbis_dsp_headerin(vorbis_info* vi, vorbis_comment* vc,
  14. ogg_packet* op);
  15. extern int vorbis_dsp_synthesis(vorbis_dsp_state* vd, ogg_packet* op,
  16. int decodep);
  17. extern int vorbis_dsp_pcmout(vorbis_dsp_state* v, ogg_int16_t* pcm,
  18. int samples);
  19. extern int vorbis_dsp_read(vorbis_dsp_state* v, int samples);
  20. }
  21. #define VORBIS_BUF_SAMPLES 1024
  22. #define VORBIS_BUF_CHANNELS 2
  23. VorbisDecoder::VorbisDecoder() {
  24. vi = new vorbis_info;
  25. vorbis_info_init(vi);
  26. vc = new vorbis_comment;
  27. vorbis_comment_init(vc);
  28. op.packet = new ogg_reference;
  29. op.packet->buffer = new ogg_buffer;
  30. op.packet->buffer->refcount = 0;
  31. op.packet->buffer->ptr.owner = nullptr;
  32. op.packet->buffer->ptr.next = nullptr;
  33. op.packet->begin = 0;
  34. op.packet->next = nullptr;
  35. op.granulepos = -1;
  36. op.packetno = 10;
  37. pcmData = (int16_t*)malloc(VORBIS_BUF_SAMPLES * VORBIS_BUF_CHANNELS *
  38. sizeof(uint16_t));
  39. }
  40. VorbisDecoder::~VorbisDecoder() {
  41. vorbis_info_clear(vi);
  42. vorbis_comment_clear(vc);
  43. if (vd)
  44. vorbis_dsp_destroy(vd);
  45. vd = nullptr;
  46. free(pcmData);
  47. }
  48. bool VorbisDecoder::setup(AudioContainer* container) {
  49. /*
  50. uint32_t setupLen;
  51. uint8_t* setup = container->getSetupData(setupLen, AudioCodec::VORBIS);
  52. if (!setup)
  53. return false;
  54. op.b_o_s = true; // mark this page as beginning of stream
  55. uint32_t bytesLeft = setupLen - 1; // minus header count length (8 bit)
  56. std::vector<uint32_t> headers(setup[0]);
  57. for (uint8_t i = 0; i < setup[0]; i++) {
  58. uint8_t* sizeByte = (uint8_t*)setup + 1 + i;
  59. headers[i] = 0;
  60. while (*sizeByte == 255) {
  61. headers[i] += *(sizeByte++);
  62. bytesLeft--;
  63. }
  64. headers[i] += *sizeByte;
  65. bytesLeft--;
  66. }
  67. // parse all headers from the setup data
  68. for (const auto& headerSize : headers) {
  69. setPacket(setup + setupLen - bytesLeft, headerSize);
  70. bytesLeft -= headerSize;
  71. lastErrno = vorbis_dsp_headerin(vi, vc, &op);
  72. if (lastErrno < 0) {
  73. bytesLeft = 0;
  74. break;
  75. }
  76. }
  77. // parse last header, not present in header table (seems to happen for MP4 containers)
  78. if (bytesLeft) {
  79. setPacket(setup + setupLen - bytesLeft, bytesLeft);
  80. lastErrno = vorbis_dsp_headerin(vi, vc, &op);
  81. }
  82. // disable BOS to allow reading audio data
  83. op.b_o_s = false;
  84. // set up the codec
  85. if (vd)
  86. vorbis_dsp_restart(vd);
  87. else
  88. vd = vorbis_dsp_create(vi);
  89. return !lastErrno;
  90. */
  91. return false;
  92. }
  93. bool VorbisDecoder::setup(uint32_t sampleRate, uint8_t channelCount,
  94. uint8_t bitDepth) {
  95. // manual setup is not allowed
  96. return false;
  97. }
  98. uint8_t* VorbisDecoder::decode(uint8_t* inData, uint32_t& inLen,
  99. uint32_t& outLen) {
  100. if (!inData || !vi)
  101. return nullptr;
  102. setPacket(inData, inLen);
  103. // sources:
  104. // - vorbisfile.c:556
  105. // - vorbisfile.c:1557
  106. lastErrno = vorbis_dsp_synthesis(vd, &op, 1);
  107. if (lastErrno < 0)
  108. return nullptr;
  109. int samples = vorbis_dsp_pcmout(vd, pcmData, VORBIS_BUF_SAMPLES);
  110. outLen = samples;
  111. if (samples) {
  112. if (samples > 0) {
  113. vorbis_dsp_read(vd, samples);
  114. outLen = samples * 2 * vi->channels;
  115. }
  116. }
  117. inLen = 0;
  118. return (uint8_t*)pcmData;
  119. }
  120. void VorbisDecoder::setPacket(uint8_t* inData, uint32_t inLen) const {
  121. op.packet->buffer->data = static_cast<unsigned char*>(inData);
  122. op.packet->buffer->size = static_cast<long>(inLen);
  123. op.packet->length = static_cast<long>(inLen);
  124. }