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#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;
34 };
35
37
38 const char *mime() override { return "audio/aac"; }
39
41 bool begin() {
42 TRACED();
43
44 unsigned long cap = NeAACDecGetCapabilities();
45 // Check if decoder has the needed capabilities
46
47 if (!cap & FIXED_POINT_CAP) {
48 LOGE("Fixed Point");
49 return false;
50 }
51
52 // Open the library
53 hAac = NeAACDecOpen();
54
55 // // Get the current config
56 conf = NeAACDecGetCurrentConfiguration(hAac);
57
58 // // If needed change some of the values in conf
59 conf->outputFormat = FAAD_FMT_16BIT;
60 //conf->defObjectType = LC;
61 conf->defSampleRate = info.sample_rate;
62 conf->downMatrix = true; // 5.1 channel downmatrixed to 2 channel
63 conf->useOldADTSFormat = false;
64 conf->dontUpSampleImplicitSBR = false;
65
66 // Set the new configuration
67 if (!NeAACDecSetConfiguration(hAac, conf)) {
68 LOGE("NeAACDecSetConfiguration");
69 return false;
70 }
71
72 // setup input buffer
75 }
76 is_init = false;
77 return true;
78 }
79
81 virtual void end() {
82 TRACED();
83 flush();
84 if (hAac != nullptr) {
85 NeAACDecClose(hAac);
86 hAac = nullptr;
87 }
88 }
89
91 size_t write(const uint8_t *data, size_t len) {
92 // Write supplied data to input buffer
93 size_t result = input_buffer.writeArray((uint8_t *)data, len);
94 // Decode from input buffer
96
97 return result;
98 }
99
100 void flush() {
101 decode(0);
102 }
103
105 void setInputBufferSize(int len){
106 buffer_size_input = len;
107 }
108
110 void setUnderflowLimit(int len){
111 underflow_limit = len;
112 }
113
115 virtual operator bool() { return hAac != nullptr; }
116
117 protected:
120 NeAACDecHandle hAac = nullptr;
121 NeAACDecConfigurationPtr conf;
123 bool is_init = false;
124
125 void init(uint8_t *data, size_t len) {
126 TRACEI();
127 // Initialise the library using one of the initialization functions
128 unsigned long samplerate = info.sample_rate;
129 unsigned char channels = info.channels;
130
131 if (NeAACDecInit(hAac, data, len, &samplerate, &channels)==-1) {
132 LOGE("NeAACDecInit");
133 }
134 info.sample_rate = samplerate;
135 info.channels = channels;
136 is_init = true;
137 }
138
139 void decode(int minBufferSize) {
140 TRACED();
141 NeAACDecFrameInfo hInfo;
142
143 // decode until we do not conume any bytes
144 while (input_buffer.available()>minBufferSize) {
145 int eff_len = input_buffer.available();
146
147 if (!is_init) {
148 init(input_buffer.data(), eff_len);
149 }
150
151 uint8_t *sample_buffer=(uint8_t *)NeAACDecDecode(hAac, &hInfo, input_buffer.address(), eff_len);
152
153 LOGD("bytesconsumed: %d of %d", (int)hInfo.bytesconsumed, (int)eff_len);
154 if (hInfo.error != 0) {
155 LOGW("Decoding error: %s", NeAACDecGetErrorMessage(hInfo.error));
156 }
157
158 if (hInfo.bytesconsumed == 0 ) {
159 break;
160 }
161
162 LOGD("Decoded %lu samples", hInfo.samples);
163 LOGD(" bytesconsumed: %lu", hInfo.bytesconsumed);
164 LOGD(" channels: %d", hInfo.channels);
165 LOGD(" samplerate: %lu", hInfo.samplerate);
166 LOGD(" sbr: %u", hInfo.sbr);
167 LOGD(" object_type: %u", hInfo.object_type);
168 LOGD(" header_type: %u", hInfo.header_type);
169 LOGD(" num_front_channels: %u", hInfo.num_front_channels);
170 LOGD(" num_side_channels: %u", hInfo.num_side_channels);
171 LOGD(" num_back_channels: %u", hInfo.num_back_channels);
172 LOGD(" num_lfe_channels: %u", hInfo.num_lfe_channels);
173 LOGD(" ps: %u", hInfo.ps);
174
175 // removed consumed data
176 input_buffer.clearArray(hInfo.bytesconsumed);
177
178 // check for changes in config
179 AudioInfo tmp{(sample_rate_t)hInfo.samplerate, hInfo.channels, 16};
180 if (tmp != info) {
181 setAudioInfo(tmp);
182 }
183
184 int bytes = hInfo.samples * sizeof(int16_t);
185 size_t len = p_print->write(sample_buffer, bytes);
186 if (len != bytes) {
187 TRACEE();
188 }
189 }
190 }
191};
192
193} // 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:13
#define FAAD_INPUT_BUFFER_SIZE
Definition CodecAACFAAD.h:8
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
AAC Decoder using faad: https://github.com/pschatzmann/arduino-libfaad This needs a stack of around 6...
Definition CodecAACFAAD.h:28
~AACDecoderFAAD()
Definition CodecAACFAAD.h:36
NeAACDecConfigurationPtr conf
Definition CodecAACFAAD.h:121
void init(uint8_t *data, size_t len)
Definition CodecAACFAAD.h:125
AACDecoderFAAD()
Definition CodecAACFAAD.h:30
bool begin()
Starts the processing.
Definition CodecAACFAAD.h:41
int underflow_limit
Definition CodecAACFAAD.h:119
bool is_init
Definition CodecAACFAAD.h:123
void decode(int minBufferSize)
Definition CodecAACFAAD.h:139
void setUnderflowLimit(int len)
Defines the min number of bytes that are submitted to the decoder.
Definition CodecAACFAAD.h:110
const char * mime() override
Provides the mime type of the data that is expected by this decoder.
Definition CodecAACFAAD.h:38
void setInputBufferSize(int len)
Defines the input buffer size.
Definition CodecAACFAAD.h:105
int buffer_size_input
Definition CodecAACFAAD.h:118
NeAACDecHandle hAac
Definition CodecAACFAAD.h:120
SingleBuffer< uint8_t > input_buffer
Definition CodecAACFAAD.h:122
void flush()
Definition CodecAACFAAD.h:100
virtual void end()
Releases the reserved memory.
Definition CodecAACFAAD.h:81
size_t write(const uint8_t *data, size_t len)
Write AAC data to decoder.
Definition CodecAACFAAD.h:91
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:189
size_t size() override
Definition Buffers.h:320
int available() override
provides the number of entries that are available to read
Definition Buffers.h:250
T * address() override
Provides address to beginning of the buffer.
Definition Buffers.h:298
int writeArray(const T data[], int len) override
Fills the buffer data.
Definition Buffers.h:218
T * data()
Provides address of actual data.
Definition Buffers.h:301
bool resize(size_t size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:322
int clearArray(int len) override
consumes len bytes and moves current data to the beginning
Definition Buffers.h:269
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: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