Пример #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_1vbr
    (JNIEnv *env, jclass clazz, jlong encoder, jint vbr)
{
    opus_int32 x = vbr;

    return
        opus_encoder_ctl((OpusEncoder *) (intptr_t) encoder, OPUS_SET_VBR(x));
}
Пример #3
0
bool OpusEncode::SetVBR(bool enable)
{
    assert(m_encoder);
    if(!m_encoder)
        return false;

    int value = enable;
    int err = opus_encoder_ctl(m_encoder, OPUS_SET_VBR(value));
    assert(err == 0);
    return err == 0;
}
Пример #4
0
static int ms_opus_enc_set_vbr(MSFilter *f) {
	OpusEncData *d = (OpusEncData *)f->data;
	int error;

	if (d->state) {
		error = opus_encoder_ctl(d->state, OPUS_SET_VBR(d->vbr));
		if (error != OPUS_OK) {
			ms_error("could not set VBR to opus encoder: %s", opus_strerror(error));
		}
	}

	return 0;
}
Пример #5
0
bool FVoiceEncoderOpus::Init(int32 InSampleRate, int32 InNumChannels)
{
	UE_LOG(LogVoiceEncode, Display, TEXT("EncoderVersion: %s"), ANSI_TO_TCHAR(opus_get_version_string()));

	SampleRate = InSampleRate;
	NumChannels = InNumChannels;

	// 20ms frame sizes are a good choice for most applications (1000ms / 20ms = 50)
	FrameSize = SampleRate / NUM_OPUS_FRAMES_PER_SEC;
	//MaxFrameSize = FrameSize * MAX_OPUS_FRAMES;

	int32 EncError = 0;

#if USE_UE4_MEM_ALLOC
	int32 EncSize = opus_encoder_get_size(NumChannels);
	Encoder = (OpusEncoder*)FMemory::Malloc(EncSize);
	EncError = opus_encoder_init(Encoder, SampleRate, NumChannels, OPUS_APPLICATION_VOIP);
#else
	Encoder = opus_encoder_create(SampleRate, NumChannels, OPUS_APPLICATION_VOIP, &EncError);
#endif

	if (EncError != OPUS_OK)
	{
		UE_LOG(LogVoiceEncode, Warning, TEXT("Failed to init Opus Encoder: %s"), ANSI_TO_TCHAR(opus_strerror(EncError)));
		Destroy();
	}

	// Turn on variable bit rate encoding
	int32 UseVbr = 1;
	opus_encoder_ctl(Encoder, OPUS_SET_VBR(UseVbr));

	// Turn off constrained VBR
	int32 UseCVbr = 0;
	opus_encoder_ctl(Encoder, OPUS_SET_VBR_CONSTRAINT(UseCVbr));

	// Complexity (1-10)
	int32 Complexity = 1;
	opus_encoder_ctl(Encoder, OPUS_SET_COMPLEXITY(Complexity));

	// Forward error correction
	int32 InbandFEC = 0;
	opus_encoder_ctl(Encoder, OPUS_SET_INBAND_FEC(InbandFEC));

#if DEBUG_OPUS
	DebugEncoderInfo(Encoder);
#endif // DEBUG_OPUS
	return EncError == OPUS_OK;
}
Пример #6
0
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;
}
Пример #7
0
            opus_encoder::opus_encoder()
            {
                int err;

                _opus = opus_encoder_create(SAMPLE_RATE,CHANNELS, OPUS_APPLICATION_VOIP, &err); 

                if(err != OPUS_OK) 
                { 
                    LOG << "opus encoder create error: "; 
                    log_opus_error(err);
                }

                opus_encoder_ctl(_opus, OPUS_SET_BITRATE(OPUS_AUTO));
                opus_encoder_ctl(_opus, OPUS_SET_VBR(1));
                opus_encoder_ctl(_opus, OPUS_SET_FORCE_CHANNELS(1)); //force mono
                opus_encoder_ctl(_opus, OPUS_SET_PACKET_LOSS_PERC(2));

                ENSURE(_opus);
            }
Пример #8
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;
}
Пример #9
0
/*
 * Open codec.
 */
