arduino-audio-tools
Loading...
Searching...
No Matches
CodecAACFAAD.h
Go to the documentation of this file.
1#pragma once
2
3// #include "Stream.h"
5#include "faad.h"
6
7// faad'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) that are not used outside of this header but leak globally and
10// clash with identifiers (e.g. VideoFormat::RAW in ContainerAVI.h) in other
11// audio-tools headers when both are included in the same sketch.
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
26#ifndef FAAD_INPUT_BUFFER_SIZE
27#define FAAD_INPUT_BUFFER_SIZE 1024*2
28#endif
29
30// to prevent Decoding error: Maximum number of bitstream elements exceeded
31#ifndef FAAD_UNDERFLOW_LIMIT
32#define FAAD_UNDERFLOW_LIMIT 500
33#endif
34
35
36namespace audio_tools {
37
48 public:
50 info.channels = 2;
51 info.sample_rate = 44100;
53 };
54
56
57 const char *mime() override { return "audio/aac"; }
58
60 bool begin() {
61 TRACED();
62
63 unsigned long cap = NeAACDecGetCapabilities();
64 // Check if decoder has the needed capabilities
65
66 if (!cap & FIXED_POINT_CAP) {
67 LOGE("Fixed Point");
68 return false;
69 }
70
71 // Open the library
72 hAac = NeAACDecOpen();
73
74 // // Get the current config
75 conf = NeAACDecGetCurrentConfiguration(hAac);
76
77 // // If needed change some of the values in conf
78 conf->outputFormat = FAAD_FMT_16BIT;
79 //conf->defObjectType = LC;
80 conf->defSampleRate = info.sample_rate;
81 conf->downMatrix = true; // 5.1 channel downmatrixed to 2 channel
82 conf->useOldADTSFormat = false;
83 conf->dontUpSampleImplicitSBR = false;
84
85 // Set the new configuration
86 if (!NeAACDecSetConfiguration(hAac, conf)) {
87 LOGE("NeAACDecSetConfiguration");
88 return false;
89 }
90
91 // setup input buffer
94 }
95 is_init = false;
96 return true;
97 }
98
100 virtual void end() {
101 TRACED();
102 flush();
103 if (hAac != nullptr) {
104 NeAACDecClose(hAac);
105 hAac = nullptr;
106 }
107 }
108
110 size_t write(const uint8_t *data, size_t len) {
111 // Write supplied data to input buffer
112 size_t result = input_buffer.writeArray((uint8_t *)data, len);
113 // Decode from input buffer
115
116 return result;
117 }
118
119 void flush() {
120 decode(0);
121 }
122
124 void setInputBufferSize(int len){
125 buffer_size_input = len;
126 }
127
129 void setUnderflowLimit(int len){
130 underflow_limit = len;
131 }
132
134 virtual operator bool() { return hAac != nullptr; }
135
136 protected:
139 NeAACDecHandle hAac = nullptr;
140 NeAACDecConfigurationPtr conf;
142 bool is_init = false;
143
144 void init(uint8_t *data, size_t len) {
145 TRACEI();
146 // Initialise the library using one of the initialization functions
147 unsigned long samplerate = info.sample_rate;
148 unsigned char channels = info.channels;
149
150 if (NeAACDecInit(hAac, data, len, &samplerate, &channels)==-1) {
151 LOGE("NeAACDecInit");
152 }
153 info.sample_rate = samplerate;
154 info.channels = channels;
155 is_init = true;
156 }
157
158 void decode(int minBufferSize) {
159 TRACED();
160 NeAACDecFrameInfo hInfo;
161
162 // decode until we do not conume any bytes
163 while (input_buffer.available()>minBufferSize) {
164 int eff_len = input_buffer.available();
165
166 if (!is_init) {
167 init(input_buffer.data(), eff_len);
168 }
169
170 uint8_t *sample_buffer=(uint8_t *)NeAACDecDecode(hAac, &hInfo, input_buffer.address(), eff_len);
171
172 LOGD("bytesconsumed: %d of %d", (int)hInfo.bytesconsumed, (int)eff_len);
173 if (hInfo.error != 0) {
174 LOGW("Decoding error: %s", NeAACDecGetErrorMessage(hInfo.error));
175 }
176
177 if (hInfo.bytesconsumed == 0 ) {
178 break;
179 }
180
181 LOGD("Decoded %lu samples", hInfo.samples);
182 LOGD(" bytesconsumed: %lu", hInfo.bytesconsumed);
183 LOGD(" channels: %d", hInfo.channels);
184 LOGD(" samplerate: %lu", hInfo.samplerate);
185 LOGD(" sbr: %u", hInfo.sbr);
186 LOGD(" object_type: %u", hInfo.object_type);
187 LOGD(" header_type: %u", hInfo.header_type);
188 LOGD(" num_front_channels: %u", hInfo.num_front_channels);
189 LOGD(" num_side_channels: %u", hInfo.num_side_channels);
190 LOGD(" num_back_channels: %u", hInfo.num_back_channels);
191 LOGD(" num_lfe_channels: %u", hInfo.num_lfe_channels);
192 LOGD(" ps: %u", hInfo.ps);
193
194 // removed consumed data
195 input_buffer.clearArray(hInfo.bytesconsumed);
196
197 // check for changes in config
198 AudioInfo tmp{(sample_rate_t)hInfo.samplerate, hInfo.channels, 16};
199 if (tmp != info) {
200 setAudioInfo(tmp);
201 }
202
203 int bytes = hInfo.samples * sizeof(int16_t);
204 size_t len = p_print->write(sample_buffer, bytes);
205 if (len != bytes) {
206 TRACEE();
207 }
208 }
209 }
210};
211
212} // 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 FAAD_UNDERFLOW_LIMIT
Definition CodecAACFAAD.h:32
#define FAAD_INPUT_BUFFER_SIZE
Definition CodecAACFAAD.h:27
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
AAC Decoder using faad: https://github.com/pschatzmann/codec-faad This needs a stack of around 60000 ...
Definition CodecAACFAAD.h:47
~AACDecoderFAAD()
Definition CodecAACFAAD.h:55
NeAACDecConfigurationPtr conf
Definition CodecAACFAAD.h:140
void init(uint8_t *data, size_t len)
Definition CodecAACFAAD.h:144
AACDecoderFAAD()
Definition CodecAACFAAD.h:49
bool begin()
Starts the processing.
Definition CodecAACFAAD.h:60
int underflow_limit
Definition CodecAACFAAD.h:138
bool is_init
Definition CodecAACFAAD.h:142
void decode(int minBufferSize)
Definition CodecAACFAAD.h:158
void setUnderflowLimit(int len)
Defines the min number of bytes that are submitted to the decoder.
Definition CodecAACFAAD.h:129
const char * mime() override
Provides the mime type of the data that is expected by this decoder.
Definition CodecAACFAAD.h:57
void setInputBufferSize(int len)
Defines the input buffer size.
Definition CodecAACFAAD.h:124
int buffer_size_input
Definition CodecAACFAAD.h:137
NeAACDecHandle hAac
Definition CodecAACFAAD.h:139
SingleBuffer< uint8_t > input_buffer
Definition CodecAACFAAD.h:141
void flush()
Definition CodecAACFAAD.h:119
virtual void end()
Releases the reserved memory.
Definition CodecAACFAAD.h:100
size_t write(const uint8_t *data, size_t len)
Write AAC data to decoder.
Definition CodecAACFAAD.h:110
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
T * address() override
Provides address to beginning of the buffer.
Definition Buffers.h:303
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
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