int init_audio_encoder(CodecState *cs, uint32_t audio_channels) { int rc = OPUS_OK; cs->audio_encoder = opus_encoder_create(cs->audio_sample_rate, audio_channels, OPUS_APPLICATION_AUDIO, &rc); if ( rc != OPUS_OK ) { LOGGER_ERROR("Error while starting audio encoder: %s", opus_strerror(rc)); return -1; } rc = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate)); if ( rc != OPUS_OK ) { LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc)); return -1; } rc = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10)); if ( rc != OPUS_OK ) { LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc)); return -1; } return 0; }
static void ms_opus_enc_preprocess(MSFilter *f) { int error; OpusEncData *d = (OpusEncData *)f->data; /* create the encoder */ d->state = opus_encoder_create(d->samplerate, d->channels, d->application, &error); if (error != OPUS_OK) { ms_error("Opus encoder creation failed: %s", opus_strerror(error)); return; } /* set complexity to 0 for single processor arm devices */ #if defined(__arm__) || defined(_M_ARM) if (ms_factory_get_cpu_count(f->factory)==1){ opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(0)); }else{ opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(5)); } #endif error = opus_encoder_ctl(d->state, OPUS_SET_PACKET_LOSS_PERC(10)); if (error != OPUS_OK) { ms_error("Could not set default loss percentage to opus encoder: %s", opus_strerror(error)); } /* set the encoder parameters: VBR, IN_BAND_FEC, DTX and bitrate settings */ ms_opus_enc_set_vbr(f); ms_opus_enc_set_inbandfec(f); ms_opus_enc_set_dtx(f); /* if decoder prefers mono signal, force encoder to output mono signal */ if (d->stereo == 0) { error = opus_encoder_ctl(d->state, OPUS_SET_FORCE_CHANNELS(1)); if (error != OPUS_OK) { ms_error("could not force mono channel to opus encoder: %s", opus_strerror(error)); } if (d->channels == 2) ms_message("Opus encoder configured to encode mono despite it is feed with stereo."); }else if (d->channels == 2){ ms_message("Opus encoder configured to encode stereo."); } ms_filter_lock(f); // set bitrate wasn't call, compute it with the default network bitrate (36000) if (d->bitrate==-1) { compute_max_bitrate(d, 0); } apply_max_bitrate(d); ms_filter_unlock(f); }
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; }
bool OpusEncode::SetComplexity(int complex) { assert(m_encoder); if(!m_encoder) return false; int err = opus_encoder_ctl(m_encoder, OPUS_SET_COMPLEXITY(complex)); assert(err == 0); return err == 0; }
int init_audio_encoder(CodecState *cs, uint32_t audio_channels) { int err = OPUS_OK; cs->audio_encoder = opus_encoder_create(cs->audio_sample_rate, audio_channels, OPUS_APPLICATION_AUDIO, &err); err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate)); err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10)); return err == OPUS_OK ? 0 : -1; }
JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_audio_opus_Opus_encoder_1set_1complexity (JNIEnv *env, jclass clazz, jlong encoder, jint complexity) { opus_int32 x = complexity; return opus_encoder_ctl( (OpusEncoder *) (intptr_t) encoder, OPUS_SET_COMPLEXITY(x)); }
//function sets up the encoder/decoder structs and buffers, returns required samples/frame int setup_codecs(){ //create the encoder and decoder state structs int error = 0; if(!(enc_state = opus_encoder_create(SAMPLE_RATE,1,APP_MODE,&error))) printf("Error Creating Encoder: %d\n",error); if(!(dec_state = opus_decoder_create(SAMPLE_RATE,1,&error))) printf("Error Creating Decoder: %d\n",error); opus_encoder_ctl(enc_state, OPUS_SET_COMPLEXITY(QUALITY)); return FRAME_SIZE; //return the frame size ( }
OpusEncoder *create_audio_encoder(Logger *log, int32_t bit_rate, int32_t sampling_rate, int32_t channel_count) { int status = OPUS_OK; OpusEncoder *rc = opus_encoder_create(sampling_rate, channel_count, OPUS_APPLICATION_VOIP, &status); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while starting audio encoder: %s", opus_strerror(status)); return NULL; } status = opus_encoder_ctl(rc, OPUS_SET_BITRATE(bit_rate)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); goto FAILURE; } /* Enable in-band forward error correction in codec */ status = opus_encoder_ctl(rc, OPUS_SET_INBAND_FEC(1)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); goto FAILURE; } /* Make codec resistant to up to 10% packet loss * NOTE This could also be adjusted on the fly, rather than hard-coded, * with feedback from the receiving client. */ status = opus_encoder_ctl(rc, OPUS_SET_PACKET_LOSS_PERC(10)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); goto FAILURE; } /* Set algorithm to the highest complexity, maximizing compression */ status = opus_encoder_ctl(rc, OPUS_SET_COMPLEXITY(10)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); goto FAILURE; } return rc; FAILURE: opus_encoder_destroy(rc); return NULL; }
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; }
int init_send_audio(codec_state *cs) { cs->support_send_audio = 0; const ALchar *pDeviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); int i = 0; const ALchar *device_names[20]; if (pDeviceList) { printf("\nAvailable Capture Devices are:\n"); while (*pDeviceList) { device_names[i] = pDeviceList; printf("%d) %s\n", i, device_names[i]); pDeviceList += strlen(pDeviceList) + 1; ++i; } } printf("enter capture device number: \n"); char dev[2]; fgets(dev, sizeof(dev), stdin); cs->audio_capture_device = alcCaptureOpenDevice(device_names[dev[0] - 48], AUDIO_SAMPLE_RATE, AL_FORMAT_MONO16, AUDIO_FRAME_SIZE * 4); if (alcGetError(cs->audio_capture_device) != AL_NO_ERROR) { printf("could not start capture device! %d\n", alcGetError(cs->audio_capture_device)); return 0; } int err = OPUS_OK; cs->audio_bitrate = AUDIO_BITRATE; cs->audio_encoder = opus_encoder_create(AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &err); err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate)); err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10)); err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); opus_encoder_init(cs->audio_encoder, AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP); int nfo; err = opus_encoder_ctl(cs->audio_encoder, OPUS_GET_LOOKAHEAD(&nfo)); /* printf("Encoder lookahead delay : %d\n", nfo); */ printf("init audio encoder successful\n"); return 1; }
static void audio_encoder_init(uint32_t samplerate, int complexity, uint32_t bitrate) { assert(opus_enc == NULL); int err = 0; /* 1 channel (mono), OPUS audio profile */ opus_enc = opus_encoder_create(samplerate, 1, OPUS_APPLICATION_AUDIO, &err); if (!opus_enc) { fprintf(stderr, "ERROR: opus_encoder_create() has failed - %d\n", err); exit(EXIT_FAILURE); } opus_encoder_ctl(opus_enc, OPUS_SET_COMPLEXITY(complexity)); opus_encoder_ctl(opus_enc, OPUS_SET_BITRATE(bitrate)); opus_encoder_ctl(opus_enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_encoder_ctl(opus_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); }
static void ms_opus_enc_preprocess(MSFilter *f) { int error; OpusEncData *d = (OpusEncData *)f->data; /* create the encoder */ d->state = opus_encoder_create(d->samplerate, d->channels, d->application, &error); if (error != OPUS_OK) { ms_error("Opus encoder creation failed: %s", opus_strerror(error)); return; } /* set complexity to 0 for arm devices */ #ifdef __arm__ opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(0)); #endif error = opus_encoder_ctl(d->state, OPUS_SET_PACKET_LOSS_PERC(10)); if (error != OPUS_OK) { ms_error("Could not set default loss percentage to opus encoder: %s", opus_strerror(error)); } /* set the encoder parameters: VBR, IN_BAND_FEC, DTX and bitrate settings */ ms_opus_enc_set_vbr(f); ms_opus_enc_set_inbandfec(f); ms_opus_enc_set_dtx(f); /* if decoder prefers mono signal, force encoder to output mono signal */ if (d->stereo == 0) { error = opus_encoder_ctl(d->state, OPUS_SET_FORCE_CHANNELS(1)); if (error != OPUS_OK) { ms_error("could not force mono channel to opus encoder: %s", opus_strerror(error)); } } ms_filter_lock(f); if (d->ptime==-1) { // set ptime wasn't call, set default:20ms d->ptime = 20; } if (d->bitrate==-1) { // set bitrate wasn't call, compute it with the default network bitrate (36000) compute_max_bitrate(d, 0); } apply_max_bitrate(d); ms_filter_unlock(f); }
/** * OPUS init */ static void opus_init () { int err; pcm_length = FRAME_SIZE * CHANNELS * sizeof (float); pcm_buffer = pa_xmalloc (pcm_length); opus_data = GNUNET_malloc (MAX_PAYLOAD_BYTES); enc = opus_encoder_create (SAMPLING_RATE, CHANNELS, CONV_OPUS_APP_TYPE, &err); opus_encoder_ctl (enc, OPUS_SET_PACKET_LOSS_PERC (CONV_OPUS_PACKET_LOSS_PERCENTAGE)); opus_encoder_ctl (enc, OPUS_SET_COMPLEXITY (CONV_OPUS_ENCODING_COMPLEXITY)); opus_encoder_ctl (enc, OPUS_SET_INBAND_FEC (CONV_OPUS_INBAND_FEC)); opus_encoder_ctl (enc, OPUS_SET_SIGNAL (CONV_OPUS_SIGNAL)); }
static int recreate_encoder(Group_AV *group_av) { if (group_av->audio_encoder) { opus_encoder_destroy(group_av->audio_encoder); group_av->audio_encoder = NULL; } int rc = OPUS_OK; group_av->audio_encoder = opus_encoder_create(group_av->audio_sample_rate, group_av->audio_channels, OPUS_APPLICATION_AUDIO, &rc); if (rc != OPUS_OK) { LOGGER_ERROR("Error while starting audio encoder: %s", opus_strerror(rc)); group_av->audio_encoder = NULL; return -1; } rc = opus_encoder_ctl(group_av->audio_encoder, OPUS_SET_BITRATE(group_av->audio_bitrate)); if (rc != OPUS_OK) { LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc)); opus_encoder_destroy(group_av->audio_encoder); group_av->audio_encoder = NULL; return -1; } rc = opus_encoder_ctl(group_av->audio_encoder, OPUS_SET_COMPLEXITY(10)); if (rc != OPUS_OK) { LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc)); opus_encoder_destroy(group_av->audio_encoder); group_av->audio_encoder = NULL; return -1; } return 0; }
JNIEXPORT jint JNICALL Java_com_air_mobilebrowser_opusogg_OpusEncoder_native_1OpusEncoderCreate(JNIEnv *env, jobject jobj, jint sampleRate, jint channels, jdouble frameDur, jint bufSize) { int error = 0; if (curEncoder != NULL) { return -999; } curEncoder = opus_encoder_create(sampleRate, channels, OPUS_APPLICATION_VOIP, &error); if (error == OPUS_OK) { opus_encoder_ctl(curEncoder, OPUS_SET_COMPLEXITY(5)); opus_encoder_ctl(curEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); opus_encoder_ctl(curEncoder, OPUS_SET_LSB_DEPTH(8)); frame_size = frameDur * sampleRate; pcm_len = frame_size*channels*sizeof(opus_int16); jclass cls = (*env)->GetObjectClass(env, jobj); jmethodID mid = (*env)->GetMethodID(env, cls, "setTargetSize", "(I)V"); (*env)->CallVoidMethod(env, jobj, mid, pcm_len); } return error; }
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 result_t encode_opus_file(char *filename, struct PCMReader *pcmreader, int quality, unsigned original_sample_rate) { const int multichannel = (pcmreader->channels > 2); const unsigned channel_mapping = (pcmreader->channels > 8 ? 255 : pcmreader->channels > 2); int stream_count; int coupled_stream_count; unsigned char stream_map[255]; int samples[BLOCK_SIZE * pcmreader->channels]; unsigned pcm_frames; result_t result = ENCODE_OK; FILE *output_file = NULL; ogg_stream_state ogg_stream; ogg_page ogg_page; OpusEncoder *opus_encoder = NULL; OpusMSEncoder *opus_ms_encoder = NULL; int error; opus_int16 *opus_samples = NULL; unsigned char opus_frame[OPUS_FRAME_LEN]; ogg_int64_t granulepos = 0; ogg_int64_t packetno = 0; opus_int32 preskip; /*open output file for writing*/ if ((output_file = fopen(filename, "w+b")) == NULL) { return ERR_IOERROR; } if (!multichannel) { if ((opus_encoder = opus_encoder_create(48000, pcmreader->channels, OPUS_APPLICATION_AUDIO, &error)) == NULL) { fclose(output_file); return ERR_ENCODER_INIT; } opus_encoder_ctl(opus_encoder, OPUS_SET_COMPLEXITY(quality)); opus_encoder_ctl(opus_encoder, OPUS_GET_LOOKAHEAD(&preskip)); } else { if ((opus_ms_encoder = opus_multistream_surround_encoder_create( 48000, pcmreader->channels, channel_mapping, &stream_count, &coupled_stream_count, stream_map, OPUS_APPLICATION_AUDIO, &error)) == NULL) { fclose(output_file); return ERR_ENCODER_INIT; } opus_multistream_encoder_ctl(opus_ms_encoder, OPUS_SET_COMPLEXITY(quality)); opus_multistream_encoder_ctl(opus_ms_encoder, OPUS_GET_LOOKAHEAD(&preskip)); } srand((unsigned)time(NULL)); ogg_stream_init(&ogg_stream, rand()); /*write header and comment packets to Ogg stream*/ { BitstreamRecorder *header = bw_open_bytes_recorder(BS_LITTLE_ENDIAN); BitstreamWriter *header_w =(BitstreamWriter*)header; BitstreamRecorder *comment = bw_open_bytes_recorder(BS_LITTLE_ENDIAN); BitstreamWriter *comment_w = (BitstreamWriter*)comment; int i; /*write header packet to Ogg stream*/ const char opushead[] = "OpusHead"; const char opuscomment[] = "OpusTags"; const char *vendor_string = opus_get_version_string(); const size_t vendor_string_len = strlen(vendor_string); ogg_packet packet_head; ogg_packet packet_tags; header_w->write_bytes(header_w, (uint8_t*)opushead, (unsigned)strlen(opushead)); header_w->write(header_w, 8, 1); /*version*/ header_w->write(header_w, 8, pcmreader->channels); header_w->write(header_w, 16, preskip); header_w->write(header_w, 32, original_sample_rate); header_w->write(header_w, 16, 0); /*output gain*/ header_w->write(header_w, 8, channel_mapping); if (channel_mapping != 0) { header_w->write(header_w, 8, stream_count); header_w->write(header_w, 8, coupled_stream_count); for (i = 0; i < pcmreader->channels; i++) { header_w->write(header_w, 8, stream_map[i]); } } packet_head.packet = malloc(header->bytes_written(header)); header->data(header, (uint8_t*)packet_head.packet); packet_head.bytes = header->bytes_written(header); packet_head.b_o_s = 1; packet_head.e_o_s = 0; packet_head.granulepos = 0; packet_head.packetno = packetno++; header->close(header); ogg_stream_packetin(&ogg_stream, &packet_head); for (i = ogg_stream_flush(&ogg_stream, &ogg_page); i != 0; i = ogg_stream_flush(&ogg_stream, &ogg_page)) { fwrite(ogg_page.header, 1, ogg_page.header_len, output_file); fwrite(ogg_page.body, 1, ogg_page.body_len, output_file); } free(packet_head.packet); /*write comment packet to Ogg stream*/ comment_w->write_bytes(comment_w, (uint8_t*)opuscomment, (unsigned)strlen(opuscomment)); comment_w->write(comment_w, 32, (unsigned)vendor_string_len); comment_w->write_bytes(comment_w, (uint8_t*)vendor_string, (unsigned)vendor_string_len); comment_w->write(comment_w, 32, 0); packet_tags.packet = malloc(comment->bytes_written(comment)); comment->data(comment, (uint8_t*)packet_tags.packet); packet_tags.bytes = comment->bytes_written(comment); packet_tags.b_o_s = 0; packet_tags.e_o_s = 0; packet_tags.granulepos = 0; packet_tags.packetno = packetno++; comment->close(comment); ogg_stream_packetin(&ogg_stream, &packet_tags); for (i = ogg_stream_flush(&ogg_stream, &ogg_page); i != 0; i = ogg_stream_flush(&ogg_stream, &ogg_page)) { fwrite(ogg_page.header, 1, ogg_page.header_len, output_file); fwrite(ogg_page.body, 1, ogg_page.body_len, output_file); } free(packet_tags.packet); } opus_samples = malloc(sizeof(opus_int16) * pcmreader->channels * BLOCK_SIZE); pcm_frames = pcmreader->read(pcmreader, BLOCK_SIZE, samples); if (!pcm_frames && (pcmreader->status != PCM_OK)) { result = ERR_PCMREADER; goto cleanup; } /*for each non-empty FrameList from PCMReader, encode Opus frame*/ while (pcm_frames) { const int short_framelist = (pcm_frames < BLOCK_SIZE); unsigned i; opus_int32 encoded_size; ogg_packet packet; granulepos += pcm_frames; /*pad FrameList with additional null samples if necessary*/ memset(samples + pcm_frames * pcmreader->channels, 0, sizeof(int) * (BLOCK_SIZE - pcm_frames) * pcmreader->channels); /*rearrange channels to Vorbis order if necessary*/ reorder_channels(pcmreader->channel_mask, BLOCK_SIZE, samples); /*place samples in interleaved buffer*/ for (i = 0; i < (pcm_frames * pcmreader->channels); i++) { opus_samples[i] = (opus_int16)samples[i]; } /*call opus_encode on interleaved buffer to get next packet*/ if (!multichannel) { encoded_size = opus_encode(opus_encoder, opus_samples, BLOCK_SIZE, opus_frame, OPUS_FRAME_LEN); } else { encoded_size = opus_multistream_encode(opus_ms_encoder, opus_samples, BLOCK_SIZE, opus_frame, OPUS_FRAME_LEN); } /*get next FrameList to encode*/ pcm_frames = pcmreader->read(pcmreader, BLOCK_SIZE, samples); if (!pcm_frames && (pcmreader->status != PCM_OK)) { result = ERR_PCMREADER; goto cleanup; } /*dump Opus packet to Ogg stream*/ /*do this *after* reading the next FrameList in order to detect the end of stream properly based on whether the FrameList has no frames*/ packet.packet = (unsigned char *)opus_frame; packet.bytes = encoded_size; packet.b_o_s = 0; packet.e_o_s = (short_framelist || (pcm_frames == 0)); packet.granulepos = granulepos; packet.packetno = packetno; ogg_stream_packetin(&ogg_stream, &packet); while (ogg_stream_pageout(&ogg_stream, &ogg_page)) { fwrite(ogg_page.header, 1, ogg_page.header_len, output_file); fwrite(ogg_page.body, 1, ogg_page.body_len, output_file); } } /*flush any remaining Ogg pages to disk*/ while (ogg_stream_flush(&ogg_stream, &ogg_page)) { fwrite(ogg_page.header, 1, ogg_page.header_len, output_file); fwrite(ogg_page.body, 1, ogg_page.body_len, output_file); } cleanup: fclose(output_file); ogg_stream_clear(&ogg_stream); if (!multichannel) { opus_encoder_destroy(opus_encoder); } else { opus_multistream_encoder_destroy(opus_ms_encoder); } free(opus_samples); return result; }
int krad_opus_encoder_read (krad_opus_t *krad_opus, unsigned char *buffer, int *nframes) { int ready; int bytes; int resp; int s, c; while (krad_ringbuffer_read_space (krad_opus->ringbuf[krad_opus->channels - 1]) >= 512 * 4 ) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->ret = krad_ringbuffer_peek (krad_opus->ringbuf[c], (char *)krad_opus->samples[c], (512 * 4) ); krad_opus->src_data[c].data_in = krad_opus->samples[c]; krad_opus->src_data[c].input_frames = 512; krad_opus->src_data[c].data_out = krad_opus->resampled_samples[c]; krad_opus->src_data[c].output_frames = 2048; krad_opus->src_error[c] = src_process (krad_opus->src_resampler[c], &krad_opus->src_data[c]); if (krad_opus->src_error[c] != 0) { failfast ("Krad Opus Encoder: src resampler error: %s\n", src_strerror(krad_opus->src_error[c])); } krad_ringbuffer_read_advance (krad_opus->ringbuf[c], (krad_opus->src_data[c].input_frames_used * 4) ); krad_opus->ret = krad_ringbuffer_write (krad_opus->resampled_ringbuf[c], (char *)krad_opus->resampled_samples[c], (krad_opus->src_data[c].output_frames_gen * 4) ); } } if (krad_opus->new_bitrate != krad_opus->bitrate) { krad_opus->bitrate = krad_opus->new_bitrate; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE(krad_opus->bitrate)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: bitrate request failed %s\n", opus_strerror (resp)); } else { printk ("Krad Opus Encoder: set opus bitrate %d\n", krad_opus->bitrate); } } if (krad_opus->new_frame_size != krad_opus->frame_size) { krad_opus->frame_size = krad_opus->new_frame_size; printk ("Krad Opus Encoder: frame size is now %d\n", krad_opus->frame_size); } if (krad_opus->new_complexity != krad_opus->complexity) { krad_opus->complexity = krad_opus->new_complexity; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_COMPLEXITY(krad_opus->complexity)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: complexity request failed %s. \n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: set opus complexity %d\n", krad_opus->complexity); } } if (krad_opus->new_signal != krad_opus->signal) { krad_opus->signal = krad_opus->new_signal; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_SIGNAL(krad_opus->signal)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: signal request failed %s\n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: set opus signal mode %d\n", krad_opus->signal); } } if (krad_opus->new_bandwidth != krad_opus->bandwidth) { krad_opus->bandwidth = krad_opus->new_bandwidth; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BANDWIDTH(krad_opus->bandwidth)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: bandwidth request failed %s\n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: Set Opus bandwidth mode %d\n", krad_opus->bandwidth); } } ready = 1; for (c = 0; c < krad_opus->channels; c++) { if (krad_ringbuffer_read_space (krad_opus->resampled_ringbuf[c]) < krad_opus->frame_size * 4) { ready = 0; } } if (ready == 1) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->ret = krad_ringbuffer_read (krad_opus->resampled_ringbuf[c], (char *)krad_opus->resampled_samples[c], (krad_opus->frame_size * 4) ); } for (s = 0; s < krad_opus->frame_size; s++) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->interleaved_resampled_samples[s * krad_opus->channels + c] = krad_opus->resampled_samples[c][s]; } } bytes = opus_multistream_encode_float (krad_opus->encoder, krad_opus->interleaved_resampled_samples, krad_opus->frame_size, buffer, krad_opus->frame_size * 2); if (bytes < 0) { failfast ("Krad Opus Encoding failed: %s.", opus_strerror (bytes)); } *nframes = krad_opus->frame_size; return bytes; } return 0; }
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 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; }
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); }
static void ms_opus_enc_preprocess(MSFilter *f) { int error; int opusComplexity = -1; const char *env = NULL; OpusEncData *d = (OpusEncData *)f->data; /* create the encoder */ d->state = opus_encoder_create(d->samplerate, d->channels, d->application, &error); if (error != OPUS_OK) { ms_error("Opus encoder creation failed: %s", opus_strerror(error)); return; } #ifndef MS2_WINDOWS_UNIVERSAL env = getenv("MS2_OPUS_COMPLEXITY"); #endif if (env != NULL) { opusComplexity = atoi(env); if (opusComplexity < -1) opusComplexity = -1; /*our default value*/ if (opusComplexity > 10) opusComplexity = 10; } if (opusComplexity == -1){ #if defined(__arm__) || defined(_M_ARM) int cpucount = ms_factory_get_cpu_count(f->factory); if (cpucount == 1){ opusComplexity = 0; /* set complexity to 0 for single processor arm devices */ }else if (cpucount == 2) { opusComplexity = 5; } #endif } if (opusComplexity != -1){ ms_message("Set Opus complexity to %d", opusComplexity); opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(opusComplexity)); } /*otherwise we let opus with its default value, which is 9*/ error = opus_encoder_ctl(d->state, OPUS_SET_PACKET_LOSS_PERC(10)); if (error != OPUS_OK) { ms_error("Could not set default loss percentage to opus encoder: %s", opus_strerror(error)); } /* set the encoder parameters: VBR, IN_BAND_FEC, DTX and bitrate settings */ ms_opus_enc_set_vbr(f); ms_opus_enc_set_inbandfec(f); ms_opus_enc_set_dtx(f); /* if decoder prefers mono signal, force encoder to output mono signal */ if (d->stereo == 0) { error = opus_encoder_ctl(d->state, OPUS_SET_FORCE_CHANNELS(1)); if (error != OPUS_OK) { ms_error("could not force mono channel to opus encoder: %s", opus_strerror(error)); } if (d->channels == 2) ms_message("Opus encoder configured to encode mono despite it is feed with stereo."); }else if (d->channels == 2){ ms_message("Opus encoder configured to encode stereo."); } ms_filter_lock(f); // set bitrate wasn't call, compute it with the default network bitrate (36000) if (d->bitrate==-1) { compute_max_bitrate(d, 0); } apply_max_bitrate(d); ms_filter_unlock(f); }
/* * Open codec. */ static pj_status_t opus_codec_open(pjmedia_codec *codec, pjmedia_codec_param *attr) { pj_status_t status; struct opus_private *opus; int id, ret = 0; unsigned i; int structSizeBytes; int tmpFmtpVal = 0; unsigned max_nsamples; const pj_str_t STR_FMTP_USE_INBAND_FEC = {"useinbandfec", 12}; const pj_str_t STR_FMTP_MAX_AVERAGE_BITRATE = {"maxaveragebitrate", 17}; const pj_str_t STR_FMTP_MAX_CODED_AUDIO_BANDWIDTH = {"maxplaybackrate", 15}; const pj_str_t STR_FMTP_USE_DTX = {"usedtx", 6}; opus = (struct opus_private *)codec->codec_data; pj_assert(opus != NULL); pj_assert(opus->enc_ready == PJ_FALSE && opus->dec_ready == PJ_FALSE); PJ_LOG(4, (THIS_FILE, "Clock rate is %d ", attr->info.clock_rate)); opus->externalFs = attr->info.clock_rate; /* Create Encoder */ structSizeBytes = opus_encoder_get_size(attr->info.channel_cnt); opus->psEnc = pj_pool_zalloc(opus->pool, structSizeBytes); ret = opus_encoder_init(opus->psEnc, opus->externalFs, attr->info.channel_cnt, OPUS_APPLICATION_VOIP); if (ret) { PJ_LOG(1, (THIS_FILE, "Unable to init encoder : %d", ret)); return PJ_EINVAL; } /* * Set Encoder parameters * TODO : have it configurable */ opus_encoder_ctl(opus->psEnc, OPUS_SET_COMPLEXITY(2)); opus_encoder_ctl(opus->psEnc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); /* Apply fmtp params to Encoder */ for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_USE_INBAND_FEC) == 0) { tmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val)); opus_encoder_ctl(opus->psEnc, OPUS_SET_INBAND_FEC(tmpFmtpVal)); break; } else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_MAX_AVERAGE_BITRATE) == 0) { tmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val)); if (tmpFmtpVal >= 6000 && tmpFmtpVal <= 510000) { opus_encoder_ctl(opus->psEnc, OPUS_SET_BITRATE(tmpFmtpVal)); } } else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_MAX_CODED_AUDIO_BANDWIDTH) == 0) { tmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val)); if (tmpFmtpVal <= 8000) { opus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); } else if (tmpFmtpVal <= 12000) { opus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND)); } else if (tmpFmtpVal <= 16000) { opus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)); } else if (tmpFmtpVal <= 24000) { opus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); } else if (tmpFmtpVal <= 48000) { opus_encoder_ctl(opus->psEnc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); } } else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_USE_DTX) == 0) { tmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val)); opus_encoder_ctl(opus->psEnc, OPUS_SET_DTX(tmpFmtpVal)); } } opus->enc_ready = PJ_TRUE; /* Decoder buffer */ opus->pcm_bytes_per_sample = attr->info.pcm_bits_per_sample / 8; max_nsamples = 120 * OPUS_CLOCK_RATE / 1000; /* 120ms is max frame time */ opus->dec_buf_max_size = max_nsamples * opus->pcm_bytes_per_sample; opus->dec_buf = pj_pool_alloc(opus->pool, opus->dec_buf_max_size); /* Create decoder */ structSizeBytes = opus_decoder_get_size(attr->info.channel_cnt); opus->psDec = pj_pool_zalloc(opus->pool, structSizeBytes); ret = opus_decoder_init(opus->psDec, opus->externalFs, attr->info.channel_cnt); if (ret) { PJ_LOG(1, (THIS_FILE, "Unable to init decoder : %d", ret)); return PJ_EINVAL; } opus->dec_ready = PJ_TRUE; return PJ_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; }
void netjack_attach( netjack_driver_state_t *netj ) { //puts ("net_driver_attach"); jack_port_t * port; char buf[32]; unsigned int chn; int port_flags; if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 celt_int32 lookahead; netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); #else celt_int32_t lookahead; netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); #endif celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); netj->codec_latency = 2 * lookahead; #endif } if( netj->bitdepth == OPUS_MODE ) { #if HAVE_OPUS netj->opus_mode = opus_custom_mode_create(netj->sample_rate, netj->period_size, NULL); #endif } if (netj->handle_transport_sync) jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL); port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; for (chn = 0; chn < netj->capture_channels_audio; chn++) { snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); port = jack_port_register (netj->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); if (!port) { jack_error ("NET: cannot register port for %s", buf); break; } netj->capture_ports = jack_slist_append (netj->capture_ports, port); if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_11 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) ); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) ); #else netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) ); #endif #endif } else if( netj->bitdepth == OPUS_MODE ) { #if HAVE_OPUS OpusCustomDecoder *decoder = opus_custom_decoder_create( netj->opus_mode, 1, NULL ); netj->capture_srcs = jack_slist_append(netj->capture_srcs, decoder ); #endif } else { #if HAVE_SAMPLERATE netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL)); #endif } } for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) { snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); port = jack_port_register (netj->client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); if (!port) { jack_error ("NET: cannot register port for %s", buf); break; } netj->capture_ports = jack_slist_append (netj->capture_ports, port); } port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for (chn = 0; chn < netj->playback_channels_audio; chn++) { snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); port = jack_port_register (netj->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); if (!port) { jack_error ("NET: cannot register port for %s", buf); break; } netj->playback_ports = jack_slist_append (netj->playback_ports, port); if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_11 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); #else CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) ); #endif #endif } else if( netj->bitdepth == OPUS_MODE ) { #if HAVE_OPUS const int kbps = netj->resample_factor; jack_log( "OPUS %dkbps\n", kbps); OpusCustomMode *opus_mode = opus_custom_mode_create( netj->sample_rate, netj->period_size, NULL ); // XXX free me in the end OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, NULL ); opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10)); opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY)); netj->playback_srcs = jack_slist_append(netj->playback_srcs, oe ); #endif } else { #if HAVE_SAMPLERATE netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL)); #endif } } for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) { snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); port = jack_port_register (netj->client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); if (!port) { jack_error ("NET: cannot register port for %s", buf); break; } netj->playback_ports = jack_slist_append (netj->playback_ports, port); } jack_activate (netj->client); }
bool CAudioCodecOpus::InitCodec(AudioCodecInfo &codecInfo, AmAudioCodecMode mode) { mAudioInfo = &codecInfo.audio_info; if (AM_LIKELY(!mIsInitialized)) { codecInfo.audio_info.format = MF_OPUS; switch(mode) { case AM_AUDIO_CODEC_MODE_ENCODE: { int error; mEncoder = opus_encoder_create(codecInfo.audio_info.sampleRate, codecInfo.audio_info.channels, OPUS_APPLICATION_AUDIO, &error); mEncFrameSize = 20 * codecInfo.audio_info.sampleRate / 1000; mEncFrameBytes = mEncFrameSize * codecInfo.audio_info.channels * codecInfo.audio_info.sampleSize; if (AM_LIKELY(mEncoder)) { AM_U32& bitrate = codecInfo.codec_opus.opus_avg_bitrate; AM_U32& complexity = codecInfo.codec_opus.opus_complexity; int ret = opus_encoder_ctl(mEncoder, OPUS_SET_BITRATE(bitrate)); if (AM_UNLIKELY(ret != OPUS_OK)) { ERROR("Failed to set bitrate to %u: %s", bitrate, opus_strerror(ret)); } else { ret = opus_encoder_ctl(mEncoder, OPUS_SET_COMPLEXITY(complexity)); if (AM_UNLIKELY(ret != OPUS_OK)) { ERROR("Failed to set complexity to %u: %s", complexity, opus_strerror(ret)); } else { mRepacketizer = opus_repacketizer_create(); if (AM_LIKELY(mRepacketizer)) { mIsInitialized = true; } else { ERROR("Failed to create Opus repacketizer!"); } } } } else { ERROR("Failed to create OPUS encoder: %s!", opus_strerror(error)); } }break; case AM_AUDIO_CODEC_MODE_DECODE: { int error; codecInfo.audio_info.channels = 2; mDecoder = opus_decoder_create( codecInfo.audio_info.sampleRate, /* Always 48000 */ codecInfo.audio_info.channels, /* Always decode to stereo */ &error); mIsInitialized = (mDecoder != NULL); if (AM_UNLIKELY(!mDecoder)) { ERROR("Failed to create OPUS decoder: %s!", opus_strerror(error)); } }break; default: { ERROR("Invalid Opus codec mode!"); }break; } } else { int ret = 0; INFO("Audio codec %s is already initialized, reset to initial state!", CodecTypeToName[mCodecType]); mEncFrameSize = 20 * codecInfo.audio_info.sampleRate / 1000; mEncFrameBytes = mEncFrameSize * codecInfo.audio_info.channels * codecInfo.audio_info.sampleSize; switch(mode) { case AM_AUDIO_CODEC_MODE_ENCODE: case AM_AUDIO_CODEC_MODE_DECODE: { if (AM_LIKELY(mEncoder)) { ret = opus_encoder_ctl(mEncoder, OPUS_RESET_STATE); } if (AM_LIKELY(mDecoder)) { ret = opus_decoder_ctl(mDecoder, OPUS_RESET_STATE); } mIsInitialized = (ret == OPUS_OK); if (AM_UNLIKELY(!mIsInitialized)) { ERROR("Failed to reset audio codec %s: %s", CodecTypeToName[mCodecType], opus_strerror(ret)); } }break; default: { ERROR("Invalid mode!"); ret = -1; mIsInitialized = false; }break; } } return mIsInitialized; }
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; }
/** * This Function allocates all the I/O Ports which are added the lists. */ void alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi) { int port_flags = JackPortIsOutput; int chn; jack_port_t *port; char buf[32]; capture_ports = NULL; /* Allocate audio capture channels */ for (chn = 0; chn < n_capture_audio; chn++) { snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); if (!port) { printf( "jack_netsource: cannot register %s port\n", buf); break; } if (bitdepth == 1000) { #if HAVE_CELT #if HAVE_CELT_API_0_11 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); #else CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); #endif #endif } else if (bitdepth == 999) { #if HAVE_OPUS int err; OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate( client ), jack_get_buffer_size(client), &err); if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); } OpusCustomDecoder *decoder = opus_custom_decoder_create(opus_mode, 1, &err); if (err != OPUS_OK) { printf("OPUS DECODER FAILED\n"); } opus_custom_decoder_init(decoder, opus_mode, 1); capture_srcs = jack_slist_append(capture_srcs, decoder); #endif } else { #if HAVE_SAMPLERATE capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL)); #endif } capture_ports = jack_slist_append (capture_ports, port); } /* Allocate midi capture channels */ for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) { snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); if (!port) { printf ("jack_netsource: cannot register %s port\n", buf); break; } capture_ports = jack_slist_append(capture_ports, port); } /* Allocate audio playback channels */ port_flags = JackPortIsInput; playback_ports = NULL; for (chn = 0; chn < n_playback_audio; chn++) { snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); if (!port) { printf ("jack_netsource: cannot register %s port\n", buf); break; } if( bitdepth == 1000 ) { #if HAVE_CELT #if HAVE_CELT_API_0_11 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); #else CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); #endif #endif } else if( bitdepth == 999 ) { #if HAVE_OPUS const int kbps = factor; printf("new opus encoder %d kbps\n", kbps); int err; OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate (client), jack_get_buffer_size(client), &err ); // XXX free me if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); } OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err ); if (err != OPUS_OK) { printf("OPUS ENCODER FAILED\n"); } opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10)); opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY)); opus_custom_encoder_init(oe, opus_mode, 1); playback_srcs = jack_slist_append(playback_srcs, oe); #endif } else { #if HAVE_SAMPLERATE playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL)); #endif } playback_ports = jack_slist_append (playback_ports, port); } /* Allocate midi playback channels */ for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) { snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); if (!port) { printf ("jack_netsource: cannot register %s port\n", buf); break; } playback_ports = jack_slist_append (playback_ports, port); } }
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; }