static pj_status_t  codec_open( pjmedia_codec *codec,
				pjmedia_codec_param *attr )
{
    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
    int idx, err;

    PJ_ASSERT_RETURN(codec && attr && opus_data, PJ_EINVAL);

    pj_mutex_lock (opus_data->mutex);

    TRACE_((THIS_FILE, "%s:%d: - TRACE", __FUNCTION__, __LINE__));

    opus_data->cfg.sample_rate = attr->info.clock_rate;
    opus_data->cfg.channel_cnt = attr->info.channel_cnt;
    opus_data->ptime       = attr->info.frm_ptime;

    /* Allocate memory used by the codec */
    if (!opus_data->enc) {
	/* Allocate memory for max 2 channels */
	opus_data->enc = pj_pool_zalloc(opus_data->pool,
					opus_encoder_get_size(2));
    }
    if (!opus_data->dec) {
	/* Allocate memory for max 2 channels */
	opus_data->dec = pj_pool_zalloc(opus_data->pool,
					opus_decoder_get_size(2));
    }
    if (!opus_data->enc_packer) {
	opus_data->enc_packer = pj_pool_zalloc(opus_data->pool,
					       opus_repacketizer_get_size());
    }
    if (!opus_data->dec_packer) {
	opus_data->dec_packer = pj_pool_zalloc(opus_data->pool,
					       opus_repacketizer_get_size());
    }
    if (!opus_data->enc || !opus_data->dec ||
	!opus_data->enc_packer || !opus_data->dec_packer)
    {
	PJ_LOG(2, (THIS_FILE, "Unable to allocate memory for the codec"));
        pj_mutex_unlock (opus_data->mutex);
	return PJ_ENOMEM;
    }

    /* Check max average bit rate */
    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_MAX_BIT_RATE, PJ_FALSE);
    if (idx >= 0) {
	unsigned rate;
	rate = (unsigned)pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
	if (rate < attr->info.avg_bps)
	    attr->info.avg_bps = rate;
    }

    /* Check plc */
    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_INBAND_FEC, PJ_FALSE);
    if (idx >= 0) {
	unsigned plc;
	plc = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
	attr->setting.plc = plc > 0? PJ_TRUE: PJ_FALSE;
    }

    /* Check vad */
    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_DTX, PJ_FALSE);
    if (idx >= 0) {
	unsigned vad;
	vad = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
	attr->setting.vad = vad > 0? PJ_TRUE: PJ_FALSE;
    }

    /* Check cbr */
    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_CBR, PJ_FALSE);
    if (idx >= 0) {
	unsigned cbr;
	cbr = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
	opus_data->cfg.cbr = cbr > 0? PJ_TRUE: PJ_FALSE;
    }
    
    /* Check max average bit rate */
    idx = find_fmtp(&attr->setting.dec_fmtp, &STR_MAX_BIT_RATE, PJ_FALSE);
    if (idx >= 0) {
	unsigned rate;
	rate = (unsigned) pj_strtoul(&attr->setting.dec_fmtp.param[idx].val);
	if (rate < attr->info.avg_bps)
	    attr->info.avg_bps = rate;
    }

    TRACE_((THIS_FILE, "%s:%d: sample_rate: %u",
	    __FUNCTION__, __LINE__, opus_data->cfg.sample_rate));

    /* Initialize encoder */
    err = opus_encoder_init(opus_data->enc,
			    opus_data->cfg.sample_rate,
			    attr->info.channel_cnt,
			    OPUS_APPLICATION_VOIP);
    if (err != OPUS_OK) {
	PJ_LOG(2, (THIS_FILE, "Unable to create encoder"));
	return PJMEDIA_CODEC_EFAILED;
    }
    
    /* Set signal type */
    opus_encoder_ctl(opus_data->enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
    /* Set bitrate */
    opus_encoder_ctl(opus_data->enc, OPUS_SET_BITRATE(attr->info.avg_bps));
    /* Set VAD */
    opus_encoder_ctl(opus_data->enc, OPUS_SET_DTX(attr->setting.vad ? 1 : 0));
    /* Set PLC */
    opus_encoder_ctl(opus_data->enc,
    		     OPUS_SET_INBAND_FEC(attr->setting.plc ? 1 : 0));
    /* Set bandwidth */
    opus_encoder_ctl(opus_data->enc,
    		     OPUS_SET_MAX_BANDWIDTH(get_opus_bw_constant(
    					    opus_data->cfg.sample_rate)));
    /* Set expected packet loss */
    opus_encoder_ctl(opus_data->enc,
    		OPUS_SET_PACKET_LOSS_PERC(opus_data->cfg.packet_loss));
    /* Set complexity */
    opus_encoder_ctl(opus_data->enc,
		     OPUS_SET_COMPLEXITY(opus_data->cfg.complexity));
    /* Set constant bit rate */
    opus_encoder_ctl(opus_data->enc,
    		     OPUS_SET_VBR(opus_data->cfg.cbr ? 0 : 1));

    PJ_LOG(5, (THIS_FILE, "Initialize Opus encoder, sample rate: %d, "
    			  "avg bitrate: %d, vad: %d, plc: %d, pkt loss: %d, "
    			  "complexity: %d, constant bit rate: %d",
               		  opus_data->cfg.sample_rate,
               		  attr->info.avg_bps, attr->setting.vad?1:0,
               		  attr->setting.plc?1:0,
               		  opus_data->cfg.packet_loss,
               		  opus_data->cfg.complexity,
               		  opus_data->cfg.cbr?1:0));

    /* Initialize decoder */
    err = opus_decoder_init (opus_data->dec,
			     opus_data->cfg.sample_rate,
			     attr->info.channel_cnt);
    if (err != OPUS_OK) {
	PJ_LOG(2, (THIS_FILE, "Unable to initialize decoder"));
	return PJMEDIA_CODEC_EFAILED;
    }

    /* Initialize temporary decode frames used for FEC */
    opus_data->dec_frame[0].type = PJMEDIA_FRAME_TYPE_NONE;
    opus_data->dec_frame[0].buf  = pj_pool_zalloc(opus_data->pool,                                   
        	(opus_data->cfg.sample_rate / 1000)
                * 60 * attr->info.channel_cnt * 2 /* bytes per sample */);
    opus_data->dec_frame[1].type = PJMEDIA_FRAME_TYPE_NONE;
    opus_data->dec_frame[1].buf  = pj_pool_zalloc(opus_data->pool,
		(opus_data->cfg.sample_rate / 1000)
                * 60 * attr->info.channel_cnt * 2 /* bytes per sample */);
    opus_data->dec_frame_index = -1;

    /* Initialize the repacketizers */
    opus_repacketizer_init(opus_data->enc_packer);
    opus_repacketizer_init(opus_data->dec_packer);

    pj_mutex_unlock (opus_data->mutex);
    return PJ_SUCCESS;
}
Пример #10
0
bool OpusCodec::startCodec()
{
#ifdef HAVE_OPUS
  int err;

  //
  // Load Libraries
  //
  opus_handle=dlopen("libopus.so.0",RTLD_LAZY);

  if(opus_handle==NULL) {
    Log(LOG_ERR,"unsupported audio format (library not found)");
    return false;
  }
  *(void **)(&opus_encoder_create)=dlsym(opus_handle,"opus_encoder_create");
  *(void **)(&opus_encoder_init)=dlsym(opus_handle,"opus_encoder_init");
  *(void **)(&opus_encode)=dlsym(opus_handle,"opus_encode");
  *(void **)(&opus_encode_float)=dlsym(opus_handle,"opus_encode_float");
  *(void **)(&opus_encoder_destroy)=dlsym(opus_handle,"opus_encoder_destroy");
  *(void **)(&opus_encoder_ctl)=dlsym(opus_handle,"opus_encoder_ctl");
  *(void **)(&opus_strerror)=dlsym(opus_handle,"opus_strerror");

  opus_ogg_handle=dlopen("libogg.so.0",RTLD_LAZY);
  if(opus_ogg_handle==NULL) {
    Log(LOG_ERR,"unsupported audio format (library not found)");
    return false;
  }
  *(void **)(&oggpack_writeinit)=dlsym(opus_ogg_handle,"oggpack_writeint");
  *(void **)(&oggpack_writecheck)=dlsym(opus_ogg_handle,"oggpack_writecheck");
  *(void **)(&oggpack_writetrunc)=dlsym(opus_ogg_handle,"oggpack_writetrunc");
  *(void **)(&oggpack_writealign)=dlsym(opus_ogg_handle,"oggpack_writealign");
  *(void **)(&oggpack_writecopy)=dlsym(opus_ogg_handle,"oggpack_writecopy");
  *(void **)(&oggpack_reset)=dlsym(opus_ogg_handle,"oggpack_reset");
  *(void **)(&oggpack_writeclear)=dlsym(opus_ogg_handle,"oggpack_writeclear");
  *(void **)(&oggpack_readinit)=dlsym(opus_ogg_handle,"oggpack_readinit");
  *(void **)(&oggpack_write)=dlsym(opus_ogg_handle,"oggpack_write");
  *(void **)(&oggpack_look)=dlsym(opus_ogg_handle,"oggpack_look");
  *(void **)(&oggpack_look1)=dlsym(opus_ogg_handle,"oggpack_look1");
  *(void **)(&oggpack_adv)=dlsym(opus_ogg_handle,"oggpack_adv");
  *(void **)(&oggpack_adv1)=dlsym(opus_ogg_handle,"oggpack_adv1");
  *(void **)(&oggpack_read)=dlsym(opus_ogg_handle,"oggpack_read");
  *(void **)(&oggpack_read1)=dlsym(opus_ogg_handle,"oggpack_read1");
  *(void **)(&oggpack_bytes)=dlsym(opus_ogg_handle,"oggpack_bytes");
  *(void **)(&oggpack_bits)=dlsym(opus_ogg_handle,"oggpack_bits");
    *(void **)(&oggpack_get_buffer)=
      dlsym(opus_ogg_handle,"oggpack_get_buffer");
  *(void **)(&oggpackB_writeinit)=dlsym(opus_ogg_handle,"oggpackB_writeinit");
  *(void **)(&oggpackB_writecheck)=
    dlsym(opus_ogg_handle,"oggpackB_writecheck");
  *(void **)(&oggpackB_writetrunc)=
    dlsym(opus_ogg_handle,"oggpackB_writetrunc");
  *(void **)(&oggpackB_writealign)=
    dlsym(opus_ogg_handle,"oggpackB_writealign");
  *(void **)(&oggpackB_writecopy)=dlsym(opus_ogg_handle,"oggpackB_writecopy");
  *(void **)(&oggpackB_reset)=dlsym(opus_ogg_handle,"oggpackB_reset");
  *(void **)(&oggpackB_writeclear)=
    dlsym(opus_ogg_handle,"oggpackB_writeclear");
  *(void **)(&oggpackB_readinit)=dlsym(opus_ogg_handle,"oggpackB_readini");
  *(void **)(&oggpackB_write)=dlsym(opus_ogg_handle,"oggpackB_write");
  *(void **)(&oggpackB_look)=dlsym(opus_ogg_handle,"oggpackB_look");
  *(void **)(&oggpackB_look1)=dlsym(opus_ogg_handle,"oggpackB_look1");
  *(void **)(&oggpackB_adv)=dlsym(opus_ogg_handle,"oggpackB_adv");
  *(void **)(&oggpackB_adv1)=dlsym(opus_ogg_handle,"oggpackB_adv1");
  *(void **)(&oggpackB_read)=dlsym(opus_ogg_handle,"oggpackB_read");
  *(void **)(&oggpackB_read1)=dlsym(opus_ogg_handle,"oggpackB_read1");
  *(void **)(&oggpackB_bytes)=dlsym(opus_ogg_handle,"oggpackB_bytes");
  *(void **)(&oggpackB_bits)=dlsym(opus_ogg_handle,"oggpackB_bits");
  *(void **)(&oggpackB_get_buffer)=
    dlsym(opus_ogg_handle,"oggpackB_get_buffer");
  *(void **)(&ogg_stream_packetin)=
    dlsym(opus_ogg_handle,"ogg_stream_packetin");
  *(void **)(&ogg_stream_iovecin)=dlsym(opus_ogg_handle,"ogg_stream_iovecin");
  *(void **)(&ogg_stream_pageout)=dlsym(opus_ogg_handle,"ogg_stream_pageout");
  *(void **)(&ogg_stream_flush)=dlsym(opus_ogg_handle,"ogg_stream_flush");
  *(void **)(&ogg_sync_init)=dlsym(opus_ogg_handle,"ogg_sync_init");
  *(void **)(&ogg_sync_clear)=dlsym(opus_ogg_handle,"ogg_sync_clear");
  *(void **)(&ogg_sync_reset)=dlsym(opus_ogg_handle,"ogg_sync_reset");
  *(void **)(&ogg_sync_destroy)=dlsym(opus_ogg_handle,"ogg_sync_destroy");
  *(void **)(&ogg_sync_check)=dlsym(opus_ogg_handle,"ogg_sync_check");
  *(void **)(&ogg_sync_buffer)=dlsym(opus_ogg_handle,"ogg_sync_buffer");
  *(void **)(&ogg_sync_wrote)=dlsym(opus_ogg_handle,"ogg_sync_wrote");
  *(void **)(&ogg_sync_pageseek)=dlsym(opus_ogg_handle,"ogg_sync_pageseek");
  *(void **)(&ogg_sync_pageout)=dlsym(opus_ogg_handle,"ogg_sync_pageout");
  *(void **)(&ogg_stream_pagein)=dlsym(opus_ogg_handle,"ogg_stream_pagein");
  *(void **)(&ogg_stream_packetout)=
    dlsym(opus_ogg_handle,"ogg_stream_packetout");
  *(void **)(&ogg_stream_packetpeek)=
    dlsym(opus_ogg_handle,"ogg_stream_packetpeek");
  *(void **)(&ogg_stream_init)=dlsym(opus_ogg_handle,"ogg_stream_init");
  *(void **)(&ogg_stream_clear)=dlsym(opus_ogg_handle,"ogg_stream_clear");
  *(void **)(&ogg_stream_reset)=dlsym(opus_ogg_handle,"ogg_stream_reset");
  *(void **)(&ogg_stream_reset_serialno)=
    dlsym(opus_ogg_handle,"ogg_stream_reset_serialn");
  *(void **)(&ogg_stream_destroy)=dlsym(opus_ogg_handle,"ogg_stream_destroy");
  *(void **)(&ogg_stream_check)=dlsym(opus_ogg_handle,"ogg_stream_check");
  *(void **)(&ogg_stream_eos)=dlsym(opus_ogg_handle,"ogg_stream_eos");
  *(void **)(&ogg_page_checksum_set)=
    dlsym(opus_ogg_handle,"ogg_page_checksum_set");
  *(void **)(&ogg_page_version)=dlsym(opus_ogg_handle,"ogg_page_version");
  *(void **)(&ogg_page_continued)=dlsym(opus_ogg_handle,"ogg_page_continued");
  *(void **)(&ogg_page_bos)=dlsym(opus_ogg_handle,"ogg_page_bos");
  *(void **)(&ogg_page_eos)=dlsym(opus_ogg_handle,"ogg_page_eos");
  *(void **)(&ogg_page_granulepos)=
    dlsym(opus_ogg_handle,"ogg_page_granulepos");
  *(void **)(&ogg_page_serialno)=dlsym(opus_ogg_handle,"ogg_page_serialno");
  *(void **)(&ogg_page_pageno)=dlsym(opus_ogg_handle,"ogg_page_pageno");
  *(void **)(&ogg_page_packets)=dlsym(opus_ogg_handle,"ogg_page_packets");
  *(void **)(&ogg_packet_clear)=dlsym(opus_ogg_handle,"ogg_packet_clear");

  //
  // Initialize Encoder Instance
  //
  if((opus_encoder=opus_encoder_create(streamSamplerate(),channels(),
				       OPUS_APPLICATION_AUDIO,&err))==NULL) {
    Log(LOG_ERR,QString().sprintf("unable to create codec [%s]",
				  opus_strerror(err)));
    return false;
  }
  if(bitrate()==0) {
    opus_encoder_ctl(opus_encoder,OPUS_SET_VBR(1));
    opus_encoder_ctl(opus_encoder,OPUS_SET_COMPLEXITY(10.0*quality()));
  }
  else {
    opus_encoder_ctl(opus_encoder,OPUS_SET_VBR(0));
    opus_encoder_ctl(opus_encoder,OPUS_SET_BITRATE(1000*bitrate()));
  }
  opus_encoder_ctl(opus_encoder,
		   OPUS_SET_COMPLEXITY(OPUSCODEC_ENCODER_COMPLEXITY));

  //
  // Initialize the stream
  //
  ogg_stream_init(&opus_ogg_stream,rand());

  //
  // Header Packet
  //
  QByteArray info=MakeInfoHeader(channels(),streamSamplerate());
  opus_ogg_packet.packet=(unsigned char *)info.constData();
  opus_ogg_packet.bytes=info.length();
  opus_ogg_packet.b_o_s=1;
  opus_ogg_packet.e_o_s=0;
  opus_ogg_packet.granulepos=0;
  opus_ogg_packet.packetno=opus_packet_number++;
  ogg_stream_packetin(&opus_ogg_stream,&opus_ogg_packet);
  while(ogg_stream_flush(&opus_ogg_stream,&opus_ogg_page)) {
    opus_stream_prologue.append((const char *)opus_ogg_page.header,
			     opus_ogg_page.header_len);
    opus_stream_prologue.append((const char *)opus_ogg_page.body,
			     opus_ogg_page.body_len);
  }

  //
  // Comment Packet
  //
  QByteArray comment=MakeCommentHeader();
  opus_ogg_packet.packet=(unsigned char *)comment.constData();
  opus_ogg_packet.bytes=comment.length();
  opus_ogg_packet.b_o_s=0;
  opus_ogg_packet.e_o_s=0;
  opus_ogg_packet.granulepos=0;
  opus_ogg_packet.packetno=opus_packet_number++;
  ogg_stream_packetin(&opus_ogg_stream,&opus_ogg_packet);
  while(ogg_stream_flush(&opus_ogg_stream,&opus_ogg_page)!=0) {
    opus_stream_prologue.append((const char *)opus_ogg_page.header,
			     opus_ogg_page.header_len);
    opus_stream_prologue.append((const char *)opus_ogg_page.body,
			     opus_ogg_page.body_len);
  }
  return true;
#else
  Log(LOG_ERR,"unsupported audio format (no build support)");
  return false;
#endif  // HAVE_OPUS
}
Пример #11
0
static void
gst_opus_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstOpusEnc *enc;

  enc = GST_OPUS_ENC (object);

