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)); }
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; }
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; }
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; }
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; }
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); }
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; }
/* * 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; }
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 }
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 }
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; }
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); }
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; }
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; }
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 _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; }
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); }