arduino-audio-tools
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 
17 namespace audio_tools {
18 
28 class AACDecoderFAAD : public AudioDecoder {
29  public:
30  AACDecoderFAAD() {
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 = false;
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
Docoding of encoded audio into PCM data.
Definition: AudioCodecsBase.h:16
virtual void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition: AudioCodecsBase.h:26
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition: Buffers.h:65
T * address() override
Provides address to beginning of the buffer.
Definition: Buffers.h:249
T * data()
Provides address of actual data.
Definition: Buffers.h:252
int available() override
provides the number of entries that are available to read
Definition: Buffers.h:219
int clearArray(int len) override
consumes len bytes and moves current data to the beginning
Definition: Buffers.h:229
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:823
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