#define GST_OPUS_UPDATE_PROPERTY(prop,type,ctl) do { \
  g_mutex_lock (enc->property_lock); \
  enc->prop = g_value_get_##type (value); \
  if (enc->state) { \
    opus_multistream_encoder_ctl (enc->state, OPUS_SET_##ctl (enc->prop)); \
  } \
  g_mutex_unlock (enc->property_lock); \
} while(0)

  switch (prop_id) {
    case PROP_AUDIO:
      enc->audio_or_voip = g_value_get_boolean (value);
      break;
    case PROP_BITRATE:
      GST_OPUS_UPDATE_PROPERTY (bitrate, int, BITRATE);
      break;
    case PROP_BANDWIDTH:
      GST_OPUS_UPDATE_PROPERTY (bandwidth, enum, BANDWIDTH);
      break;
    case PROP_FRAME_SIZE:
      g_mutex_lock (enc->property_lock);
      enc->frame_size = g_value_get_enum (value);
      enc->frame_samples = gst_opus_enc_get_frame_samples (enc);
      gst_opus_enc_setup_base_class (enc, GST_AUDIO_ENCODER (enc));
      g_mutex_unlock (enc->property_lock);
      break;
    case PROP_CBR:
      /* this one has an opposite meaning to the opus ctl... */
      g_mutex_lock (enc->property_lock);
      enc->cbr = g_value_get_boolean (value);
      opus_multistream_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr));
      g_mutex_unlock (enc->property_lock);
      break;
    case PROP_CONSTRAINED_VBR:
      GST_OPUS_UPDATE_PROPERTY (constrained_vbr, boolean, VBR_CONSTRAINT);
      break;
    case PROP_COMPLEXITY:
      GST_OPUS_UPDATE_PROPERTY (complexity, int, COMPLEXITY);
      break;
    case PROP_INBAND_FEC:
      GST_OPUS_UPDATE_PROPERTY (inband_fec, boolean, INBAND_FEC);
      break;
    case PROP_DTX:
      GST_OPUS_UPDATE_PROPERTY (dtx, boolean, DTX);
      break;
    case PROP_PACKET_LOSS_PERCENT:
      GST_OPUS_UPDATE_PROPERTY (packet_loss_percentage, int, PACKET_LOSS_PERC);
      break;
    case PROP_MAX_PAYLOAD_SIZE:
      g_mutex_lock (enc->property_lock);
      enc->max_payload_size = g_value_get_uint (value);
      g_mutex_unlock (enc->property_lock);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

