arduino-audio-tools
Loading...
Searching...
No Matches
CodecAACFAAD2.h
Go to the documentation of this file.
1#pragma once
2
4#include "faad2.h"
5#include "neaacdec.h"
6
7// faad2's neaacdec.h defines short, common object/header-type macros (RAW,
8// ADIF, ADTS, LATM, MAIN, LC, SSR, LTP, HE_AAC, ER_LC, ER_LTP, LD,
9// DRM_ER_LC, AudioSpecificConfig) that are not used outside of this header
10// but leak globally and clash with identifiers (e.g. VideoFormat::RAW in
11// ContainerAVI.h) in other audio-tools headers.
12#undef MAIN
13#undef LC
14#undef SSR
15#undef LTP
16#undef HE_AAC
17#undef ER_LC
18#undef ER_LTP
19#undef LD
20#undef DRM_ER_LC
21#undef RAW
22#undef ADIF
23#undef ADTS
24#undef LATM
25#undef AudioSpecificConfig
26
27#ifndef FAAD2_INPUT_BUFFER_SIZE
28#define FAAD2_INPUT_BUFFER_SIZE 1024 * 2
29#endif
30
31// to prevent Decoding error: Maximum number of bitstream elements exceeded
32#ifndef FAAD2_UNDERFLOW_LIMIT
33#define FAAD2_UNDERFLOW_LIMIT 500
34#endif
35
36namespace audio_tools {
37
49 public:
51 info.channels = 2;
52 info.sample_rate = 44100;
54 };
55
57
58 const char *mime() override { return "audio/aac"; }
59
61 bool begin() override {
62 TRACED();
63 end();
64
65 // Open the library
66 hAac = NeAACDecOpen();
67 if (hAac == nullptr) {
68 LOGE("NeAACDecOpen");
69 return false;
70 }
71
72 // Get the current config and adjust it
73 conf = NeAACDecGetCurrentConfiguration(hAac);
74 conf->outputFormat = FAAD_FMT_16BIT;
75 conf->defSampleRate = info.sample_rate;
76 conf->downMatrix = true; // 5.1 channel downmatrixed to 2 channel
77 conf->useOldADTSFormat = false;
78 conf->dontUpSampleImplicitSBR = false;
79
80 // Set the new configuration
81 if (!NeAACDecSetConfiguration(hAac, conf)) {
82 LOGE("NeAACDecSetConfiguration");
83 return false;
84 }
85
86 // setup input buffer
89 }
91 is_init = false;
92 return true;
93 }
94
96 void end() override {
97 TRACED();
98 if (hAac != nullptr) {
99 flush();
100 NeAACDecClose(hAac);
101 hAac = nullptr;
102 }
103 }
104
106 size_t write(const uint8_t *data, size_t len) override {
107 if (hAac == nullptr) return 0;
108 size_t result = 0;
109 while (result < len) {
110 // Write supplied data to input buffer
111 size_t written =
112 input_buffer.writeArray((uint8_t *)data + result, len - result);
113 result += written;
114 // Decode from input buffer
116 // decoder is stuck: avoid an endless loop
117 if (written == 0 && input_buffer.availableForWrite() == 0) {
118 LOGE("Input buffer full: discarding data");
120 }
121 }
122 return result;
123 }
124
126 void flush() { decode(0); }
127
129 void setInputBufferSize(int len) { buffer_size_input = len; }
130
132 void setUnderflowLimit(int len) { underflow_limit = len; }
133
135 NeAACDecHandle driver() { return hAac; }
136
138 operator bool() override { return hAac != nullptr; }
139
140 protected:
143 NeAACDecHandle hAac = nullptr;
144 NeAACDecConfigurationPtr conf = nullptr;
146 bool is_init = false;
147
148 bool init(uint8_t *data, size_t len) {
149 TRACEI();
150 unsigned long samplerate = info.sample_rate;
151 unsigned char channels = info.channels;
152
153 long consumed = NeAACDecInit(hAac, data, len, &samplerate, &channels);
154 if (consumed < 0) {
155 LOGE("NeAACDecInit");
156 return false;
157 }
158 // skip any data before the first frame
159 if (consumed > 0) {
160 input_buffer.clearArray(consumed);
161 }
162 info.sample_rate = samplerate;
163 info.channels = channels;
164 is_init = true;
165 return true;
166 }
167
168 void decode(int minBufferSize) {
169 TRACED();
170 if (hAac == nullptr) return;
171 NeAACDecFrameInfo hInfo;
172
173 // decode until we do not consume any bytes
174 while (input_buffer.available() > minBufferSize) {
176 // drop the data so that we can retry with the next bytes
178 continue;
179 }
180
181 int eff_len = input_buffer.available();
182 if (eff_len <= 0) break;
183 uint8_t *sample_buffer = (uint8_t *)NeAACDecDecode(
184 hAac, &hInfo, input_buffer.data(), eff_len);
185
186 LOGD("bytesconsumed: %d of %d", (int)hInfo.bytesconsumed, eff_len);
187 if (hInfo.error != 0) {
188 LOGW("Decoding error: %s", NeAACDecGetErrorMessage(hInfo.error));
189 }
190
191 if (hInfo.bytesconsumed == 0) {
192 break;
193 }
194
195 // removed consumed data
196 input_buffer.clearArray(hInfo.bytesconsumed);
197
198 if (hInfo.error != 0 || sample_buffer == nullptr || hInfo.samples == 0) {
199 continue;
200 }
201
202 // check for changes in config
203 AudioInfo tmp{(sample_rate_t)hInfo.samplerate, hInfo.channels, 16};
204 if (tmp != info) {
205 setAudioInfo(tmp);
206 }
207
208 size_t bytes = hInfo.samples * sizeof(int16_t);
209 size_t len = p_print->write(sample_buffer, bytes);
210 if (len != bytes) {
211 TRACEE();
212 }
213 }
214 }
215};
216
217} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define TRACEE()
Definition AudioLoggerIDF.h:34
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define FAAD2_INPUT_BUFFER_SIZE
Definition CodecAACFAAD2.h:28
#define FAAD2_UNDERFLOW_LIMIT
Definition CodecAACFAAD2.h:33
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
AAC Decoder (LC, HE-AAC, MAIN, LTP) using faad2: https://github.com/pschatzmann/codec-faad2 Supports ...
Definition CodecAACFAAD2.h:48
NeAACDecConfigurationPtr conf
Definition CodecAACFAAD2.h:144
void end() override
Releases the reserved memory.
Definition CodecAACFAAD2.h:96
int underflow_limit
Definition CodecAACFAAD2.h:142
size_t write(const uint8_t *data, size_t len) override
Write AAC data to decoder.
Definition CodecAACFAAD2.h:106
NeAACDecHandle driver()
Provides access to the faad2 decoder handle.
Definition CodecAACFAAD2.h:135
bool is_init
Definition CodecAACFAAD2.h:146
~AACDecoderFAAD2()
Definition CodecAACFAAD2.h:56
void decode(int minBufferSize)
Definition CodecAACFAAD2.h:168
void setUnderflowLimit(int len)
Defines the min number of bytes that are submitted to the decoder.
Definition CodecAACFAAD2.h:132
const char * mime() override
Provides the mime type of the data that is expected by this decoder.
Definition CodecAACFAAD2.h:58
bool init(uint8_t *data, size_t len)
Definition CodecAACFAAD2.h:148
AACDecoderFAAD2()
Definition CodecAACFAAD2.h:50
void setInputBufferSize(int len)
Defines the input buffer size.
Definition CodecAACFAAD2.h:129
int buffer_size_input
Definition CodecAACFAAD2.h:141
NeAACDecHandle hAac
Definition CodecAACFAAD2.h:143
bool begin() override
Starts the processing.
Definition CodecAACFAAD2.h:61
SingleBuffer< uint8_t > input_buffer
Definition CodecAACFAAD2.h:145
void flush()
Decodes all remaining data in the input buffer.
Definition CodecAACFAAD2.h:126
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:19
AudioInfo info
Definition AudioCodecsBase.h:80
void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition AudioCodecsBase.h:32
Print * p_print
Definition AudioCodecsBase.h:79
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:194
size_t size() override
Definition Buffers.h:325
int available() override
provides the number of entries that are available to read
Definition Buffers.h:255
int availableForWrite() override
provides the number of entries that are available to write
Definition Buffers.h:260
int writeArray(const T data[], int len) override
Fills the buffer data.
Definition Buffers.h:223
T * data()
Provides address of actual data.
Definition Buffers.h:306
bool resize(size_t size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:327
void reset() override
clears the buffer
Definition Buffers.h:308
int clearArray(int len) override
consumes len bytes and moves current data to the beginning
Definition Buffers.h:274
uint32_t sample_rate_t
Type alias for sample rate values.
Definition AudioTypes.h:19
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:56
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:58
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:60
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:62