arduino-audio-tools
Loading...
Searching...
No Matches
VorbisDecoder.h
Go to the documentation of this file.
1#pragma once
2
3
6
7#include <vorbis.h>
8
9namespace audio_tools {
10
30class VorbisDecoder : public AudioDecoder {
31 public:
39 VorbisDecoder(size_t buffer_size = 256, int header_packets = 3)
41
48
49 const char *mime() override { return "audio/vorbis"; }
50
58 bool begin() override {
59 end();
61 vorbis_info_init(&vi);
62 vorbis_comment_init(&vc);
63 active = true;
64 return true;
65 }
66
70 void end() override {
71 vorbis_block_clear(&vb);
72 vorbis_dsp_clear(&vd);
73 vorbis_comment_clear(&vc);
74 vorbis_info_clear(&vi);
76 decoder_initialized = false;
77 active = false;
78 }
79
90 size_t write(const uint8_t *data, size_t len) override {
91 ogg_packet packet;
92 packet.packet = (unsigned char *)data;
93 packet.bytes = len;
94 packet.b_o_s = (header_packets == 0) ? 1 : 0;
95 packet.e_o_s = 0;
96 packet.granulepos = 0;
97 packet.packetno = header_packets;
98
100 if (!initDecoder()) return 0;
101 decoder_initialized = true;
102 }
104 if (!parseHeaderPacket(packet, header_packets)) return 0;
107 if (!initDecoder()) return 0;
108 decoder_initialized = true;
109 }
110 return 0;
111 }
114 }
115 if (!decoder_initialized) return 0;
116 return decodeAudioPacket(packet);
117 }
118
123 AudioInfo audioInfo() override {
125 if (vi.channels > 0 && vi.rate > 0) {
126 info.sample_rate = vi.rate;
127 info.channels = vi.channels;
129 }
130 return info;
131 }
132
136 operator bool() override { return active; }
137
138 protected:
140 vorbis_info vi{};
142 vorbis_comment vc{};
144 vorbis_dsp_state vd{};
146 vorbis_block vb{};
148 Print *p_print = nullptr;
150 bool active = false;
152 size_t pcm_buffer_size = 256;
165 bool parseHeaderPacket(ogg_packet &packet, int header_packets) {
166 if (vorbis_synthesis_headerin(&vi, &vc, &packet) != 0) {
167 LOGE("Header packet %d invalid", header_packets);
168 return false;
169 }
170 return true;
171 }
172
177 bool initDecoder() {
178 if (vorbis_synthesis_init(&vd, &vi) != 0) {
179 LOGE("vorbis_synthesis_init failed");
180 return false;
181 }
182 vorbis_block_init(&vd, &vb);
183 return true;
184 }
185
191 size_t decodeAudioPacket(ogg_packet &packet) {
192 size_t total_written = 0;
193 if (vorbis_synthesis(&vb, &packet) == 0) {
194 vorbis_synthesis_blockin(&vd, &vb);
195 float **pcm = nullptr;
196 int samples = vorbis_synthesis_pcmout(&vd, &pcm);
197 while (samples > 0 && pcm) {
198 int chunk = (samples > pcm_buffer_size) ? pcm_buffer_size : samples;
199 convertFloatToInt16PCM(pcm, chunk, vi.channels);
200 if (!pcmout_buffer.empty() && p_print) {
201 p_print->write((uint8_t *)pcmout_buffer.data(),
202 pcmout_buffer.size() * sizeof(int16_t));
203 total_written += pcmout_buffer.size() * sizeof(int16_t);
205 }
206 vorbis_synthesis_read(&vd, chunk);
207 samples = vorbis_synthesis_pcmout(&vd, &pcm);
208 }
209 }
210 return total_written;
211 }
212
220 void convertFloatToInt16PCM(float **pcm, int samples, int channels) {
221 for (int i = 0; i < samples; ++i) {
222 for (int ch = 0; ch < channels; ++ch) {
223 float val = pcm[ch][i];
224 int16_t sample = (int16_t)(val * 32767.0f);
225 if (sample > 32767) sample = 32767;
226 if (sample < -32768) sample = -32768;
227 pcmout_buffer.push_back(sample);
228 }
229 }
230 }
231};
232
233} // namespace audio_tools
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Definition Arduino.h:56
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
AudioInfo info
Definition AudioCodecsBase.h:80
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:175
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool empty()
Definition Vector.h:180
void push_back(T &&value)
Definition Vector.h:182
void clear()
Definition Vector.h:176
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
~VorbisDecoder()
Destructor for VorbisDecoder.
Definition VorbisDecoder.h:47
int num_header_packets
Number of Vorbis header packets.
Definition VorbisDecoder.h:154
bool active
Decoder active state.
Definition CodecVorbis.h:181
bool parseHeaderPacket(ogg_packet &packet, int header_packets)
Parses a Vorbis header packet.
Definition VorbisDecoder.h:165
void convertFloatToInt16PCM(float **pcm, int samples, int channels)
Converts float PCM to interleaved int16 PCM and stores in pcmout_buffer.
Definition VorbisDecoder.h:220
vorbis_comment vc
Vorbis comment metadata.
Definition VorbisDecoder.h:142
size_t decodeAudioPacket(ogg_packet &packet)
Decodes an audio packet and writes PCM to output.
Definition VorbisDecoder.h:191
bool decoder_initialized
Definition VorbisDecoder.h:158
Vector< uint8_t > pcm
Definition CodecVorbis.h:174
bool initDecoder()
Initializes the Vorbis decoder after header parsing.
Definition VorbisDecoder.h:177
size_t pcm_buffer_size
PCM output buffer size.
Definition VorbisDecoder.h:152
int header_packets
Definition VorbisDecoder.h:157
vorbis_block vb
Block structure for synthesis.
Definition VorbisDecoder.h:146
void end() override
Releases the reserved memory.
Definition CodecVorbis.h:72
size_t write(const uint8_t *data, size_t len) override
Feeds a Vorbis packet (header or audio) to the decoder.
Definition VorbisDecoder.h:90
Vector< int16_t > pcmout_buffer
Buffer for interleaved PCM output.
Definition VorbisDecoder.h:156
vorbis_info vi
Vorbis stream info (channels, sample rate, etc.)
Definition VorbisDecoder.h:140
const char * mime() override
Provides the MIME type of the audio format handled by this decoder.
Definition VorbisDecoder.h:49
VorbisDecoder(size_t buffer_size=256, int header_packets=3)
Constructor for VorbisDecoder.
Definition VorbisDecoder.h:39
bool begin() override
Resets decoder state and prepares for new Vorbis stream.
Definition VorbisDecoder.h:58
Print * p_print
Output stream for PCM audio.
Definition VorbisDecoder.h:148
vorbis_dsp_state vd
Decoder state for synthesis.
Definition VorbisDecoder.h:144
AudioInfo audioInfo() override
Provides the last available MP3FrameInfo.
Definition CodecVorbis.h:85
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57