#undef GST_OPUS_UPDATE_PROPERTY

}
Пример #12
0
int opus_encode_update(struct auenc_state **aesp, const struct aucodec *ac,
		       struct auenc_param *param, const char *fmtp)
{
	struct auenc_state *aes;
	struct opus_param prm, conf_prm;
	opus_int32 fch, vbr;
	const struct aucodec *auc = ac;

	(void)param;

	if (!aesp || !ac || !ac->ch)
		return EINVAL;

	debug("opus: encoder fmtp (%s)\n", fmtp);

	/* Save the incoming OPUS parameters from SDP offer */
	if (str_isset(fmtp)) {
		opus_mirror_params(fmtp);
	}

	aes = *aesp;

	if (!aes) {
		const opus_int32 complex = 10;
		int opuserr;

		aes = mem_zalloc(sizeof(*aes), destructor);
		if (!aes)
			return ENOMEM;

		aes->ch = ac->ch;

		aes->enc = opus_encoder_create(ac->srate, ac->ch,
					       /* this has big impact on cpu */
					       OPUS_APPLICATION_AUDIO,
					       &opuserr);
		if (!aes->enc) {
			warning("opus: encoder create: %s\n",
				opus_strerror(opuserr));
			mem_deref(aes);
			return ENOMEM;
		}

		(void)opus_encoder_ctl(aes->enc, OPUS_SET_COMPLEXITY(complex));

		*aesp = aes;
	}

	prm.srate      = 48000;
	prm.bitrate    = OPUS_AUTO;
	prm.stereo     = 1;
	prm.cbr        = 0;
	prm.inband_fec = 0;
	prm.dtx        = 0;

	opus_decode_fmtp(&prm, fmtp);

	conf_prm.bitrate = OPUS_AUTO;
	opus_decode_fmtp(&conf_prm, auc->fmtp);

	if ((prm.bitrate == OPUS_AUTO) ||
	    ((conf_prm.bitrate != OPUS_AUTO) &&
	     (conf_prm.bitrate < prm.bitrate)))
		prm.bitrate = conf_prm.bitrate;

	fch = prm.stereo ? OPUS_AUTO : 1;
	vbr = prm.cbr ? 0 : 1;

	(void)opus_encoder_ctl(aes->enc,
			       OPUS_SET_MAX_BANDWIDTH(srate2bw(prm.srate)));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_BITRATE(prm.bitrate));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_FORCE_CHANNELS(fch));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_VBR(vbr));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_INBAND_FEC(prm.inband_fec));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_DTX(prm.dtx));


#if 0
	{
	opus_int32 bw, complex;

	(void)opus_encoder_ctl(aes->enc, OPUS_GET_MAX_BANDWIDTH(&bw));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_BITRATE(&prm.bitrate));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_FORCE_CHANNELS(&fch));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_VBR(&vbr));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_INBAND_FEC(&prm.inband_fec));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_DTX(&prm.dtx));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_COMPLEXITY(&complex));

	debug("opus: encode bw=%s bitrate=%i fch=%s "
	      "vbr=%i fec=%i dtx=%i complex=%i\n",
	      bwname(bw), prm.bitrate, chname(fch),
	      vbr, prm.inband_fec, prm.dtx, complex);
	}
