arduino-audio-tools
Loading...
Searching...
No Matches
CodecGSM.h
Go to the documentation of this file.
1
9#pragma once
10
12#include "gsm.h"
13
14
15namespace audio_tools {
16
26class GSMDecoder : public AudioDecoder {
27 public:
29 info.sample_rate = 8000;
30 info.channels = 1;
31 }
32
33 virtual const char *mime() override { return "audio/gsm"; }
34
35 virtual bool begin() {
36 TRACEI();
37 // 160 13-bit samples
38 result_buffer.resize(160 * sizeof(int16_t));
39 // gsm_frame of 33 bytes
41
42 v_gsm = gsm_create();
44 is_active = true;
45 return true;
46 }
47
48 virtual void end() {
49 TRACEI();
50 gsm_destroy(v_gsm);
51 is_active = false;
52 }
53
54 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
55
56 operator bool() { return is_active; }
57
58 virtual size_t write(const uint8_t *data, size_t len) {
59 LOGD("write: %d", len);
60 if (!is_active) {
61 LOGE("inactive");
62 return 0;
63 }
64
65 for (int j = 0; j < len; j++) {
66 processByte(data[j]);
67 }
68
69 return len;
70 }
71
72 protected:
73 Print *p_print = nullptr;
74 gsm v_gsm;
75 bool is_active = false;
78 int input_pos = 0;
79
81 void processByte(uint8_t byte) {
82 // add byte to buffer
83 input_buffer[input_pos++] = byte;
84
85 // decode if buffer is full
86 if (input_pos >= input_buffer.size()) {
87 if (gsm_decode(v_gsm, input_buffer.data(), (gsm_signal*)result_buffer.data())!=0){
88 LOGE("gsm_decode");
89 }
90
91 //fromBigEndian(result_buffer);
92 // scale to 13 to 16-bit samples
94
96 input_pos = 0;
97 }
98 }
99
100 void scale(Vector<uint8_t> &vector){
101 int16_t *pt16 = (int16_t *)vector.data();
102 for (int j = 0; j < vector.size() / 2; j++) {
103 if (abs(pt16[j])<=4095){
104 pt16[j] = pt16[j] * 8;
105 } else if(pt16[j]<0){
106 pt16[j] = -32767;
107 } else if(pt16[j]>0){
108 pt16[j] = 32767;
109 }
110 }
111 }
112
114 int size = vector.size() / 2;
115 int16_t *data16 = (int16_t*) vector.data();
116 for (int i=0; i<size; i++){
117 data16[i] = ntohs(data16[i]);
118 }
119 }
120
121
122};
123
133class GSMEncoder : public AudioEncoder {
134 public:
135 GSMEncoder(bool scaling=true) {
136 info.sample_rate = 8000;
137 info.channels = 1;
138 scaling_active = scaling;
139 }
140
141 bool begin() {
142 TRACEI();
143
144 if (info.sample_rate != 8000) {
145 LOGW("Sample rate is supposed to be 8000 - it was %d", info.sample_rate);
146 }
147 if (info.channels != 1) {
148 LOGW("channels is supposed to be 1 - it was %d", info.channels);
149 }
150
151 v_gsm = gsm_create();
152 // 160 13-bit samples
153 input_buffer.resize(160 * sizeof(int16_t));
154 // gsm_frame of 33 bytes
156 is_active = true;
157 return true;
158 }
159
160 virtual void end() {
161 TRACEI();
162 gsm_destroy(v_gsm);
163 is_active = false;
164 }
165
166 virtual const char *mime() { return "audio/gsm"; }
167
168 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
169
170 operator bool() { return is_active; }
171
172 virtual size_t write(const uint8_t *data, size_t len) {
173 LOGD("write: %d", len);
174 if (!is_active) {
175 LOGE("inactive");
176 return 0;
177 }
178 // encode bytes
179 for (int j = 0; j < len; j++) {
180 processByte(data[j]);
181 }
182 return len;
183 }
184
185 protected:
186 Print *p_print = nullptr;
187 gsm v_gsm;
188 bool is_active = false;
189 int buffer_pos = 0;
193
194 // add byte to decoding buffer and decode if buffer is full
195 void processByte(uint8_t byte) {
196 input_buffer[buffer_pos++] = byte;
197 if (buffer_pos >= input_buffer.size()) {
199 // toBigEndian(input_buffer);
200 // encode
201 gsm_encode(v_gsm, (gsm_signal*)input_buffer.data(), result_buffer.data());
202 size_t written = p_print->write(result_buffer.data(), result_buffer.size());
203 assert(written == result_buffer.size());
204 buffer_pos = 0;
205 }
206 }
207
209 int size = vector.size() / 2;
210 int16_t *data16 = (int16_t*) vector.data();
211 for (int i=0; i<size; i++){
212 data16[i] = htons(data16[i]);
213 }
214 }
215
217 int16_t *pt16 = (int16_t *)vector.data();
218 int size = vector.size() / 2;
219 if (scaling_active){
220 // scale to 16 to 13-bit samples
221 for (int j = 0; j < size; j++) {
222 pt16[j] = pt16[j] / 8;
223 }
224 } else {
225 // clip value to 13-bits
226 for (int j = 0; j < size; j++) {
227 if ( pt16[j]>4095){
228 pt16[j] = 4095;
229 }
230 if ( pt16[j]<-4095){
231 pt16[j] = -4095;
232 }
233 }
234 }
235 }
236};
237
238} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define htons(x)
Definition Net.h:15
#define ntohs(x)
Definition Net.h:17
#define assert(T)
Definition avr.h:10
Definition Arduino.h:56
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:19
AudioInfo info
Definition AudioCodecsBase.h:80
Encoding of PCM data.
Definition AudioCodecsBase.h:101
AudioInfo info
Definition AudioCodecsBase.h:120
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:175
Decoder for GSM. Depends on https://github.com/pschatzmann/arduino-libgsm. Inspired by gsmdec....
Definition CodecGSM.h:26
int input_pos
Definition CodecGSM.h:78
void fromBigEndian(Vector< uint8_t > &vector)
Definition CodecGSM.h:113
virtual void setOutput(Print &out_stream)
Defines where the decoded result is written to.
Definition CodecGSM.h:54
bool is_active
Definition CodecGSM.h:75
Vector< uint8_t > result_buffer
Definition CodecGSM.h:77
virtual bool begin()
Definition CodecGSM.h:35
GSMDecoder()
Definition CodecGSM.h:28
virtual const char * mime() override
Provides the mime type of the data that is expected by this decoder.
Definition CodecGSM.h:33
virtual size_t write(const uint8_t *data, size_t len)
Definition CodecGSM.h:58
void processByte(uint8_t byte)
Build decoding buffer and decode when frame is full.
Definition CodecGSM.h:81
void scale(Vector< uint8_t > &vector)
Definition CodecGSM.h:100
Print * p_print
Definition CodecGSM.h:73
virtual void end()
Definition CodecGSM.h:48
Vector< uint8_t > input_buffer
Definition CodecGSM.h:76
gsm v_gsm
Definition CodecGSM.h:74
Encoder for GSM - Depends on https://github.com/pschatzmann/arduino-libgsm. Inspired by gsmenc....
Definition CodecGSM.h:133
GSMEncoder(bool scaling=true)
Definition CodecGSM.h:135
virtual void setOutput(Print &out_stream)
Default output assignment (encoders may override to store Print reference)
Definition CodecGSM.h:168
bool is_active
Definition CodecGSM.h:188
Vector< uint8_t > result_buffer
Definition CodecGSM.h:192
bool begin()
Definition CodecGSM.h:141
virtual const char * mime()
Provides the mime type of the encoded result.
Definition CodecGSM.h:166
void scaleValues(Vector< uint8_t > &vector)
Definition CodecGSM.h:216
int buffer_pos
Definition CodecGSM.h:189
virtual size_t write(const uint8_t *data, size_t len)
Definition CodecGSM.h:172
void processByte(uint8_t byte)
Definition CodecGSM.h:195
bool scaling_active
Definition CodecGSM.h:190
Print * p_print
Definition CodecGSM.h:186
virtual void end()
Definition CodecGSM.h:160
Vector< uint8_t > input_buffer
Definition CodecGSM.h:191
void toBigEndian(Vector< uint8_t > &vector)
Definition CodecGSM.h:208
gsm v_gsm
Definition CodecGSM.h:187
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
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