Codecs play an important role in audio streaming, as we have seen in one of my last blogs.
I have spent some time to make the Opus Codec available as Arduino Library and I am providing some simple integration from my Arduino Audio Tools library.
Opus is a codec for interactive speech and audio transmission over the Internet.
Opus can handle a wide range of interactive audio applications, including Voice over IP, videoconferencing, in-game chat, and even remote live music performances. It can scale from low bit-rate narrowband speech to very high quality stereo music.
Opus packets are not self-delimiting, but are designed to be used inside a container of some sort which supplies the decoder with each packet’s length. Opus was originally specified for encapsulation in Ogg containers.
Nevertheless we can test the codec w/o container.
Arduino Sketch
We can test the codec e.g. with the following Sketch which makes sure that the encoded packets are subsequently decoded again:
#include "AudioTools.h"
#include "AudioCodecs/CodecOpus.h"
int sample_rate = 24000;
int channels = 2; // The stream will have 2 channels
SineWaveGenerator<int16_t> sineWave( 32000); // SoundGenerator max amplitude of 32000
GeneratedSoundStream<int16_t> sound( sineWave); // Stream generated from sine wave
MeasuringStream out;
OpusAudioEncoder enc;
EncodedAudioStream decoder(&out, new OpusAudioDecoder()); // encode and write
EncodedAudioStream encoder(&decoder, &enc); // encode and write
StreamCopy copier(encoder, sound);
void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Info);
// 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 = OPUS_APPLICATION_VOIP;
enc.config().complexity = 5;
encoder.begin(cfgs);
Serial.println("Test started...");
}
void loop() {
copier.copy();
}
Performance Overview
Please note that the values of the valid supported sample rates is limited to 8000,12000,16000 ,24000,48000 and there are quite a few encoder settings that we can play with, but the most important ones are:
- application
- complexity
- data type (defined in opus_config.h)
data type | complexity | application | Sampling Rate | bytes/second Required | bytes/second Processed |
---|---|---|---|---|---|
fixed | default | OPUS_APPLICATION_AUDIO | 24000 | 60000 | 15000 |
fixed | 1 | OPUS_APPLICATION_AUDIO | 24000 | 60000 | 89000 |
fixed | 2 | OPUS_APPLICATION_AUDIO | 24000 | 60000 | 88000 |
fixed | 5 | OPUS_APPLICATION_AUDIO | 24000 | 60000 | 66000 |
fixed | 5 | OPUS_APPLICATION_VOIP | 24000 | 60000 | 65000 |
float | 5 | OPUS_APPLICATION_AUDIO | 24000 | 60000 | 52000 |
float | 5 | OPUS_APPLICATION_VOIP | 24000 | 60000 | 53000 |
Conclusion
By adjusting the complexity parameter we can improve the performance to achieve the rate that is needed by real time processing.
Using the fixed point is faster, so I used this as default setting in the library.
Next Steps
As the next step I need to support of Ogg containers.
0 Comments