4
4
#include " Print.h"
5
5
#include " opus.h"
6
6
7
- #ifndef OPUS_ENC_MAX_BUFFER_SIZE
7
+ #ifndef OPUS_ENC_MAX_BUFFER_SIZE
8
8
#define OPUS_ENC_MAX_BUFFER_SIZE 2048
9
9
#endif
10
10
11
11
#ifndef OPUS_DEC_MAX_BUFFER_SIZE
12
- #define OPUS_DEC_MAX_BUFFER_SIZE 4 * 1024
12
+ #define OPUS_DEC_MAX_BUFFER_SIZE 4 * 1024
13
13
#endif
14
14
15
-
16
15
namespace audio_tools {
17
16
18
17
/* *
@@ -31,7 +30,6 @@ struct OpusSettings : public AudioInfo {
31
30
}
32
31
int max_buffer_size = OPUS_DEC_MAX_BUFFER_SIZE;
33
32
int max_buffer_write_size = 512 ;
34
-
35
33
};
36
34
37
35
/* *
@@ -60,14 +58,16 @@ setting the value.
60
58
OPUS_SIGNAL_MUSIC};<br> int inband_fecs[3] = {0, 0, 1};<br> int
61
59
packet_loss_perc[4] = {0, 1, 2, 5};<br> int lsb_depths[2] = {8, 24};<br> int
62
60
prediction_disabled[3] = {0, 0, 1};<br> int use_dtx[2] = {0, 1};<br> int
63
- frame_sizes_ms_x2[9] = {OPUS_FRAMESIZE_2_5_MS,OPUS_FRAMESIZE_5_MS,OPUS_FRAMESIZE_10_MS,OPUS_FRAMESIZE_20_MS,OPUS_FRAMESIZE_40_MS,OPUS_FRAMESIZE_60_MS,OPUS_FRAMESIZE_80_MS,OPUS_FRAMESIZE_100_MS,OPUS_FRAMESIZE_120_MS} x2 to avoid 2.5 ms <br>
61
+ frame_sizes_ms_x2[9] =
62
+ {OPUS_FRAMESIZE_2_5_MS,OPUS_FRAMESIZE_5_MS,OPUS_FRAMESIZE_10_MS,OPUS_FRAMESIZE_20_MS,OPUS_FRAMESIZE_40_MS,OPUS_FRAMESIZE_60_MS,OPUS_FRAMESIZE_80_MS,OPUS_FRAMESIZE_100_MS,OPUS_FRAMESIZE_120_MS}
63
+ x2 to avoid 2.5 ms <br>
64
64
* @author Phil Schatzmann
65
65
* @copyright GPLv3
66
66
**/
67
67
68
68
struct OpusEncoderSettings : public OpusSettings {
69
69
OpusEncoderSettings () : OpusSettings() {
70
- // / Default is 5760
70
+ // / Default is 5760
71
71
max_buffer_size = OPUS_ENC_MAX_BUFFER_SIZE;
72
72
}
73
73
// / OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_VOIP,
@@ -106,7 +106,13 @@ struct OpusEncoderSettings : public OpusSettings {
106
106
};
107
107
108
108
/* *
109
- * @brief OpusAudioDecoder: Depends on https://github.com/pschatzmann/arduino-libopus.git
109
+ * @brief Decoder for the Opus audio format.
110
+ * Each Opus frame must be provided with one write() call. Therefore, Opus
111
+ * is usually encapsulated in a container format (e.g., Ogg) that splits
112
+ * the stream into frames.
113
+ *
114
+ * Depends on https://github.com/pschatzmann/arduino-libopus.git
115
+ *
110
116
* @author Phil Schatzmann
111
117
* @ingroup codecs
112
118
* @ingroup decoder
@@ -148,22 +154,21 @@ class OpusAudioDecoder : public AudioDecoder {
148
154
149
155
bool begin () override {
150
156
TRACED ();
151
- if (!isValidRate (cfg.sample_rate )){
157
+ if (!isValidRate (cfg.sample_rate )) {
152
158
LOGE (" Sample rate not supported: %d" , cfg.sample_rate );
153
159
return false ;
154
160
}
155
161
outbuf.resize (cfg.max_buffer_size );
156
162
assert (outbuf.data () != nullptr );
157
-
163
+
158
164
// int err;
159
165
// dec = opus_decoder_create(cfg.sample_rate, cfg.channels, &err);
160
-
166
+
161
167
size_t size = opus_decoder_get_size (cfg.channels );
162
168
decbuf.resize (size);
163
169
assert (decbuf.data () != nullptr );
164
- dec = (OpusDecoder*)decbuf.data ();
170
+ dec = (OpusDecoder *)decbuf.data ();
165
171
int err = opus_decoder_init (dec, cfg.sample_rate , cfg.channels );
166
-
167
172
168
173
if (err != OPUS_OK) {
169
174
LOGE (" opus_decoder_create: %s for sample_rate: %d, channels:%d" ,
@@ -190,15 +195,16 @@ class OpusAudioDecoder : public AudioDecoder {
190
195
cfg.bits_per_sample = from.bits_per_sample ;
191
196
}
192
197
198
+ // / write one full opus frame
193
199
size_t write (const uint8_t *data, size_t len) override {
194
200
if (!active || p_print == nullptr ) return 0 ;
195
201
// decode data
196
202
LOGD (" OpusAudioDecoder::write: %d" , (int )len);
197
203
int in_band_forward_error_correction = 0 ;
198
204
int frame_count = cfg.max_buffer_size / cfg.channels / sizeof (opus_int16);
199
- int out_samples = opus_decode (
200
- dec, (uint8_t *)data, len, (opus_int16 *)outbuf.data (),
201
- frame_count, in_band_forward_error_correction);
205
+ int out_samples =
206
+ opus_decode ( dec, (uint8_t *)data, len, (opus_int16 *)outbuf.data (),
207
+ frame_count, in_band_forward_error_correction);
202
208
if (out_samples < 0 ) {
203
209
LOGW (" opus-decode: %s" , opus_strerror (out_samples));
204
210
} else if (out_samples > 0 ) {
@@ -207,9 +213,9 @@ class OpusAudioDecoder : public AudioDecoder {
207
213
LOGD (" opus-decode: %d" , out_bytes);
208
214
int open = out_bytes;
209
215
int processed = 0 ;
210
- while (open> 0 ) {
216
+ while (open > 0 ) {
211
217
int to_write = std::min (open, cfg.max_buffer_write_size );
212
- int written = p_print->write (outbuf.data ()+ processed, to_write);
218
+ int written = p_print->write (outbuf.data () + processed, to_write);
213
219
open -= written;
214
220
processed += written;
215
221
}
@@ -226,18 +232,21 @@ class OpusAudioDecoder : public AudioDecoder {
226
232
bool active = false ;
227
233
Vector<uint8_t > outbuf{0 };
228
234
Vector<uint8_t > decbuf{0 };
229
- const uint32_t valid_rates[5 ] = {8000 , 12000 , 16000 , 24000 , 48000 };
235
+ const uint32_t valid_rates[5 ] = {8000 , 12000 , 16000 , 24000 , 48000 };
230
236
231
- bool isValidRate (int rate){
232
- for (auto &valid : valid_rates){
233
- if (valid== rate) return true ;
237
+ bool isValidRate (int rate) {
238
+ for (auto &valid : valid_rates) {
239
+ if (valid == rate) return true ;
234
240
}
235
241
return false ;
236
242
}
237
243
};
238
244
239
245
/* *
240
- * @brief OpusAudioEncoder: Dependens on https://github.com/pschatzmann/arduino-libopus.git
246
+ * @brief Encode for Opus audio.
247
+ *
248
+ * Depends on https://github.com/pschatzmann/arduino-libopus.git
249
+ * Please note that each fully encoded frame is written to the output stream.
241
250
* @ingroup codecs
242
251
* @ingroup encoder
243
252
* @author Phil Schatzmann
@@ -271,7 +280,8 @@ class OpusAudioEncoder : public AudioEncoder {
271
280
int size = getFrameSizeSamples (cfg.sample_rate ) * 2 ;
272
281
frame.resize (size);
273
282
assert (frame.data () != nullptr );
274
- enc = opus_encoder_create (cfg.sample_rate , cfg.channels , cfg.application , &err);
283
+ enc = opus_encoder_create (cfg.sample_rate , cfg.channels , cfg.application ,
284
+ &err);
275
285
if (err != OPUS_OK) {
276
286
LOGE (" opus_encoder_create: %s for sample_rate: %d, channels:%d" ,
277
287
opus_strerror (err), cfg.sample_rate , cfg.channels );
@@ -338,19 +348,20 @@ class OpusAudioEncoder : public AudioEncoder {
338
348
void encodeFrame () {
339
349
if (frame.size () > 0 ) {
340
350
// allocate temp buffer on stack
341
- int packet_len = OPUS_ENC_MAX_BUFFER_SIZE > 0 ? OPUS_ENC_MAX_BUFFER_SIZE : 512 ;
351
+ int packet_len =
352
+ OPUS_ENC_MAX_BUFFER_SIZE > 0 ? OPUS_ENC_MAX_BUFFER_SIZE : 512 ;
342
353
uint8_t packet[packet_len];
343
354
344
355
int frames = frame.size () / cfg.channels / sizeof (int16_t );
345
356
LOGD (" opus_encode - frame_size: %d" , frames);
346
- int len = opus_encode (enc, (opus_int16 *)frame.data (), frames,
347
- packet, packet_len);
357
+ int len = opus_encode (enc, (opus_int16 *)frame.data (), frames, packet,
358
+ packet_len);
348
359
if (len < 0 ) {
349
360
LOGE (" opus_encode: %s" , opus_strerror (len));
350
361
} else if (len > 0 ) {
351
362
LOGD (" opus-encode: %d" , len);
352
363
int eff = p_print->write (packet, len);
353
- if (eff!= len){
364
+ if (eff != len) {
354
365
LOGE (" encodeFrame data lost: %d->%d" , len, eff);
355
366
}
356
367
}
0 commit comments