#endif

	return 0;
}
Пример #13
0
AudioInput::AudioInput() : opusBuffer(g.s.iFramesPerPacket * (SAMPLE_RATE / 100)) {
	adjustBandwidth(g.iMaxBandwidth, iAudioQuality, iAudioFrames);

	g.iAudioBandwidth = getNetworkBandwidth(iAudioQuality, iAudioFrames);

	umtType = MessageHandler::UDPVoiceCELTAlpha;

	cCodec = NULL;
	ceEncoder = NULL;

	iSampleRate = SAMPLE_RATE;
	iFrameSize = SAMPLE_RATE / 100;

#ifdef USE_OPUS
	opusState = opus_encoder_create(SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, NULL);
	opus_encoder_ctl(opusState, OPUS_SET_VBR(0)); // CBR
#endif

	qWarning("AudioInput: %d bits/s, %d hz, %d sample", iAudioQuality, iSampleRate, iFrameSize);
	iEchoFreq = iMicFreq = iSampleRate;

	iFrameCounter = 0;
	iSilentFrames = 0;
	iHoldFrames = 0;
	iBufferedFrames = 0;

	bResetProcessor = true;

	bEchoMulti = false;

	sppPreprocess = NULL;
	sesEcho = NULL;
	srsMic = srsEcho = NULL;
	iJitterSeq = 0;
	iMinBuffered = 1000;

	psMic = new short[iFrameSize];
	psClean = new short[iFrameSize];

	psSpeaker = NULL;

	iEchoChannels = iMicChannels = 0;
	iEchoFilled = iMicFilled = 0;
	eMicFormat = eEchoFormat = SampleFloat;
	iMicSampleSize = iEchoSampleSize = 0;

	bPreviousVoice = false;

	bResetEncoder = true;

	pfMicInput = pfEchoInput = pfOutput = NULL;

	iBitrate = 0;
	dPeakSignal = dPeakSpeaker = dPeakMic = dPeakCleanMic = 0.0;

	if (g.uiSession) {
		setMaxBandwidth(g.iMaxBandwidth);
	}

	bRunning = true;

	connect(this, SIGNAL(doDeaf()), g.mw->qaAudioDeaf, SLOT(trigger()), Qt::QueuedConnection);
	connect(this, SIGNAL(doMute()), g.mw->qaAudioMute, SLOT(trigger()), Qt::QueuedConnection);
}
Пример #14
0
int mumble_connect(lua_State *l)
{
	const char* server_host_str = luaL_checkstring(l, 1);
	int port = luaL_checkinteger(l, 2);

	const char* certificate_file = luaL_checkstring(l, 3);
	const char* key_file = luaL_checkstring(l, 4);

	MumbleClient *client = lua_newuserdata(l, sizeof(MumbleClient));
	luaL_getmetatable(l, METATABLE_CLIENT);
	lua_setmetatable(l, -2);

	lua_rawgeti(l, LUA_REGISTRYINDEX, MUMBLE_CONNECTIONS);
	lua_pushvalue(l, -2);

	client->self = luaL_ref(l, -2);
	lua_pop(l, 1);

	client->l = l;

	lua_newtable(l);
	client->hooks = luaL_ref(l, LUA_REGISTRYINDEX);

	lua_newtable(l);
	client->users = luaL_ref(l, LUA_REGISTRYINDEX);

	lua_newtable(l);
	client->channels = luaL_ref(l, LUA_REGISTRYINDEX);

	client->host = server_host_str;
	client->port = port;
	client->nextping = gettime() + PING_TIMEOUT;
	client->time = gettime();
	client->volume = 1;
	client->audio_job = NULL;
	client->connected = true;
	client->synced = false;
	client->audio_finished = false;
	client->audio_target = 0;

	int err;
	client->encoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &err);

	if (err != OPUS_OK) {
		lua_pushnil(l);
		lua_pushfstring(l, "could not initialize encoder: %s", opus_strerror(err));
		return 2;
	}

	opus_encoder_ctl(client->encoder, OPUS_SET_VBR(0));
	opus_encoder_ctl(client->encoder, OPUS_SET_BITRATE(40000));

	client->socket = socket(AF_INET, SOCK_STREAM, 0);
	if (client->socket < 0) {
		lua_pushnil(l);
		lua_pushfstring(l, "could not create socket: %s", strerror(errno));
		return 2;
	}

	struct timeval timeout;
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;

	if (setsockopt(client->socket, SOL_SOCKET, (SO_RCVTIMEO | SO_SNDTIMEO), (char *)&timeout, sizeof(timeout)) < 0) {
		lua_pushnil(l);
		lua_pushfstring(l, "setsockopt failed: %s", strerror(errno));
		return 2;
	}

	client->ssl_context = SSL_CTX_new(SSLv23_client_method());

	if (client->ssl_context == NULL) {
		lua_pushnil(l);
		lua_pushstring(l, "could not create SSL context");
		return 2;
	}

	if (certificate_file != NULL) {
		if (!SSL_CTX_use_certificate_chain_file(client->ssl_context, certificate_file) ||
			!SSL_CTX_use_PrivateKey_file(client->ssl_context, key_file, SSL_FILETYPE_PEM) ||
			!SSL_CTX_check_private_key(client->ssl_context)) {

			lua_pushnil(l);
			lua_pushstring(l, "could not load certificate and/or key file");
			return 2;
		}
	}

	struct hostent *server_host;
	struct sockaddr_in server_addr;

	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(port);

	server_host = gethostbyname(server_host_str);
	if (server_host == NULL || server_host->h_addr_list[0] == NULL || server_host->h_addrtype != AF_INET) {
		lua_pushnil(l);
		lua_pushstring(l, "could not parse server address");
		return 2;
	}
	memmove(&server_addr.sin_addr, server_host->h_addr_list[0], server_host->h_length);

	if (connect(client->socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) {
		lua_pushnil(l);
		lua_pushfstring(l, "could not connect to server: %s", strerror(errno));
		return 2;
	}
	
	client->ssl = SSL_new(client->ssl_context);

	if (client->ssl == NULL) {
		lua_pushnil(l);
		lua_pushstring(l, "could not create SSL object");
		return 2;
	}

	if (SSL_set_fd(client->ssl, client->socket) == 0) {
		lua_pushnil(l);
		lua_pushstring(l, "could not set SSL file descriptor");
		return 2;
	}

	if (err = SSL_connect(client->ssl) != 1) {
		lua_pushnil(l);
		lua_pushfstring(l, "could not create secure connection: %s", SSL_get_error(client->ssl, err));
		return 2;
	}

	// Non blocking after connect
	int flags = fcntl(client->socket, F_GETFL, 0);
	fcntl(client->socket, F_SETFL, flags | O_NONBLOCK);

	if (pthread_mutex_init(&client->lock , NULL)) {
		lua_pushnil(l);
		lua_pushstring(l, "could not init mutex");
		return 2;
	}

	if (pthread_cond_init(&client->cond, NULL)) {
		lua_pushnil(l);
		lua_pushstring(l, "could not init condition");
		return 2;
	}

	if (pthread_create(&client->audio_thread, NULL, (void*) mumble_audiothread, client)){
		lua_pushnil(l);
		lua_pushstring(l, "could not create audio thread");
		return 2;
	}

	return 1;
}
Пример #15
0
int
main(int argc, char *argv[])
{
    struct hostent *server_host;
    char *server_host_str = "localhost";
    char *certificate_file = NULL;
    char *key_file = NULL;
    char *password_file = NULL;
    char *token_file = NULL;
    char *username = "******";
    int port = 64738;
    int ret;
    int development_mode = 0;

    int socket_fd;
    struct sockaddr_in server_addr;

    SSLRead socket_watcher;
    ev_io user_thread_watcher;
    ev_timer ping_watcher;
    ev_signal signal_watcher;
    ev_loop_main = EV_DEFAULT;

    /*
     * Lua initialization
     */
    lua = luaL_newstate();
    if (lua == NULL) {
        fprintf(stderr, "%s: could not initialize Lua\n", PIEPAN_NAME);
        return 1;
    }
    luaL_openlibs(lua);
    if (luaL_loadbuffer(lua, (const char *)src_piepan_impl_luac,
            src_piepan_impl_luac_len, "piepan_impl") != LUA_OK) {
        fprintf(stderr, "%s: could not load piepan implementation\n", PIEPAN_NAME);
        return 1;
    }
    lua_call(lua, 0, 0);

    lua_getglobal(lua, "piepan");
    lua_getfield(lua, -1, "internal");
    lua_getfield(lua, -1, "api");
    lua_pushcfunction(lua, api_init);
    lua_setfield(lua, -2, "apiInit");
    lua_settop(lua, 0);

    /*
     * Argument parsing
     */
    {
        int opt;
        int i;
        int show_help = 0;
        int show_version = 0;
        lua_getglobal(lua, "piepan");
        lua_getfield(lua, -1, "internal");
        lua_getfield(lua, -1, "events");
        lua_getfield(lua, -1, "onArgument");
        opterr = 0;
        while ((opt = getopt(argc, argv, "u:c:k:s:t:p:-:dhv")) != -1) {
            switch (opt) {
                case 'u':
                    username = optarg;
                    break;
                case 'c':
                    certificate_file = optarg;
                    if (key_file == NULL) {
                        key_file = certificate_file;
                    }
                    break;
                case 'k':
                    key_file = optarg;
                    break;
                case 's': {
                    char *port_str;
                    server_host_str = optarg;
                    port_str = strrchr(server_host_str, ':');
                    if (port_str != NULL) {
                        *port_str = '\0';
                        port = atoi(++port_str);
                    }
                    break;
                }
                case 't':
                    token_file = optarg;
                    break;
                case 'p':
                    password_file = optarg;
                    break;
                case '-': {
                    char *key = optarg;
                    char *value = strchr(key, '=');
                    if (key == value) {
                        break;
                    }
                    if (value != NULL) {
                        *value++ = 0;
                    }
                    lua_pushvalue(lua, -1);
                    lua_pushstring(lua, key);
                    lua_pushstring(lua, value);
                    lua_call(lua, 2, 0);
                    break;
                }
                case 'd':
                    development_mode = 1;
                    break;
                case 'h':
                    usage(stdout);
                    return 0;
                case 'v':
                    printf("%s %s (compiled on " __DATE__ " " __TIME__ ")\n",
                           PIEPAN_NAME, PIEPAN_VERSION);
                    return 0;
                default:
                    fprintf(stderr, "%s: unknown or incomplete option '%c'\n",
                            PIEPAN_NAME, optopt);
                    return 1;
            }
        }
        lua_settop(lua, 0);
    }

    /*
     * Load user scripts
     */
    {
        int i;
        lua_getglobal(lua, "piepan");
        lua_getfield(lua, -1, "internal");
        lua_getfield(lua, -1, "events");
        lua_getfield(lua, -1, "onLoadScript");
        for (i = optind; i < argc; i++) {
            lua_pushvalue(lua, -1);
            lua_pushstring(lua, argv[i]);
            if (development_mode) {
                lua_newuserdata(lua, sizeof(ScriptStat));
            } else {
                lua_pushnil(lua);
            }
            lua_call(lua, 2, 3);
            if (lua_toboolean(lua, -3)) {
                if (development_mode) {
                    ScriptStat *item = lua_touserdata(lua, -1);
                    item->lua = lua;
                    item->id = lua_tointeger(lua, -2);
                    item->filename = argv[i];
                    ev_stat_init(&item->ev, script_stat_event, item->filename, 0);
                    ev_stat_start(ev_loop_main, &item->ev);
                }
            } else {
                fprintf(stderr, "%s: %s\n", PIEPAN_NAME, lua_tostring(lua, -2));
            }
            lua_pop(lua, 3);
        }
        lua_settop(lua, 0);
    }

    /*
     * Initialize Opus
     */
    {
        OpusEncoder *encoder;
        int error;

        lua_getglobal(lua, "piepan");
        lua_getfield(lua, -1, "internal");
        lua_getfield(lua, -1, "opus");
        encoder = lua_newuserdata(lua, opus_encoder_get_size(1));
        lua_setfield(lua, -2, "encoder");

        error = opus_encoder_init(encoder, 48000, 1, OPUS_APPLICATION_AUDIO);
        if (error != OPUS_OK) {
            fprintf(stderr, "%s: could not initialize the Opus encoder: %s\n",
                    PIEPAN_NAME, opus_strerror(error));
            return 1;
        }
        opus_encoder_ctl(encoder, OPUS_SET_VBR(0));
        /* TODO: set this to the server's max bitrate */
        opus_encoder_ctl(encoder, OPUS_SET_BITRATE(40000));

        lua_settop(lua, 0);
    }

    /*
     * SSL initialization
     */
    SSL_library_init();

    ssl_context = SSL_CTX_new(SSLv23_client_method());
    if (ssl_context == NULL) {
        fprintf(stderr, "%s: could not create SSL context\n", PIEPAN_NAME);
        return 1;
    }

    if (certificate_file != NULL) {
        if (!SSL_CTX_use_certificate_chain_file(ssl_context, certificate_file) ||
                !SSL_CTX_use_PrivateKey_file(ssl_context, key_file,
                                                SSL_FILETYPE_PEM) ||
                !SSL_CTX_check_private_key(ssl_context)) {
            fprintf(stderr, "%s: could not load certificate and/or key file\n",
                    PIEPAN_NAME);
            return 1;
        }
    }

    /*
     * Socket initialization and connection
     */
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0) {
        fprintf(stderr, "%s: could not create socket\n", PIEPAN_NAME);
        return 1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);

    server_host = gethostbyname(server_host_str);
    if (server_host == NULL || server_host->h_addr_list[0] == NULL ||
            server_host->h_addrtype != AF_INET) {
        fprintf(stderr, "%s: could not parse server address\n", PIEPAN_NAME);
        return 1;
    }
    memmove(&server_addr.sin_addr, server_host->h_addr_list[0],
            server_host->h_length);

    ret = connect(socket_fd, (struct sockaddr *) &server_addr,
                  sizeof(server_addr));
    if (ret != 0) {
        fprintf(stderr, "%s: could not connect to server\n", PIEPAN_NAME);
        return 1;
    }

    ssl = SSL_new(ssl_context);
    if (ssl == NULL) {
        fprintf(stderr, "%s: could not create SSL object\n", PIEPAN_NAME);
        return 1;
    }

    if (SSL_set_fd(ssl, socket_fd) == 0) {
        fprintf(stderr, "%s: could not set SSL file descriptor\n", PIEPAN_NAME);
        return 1;
    }

    if (SSL_connect(ssl) != 1) {
        fprintf(stderr, "%s: could not create secure connection\n", PIEPAN_NAME);
        return 1;
    }

    /*
     * User thread pipe
     */
    if (pipe(user_thread_pipe) != 0) {
        fprintf(stderr, "%s: could not create user thread pipe\n", PIEPAN_NAME);
        return 1;
    }

    /*
     * Trigger initial event
     */
    lua_getglobal(lua, "piepan");
    lua_getfield(lua, -1, "internal");
    lua_getfield(lua, -1, "initialize");
    lua_newtable(lua);
    lua_pushstring(lua, username);
    lua_setfield(lua, -2, "username");
    if (password_file != NULL) {
        lua_pushstring(lua, password_file);
        lua_setfield(lua, -2, "passwordFile");
    }
    if (token_file != NULL) {
        lua_pushstring(lua, token_file);
        lua_setfield(lua, -2, "tokenFile");
    }
    lua_pushlightuserdata(lua, lua);
    lua_setfield(lua, -2, "state");
    lua_call(lua, 1, 0);
    lua_settop(lua, 0);

    /*
     * Event loop
     */
    ev_signal_init(&signal_watcher, signal_event, SIGINT);
    ev_signal_start(ev_loop_main, &signal_watcher);

    ev_io_init(&socket_watcher.ev, socket_read_event, socket_fd, EV_READ);
    socket_watcher.lua = lua;
    socket_watcher.ssl = ssl;
    ev_io_start(ev_loop_main, &socket_watcher.ev);

    ev_io_init(&user_thread_watcher, user_thread_event, user_thread_pipe[0],
               EV_READ);
    ev_io_start(ev_loop_main, &user_thread_watcher);

    ev_timer_init(&ping_watcher, ping_event, PING_TIMEOUT, PING_TIMEOUT);
    ev_timer_start(ev_loop_main, &ping_watcher);

    ev_run(ev_loop_main, 0);

    /*
     * Cleanup
     */
    lua_getglobal(lua, "piepan");
    lua_getfield(lua, -1, "internal");
    lua_getfield(lua, -1, "events");
    lua_getfield(lua, -1, "onDisconnect");
    if (lua_isfunction(lua, -1)) {
        lua_newtable(lua);
        lua_call(lua, 1, 0);
    }

    SSL_shutdown(ssl); /* TODO:  sigpipe is triggered here if connection breaks */
    close(socket_fd);
    lua_close(lua);

    return 0;
}
Пример #16
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;
}
Пример #17
0
int
_v3_audio_encode(
        v3_handle v3h,
        /* pcm input */
        const uint8_t *pcm,
        uint32_t pcmlen,
        /* payload output */
        int16_t index,
        int16_t format,
        v3_coder *coder,
        uint8_t *data,
        uint32_t *datalen,
        /* optional args */
        uint8_t channels) {
    uint32_t maxdatalen;
    int ret = V3_OK;

    _v3_enter(v3h, __func__);

    if (!pcm || !pcmlen || !coder || !data || !datalen || (datalen && !*datalen)) {
        _v3_leave(v3h, __func__);
        return V3_FAILURE;
    }

    maxdatalen = *datalen;
    *datalen = 0;
    channels = (channels == 2) ? 2 : 1;

    if (coder->state && (coder->index != index || coder->format != format)) {
        _v3_coder_destroy(v3h, coder);
    }
    switch (index) {
#ifdef HAVE_GSM
      case 0:
        {
            const v3_codec *codec = v3_codec_get(index, format);
            int opt = 1;
            size_t ctr;

            _v3_debug(v3h, V3_DBG_INFO, "encoding %u bytes of pcm to gsm @ %u", pcmlen, codec->rate);
            if (!coder->state) {
                if (!(coder->state = gsm_create())) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create gsm encoder");
                    ret = V3_FAILURE;
                    break;
                }
                gsm_option(coder->state, GSM_OPT_WAV49, &opt);
                coder->index = index;
                coder->format = format;
                coder->encoder = true;
            }
            for (ctr = 0; ctr < pcmlen / codec->framesize && *datalen + 65 <= maxdatalen; ++ctr) {
                gsm_encode(coder->state, (void *)pcm, (void *)data);
                gsm_encode(coder->state, (void *)pcm+(codec->framesize/2), (void *)data+32);
                pcm      += codec->framesize;
                data     += 65;
                *datalen += 65;
            }
        }
        break;
#endif
#ifdef HAVE_OPUS
      case 1:
      case 2:
        {
            const v3_codec *codec = v3_codec_get(index, format);
            int tmp;

            _v3_debug(v3h, V3_DBG_INFO, "encoding %u bytes of pcm to opus @ %u", pcmlen, codec->rate);
            if (!coder->state || channels != coder->channels) {
                if (coder->state) {
                    opus_encoder_destroy(coder->state);
                    coder->state = NULL;
                    _v3_debug(v3h, V3_DBG_MEMORY, "released opus state");
                }
                if (!(coder->state = opus_encoder_create(codec->rate, channels, OPUS_APPLICATION_AUDIO, &tmp))) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create opus encoder: %s", opus_strerror(tmp));
                    ret = V3_FAILURE;
                    break;
                }
                if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_COMPLEXITY(10))) != OPUS_OK) {
                    _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_COMPLEXITY: %s", opus_strerror(tmp));
                    opus_encoder_destroy(coder->state);
                    coder->state = NULL;
                    ret = V3_FAILURE;
                    break;
                }
                if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_VBR(0))) != OPUS_OK) {
                    _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_VBR: %s", opus_strerror(tmp));
                    opus_encoder_destroy(coder->state);
                    coder->state = NULL;
                    ret = V3_FAILURE;
                    break;
                }
                if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_BITRATE(((index == 1) ? 79 : 43) * 1000))) != OPUS_OK) {
                    _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_BITRATE: %s", opus_strerror(tmp));
                    opus_encoder_destroy(coder->state);
                    coder->state = NULL;
                    ret = V3_FAILURE;
                    break;
                }
                coder->index = index;
                coder->format = format;
                coder->channels = channels;
                coder->encoder = true;
            }
            maxdatalen = (maxdatalen <= ((index == 1) ? 198 : 108)) ? maxdatalen : ((index == 1) ? 198 : 108);
            if ((tmp = opus_encode(coder->state, (void *)pcm, codec->framesize / sizeof(int16_t), (void *)data, maxdatalen)) <= 0) {
                _v3_debug(v3h, V3_DBG_INFO, "failed to encode opus packet");
            }
            *datalen = tmp;
        }
        break;
