static int alloc(struct aucodec_st **stp, struct aucodec *ac, struct aucodec_prm *encp, struct aucodec_prm *decp, const char *fmtp) { struct aucodec_st *st; const uint32_t srate = aucodec_srate(ac); const uint8_t ch = aucodec_ch(ac); uint32_t ptime = DEFAULT_PTIME; int use_inbandfec; int use_dtx; int err = 0; int opuserr; (void)decp; (void)fmtp; st = mem_zalloc(sizeof(*st), destructor); if (!st) return ENOMEM; if (encp && encp->ptime) ptime = encp->ptime; st->ac = mem_ref(ac); st->frame_size = srate * ptime / 1000; st->fsize = 2 * st->frame_size * ch; /* Encoder */ st->enc = opus_encoder_create(srate, ch, opus.app, &opuserr); if (!st->enc) { err = ENOMEM; goto out; } use_inbandfec = 1; use_dtx = 1; opus_encoder_ctl(st->enc, OPUS_SET_BITRATE(opus.bitrate)); opus_encoder_ctl(st->enc, OPUS_SET_BANDWIDTH(opus.bandwidth)); opus_encoder_ctl(st->enc, OPUS_SET_VBR(opus.vbr)); opus_encoder_ctl(st->enc, OPUS_SET_COMPLEXITY(opus.complex)); opus_encoder_ctl(st->enc, OPUS_SET_INBAND_FEC(use_inbandfec)); opus_encoder_ctl(st->enc, OPUS_SET_DTX(use_dtx)); /* Decoder */ st->dec = opus_decoder_create(srate, ch, &opuserr); if (!st->dec) { err = ENOMEM; goto out; } out: if (err) mem_deref(st); else *stp = st; return err; }
JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_audio_opus_Opus_encoder_1set_1bandwidth (JNIEnv *env, jclass clazz, jlong encoder, jint bandwidth) { opus_int32 x = bandwidth; return opus_encoder_ctl( (OpusEncoder *) (intptr_t) encoder, OPUS_SET_BANDWIDTH(x)); }
static gboolean gst_opus_enc_setup (GstOpusEnc * enc) { int error = OPUS_OK; #ifndef GST_DISABLE_DEBUG GST_DEBUG_OBJECT (enc, "setup: %d Hz, %d channels, %d stereo streams, family %d", enc->sample_rate, enc->n_channels, enc->n_stereo_streams, enc->channel_mapping_family); GST_INFO_OBJECT (enc, "Mapping tables built: %d channels, %d stereo streams", enc->n_channels, enc->n_stereo_streams); gst_opus_common_log_channel_mapping_table (GST_ELEMENT (enc), opusenc_debug, "Encoding mapping table", enc->n_channels, enc->encoding_channel_mapping); gst_opus_common_log_channel_mapping_table (GST_ELEMENT (enc), opusenc_debug, "Decoding mapping table", enc->n_channels, enc->decoding_channel_mapping); #endif enc->state = opus_multistream_encoder_create (enc->sample_rate, enc->n_channels, enc->n_channels - enc->n_stereo_streams, enc->n_stereo_streams, enc->encoding_channel_mapping, enc->audio_or_voip ? OPUS_APPLICATION_AUDIO : OPUS_APPLICATION_VOIP, &error); if (!enc->state || error != OPUS_OK) goto encoder_creation_failed; opus_multistream_encoder_ctl (enc->state, OPUS_SET_BITRATE (enc->bitrate), 0); opus_multistream_encoder_ctl (enc->state, OPUS_SET_BANDWIDTH (enc->bandwidth), 0); opus_multistream_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr), 0); opus_multistream_encoder_ctl (enc->state, OPUS_SET_VBR_CONSTRAINT (enc->constrained_vbr), 0); opus_multistream_encoder_ctl (enc->state, OPUS_SET_COMPLEXITY (enc->complexity), 0); opus_multistream_encoder_ctl (enc->state, OPUS_SET_INBAND_FEC (enc->inband_fec), 0); opus_multistream_encoder_ctl (enc->state, OPUS_SET_DTX (enc->dtx), 0); opus_multistream_encoder_ctl (enc->state, OPUS_SET_PACKET_LOSS_PERC (enc->packet_loss_percentage), 0); GST_LOG_OBJECT (enc, "we have frame size %d", enc->frame_size); return TRUE; encoder_creation_failed: GST_ERROR_OBJECT (enc, "Encoder creation failed"); return FALSE; }
static void audio_encoder_init(uint32_t samplerate, int complexity, uint32_t bitrate) { assert(opus_enc == NULL); int err = 0; /* 1 channel (mono), OPUS audio profile */ opus_enc = opus_encoder_create(samplerate, 1, OPUS_APPLICATION_AUDIO, &err); if (!opus_enc) { fprintf(stderr, "ERROR: opus_encoder_create() has failed - %d\n", err); exit(EXIT_FAILURE); } opus_encoder_ctl(opus_enc, OPUS_SET_COMPLEXITY(complexity)); opus_encoder_ctl(opus_enc, OPUS_SET_BITRATE(bitrate)); opus_encoder_ctl(opus_enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_encoder_ctl(opus_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); }
static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct opus_context *context = NULL; int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); int decoding = (flags & SWITCH_CODEC_FLAG_DECODE); switch_codec_fmtp_t codec_fmtp; opus_codec_settings_t opus_codec_settings = { 0 }; if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; } context->enc_frame_size = codec->implementation->actual_samples_per_second * (codec->implementation->microseconds_per_packet / 1000) / 1000; memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); codec_fmtp.private_info = &opus_codec_settings; switch_opus_fmtp_parse(codec->fmtp_in, &codec_fmtp); /* Verify if the local or remote configuration are lowering maxaveragebitrate and/or maxplaybackrate */ if ( opus_prefs.maxaveragebitrate && (opus_prefs.maxaveragebitrate < opus_codec_settings.maxaveragebitrate || !opus_codec_settings.maxaveragebitrate) ) { opus_codec_settings.maxaveragebitrate = opus_prefs.maxaveragebitrate; } if ( opus_prefs.maxplaybackrate && (opus_prefs.maxplaybackrate < opus_codec_settings.maxplaybackrate || !opus_codec_settings.maxplaybackrate) ) { opus_codec_settings.maxplaybackrate = opus_prefs.maxplaybackrate; } codec->fmtp_out = gen_fmtp(&opus_codec_settings, codec->memory_pool); if (encoding) { /* come up with a way to specify these */ int bitrate_bps = OPUS_AUTO; int use_vbr = opus_prefs.use_vbr; int complexity = opus_prefs.complexity; int err; int samplerate = opus_codec_settings.samplerate ? opus_codec_settings.samplerate : codec->implementation->actual_samples_per_second; context->encoder_object = opus_encoder_create(samplerate, codec->implementation->number_of_channels, codec->implementation->number_of_channels == 1 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, &err); if (err != OPUS_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err)); return SWITCH_STATUS_GENERR; } /* Setting documented in "RTP Payload Format for Opus Speech and Audio Codec" draft-spittka-payload-rtp-opus-03 */ if( opus_codec_settings.maxaveragebitrate ) { /* Remote codec settings found in SDP "fmtp", we accept to tune the Encoder */ opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder set bitrate based on maxaveragebitrate found in SDP [%dbps]\n", opus_codec_settings.maxaveragebitrate); } else { /* Default codec settings used, may have been modified by SDP "samplerate" */ opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); if (codec->implementation->actual_samples_per_second == 8000) { opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); } else { opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder set bitrate to local settings [%dbps]\n", bitrate_bps); } /* Another setting from "RTP Payload Format for Opus Speech and Audio Codec" */ if ( opus_codec_settings.maxplaybackrate ) { if (opus_codec_settings.maxplaybackrate == 8000) { /* Audio Bandwidth: 0-4000Hz Sampling Rate: 8000Hz */ opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); } else if (opus_codec_settings.maxplaybackrate == 12000) { /* Audio Bandwidth: 0-6000Hz Sampling Rate: 12000Hz */ opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND)); } else if (opus_codec_settings.maxplaybackrate == 16000) { /* Audio Bandwidth: 0-8000Hz Sampling Rate: 16000Hz */ opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)); } else if (opus_codec_settings.maxplaybackrate == 24000) { /* Audio Bandwidth: 0-12000Hz Sampling Rate: 24000Hz */ opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); } else if (opus_codec_settings.maxplaybackrate == 48000) { /* Audio Bandwidth: 0-20000Hz Sampling Rate: 48000Hz */ opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder set bandwidth based on maxplaybackrate found in SDP [%dHz]\n", opus_codec_settings.maxplaybackrate); } if (use_vbr) { opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr)); } if (complexity) { opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity)); } if (opus_codec_settings.useinbandfec) { opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(opus_codec_settings.useinbandfec)); } if (opus_codec_settings.usedtx) { opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX(opus_codec_settings.usedtx)); } } if (decoding) { int err; context->decoder_object = opus_decoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels, &err); if (err != OPUS_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err)); if (context->encoder_object) { opus_encoder_destroy(context->encoder_object); context->encoder_object = NULL; } return SWITCH_STATUS_GENERR; } } codec->private_info = context; return SWITCH_STATUS_SUCCESS; }
int main(int argc, char *argv[]) { int err; char *inFile, *outFile; FILE *fin, *fout; OpusEncoder *enc; int len; int frame_size, channels; int bytes_per_packet; unsigned char data[MAX_PACKET]; int rate; int count = 0; int stop=0; int vbr=0; int tot_read=0, tot_written=0; short *in, *out; int mode=MODE_HYBRID; double bits=0; if (argc != 9 && argc != 8 && argc != 7) { fprintf (stderr, "Usage: test_opus <rate (kHz)> <channels> <frame size> " " <bytes per packet> [<VBR rate (kb/s)>] [<packet loss rate>] " "<input> <output>\n"); return 1; } rate = atoi(argv[1]); channels = atoi(argv[2]); frame_size = atoi(argv[3]); bytes_per_packet = atoi(argv[4]); if (argc >= 8) vbr = atoi(argv[5]); if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) { fprintf (stderr, "bytes per packet must be between 0 and %d\n", MAX_PACKET); return 1; } inFile = argv[argc-2]; fin = fopen(inFile, "rb"); if (!fin) { fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); return 1; } outFile = argv[argc-1]; fout = fopen(outFile, "wb+"); if (!fout) { fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); return 1; } enc = opus_encoder_create(rate, channels); mode = MODE_HYBRID; opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(BANDWIDTH_FULLBAND)); opus_encoder_ctl(enc, OPUS_SET_MODE(mode)); in = (short*)malloc(frame_size*channels*sizeof(short)); while (!stop) { int write_samples; err = fread(in, sizeof(short), frame_size*channels, fin); tot_read += err; if (err < frame_size*channels) { int i; for (i=err;i<frame_size*channels;i++) in[i] = 0; stop = 1; } len = opus_encode(enc, in, frame_size, data, bytes_per_packet); if (len <= 0) { fprintf (stderr, "opus_encode() returned %d\n", len); return 1; } bits += len*8; count++; fputc((len>>8)&0xFF, fout); fputc((len)&0xFF, fout); fwrite(data, 1, len, fout); } fprintf (stderr, "average bit-rate: %f kb/s\n", bits*rate/(frame_size*(double)count)); opus_encoder_destroy(enc); fclose(fin); fclose(fout); free(in); free(out); return 0; }
static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct opus_context *context = NULL; int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); int decoding = (flags & SWITCH_CODEC_FLAG_DECODE); if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; } context->frame_size = codec->implementation->samples_per_packet; if (encoding) { /* come up with a way to specify these */ int bitrate_bps = codec->implementation->bits_per_second; int use_vbr = 1; int complexity = 10; int use_inbandfec = 1; int use_dtx = 1; int bandwidth = OPUS_BANDWIDTH_FULLBAND; int err; context->encoder_object = opus_encoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels, OPUS_APPLICATION_VOIP, &err); if (err != OPUS_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err)); return SWITCH_STATUS_GENERR; } opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(bandwidth)); opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr)); opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity)); opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(use_inbandfec)); opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX(use_dtx)); } if (decoding) { int err; context->decoder_object = opus_decoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels, &err); if (err != OPUS_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err)); if (context->encoder_object) { opus_encoder_destroy(context->encoder_object); context->encoder_object = NULL; } return SWITCH_STATUS_GENERR; } } codec->private_info = context; return SWITCH_STATUS_SUCCESS; }
int krad_opus_encoder_read (krad_opus_t *krad_opus, unsigned char *buffer, int *nframes) { int ready; int bytes; int resp; int s, c; while (krad_ringbuffer_read_space (krad_opus->ringbuf[krad_opus->channels - 1]) >= 512 * 4 ) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->ret = krad_ringbuffer_peek (krad_opus->ringbuf[c], (char *)krad_opus->samples[c], (512 * 4) ); krad_opus->src_data[c].data_in = krad_opus->samples[c]; krad_opus->src_data[c].input_frames = 512; krad_opus->src_data[c].data_out = krad_opus->resampled_samples[c]; krad_opus->src_data[c].output_frames = 2048; krad_opus->src_error[c] = src_process (krad_opus->src_resampler[c], &krad_opus->src_data[c]); if (krad_opus->src_error[c] != 0) { failfast ("Krad Opus Encoder: src resampler error: %s\n", src_strerror(krad_opus->src_error[c])); } krad_ringbuffer_read_advance (krad_opus->ringbuf[c], (krad_opus->src_data[c].input_frames_used * 4) ); krad_opus->ret = krad_ringbuffer_write (krad_opus->resampled_ringbuf[c], (char *)krad_opus->resampled_samples[c], (krad_opus->src_data[c].output_frames_gen * 4) ); } } if (krad_opus->new_bitrate != krad_opus->bitrate) { krad_opus->bitrate = krad_opus->new_bitrate; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE(krad_opus->bitrate)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: bitrate request failed %s\n", opus_strerror (resp)); } else { printk ("Krad Opus Encoder: set opus bitrate %d\n", krad_opus->bitrate); } } if (krad_opus->new_frame_size != krad_opus->frame_size) { krad_opus->frame_size = krad_opus->new_frame_size; printk ("Krad Opus Encoder: frame size is now %d\n", krad_opus->frame_size); } if (krad_opus->new_complexity != krad_opus->complexity) { krad_opus->complexity = krad_opus->new_complexity; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_COMPLEXITY(krad_opus->complexity)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: complexity request failed %s. \n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: set opus complexity %d\n", krad_opus->complexity); } } if (krad_opus->new_signal != krad_opus->signal) { krad_opus->signal = krad_opus->new_signal; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_SIGNAL(krad_opus->signal)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: signal request failed %s\n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: set opus signal mode %d\n", krad_opus->signal); } } if (krad_opus->new_bandwidth != krad_opus->bandwidth) { krad_opus->bandwidth = krad_opus->new_bandwidth; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BANDWIDTH(krad_opus->bandwidth)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: bandwidth request failed %s\n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: Set Opus bandwidth mode %d\n", krad_opus->bandwidth); } } ready = 1; for (c = 0; c < krad_opus->channels; c++) { if (krad_ringbuffer_read_space (krad_opus->resampled_ringbuf[c]) < krad_opus->frame_size * 4) { ready = 0; } } if (ready == 1) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->ret = krad_ringbuffer_read (krad_opus->resampled_ringbuf[c], (char *)krad_opus->resampled_samples[c], (krad_opus->frame_size * 4) ); } for (s = 0; s < krad_opus->frame_size; s++) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->interleaved_resampled_samples[s * krad_opus->channels + c] = krad_opus->resampled_samples[c][s]; } } bytes = opus_multistream_encode_float (krad_opus->encoder, krad_opus->interleaved_resampled_samples, krad_opus->frame_size, buffer, krad_opus->frame_size * 2); if (bytes < 0) { failfast ("Krad Opus Encoding failed: %s.", opus_strerror (bytes)); } *nframes = krad_opus->frame_size; return bytes; } return 0; }
int main(int argc, char *argv[]) { int err; char *inFile, *outFile; FILE *fin, *fout; OpusEncoder *enc; OpusDecoder *dec; int args; int len[2]; int frame_size, channels; int bitrate_bps; unsigned char *data[2]; int sampling_rate; int use_vbr; int internal_sampling_rate_Hz; int max_payload_bytes; int complexity; int use_inbandfec; int use_dtx; int forcemono; int cvbr = 0; int packet_loss_perc; int count=0, count_act=0, k; int skip; int stop=0; int tot_read=0, tot_written=0; short *in, *out; int mode; double bits=0.0, bits_act=0.0, bits2=0.0, nrg; int bandwidth=-1; const char *bandwidth_string; int write_samples; int lost, lost_prev = 1; int toggle = 0; int enc_final_range[2]; if (argc < 7 ) { print_usage( argv ); return 1; } mode = atoi(argv[1]) + OPUS_MODE_AUTO; sampling_rate = atoi(argv[2]); channels = atoi(argv[3]); bitrate_bps = atoi(argv[4]); frame_size = sampling_rate/50; /* defaults: */ use_vbr = 1; bandwidth=BANDWIDTH_AUTO; internal_sampling_rate_Hz = sampling_rate; max_payload_bytes = MAX_PACKET; complexity = 10; use_inbandfec = 0; forcemono = 0; use_dtx = 0; packet_loss_perc = 0; args = 5; while( args < argc - 2 ) { /* process command line options */ if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cbr" ) == 0 ) { use_vbr = 0; args++; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-bandwidth" ) == 0 ) { if (strcmp(argv[ args + 1 ], "NB")==0) bandwidth = BANDWIDTH_NARROWBAND; else if (strcmp(argv[ args + 1 ], "MB")==0) bandwidth = BANDWIDTH_MEDIUMBAND; else if (strcmp(argv[ args + 1 ], "WB")==0) bandwidth = BANDWIDTH_WIDEBAND; else if (strcmp(argv[ args + 1 ], "SWB")==0) bandwidth = BANDWIDTH_SUPERWIDEBAND; else if (strcmp(argv[ args + 1 ], "FB")==0) bandwidth = BANDWIDTH_FULLBAND; else { fprintf(stderr, "Unknown bandwidth %s. Supported are NB, MB, WB, SWB, FB.\n", argv[ args + 1 ]); return 1; } args += 2; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-framesize" ) == 0 ) { if (strcmp(argv[ args + 1 ], "2.5")==0) frame_size = sampling_rate/400; else if (strcmp(argv[ args + 1 ], "5")==0) frame_size = sampling_rate/200; else if (strcmp(argv[ args + 1 ], "10")==0) frame_size = sampling_rate/100; else if (strcmp(argv[ args + 1 ], "20")==0) frame_size = sampling_rate/50; else if (strcmp(argv[ args + 1 ], "40")==0) frame_size = sampling_rate/25; else if (strcmp(argv[ args + 1 ], "60")==0) frame_size = 3*sampling_rate/50; else { fprintf(stderr, "Unsupported frame size: %s ms. Supported are 2.5, 5, 10, 20, 40, 60.\n", argv[ args + 1 ]); return 1; } args += 2; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-max_payload" ) == 0 ) { max_payload_bytes = atoi( argv[ args + 1 ] ); args += 2; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-complexity" ) == 0 ) { complexity = atoi( argv[ args + 1 ] ); args += 2; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-inbandfec" ) == 0 ) { use_inbandfec = 1; args++; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-forcemono" ) == 0 ) { forcemono = 1; args++; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cvbr" ) == 0 ) { cvbr = 1; args++; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-dtx") == 0 ) { use_dtx = 1; args++; } else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-loss" ) == 0 ) { packet_loss_perc = atoi( argv[ args + 1 ] ); args += 2; } else { printf( "Error: unrecognized setting: %s\n\n", argv[ args ] ); print_usage( argv ); return 1; } } if( mode < OPUS_MODE_AUTO || mode > OPUS_MODE_AUDIO) { fprintf (stderr, "mode must be: 0, 1 or 2\n"); return 1; } if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET) { fprintf (stderr, "max_payload_bytes must be between 0 and %d\n", MAX_PACKET); return 1; } if (bitrate_bps < 0 || bitrate_bps*frame_size/sampling_rate > max_payload_bytes*8) { fprintf (stderr, "bytes per packet must be between 0 and %d\n", max_payload_bytes); return 1; } inFile = argv[argc-2]; fin = fopen(inFile, "rb"); if (!fin) { fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); return 1; } outFile = argv[argc-1]; fout = fopen(outFile, "wb+"); if (!fout) { fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); return 1; } enc = opus_encoder_create(sampling_rate, channels); dec = opus_decoder_create(sampling_rate, channels); opus_encoder_ctl(enc, OPUS_SET_MODE(mode)); opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth)); opus_encoder_ctl(enc, OPUS_SET_VBR_FLAG(use_vbr)); opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr)); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC_FLAG(use_inbandfec)); opus_encoder_ctl(enc, OPUS_SET_FORCE_MONO(forcemono)); opus_encoder_ctl(enc, OPUS_SET_DTX_FLAG(use_dtx)); opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc)); skip = 5*sampling_rate/1000; /* When SILK resamples, add 18 samples delay */ /*if (mode != MODE_SILK_ONLY || sampling_rate > 16000) skip += 18;*/ switch(bandwidth) { case BANDWIDTH_NARROWBAND: bandwidth_string = "narrowband"; break; case BANDWIDTH_MEDIUMBAND: bandwidth_string = "mediumband"; break; case BANDWIDTH_WIDEBAND: bandwidth_string = "wideband"; break; case BANDWIDTH_SUPERWIDEBAND: bandwidth_string = "superwideband"; break; case BANDWIDTH_FULLBAND: bandwidth_string = "fullband"; break; case BANDWIDTH_AUTO: bandwidth_string = "auto"; break; default: bandwidth_string = "unknown"; } printf("Encoding %d Hz input at %.3f kb/s in %s mode with %d-sample frames.\n", sampling_rate, bitrate_bps*0.001, bandwidth_string, frame_size); in = (short*)malloc(frame_size*channels*sizeof(short)); out = (short*)malloc(frame_size*channels*sizeof(short)); data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(char)); if( use_inbandfec ) { data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char)); } while (!stop) { err = fread(in, sizeof(short), frame_size*channels, fin); tot_read += err; if (err < frame_size*channels) { int i; for (i=err;i<frame_size*channels;i++) in[i] = 0; } len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes); #if OPUS_TEST_RANGE_CODER_STATE enc_final_range[toggle] = opus_encoder_get_final_range( enc ); #endif if (len[toggle] < 0) { fprintf (stderr, "opus_encode() returned %d\n", len[toggle]); return 1; } lost = rand()%100 < packet_loss_perc || len[toggle]==0; if( count >= use_inbandfec ) { /* delay by one packet when using in-band FEC */ if( use_inbandfec ) { if( lost_prev ) { /* attempt to decode with in-band FEC from next packet */ opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, frame_size, 1); } else { /* regular decode */ opus_decode(dec, data[1-toggle], len[1-toggle], out, frame_size, 0); } } else { opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, frame_size, 0); } write_samples = frame_size-skip; tot_written += write_samples*channels; if (tot_written > tot_read) { write_samples -= (tot_written-tot_read)/channels; stop = 1; } fwrite(out+skip, sizeof(short), write_samples*channels, fout); skip = 0; } #if OPUS_TEST_RANGE_CODER_STATE /* compare final range encoder rng values of encoder and decoder */ if( !lost && !lost_prev && opus_decoder_get_final_range( dec ) != enc_final_range[toggle^use_inbandfec] ) { fprintf (stderr, "Error: Range coder state mismatch between encoder and decoder in frame %d.\n", count); return 0; } #endif lost_prev = lost; /* count bits */ bits += len[toggle]*8; if( count >= use_inbandfec ) { nrg = 0.0; for ( k = 0; k < frame_size * channels; k++ ) { nrg += in[ k ] * (double)in[ k ]; } if ( ( nrg / ( frame_size * channels ) ) > 1e5 ) { bits_act += len[toggle]*8; count_act++; } /* Variance */ bits2 += len[toggle]*len[toggle]*64; } count++; toggle = (toggle + use_inbandfec) & 1; } fprintf (stderr, "average bitrate: %7.3f kb/s\n", 1e-3*bits*sampling_rate/(frame_size*(double)count)); fprintf (stderr, "active bitrate: %7.3f kb/s\n", 1e-3*bits_act*sampling_rate/(frame_size*(double)count_act)); fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n", 1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size); /* Close any files to which intermediate results were stored */ SILK_DEBUG_STORE_CLOSE_FILES silk_TimerSave("opus_timing.txt"); opus_encoder_destroy(enc); opus_decoder_destroy(dec); free(data[0]); if (use_inbandfec) free(data[1]); fclose(fin); fclose(fout); free(in); free(out); return 0; }