Skip to content

Commit b644345

Browse files
committed
opus ogg decoder
1 parent 1d9269f commit b644345

File tree

5 files changed

+73
-51
lines changed

5 files changed

+73
-51
lines changed

src/AudioCodecs/CodecOpusOgg.h

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,18 @@ struct __attribute__((packed)) OpusOggCommentHeader {
3333
*/
3434
class OpusOggDecoder : public OggContainerDecoder {
3535
public:
36-
OpusOggDecoder() = default;
37-
38-
/// Defines the output Stream
39-
void setOutputStream(Print &out_stream) override {
40-
LOGD(LOG_METHOD);
41-
dec.setOutputStream(out_stream);
42-
p_print = &opus;
43-
}
36+
OpusOggDecoder() {
37+
p_codec = &dec; // OpusAudioDecoder
38+
};
4439

4540
/// Provides access to the Opus configuration
4641
OpusSettings &config() { return dec.config(); }
4742

43+
void begin(OpusSettings settings) {
44+
OggContainerDecoder::begin();
45+
dec.begin(settings);
46+
}
47+
4848
void begin() override {
4949
LOGD(LOG_METHOD);
5050
OggContainerDecoder::begin();
@@ -60,7 +60,7 @@ class OpusOggDecoder : public OggContainerDecoder {
6060
protected:
6161
OpusOggHeader header;
6262
OpusAudioDecoder dec;
63-
EncodedAudioStream opus{(Print *)nullptr, &dec};
63+
//EncodedAudioStream opus{(Print *)nullptr, &dec};
6464

6565
virtual void beginOfSegment(ogg_packet *op) {
6666
LOGD("bos");
@@ -85,13 +85,17 @@ class OpusOggDecoder : public OggContainerDecoder {
8585
*/
8686
class OpusOggEncoder : public OggContainerEncoder {
8787
public:
88-
OpusOggEncoder() = default;
88+
OpusOggEncoder() {
89+
p_codec = &enc; // OpusAudioEncoder
90+
};
8991

90-
/// Defines the output Stream
91-
void setOutputStream(Print &out_stream) override {
92-
LOGD(LOG_METHOD);
93-
enc.setOutputStream(out_stream);
94-
p_print = &opus;
92+
/// Provides access to the configuration
93+
OpusEncoderSettings &config() { return enc.config(); }
94+
OpusEncoderSettings &defaultConfig() { return enc.config(); }
95+
96+
void begin(OpusEncoderSettings settings) {
97+
cfg = settings;
98+
begin();
9599
}
96100

97101
void begin() override {
@@ -109,14 +113,10 @@ class OpusOggEncoder : public OggContainerEncoder {
109113
/// Provides "audio/opus"
110114
const char *mime() override { return "audio/opus"; }
111115

112-
/// Provides access to the Opus configuration
113-
OpusEncoderSettings &config() { return enc.config(); }
114-
115116
protected:
116117
OpusOggHeader header;
117118
OpusOggCommentHeader comment;
118119
OpusAudioEncoder enc;
119-
EncodedAudioStream opus{(Print *)nullptr, &enc};
120120
ogg_packet oh1;
121121

122122
bool writeHeader() override {

src/AudioCodecs/ContainerOgg.h

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,9 @@ class OggContainerEncoder : public AudioEncoder {
219219
p_print = &out_stream;
220220
} else {
221221
EncodedAudioStream* eas = new EncodedAudioStream();
222-
eas->begin(&out_stream, p_codec);
223-
p_print = eas;
222+
eas->begin(&codec_buffer, p_codec);
223+
p_encoded_audio_stream = eas;
224+
p_print = &out_stream;
224225
}
225226
}
226227

@@ -239,6 +240,7 @@ class OggContainerEncoder : public AudioEncoder {
239240
virtual void begin() override {
240241
LOGD(LOG_METHOD);
241242
is_open = true;
243+
codec_buffer.begin();
242244
if (p_oggz == nullptr) {
243245
p_oggz = oggz_new(OGGZ_WRITE | OGGZ_NONSTRICT | OGGZ_AUTO);
244246
serialno = oggz_serialno_new(p_oggz);
@@ -269,22 +271,39 @@ class OggContainerEncoder : public AudioEncoder {
269271
p_oggz = nullptr;
270272
}
271273

272-
/// Writes Ogg Packet
274+
/// Writes raw data to be encoded and packaged
273275
virtual size_t write(const void *in_ptr, size_t in_size) override {
274276
if (!is_open || p_print == nullptr) return 0;
275277
LOGD("write: %d", (int) in_size);
276278

277-
op.packet = (uint8_t *)in_ptr;
278-
op.bytes = in_size;
279-
op.granulepos = granulepos +=
280-
in_size / sizeof(int16_t) / cfg.channels; // sample
281-
op.b_o_s = false;
282-
op.e_o_s = false;
283-
op.packetno = packetno++;
284-
if (!writePacket(op, OGGZ_FLUSH_AFTER)) {
285-
return 0;
286-
}
279+
if (p_codec!=nullptr){
280+
// encode the data
281+
size_t eff = p_encoded_audio_stream->write((uint8_t*)in_ptr, in_size);
282+
if (eff!=in_size){
283+
LOGE("Write overflow");
284+
}
285+
// get the result from the buffer
286+
void *encoded_data = buffer.address();
287+
int enoded_size = buffer.available();
287288

289+
op.packet = (uint8_t *)encoded_data;
290+
op.bytes = enoded_size;
291+
} else {
292+
op.packet = (uint8_t *)in_ptr;
293+
op.bytes = in_size;
294+
}
295+
if (op.bytes>0){
296+
buffer.reset();
297+
op.granulepos = granulepos +=
298+
in_size / sizeof(int16_t) / cfg.channels; // sample
299+
op.b_o_s = false;
300+
op.e_o_s = false;
301+
op.packetno = packetno++;
302+
is_audio = true;
303+
if (!writePacket(op, OGGZ_FLUSH_AFTER)) {
304+
return 0;
305+
}
306+
}
288307
// trigger pysical write
289308
while ((oggz_write(p_oggz, in_size)) > 0)
290309
;
@@ -297,8 +316,11 @@ class OggContainerEncoder : public AudioEncoder {
297316
bool isOpen() { return is_open; }
298317

299318
protected:
300-
AudioEncoder* p_codec = nullptr;
301319
Print *p_print = nullptr;
320+
Print *p_encoded_audio_stream = nullptr;
321+
SingleBuffer<uint8_t> buffer{1024};
322+
CallbackBufferedStream<uint8_t> codec_buffer{buffer};
323+
AudioEncoder* p_codec = nullptr;
302324
volatile bool is_open;
303325
OGGZ *p_oggz = nullptr;
304326
ogg_packet op;
@@ -307,6 +329,7 @@ class OggContainerEncoder : public AudioEncoder {
307329
size_t packetno = 0;
308330
long serialno = -1;
309331
AudioBaseInfo cfg;
332+
bool is_audio = false;
310333

311334
virtual bool writePacket(ogg_packet &op, int flag = 0) {
312335
LOGD("writePacket: %d", (int) op.bytes);
@@ -326,6 +349,7 @@ class OggContainerEncoder : public AudioEncoder {
326349
oh.packetno = packetno++;
327350
oh.b_o_s = true;
328351
oh.e_o_s = false;
352+
is_audio = false;
329353
return writePacket(oh);
330354
}
331355

@@ -337,6 +361,7 @@ class OggContainerEncoder : public AudioEncoder {
337361
op.packetno = packetno++;
338362
op.b_o_s = false;
339363
op.e_o_s = true;
364+
is_audio = false;
340365
return writePacket(op, OGGZ_FLUSH_AFTER);
341366
}
342367

src/AudioEffects/SoundGenerator.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ class NoiseGenerator : public SoundGenerator<T> {
293293

294294

295295
/**
296-
* @brief Provides 0 as sound data. This can be used e.g. to test the output functionality which should optimally just output
296+
* @brief Provides a fixed value (e.g. 0) as sound data. This can be used e.g. to test the output functionality which should optimally just output
297297
* silence and no artifacts.
298298
* @author Phil Schatzmann
299299
* @copyright GPLv3
@@ -303,17 +303,17 @@ template <class T>
303303
class SilenceGenerator : public SoundGenerator<T> {
304304
public:
305305
// the scale defines the max value which is generated
306-
SilenceGenerator(double scale=1.0) {
307-
this->scale = scale;
306+
SilenceGenerator(T value=0) {
307+
this->value = value;
308308
}
309309

310310
/// Provides a single sample
311311
T readSample() {
312-
return 0; // return 0
312+
return value; // return 0
313313
}
314314

315315
protected:
316-
double scale;
316+
T value;
317317

318318
};
319319

src/AudioTools/AudioStreams.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,10 @@ class CallbackBufferedStream : public AudioStreamX {
772772
remove_oldest_data = autoRemoveOldestDataIfFull;
773773
}
774774

775+
CallbackBufferedStream(BaseBuffer<T> &buffer){
776+
callback_buffer_ptr = &buffer;
777+
}
778+
775779
virtual ~CallbackBufferedStream() { delete callback_buffer_ptr; }
776780

777781
/// Activates the output
@@ -828,7 +832,7 @@ class CallbackBufferedStream : public AudioStreamX {
828832
}
829833

830834
protected:
831-
NBuffer<T> *callback_buffer_ptr;
835+
BaseBuffer<T> *callback_buffer_ptr;
832836
bool active;
833837
bool remove_oldest_data;
834838

tests/codec/opusogg/opusogg.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "AudioCodecs/CodecOpusOgg.h"
1313

1414
int sample_rate = 24000;
15-
int channels = 2; // The stream will have 2 channels
15+
int channels = 1; // The stream will have 2 channels
1616
int application = OPUS_APPLICATION_AUDIO; // Opus application
1717

1818
SineWaveGenerator<int16_t> sineWave( 32000); // subclass of SoundGenerator with max amplitude of 32000
@@ -21,22 +21,15 @@ CsvStream<int16_t> out(Serial, channels); // Output of sound on desktop
2121
OpusOggEncoder enc;
2222
OpusOggDecoder dec;
2323
EncodedAudioStream decoder(out, dec); // encode and write
24-
HexDumpStream hex(Serial);
25-
EncodedAudioStream encoder(&hex, &enc); // encode and write
24+
EncodedAudioStream encoder(&decoder, &enc); // encode and write
2625
//EncodedAudioStream encoder(&decoder, &enc); // encode and write
2726
StreamCopy copier(encoder, sound);
2827

2928
void setup() {
3029
Serial.begin(115200);
31-
AudioLogger::instance().begin(Serial, AudioLogger::Debug);
32-
33-
// start I2S
34-
// Serial.println("starting I2S...");
35-
// auto cfgi = out.defaultConfig(TX_MODE);
36-
// cfgi.sample_rate = sample_rate;
37-
// cfgi.channels = channels;
38-
// cfgi.bits_per_sample = 16;
39-
// out.begin(cfgi);
30+
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
31+
32+
4033

4134
// Setup sine wave
4235
auto cfgs = sineWave.defaultConfig();

0 commit comments

Comments
 (0)