Skip to content

Commit

Permalink
opus-ogg
Browse files Browse the repository at this point in the history
  • Loading branch information
pschatzmann committed Sep 1, 2022
1 parent b644345 commit adc7fd9
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 65 deletions.
16 changes: 7 additions & 9 deletions examples/tests/codecs/test-codec-opus/test-codec-opus.ino
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "AudioCodecs/CodecOpus.h"

int sample_rate = 24000;
int channels = 1; // The stream will have 2 channels
int channels = 1;

SineWaveGenerator<int16_t> sineWave( 32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound( sineWave); // Stream generated from sine wave
Expand Down Expand Up @@ -42,16 +42,14 @@ void setup() {
cfgs.bits_per_sample = 16;
sineWave.begin(cfgs, N_B4);

// Opus decoder needs to know the audio info
// Opus encoder and decoder need to know the audio info
decoder.begin(cfgs);
encoder.begin(cfgs);

// configure and start encoder
auto encfg = enc.config();
encfg.copyFrom(cfgs); // use sample rate, channels ...
//encfg.application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
//encfg.frame_sizes_ms_x2 = OPUS_FRAMESIZE_20_MS;
//encfg.complexity = 5;
encoder.begin(encfg);
// configure additinal parameters
//enc.config().application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
//enc.config().frame_sizes_ms_x2 = OPUS_FRAMESIZE_20_MS;
//enc.config().complexity = 5;

Serial.println("Test started...");
}
Expand Down
28 changes: 11 additions & 17 deletions examples/tests/codecs/test-codec-opusogg/test-codec-opusogg.ino
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,36 @@
#include "AudioCodecs/CodecOpusOgg.h"

int sample_rate = 24000;
int channels = 2; // The stream will have 2 channels
int application = OPUS_APPLICATION_AUDIO; // Opus application
int channels = 1;

SineWaveGenerator<int16_t> sineWave( 32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound( sineWave); // Stream generated from sine wave
AudioKitStream out;
CsvStream<int16_t> out(Serial,channels);
OpusOggEncoder enc;
EncodedAudioStream decoder(&out, new OpusOggDecoder()); // encode and write
OpusOggDecoder dec;
EncodedAudioStream decoder(&out, &dec); // encode and write
EncodedAudioStream encoder(&decoder, &enc); // encode and write
StreamCopy copier(encoder, sound);

void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);

// start I2S
Serial.println("starting I2S...");
auto cfgi = out.defaultConfig(TX_MODE);
cfgi.sample_rate = sample_rate;
cfgi.channels = channels;
cfgi.bits_per_sample = 16;
out.begin(cfgi);

// Setup sine wave
auto cfgs = sineWave.defaultConfig();
cfgs.sample_rate = sample_rate;
cfgs.channels = channels;
cfgs.bits_per_sample = 16;
sineWave.begin(cfgs, N_B4);

// Opus decoder needs to know the audio info
decoder.begin(cfgs);

// configure and start encoder
enc.config().application = application;
// Opus encoder needs to know the audio info
encoder.begin(cfgs);
decoder.begin();

// configure additinal parameters
//enc.config().application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
//enc.config().frame_sizes_ms_x2 = OPUS_FRAMESIZE_20_MS;
//enc.config().complexity = 5;

Serial.println("Test started...");
}
Expand Down
59 changes: 33 additions & 26 deletions src/AudioCodecs/CodecOpus.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
#include "Print.h"
#include "opus.h"

#ifndef OPUS_MAX_BUFFER_SIZE
#define OPUS_MAX_BUFFER_SIZE (5760)
#ifndef OPUS_ENC_MAX_BUFFER_SIZE
#define OPUS_ENC_MAX_BUFFER_SIZE 2048
#endif

#ifndef OPUS_DEC_MAX_BUFFER_SIZE
#define OPUS_DEC_MAX_BUFFER_SIZE 1024
#endif

namespace audio_tools {
Expand All @@ -24,7 +28,7 @@ struct OpusSettings : public AudioBaseInfo {
/// must be 16!
bits_per_sample = 16;
}
int max_buffer_size = OPUS_MAX_BUFFER_SIZE;
int max_buffer_size = OPUS_DEC_MAX_BUFFER_SIZE;
};

/**
Expand Down Expand Up @@ -59,9 +63,10 @@ frame_sizes_ms_x2[9] = {OPUS_FRAMESIZE_2_5_MS,OPUS_FRAMESIZE_5_MS,OPUS_FRAMESIZE
**/

