arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
CodecILBC.h
Go to the documentation of this file.
1
11#pragma once
12
13#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
14#include "iLBC.h"
15
16
17namespace audio_tools {
18
27class ILBCDecoder : public AudioDecoder {
28 public:
29 ILBCDecoder(EnumLBCFrameSize frameSize = ms30, bool useEnhancer = true) {
30 info.sample_rate = 8000;
31 info.channels = 1;
32 info.bits_per_sample = 16;
33 frame_size = frameSize;
34 use_enhancer = useEnhancer;
35 }
36
38 end();
39 }
40
41 virtual bool begin() {
42 TRACEI();
43 if (p_print==nullptr){
44 LOGE("Output not defined");
45 return false;
46 }
47
48 if (p_ilbc==nullptr){
49 p_ilbc = new iLBCDecode(frame_size, use_enhancer);
50 }
51
52 // setup buffer
53 decoded_buffer.resize(p_ilbc->getSamples());
54 encoded_buffer.resize(p_ilbc->getEncodedBytes());
55
56 // update audio information
57 notifyAudioChange(info);
58 return true;
59 }
60
61 virtual void end() {
62 TRACEI();
63 delete p_ilbc;
64 p_ilbc = nullptr;
65 }
66
67 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
68
69 operator bool() { return p_ilbc != nullptr; }
70
71 virtual size_t write(const uint8_t *data, size_t len) {
72 if (p_ilbc==nullptr) return 0;
73 LOGI("write: %d", len);
74 int samples = len / sizeof(int16_t);
75 int16_t *p_samples = (int16_t *)data;
76 for (int j=0;j<samples;j++){
77 encoded_buffer[encoded_buffer_pos++]=p_samples[j];
78 if (encoded_buffer_pos>=encoded_buffer.size()){
79 memset(decoded_buffer.data(),0,decoded_buffer.size()*sizeof(int16_t));
80 p_ilbc->decode(encoded_buffer.data(), decoded_buffer.data());
81 if (p_print!=nullptr){
82 p_print->write((uint8_t*)decoded_buffer.data(), decoded_buffer.size()*sizeof(int16_t));
83 delay(2);
84 }
85 encoded_buffer_pos = 0;
86 }
87 }
88 return len;
89 }
90
91 protected:
92 Print *p_print = nullptr;
93 iLBCDecode *p_ilbc = nullptr;
94 Vector<int16_t> decoded_buffer{0};
95 Vector<uint8_t> encoded_buffer{0};
96 int16_t encoded_buffer_pos = 0;
97 EnumLBCFrameSize frame_size;
98 bool use_enhancer;
99
100};
101
110class ILBCEncoder : public AudioEncoder {
111 public:
112 ILBCEncoder(EnumLBCFrameSize frameSize = ms30) {
113 info.sample_rate = 8000;
114 info.channels = 1;
115 info.bits_per_sample = 16;
116 frame_size = frameSize;
117 }
118
119 ~ILBCEncoder(){
120 end();
121 }
122
123 bool begin() {
124 TRACEI();
125 if (p_print==nullptr){
126 LOGE("Output not defined");
127 return false;
128 }
129 if (info.bits_per_sample!=16){
130 LOGE("bits_per_sample must be 16: %d",info.bits_per_sample);
131 return false;
132 }
133 if (info.sample_rate!=8000){
134 LOGW("The sample rate should be 8000: %d", info.sample_rate);
135 }
136 if (info.channels!=1){
137 LOGW("channels should be 1: %d", info.channels);
138 }
139 if (p_ilbc==nullptr){
140 p_ilbc = new iLBCEncode(frame_size);
141 }
142 decoded_buffer.resize(p_ilbc->getSamples());
143 encoded_buffer.resize(p_ilbc->getEncodedBytes());
144 decoded_buffer_pos = 0;
145 return true;
146 }
147
148 virtual void end() {
149 TRACEI();
150 if (p_ilbc != nullptr) {
151 delete p_ilbc;
152 p_ilbc = nullptr;
153 }
154 }
155
156 virtual const char *mime() { return "audio/ilbc"; }
157
158 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
159
160 operator bool() { return p_ilbc != nullptr; }
161
162 virtual size_t write(const uint8_t *data, size_t len) {
163 if (p_ilbc==nullptr) return 0;
164 LOGI("write: %d", len);
165
166 int samples = len / sizeof(int16_t);
167 int16_t *p_samples = (int16_t *)data;
168
169 for (int j=0;j<samples;j++){
170 decoded_buffer[decoded_buffer_pos++]=p_samples[j];
171 if (decoded_buffer_pos>=decoded_buffer.size()){
172 memset(encoded_buffer.data(),0,encoded_buffer.size());
173 p_ilbc->encode(decoded_buffer.data(), encoded_buffer.data());
174 if (p_print!=nullptr){
175 p_print->write(encoded_buffer.data(), encoded_buffer.size());
176 }
177 decoded_buffer_pos = 0;
178 }
179 }
180 return len;
181 }
182
183 protected:
184 Print *p_print = nullptr;
185 iLBCEncode *p_ilbc = nullptr;
186 Vector<float> decoded_buffer{0};
187 Vector<uint8_t> encoded_buffer{0};
188 int16_t decoded_buffer_pos = 0;
189 EnumLBCFrameSize frame_size;
190};
191
192} // namespace audio_tools
Docoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:18
Encoding of PCM data.
Definition AudioCodecsBase.h:90
Decoder for iLBC. Depends on https://github.com/pschatzmann/libilbc.
Definition CodecILBC.h:27
virtual void setOutput(Print &out_stream)
Defines where the decoded result is written to.
Definition CodecILBC.h:67
Encoder for iLBC - Depends on https://github.com/pschatzmann/libopenilbc.
Definition CodecILBC.h:110
virtual const char * mime()
Provides the mime type of the encoded result.
Definition CodecILBC.h:156
Definition NoArduino.h:62
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioConfig.h:885
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