#endif
#ifdef HAVE_SPEEX
      case 3:
        {
            static const uint16_t maxspxbuf = 200;
            const v3_codec *codec = v3_codec_get(index, format);
            uint16_t framesize;
            SpeexBits bits;
            size_t ctr;

            _v3_debug(v3h, V3_DBG_INFO, "encoding %u bytes of pcm to speex @ %u", pcmlen, codec->rate);
            if (!coder->state) {
                switch (codec->rate) {
                  case 8000:
                    coder->state = speex_encoder_init(&speex_nb_mode);
                    break;
                  case 16000:
                    coder->state = speex_encoder_init(&speex_wb_mode);
                    break;
                  case 32000:
                    coder->state = speex_encoder_init(&speex_uwb_mode);
                    break;
                }
                if (!coder->state) {
                    _v3_debug(v3h, V3_DBG_INFO, "failed to create speex encoder");
                    ret = V3_FAILURE;
                    break;
                }
                speex_encoder_ctl(coder->state, SPEEX_SET_QUALITY, (void *)&codec->quality);
                coder->index = index;
                coder->format = format;
                coder->encoder = true;
            }
            *(uint16_t *)data = htons(pcmlen / codec->framesize);
            data     += sizeof(uint16_t);
            *datalen += sizeof(uint16_t);
            *(uint16_t *)data = htons(codec->framesize / sizeof(int16_t));
            data     += sizeof(uint16_t);
            *datalen += sizeof(uint16_t);
            speex_bits_init(&bits);
            for (ctr = 0; ctr < pcmlen / codec->framesize && *datalen + maxspxbuf <= maxdatalen; ++ctr) {
                speex_encode_int(coder->state, (void *)pcm, &bits);
                framesize = speex_bits_write(&bits, (void *)data + sizeof(uint16_t), maxspxbuf);
                speex_bits_reset(&bits);
                *(uint16_t *)data = htons(framesize);
                pcm      += codec->framesize;
                data     += sizeof(uint16_t) + framesize;
                *datalen += sizeof(uint16_t) + framesize;
            }
            speex_bits_destroy(&bits);
        }
        break;