struct OpusEncoderSettings : public OpusSettings {
OpusEncoderSettings() : OpusSettings() {}
OpusEncoderSettings() : OpusSettings() {
/// Default is 5760
int max_buffer_size = OPUS_MAX_BUFFER_SIZE;
max_buffer_size = OPUS_ENC_MAX_BUFFER_SIZE;
}
/// OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_VOIP,
/// OPUS_APPLICATION_RESTRICTED_LOWDELAY
int application = OPUS_APPLICATION_AUDIO;
Expand Down Expand Up @@ -144,6 +149,8 @@ class OpusAudioDecoder : public AudioDecoder {
void begin() override {
LOGD(LOG_METHOD);
outbuf.resize(cfg.max_buffer_size);
assert(outbuf.data() != nullptr);

int err;
dec = opus_decoder_create(cfg.sample_rate, cfg.channels, &err);
if (err != OPUS_OK) {
Expand Down Expand Up @@ -193,9 +200,9 @@ class OpusAudioDecoder : public AudioDecoder {
Print *p_print = nullptr;
AudioBaseInfoDependent *bid = nullptr;
OpusSettings cfg;
::OpusDecoder *dec;
OpusDecoder *dec;
bool active;
Vector<uint8_t> outbuf;
Vector<uint8_t> outbuf{0};
};

/**
Expand Down Expand Up @@ -228,13 +235,10 @@ class OpusAudioEncoder : public AudioEncoder {
/// starts the processing using the actual OpusAudioInfo
void begin() override {
int err;
packet.resize(cfg.max_buffer_size);
frame.resize(getFrameSizeSamples(cfg.sample_rate) * 2);
int size = getFrameSizeSamples(cfg.sample_rate) * 2;
frame.resize(size);
assert(frame.data() != nullptr);
assert(packet.data() != nullptr);

enc = opus_encoder_create(cfg.sample_rate, cfg.channels, cfg.application,
&err);
enc = opus_encoder_create(cfg.sample_rate, cfg.channels, cfg.application, &err);
if (err != OPUS_OK) {
LOGE("opus_encoder_create: %s for sample_rate: %d, channels:%d",
opus_strerror(err), cfg.sample_rate, cfg.channels);
Expand All @@ -255,7 +259,7 @@ class OpusAudioEncoder : public AudioEncoder {
/// stops the processing
void end() override {
// flush buffered data
encodeFrame(frame_pos);
encodeFrame();
// release memory
opus_encoder_destroy(enc);
is_open = false;
Expand All @@ -265,6 +269,7 @@ class OpusAudioEncoder : public AudioEncoder {
size_t write(const void *in_ptr, size_t in_size) {
if (!is_open || p_print == nullptr) return 0;

// fill frame
uint8_t *p_byte = (uint8_t *)in_ptr;
for (int j = 0; j < in_size; j++) {
encodeByte(p_byte[j]);
Expand All @@ -278,35 +283,37 @@ class OpusAudioEncoder : public AudioEncoder {

protected:
Print *p_print = nullptr;
::OpusEncoder *enc = nullptr;
OpusEncoder *enc = nullptr;
OpusEncoderSettings cfg;
bool is_open = false;
Vector<uint8_t> packet;
Vector<uint8_t> frame;
Vector<uint8_t> frame{0};
int frame_pos = 0;

void encodeByte(uint8_t data) {
// add byte to frame
frame[frame_pos++] = data;

// if frame is complete -> encode
int frame_size = frame.size();
if (frame_pos >= frame_size) {
encodeFrame(frame_size);
if (frame_pos >= frame.size()) {
encodeFrame();
frame_pos = 0;
}
}

void encodeFrame(int lenBytes) {
if (lenBytes > 0) {
int frames = lenBytes / cfg.channels / sizeof(int16_t);
void encodeFrame() {
if (frame.size() > 0) {
// allocate temp buffer on stack
int packet_len = OPUS_ENC_MAX_BUFFER_SIZE > 0 ? OPUS_ENC_MAX_BUFFER_SIZE : 512;
uint8_t packet[packet_len];

int frames = frame.size() / cfg.channels / sizeof(int16_t);
LOGD("opus_encode - frame_size: %d", frames);
int len = opus_encode(enc, (opus_int16 *)frame.data(), frames,
packet.data(), cfg.max_buffer_size);
packet, packet_len);
if (len < 0) {
LOGE("opus_encode: %s", opus_strerror(len));
} else if (len > 0 && len <= cfg.max_buffer_size) {
int eff = p_print->write(packet.data(), len);
} else if (len > 0) {
int eff = p_print->write(packet, len);
if (eff!=len){
LOGE("encodeFrame data lost");
}
Expand Down
6 changes: 3 additions & 3 deletions src/AudioCodecs/ContainerOgg.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include "AudioTools/Buffers.h"
#include "oggz/oggz.h"

#define OGG_DEFAULT_BUFFER_SIZE (2048)
#define OGG_READ_SIZE 1024
#define OGG_DEFAULT_BUFFER_SIZE (246)
#define OGG_READ_SIZE (512)

namespace audio_tools {

Expand Down Expand Up @@ -102,7 +102,7 @@ class OggContainerDecoder : public AudioDecoder {
}

virtual size_t write(const void *in_ptr, size_t in_size) override {
LOGI("write: %u", in_size);
LOGD("write: %u", in_size);
if (p_print == nullptr) return 0;

// fill buffer
Expand Down
12 changes: 2 additions & 10 deletions tests/codec/opus/opus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
#include "AudioCodecs/CodecOpus.h"

int sample_rate = 24000;
int channels = 2; // The stream will have 2 channels
int application = OPUS_APPLICATION_AUDIO; // Opus application
int channels = 1; // The stream will have 2 channels

SineWaveGenerator<int16_t> sineWave( 32000); // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound( sineWave); // Stream generated from sine wave
Expand All @@ -28,13 +27,6 @@ void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Debug);

// start I2S
// Serial.println("starting I2S...");
// auto cfgi = out.defaultConfig(TX_MODE);
// cfgi.sample_rate = sample_rate;
// cfgi.channels = channels;
// cfgi.bits_per_sample = 16;
// out.begin(cfgi);

// Setup sine wave
auto cfgs = sineWave.defaultConfig();
Expand All @@ -47,7 +39,7 @@ void setup() {
decoder.begin(cfgs);

// configure and start encoder
enc.config().application = application;
enc.config().application = OPUS_APPLICATION_AUDIO;
encoder.begin(cfgs);

Serial.println("Test started...");
Expand Down

0 comments on commit adc7fd9

Please sign in to comment.