arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
CodecAACFAAD.h
1#pragma once
2
3// #include "Stream.h"
4#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
5#include "faad.h"
6
7#ifndef FAAD_INPUT_BUFFER_SIZE
8#define FAAD_INPUT_BUFFER_SIZE 1024*2
9#endif
10
11// to prevent Decoding error: Maximum number of bitstream elements exceeded
12#ifndef FAAD_UNDERFLOW_LIMIT
13#define FAAD_UNDERFLOW_LIMIT 500
14#endif
15
16
17namespace audio_tools {
18
29 public:
31 info.channels = 2;
32 info.sample_rate = 44100;
33 info.bits_per_sample = 16;
34 };
35
36 ~AACDecoderFAAD() { end(); }
37
39 bool begin() {
40 TRACED();
41
42 unsigned long cap = NeAACDecGetCapabilities();
43 // Check if decoder has the needed capabilities
44
45 if (!cap & FIXED_POINT_CAP) {
46 LOGE("Fixed Point");
47 return false;
48 }
49
50 // Open the library
51 hAac = NeAACDecOpen();
52
53 // // Get the current config
54 conf = NeAACDecGetCurrentConfiguration(hAac);
55
56 // // If needed change some of the values in conf
57 conf->outputFormat = FAAD_FMT_16BIT;
58 //conf->defObjectType = LC;
59 conf->defSampleRate = info.sample_rate;
60 conf->downMatrix = true; // 5.1 channel downmatrixed to 2 channel
61 conf->useOldADTSFormat = false;
62 conf->dontUpSampleImplicitSBR = false;
63
64 // Set the new configuration
65 if (!NeAACDecSetConfiguration(hAac, conf)) {
66 LOGE("NeAACDecSetConfiguration");
67 return false;
68 }
69
70 // setup input buffer
71 if (input_buffer.size() != buffer_size_input){
72 input_buffer.resize(buffer_size_input);
73 }
74 is_init = false;
75 return true;
76 }
77
79 virtual void end() {
80 TRACED();
81 flush();
82 if (hAac != nullptr) {
83 NeAACDecClose(hAac);
84 hAac = nullptr;
85 }
86 }
87
89 size_t write(const uint8_t *data, size_t len) {
90 // Write supplied data to input buffer
91 size_t result = input_buffer.writeArray((uint8_t *)data, len);
92 // Decode from input buffer
93 decode(underflow_limit);
94
95 return result;
96 }
97
98 void flush() {
99 decode(0);
100 }
101
103 void setInputBufferSize(int len){
104 buffer_size_input = len;
105 }
106
108 void setUnderflowLimit(int len){
109 underflow_limit = len;
110 }
111
113 virtual operator bool() { return hAac != nullptr; }
114
115 protected:
116 int buffer_size_input = FAAD_INPUT_BUFFER_SIZE;
117 int underflow_limit = FAAD_UNDERFLOW_LIMIT;
118 NeAACDecHandle hAac = nullptr;
119 NeAACDecConfigurationPtr conf;
120 SingleBuffer<uint8_t> input_buffer{0};
121 bool is_init = false;
122
123 void init(uint8_t *data, size_t len) {
124 TRACEI();
125 // Initialise the library using one of the initialization functions
126 unsigned long samplerate = info.sample_rate;
127 unsigned char channels = info.channels;
128
129 if (NeAACDecInit(hAac, data, len, &samplerate, &channels)==-1) {
130 LOGE("NeAACDecInit");
131 }
132 info.sample_rate = samplerate;
133 info.channels = channels;
134 is_init = true;
135 }
136
137 void decode(int minBufferSize) {
138 TRACED();
139 NeAACDecFrameInfo hInfo;
140
141 // decode until we do not conume any bytes
142 while (input_buffer.available()>minBufferSize) {
143 int eff_len = input_buffer.available();
144
145 if (!is_init) {
146 init(input_buffer.data(), eff_len);
147 }
148
149 uint8_t *sample_buffer=(uint8_t *)NeAACDecDecode(hAac, &hInfo, input_buffer.address(), eff_len);
150
151 LOGD("bytesconsumed: %d of %d", (int)hInfo.bytesconsumed, (int)eff_len);
152 if (hInfo.error != 0) {
153 LOGW("Decoding error: %s", NeAACDecGetErrorMessage(hInfo.error));
154 }
155
156 if (hInfo.bytesconsumed == 0 ) {
157 break;
158 }
159
160 LOGD("Decoded %lu samples", hInfo.samples);
161 LOGD(" bytesconsumed: %lu", hInfo.bytesconsumed);
162 LOGD(" channels: %d", hInfo.channels);
163 LOGD(" samplerate: %lu", hInfo.samplerate);
164 LOGD(" sbr: %u", hInfo.sbr);
165 LOGD(" object_type: %u", hInfo.object_type);
166 LOGD(" header_type: %u", hInfo.header_type);
167 LOGD(" num_front_channels: %u", hInfo.num_front_channels);
168 LOGD(" num_side_channels: %u", hInfo.num_side_channels);
169 LOGD(" num_back_channels: %u", hInfo.num_back_channels);
170 LOGD(" num_lfe_channels: %u", hInfo.num_lfe_channels);
171 LOGD(" ps: %u", hInfo.ps);
172
173 // removed consumed data
174 input_buffer.clearArray(hInfo.bytesconsumed);
175
176 // check for changes in config
177 AudioInfo tmp{(sample_rate_t)hInfo.samplerate, hInfo.channels, 16};
178 if (tmp != info) {
179 setAudioInfo(tmp);
180 }
181
182 int bytes = hInfo.samples * sizeof(int16_t);
183 size_t len = p_print->write(sample_buffer, bytes);
184 if (len != bytes) {
185 TRACEE();
186 }
187 }
188 }
189};
190
191} // namespace audio_tools
AAC Decoder using faad: https://github.com/pschatzmann/arduino-libfaad This needs a stack of around 6...
Definition CodecAACFAAD.h:28
bool begin()
Starts the processing.
Definition CodecAACFAAD.h:39
void setUnderflowLimit(int len)
Defines the min number of bytes that are submitted to the decoder.
Definition CodecAACFAAD.h:108
void setInputBufferSize(int len)
Defines the input buffer size.
Definition CodecAACFAAD.h:103
virtual void end()
Releases the reserved memory.
Definition CodecAACFAAD.h:79
size_t write(const uint8_t *data, size_t len)
Write AAC data to decoder.
Definition CodecAACFAAD.h:89
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:18
void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition AudioCodecsBase.h:28
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition Buffers.h:59
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:175
int available() override
provides the number of entries that are available to read
Definition Buffers.h:227
T * address() override
Provides address to beginning of the buffer.
Definition Buffers.h:258
T * data()
Provides address of actual data.
Definition Buffers.h:261
int clearArray(int len) override
consumes len bytes and moves current data to the beginning
Definition Buffers.h:237
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:57
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:59