Exemple #1
0
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;
}
Exemple #4
0
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));
}
Exemple #5
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);
	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;
}
Exemple #6
0
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;
}
Exemple #7
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;
}
Exemple #8
0
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;

}
Exemple #9
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;
}