#endif
      default:
        (void)maxdatalen;
        _v3_debug(v3h, V3_DBG_INFO, "unsupported codec: index: %i | format: %i", index, format);
        ret = V3_FAILURE;
        break;
    }

    _v3_leave(v3h, __func__);
    return ret;
}
Пример #18
0
void OggOpusFile::Init()
{
    inopt.skip=0;
    //In our case, its 160 samples/frame. Changing rate to anything rather than 8000Hz may require significant change in the way of handle number of samples to fix the encoder
    frame_size=frame_size/(48000/coding_rate);  
    /*OggOpus headers*/ /*FIXME: broke forcemono*/
    header.channels=chan;
    header.channel_mapping= 0;//header.channels>8?255:chan>2;  //=0 for  wav
    header.input_sample_rate=rate;
    header.gain=inopt.gain;   //=0 here

    st=opus_multistream_surround_encoder_create(coding_rate, chan, header.channel_mapping, &header.nb_streams, &header.nb_coupled,
        header.stream_map, frame_size<480/(48000/coding_rate)?OPUS_APPLICATION_RESTRICTED_LOWDELAY:OPUS_APPLICATION_AUDIO, &ret);
    if(ret!=OPUS_OK){
        fprintf(stderr, "Error cannot create encoder: %s\n", opus_strerror(ret));
        exit(1);
    }
    
    max_frame_bytes=(1275*3+7)*header.nb_streams;
    min_bytes=max_frame_bytes;
    m_outBuf = (unsigned char*)malloc(max_frame_bytes);
    if(m_outBuf==NULL){
        fprintf(stderr,"Error allocating m_outBuf buffer.\n");
        exit(1);
    }

    //We would set bitrate configurable as low as 6k
    //Or use the provided formulae to calculate a optimized bitrate
    if(bitrate<0){
    /*Lower default rate for sampling rates [8000-44100) by a factor of (rate+16k)/(64k)*/
    // bitrate=((64000*header.nb_streams+32000*header.nb_coupled)*
    //             (IMIN(48,IMAX(8,((rate<44100?rate:48000)+1000)/1000))+16)+32)>>6;
        bitrate=6000;

    }

    if(bitrate>(1024000*chan)||bitrate<500){
        fprintf(stderr,"Error: Bitrate %d bits/sec is insane.\nDid you mistake bits for kilobits?\n",bitrate);
        fprintf(stderr,"--bitrate values from 6-256 kbit/sec per channel are meaningful.\n");
        exit(1);
    }
    bitrate=IMIN(chan*256000,bitrate);

    ret=opus_multistream_encoder_ctl(st, OPUS_SET_BITRATE(bitrate));
    if(ret!=OPUS_OK){
        fprintf(stderr,"Error OPUS_SET_BITRATE returned: %s\n",opus_strerror(ret));
        exit(1);
    }

    ret=opus_multistream_encoder_ctl(st, OPUS_SET_VBR(!with_hard_cbr));
    if(ret!=OPUS_OK){
        fprintf(stderr,"Error OPUS_SET_VBR returned: %s\n",opus_strerror(ret));
        exit(1);
    }

    if(!with_hard_cbr){
        ret=opus_multistream_encoder_ctl(st, OPUS_SET_VBR_CONSTRAINT(with_cvbr));
        if(ret!=OPUS_OK){
            fprintf(stderr,"Error OPUS_SET_VBR_CONSTRAINT returned: %s\n",opus_strerror(ret));
            exit(1);
        }
    }
    ret=opus_multistream_encoder_ctl(st, OPUS_SET_COMPLEXITY(complexity));
    if(ret!=OPUS_OK){
        fprintf(stderr,"Error OPUS_SET_COMPLEXITY returned: %s\n",opus_strerror(ret));
        exit(1);
    }

    ret=opus_multistream_encoder_ctl(st, OPUS_SET_PACKET_LOSS_PERC(expect_loss));
    if(ret!=OPUS_OK){
        fprintf(stderr,"Error OPUS_SET_PACKET_LOSS_PERC returned: %s\n",opus_strerror(ret));
        exit(1);
    }

#ifdef OPUS_SET_LSB_DEPTH
    ret=opus_multistream_encoder_ctl(st, OPUS_SET_LSB_DEPTH(IMAX(8,IMIN(24,inopt.samplesize))));
    if(ret!=OPUS_OK){
        fprintf(stderr,"Warning OPUS_SET_LSB_DEPTH returned: %s\n",opus_strerror(ret));
    }
#endif

    for(i=0;i<opt_ctls;i++){
    int target=opt_ctls_ctlval[i*3];
    if(target==-1){
        ret=opus_multistream_encoder_ctl(st,opt_ctls_ctlval[i*3+1],opt_ctls_ctlval[i*3+2]);
        if(ret!=OPUS_OK){
        fprintf(stderr,"Error opus_multistream_encoder_ctl(st,%d,%d) returned: %s\n",opt_ctls_ctlval[i*3+1],opt_ctls_ctlval[i*3+2],opus_strerror(ret));
        exit(1);
        }
    }else if(target<header.nb_streams){
        OpusEncoder *oe;
        opus_multistream_encoder_ctl(st,OPUS_MULTISTREAM_GET_ENCODER_STATE(target,&oe));
        ret=opus_encoder_ctl(oe, opt_ctls_ctlval[i*3+1],opt_ctls_ctlval[i*3+2]);
        if(ret!=OPUS_OK){
        fprintf(stderr,"Error opus_encoder_ctl(st[%d],%d,%d) returned: %s\n",target,opt_ctls_ctlval[i*3+1],opt_ctls_ctlval[i*3+2],opus_strerror(ret));
        exit(1);
        }
    }else{
        fprintf(stderr,"Error --set-ctl-int target stream %d is higher than the maximum stream number %d.\n",target,header.nb_streams-1);
        exit(1);
    }
    }


    /*We do the lookahead check late so user CTLs can change it*/
    ret=opus_multistream_encoder_ctl(st, OPUS_GET_LOOKAHEAD(&lookahead));
    if(ret!=OPUS_OK){
    fprintf(stderr,"Error OPUS_GET_LOOKAHEAD returned: %s\n",opus_strerror(ret));
    exit(1);
    }
    inopt.skip+=lookahead;
    /*Regardless of the rate we're coding at the ogg timestamping/skip is
    always timed at 48000.*/
    header.preskip=inopt.skip*(48000./coding_rate);
    /* Extra samples that need to be read to compensate for the pre-skip */
    inopt.extraout=(int)header.preskip*(rate/48000.);

    /*Initialize Ogg stream struct*/
    if(ogg_stream_init(&os, serialno)==-1){
    fprintf(stderr,"Error: stream init failed\n");
    exit(1);
    }



    int opus_app;
    fprintf(stderr,"Encoding using 1.1");
    opus_multistream_encoder_ctl(st,OPUS_GET_APPLICATION(&opus_app));
    if(opus_app==OPUS_APPLICATION_VOIP)fprintf(stderr," (VoIP)\n");
    else if(opus_app==OPUS_APPLICATION_AUDIO)fprintf(stderr," (audio)\n");
    else if(opus_app==OPUS_APPLICATION_RESTRICTED_LOWDELAY)fprintf(stderr," (low-delay)\n");
    else fprintf(stderr," (unknown)\n");
    fprintf(stderr,"-----------------------------------------------------\n");
    fprintf(stderr,"   Input: %0.6gkHz %d channel%s\n",
            header.input_sample_rate/1000.,chan,chan<2?"":"s");
    fprintf(stderr,"  Output: %d channel%s (",header.channels,header.channels<2?"":"s");
    if(header.nb_coupled>0)fprintf(stderr,"%d coupled",header.nb_coupled*2);
    if(header.nb_streams-header.nb_coupled>0)fprintf(stderr,
       "%s%d uncoupled",header.nb_coupled>0?", ":"",
       header.nb_streams-header.nb_coupled);
    fprintf(stderr,")\n          %0.2gms packets, %0.6gkbit/sec%s\n",
       frame_size/(coding_rate/1000.), bitrate/1000.,
       with_hard_cbr?" CBR":with_cvbr?" CVBR":" VBR");
    fprintf(stderr," Preskip: %d\n",header.preskip);
  

}