6#include "opus/opus_multistream.h"
8#ifndef OPUS_ENC_MAX_BUFFER_SIZE
9#define OPUS_ENC_MAX_BUFFER_SIZE 2048
12#ifndef OPUS_DEC_MAX_BUFFER_SIZE
13#define OPUS_DEC_MAX_BUFFER_SIZE 4 * 1024
139 const char*
mime()
override {
return "audio/opus"; }
159 LOGE(
"Sample rate not supported: %d",
cfg.sample_rate);
162 cfg.setupChannelMapping();
167 dec = opus_multistream_decoder_create(
cfg.sample_rate,
cfg.channels,
168 cfg.streams,
cfg.coupled_streams,
170 if (err != OPUS_OK ||
dec ==
nullptr) {
172 "opus_multistream_decoder_create: %s for sample_rate: %d, "
173 "channels:%d, streams:%d, coupled:%d",
174 opus_strerror(err),
cfg.sample_rate,
cfg.channels,
cfg.streams,
175 cfg.coupled_streams);
184 if (
dec !=
nullptr) {
185 opus_multistream_decoder_destroy(
dec);
208 if (channels_changed || !
active) {
209 cfg.setupChannelMapping();
215 size_t write(
const uint8_t* data,
size_t len)
override {
217 LOGD(
"OpusMultiStreamAudioDecoder::write: %d", (
int)len);
218 int in_band_forward_error_correction = 0;
219 int frame_count =
cfg.max_buffer_size /
cfg.channels /
sizeof(opus_int16);
220 int out_samples = opus_multistream_decode(
221 dec, (uint8_t*)data, len, (opus_int16*)
outbuf.data(), frame_count,
222 in_band_forward_error_correction);
223 if (out_samples < 0) {
224 LOGW(
"opus_multistream_decode: %s", opus_strerror(out_samples));
225 }
else if (out_samples > 0) {
226 int out_bytes = out_samples *
cfg.channels *
sizeof(int16_t);
227 LOGD(
"opus_multistream_decode: %d", out_bytes);
228 int open = out_bytes;
231 int to_write = std::min(open,
cfg.max_buffer_write_size);
232 int written =
p_print->write(
outbuf.data() + processed, to_write);
234 processed += written;
240 operator bool()
override {
return active; }
246 OpusMSDecoder*
dec =
nullptr;
250 const uint32_t
valid_rates[5] = {8000, 12000, 16000, 24000, 48000};
255 if (valid == rate)
return true;
284 const char*
mime()
override {
return "audio/opus"; }
287 LOGD(
"OpusMultiStreamAudioEncoder::setAudioInfo: sample_rate: %d, channels: %d",
294 if (
enc !=
nullptr) {
301 LOGD(
"OpusMultiStreamAudioEncoder::begin: sample_rate: %d, channels: %d",
302 cfg.sample_rate,
cfg.channels);
310 cfg.setupChannelMapping();
314 packet.resize(packet_len);
316 enc = opus_multistream_encoder_create(
cfg.sample_rate,
cfg.channels,
317 cfg.streams,
cfg.coupled_streams,
318 cfg.mapping,
cfg.application, &err);
319 if (err != OPUS_OK ||
enc ==
nullptr) {
321 "opus_multistream_encoder_create: %s for sample_rate: %d, "
322 "channels:%d, streams:%d, coupled:%d",
323 opus_strerror(err),
cfg.sample_rate,
cfg.channels,
cfg.streams,
324 cfg.coupled_streams);
346 if (
enc !=
nullptr) {
347 opus_multistream_encoder_destroy(
enc);
353 size_t write(
const uint8_t* data,
size_t len)
override {
355 LOGD(
"OpusMultiStreamAudioEncoder::write: %d", (
int)len);
356 for (
int j = 0; j < len; j++) {
367 if (
enc ==
nullptr)
return 0;
368 opus_int32 samples = 0;
369 if (opus_multistream_encoder_ctl(
enc, OPUS_GET_LOOKAHEAD(&samples)) !=
373 return samples > 0 ? samples : 0;
379 int bytesPerSample =
cfg.channels * (int)
sizeof(int16_t);
380 if (bytesPerSample <= 0)
return 0;
388 OpusMSEncoder*
enc =
nullptr;
404 if (
frame.size() > 0) {
405 int frames =
frame.size() /
cfg.channels /
sizeof(int16_t);
406 LOGD(
"opus_multistream_encode - frame_size: %d", frames);
407 int len = opus_multistream_encode(
enc, (opus_int16*)
frame.data(), frames,
410 LOGE(
"opus_multistream_encode: %s", opus_strerror(len));
411 }
else if (len > 0) {
412 LOGD(
"opus_multistream_encode: %d", len);
415 LOGE(
"encodeFrame data lost: %d->%d", len, eff);
422 switch (
cfg.frame_sizes_ms_x2) {
423 case OPUS_FRAMESIZE_2_5_MS:
424 return sampling_rate / 400;
425 case OPUS_FRAMESIZE_5_MS:
426 return sampling_rate / 200;
427 case OPUS_FRAMESIZE_10_MS:
428 return sampling_rate / 100;
429 case OPUS_FRAMESIZE_20_MS:
430 return sampling_rate / 50;
431 case OPUS_FRAMESIZE_40_MS:
432 return sampling_rate / 25;
433 case OPUS_FRAMESIZE_60_MS:
434 return 3 * sampling_rate / 50;
435 case OPUS_FRAMESIZE_80_MS:
436 return 4 * sampling_rate / 50;
437 case OPUS_FRAMESIZE_100_MS:
438 return 5 * sampling_rate / 50;
439 case OPUS_FRAMESIZE_120_MS:
440 return 6 * sampling_rate / 50;
442 return sampling_rate / 100;
447 if (
cfg.bitrate >= 0 &&
448 opus_multistream_encoder_ctl(
enc, OPUS_SET_BITRATE(
cfg.bitrate)) !=
450 LOGE(
"invalid bitrate: %d",
cfg.bitrate);
453 if (
cfg.force_channel >= 0 &&
454 opus_multistream_encoder_ctl(
455 enc, OPUS_SET_FORCE_CHANNELS(
cfg.force_channel)) != OPUS_OK) {
456 LOGE(
"invalid force_channel: %d",
cfg.force_channel);
460 opus_multistream_encoder_ctl(
enc, OPUS_SET_VBR(
cfg.vbr)) != OPUS_OK) {
461 LOGE(
"invalid vbr: %d",
cfg.vbr);
464 if (
cfg.vbr_constraint >= 0 &&
465 opus_multistream_encoder_ctl(
466 enc, OPUS_SET_VBR_CONSTRAINT(
cfg.vbr_constraint)) != OPUS_OK) {
467 LOGE(
"invalid vbr_constraint: %d",
cfg.vbr_constraint);
470 if (
cfg.complexity >= 0 &&
471 opus_multistream_encoder_ctl(
472 enc, OPUS_SET_COMPLEXITY(
cfg.complexity)) != OPUS_OK) {
473 LOGE(
"invalid complexity: %d",
cfg.complexity);
476 if (
cfg.max_bandwidth >= 0 &&
477 opus_multistream_encoder_ctl(
478 enc, OPUS_SET_MAX_BANDWIDTH(
cfg.max_bandwidth)) != OPUS_OK) {
479 LOGE(
"invalid max_bandwidth: %d",
cfg.max_bandwidth);
482 if (
cfg.signal >= 0 && opus_multistream_encoder_ctl(
483 enc, OPUS_SET_SIGNAL(
cfg.signal)) != OPUS_OK) {
484 LOGE(
"invalid signal: %d",
cfg.signal);
487 if (
cfg.inband_fec >= 0 &&
488 opus_multistream_encoder_ctl(
489 enc, OPUS_SET_INBAND_FEC(
cfg.inband_fec)) != OPUS_OK) {
490 LOGE(
"invalid inband_fec: %d",
cfg.inband_fec);
493 if (
cfg.packet_loss_perc >= 0 &&
494 opus_multistream_encoder_ctl(
495 enc, OPUS_SET_PACKET_LOSS_PERC(
cfg.packet_loss_perc)) != OPUS_OK) {
496 LOGE(
"invalid pkt_loss: %d",
cfg.packet_loss_perc);
499 if (
cfg.lsb_depth >= 0 &&
500 opus_multistream_encoder_ctl(
enc, OPUS_SET_LSB_DEPTH(
cfg.lsb_depth)) !=
502 LOGE(
"invalid lsb_depth: %d",
cfg.lsb_depth);
505 if (
cfg.prediction_disabled >= 0 &&
506 opus_multistream_encoder_ctl(
507 enc, OPUS_SET_PREDICTION_DISABLED(
cfg.prediction_disabled)) !=
509 LOGE(
"invalid pred_disabled: %d",
cfg.prediction_disabled);
512 if (
cfg.use_dtx >= 0 && opus_multistream_encoder_ctl(
513 enc, OPUS_SET_DTX(
cfg.use_dtx)) != OPUS_OK) {
514 LOGE(
"invalid use_dtx: %d",
cfg.use_dtx);
517 if (
cfg.frame_sizes_ms_x2 > 0 &&
518 opus_multistream_encoder_ctl(
519 enc, OPUS_SET_EXPERT_FRAME_DURATION(
cfg.frame_sizes_ms_x2)) !=
521 LOGE(
"invalid frame_sizes_ms_x2: %d",
cfg.frame_sizes_ms_x2);
#define OPUS_DEC_MAX_BUFFER_SIZE
Definition CodecOpus.h:12
#define OPUS_ENC_MAX_BUFFER_SIZE
Definition CodecOpus.h:8