4#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
5#include "AudioTools/CoreAudio/Buffers.h"
30class VorbisDecoder :
public AudioDecoder {
59 vorbis_info_init(&
vi);
60 vorbis_comment_init(&
vc);
69 vorbis_block_clear(&
vb);
70 vorbis_dsp_clear(&
vd);
71 vorbis_comment_clear(&
vc);
72 vorbis_info_clear(&
vi);
74 decoder_initialized =
false;
88 size_t write(
const uint8_t *data,
size_t len)
override {
90 packet.packet = (
unsigned char *)data;
92 packet.b_o_s = (header_packets == 0) ? 1 : 0;
94 packet.granulepos = 0;
95 packet.packetno = header_packets;
99 decoder_initialized =
true;
106 decoder_initialized =
true;
113 if (!decoder_initialized)
return 0;
123 if (
vi.channels > 0 &&
vi.rate > 0) {
134 operator bool()
override {
return active; }
142 vorbis_dsp_state
vd{};
155 int header_packets = 0;
156 bool decoder_initialized =
false;
164 if (vorbis_synthesis_headerin(&
vi, &
vc, &packet) != 0) {
165 LOGE(
"Header packet %d invalid", header_packets);
176 if (vorbis_synthesis_init(&
vd, &
vi) != 0) {
177 LOGE(
"vorbis_synthesis_init failed");
180 vorbis_block_init(&
vd, &
vb);
190 size_t total_written = 0;
191 if (vorbis_synthesis(&
vb, &packet) == 0) {
192 vorbis_synthesis_blockin(&
vd, &
vb);
193 float **pcm =
nullptr;
194 int samples = vorbis_synthesis_pcmout(&
vd, &pcm);
195 while (samples > 0 && pcm) {
204 vorbis_synthesis_read(&
vd, chunk);
205 samples = vorbis_synthesis_pcmout(&
vd, &pcm);
208 return total_written;
219 for (
int i = 0; i < samples; ++i) {
220 for (
int ch = 0; ch < channels; ++ch) {
221 float val = pcm[ch][i];
222 int16_t sample = (int16_t)(val * 32767.0f);
223 if (sample > 32767) sample = 32767;
224 if (sample < -32768) sample = -32768;