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

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *