예제 #1
0
파일: media.c 프로젝트: kenygia/toxcore
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;
}
예제 #2
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);
}
예제 #3
0
static int alloc(struct aucodec_st **stp, struct aucodec *ac,
		 struct aucodec_prm *encp, struct aucodec_prm *decp,
		 const char *fmtp)
{
	struct aucodec_st *st;
	const uint32_t srate = aucodec_srate(ac);
	const uint8_t ch = aucodec_ch(ac);
	uint32_t ptime = DEFAULT_PTIME;
	int use_inbandfec;
	int use_dtx;
	int err = 0;
	int opuserr;

	(void)decp;
	(void)fmtp;

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

	if (encp && encp->ptime)
		ptime = encp->ptime;

	st->ac         = mem_ref(ac);
	st->frame_size = srate * ptime / 1000;
	st->fsize      = 2 * st->frame_size * ch;

	/* Encoder */
	st->enc = opus_encoder_create(srate, ch, opus.app, &opuserr);
	if (!st->enc) {
		err = ENOMEM;
		goto out;
	}

	use_inbandfec = 1;
	use_dtx = 1;

	opus_encoder_ctl(st->enc, OPUS_SET_BITRATE(opus.bitrate));
	opus_encoder_ctl(st->enc, OPUS_SET_BANDWIDTH(opus.bandwidth));
	opus_encoder_ctl(st->enc, OPUS_SET_VBR(opus.vbr));
	opus_encoder_ctl(st->enc, OPUS_SET_COMPLEXITY(opus.complex));
	opus_encoder_ctl(st->enc, OPUS_SET_INBAND_FEC(use_inbandfec));
	opus_encoder_ctl(st->enc, OPUS_SET_DTX(use_dtx));

	/* Decoder */
	st->dec = opus_decoder_create(srate, ch, &opuserr);
	if (!st->dec) {
		err = ENOMEM;
		goto out;
	}

 out:
	if (err)
		mem_deref(st);
	else
		*stp = st;

	return err;
}
예제 #4
0
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;
}
예제 #5
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));
}
예제 #7
0
//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 (
}
예제 #8
0
파일: audio.c 프로젝트: GrayHatter/toxcore
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;
}
예제 #9
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;
}
예제 #10
0
static gboolean
gst_opus_enc_setup (GstOpusEnc * enc)
{
  int error = OPUS_OK;

#ifndef GST_DISABLE_DEBUG
  GST_DEBUG_OBJECT (enc,
      "setup: %d Hz, %d channels, %d stereo streams, family %d",
      enc->sample_rate, enc->n_channels, enc->n_stereo_streams,
      enc->channel_mapping_family);
  GST_INFO_OBJECT (enc, "Mapping tables built: %d channels, %d stereo streams",
      enc->n_channels, enc->n_stereo_streams);
  gst_opus_common_log_channel_mapping_table (GST_ELEMENT (enc), opusenc_debug,
      "Encoding mapping table", enc->n_channels, enc->encoding_channel_mapping);
  gst_opus_common_log_channel_mapping_table (GST_ELEMENT (enc), opusenc_debug,
      "Decoding mapping table", enc->n_channels, enc->decoding_channel_mapping);
#endif

  enc->state = opus_multistream_encoder_create (enc->sample_rate,
      enc->n_channels, enc->n_channels - enc->n_stereo_streams,
      enc->n_stereo_streams, enc->encoding_channel_mapping,
      enc->audio_or_voip ? OPUS_APPLICATION_AUDIO : OPUS_APPLICATION_VOIP,
      &error);
  if (!enc->state || error != OPUS_OK)
    goto encoder_creation_failed;

  opus_multistream_encoder_ctl (enc->state, OPUS_SET_BITRATE (enc->bitrate), 0);
  opus_multistream_encoder_ctl (enc->state, OPUS_SET_BANDWIDTH (enc->bandwidth),
      0);
  opus_multistream_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr), 0);
  opus_multistream_encoder_ctl (enc->state,
      OPUS_SET_VBR_CONSTRAINT (enc->constrained_vbr), 0);
  opus_multistream_encoder_ctl (enc->state,
      OPUS_SET_COMPLEXITY (enc->complexity), 0);
  opus_multistream_encoder_ctl (enc->state,
      OPUS_SET_INBAND_FEC (enc->inband_fec), 0);
  opus_multistream_encoder_ctl (enc->state, OPUS_SET_DTX (enc->dtx), 0);
  opus_multistream_encoder_ctl (enc->state,
      OPUS_SET_PACKET_LOSS_PERC (enc->packet_loss_percentage), 0);

  GST_LOG_OBJECT (enc, "we have frame size %d", enc->frame_size);

  return TRUE;

encoder_creation_failed:
  GST_ERROR_OBJECT (enc, "Encoder creation failed");
  return FALSE;
}
예제 #11
0
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;
}
예제 #12
0
static void audio_encoder_init(uint32_t samplerate, int complexity,
                                                            uint32_t bitrate)
{
    assert(opus_enc == NULL);

    int err = 0;
    /* 1 channel (mono), OPUS audio profile */
    opus_enc = opus_encoder_create(samplerate, 1, OPUS_APPLICATION_AUDIO, &err);
    if (!opus_enc) {
        fprintf(stderr, "ERROR: opus_encoder_create() has failed - %d\n", err);
        exit(EXIT_FAILURE);
    }

    opus_encoder_ctl(opus_enc, OPUS_SET_COMPLEXITY(complexity));
    opus_encoder_ctl(opus_enc, OPUS_SET_BITRATE(bitrate));
    opus_encoder_ctl(opus_enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
    opus_encoder_ctl(opus_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
}
예제 #13
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 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);
}
예제 #14
0
/**
 * 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));
}
예제 #15
0
파일: group.c 프로젝트: Ansa89/toxcore
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;
}
예제 #17
0
bool OpusCodec::startCodec()
{
#ifdef HAVE_OPUS
  int err;

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

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

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

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

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

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

  //
  // Comment Packet
  //
  QByteArray comment=MakeCommentHeader();
  opus_ogg_packet.packet=(unsigned char *)comment.constData();
  opus_ogg_packet.bytes=comment.length();
  opus_ogg_packet.b_o_s=0;
  opus_ogg_packet.e_o_s=0;
  opus_ogg_packet.granulepos=0;
  opus_ogg_packet.packetno=opus_packet_number++;
  ogg_stream_packetin(&opus_ogg_stream,&opus_ogg_packet);
  while(ogg_stream_flush(&opus_ogg_stream,&opus_ogg_page)!=0) {
    opus_stream_prologue.append((const char *)opus_ogg_page.header,
			     opus_ogg_page.header_len);
    opus_stream_prologue.append((const char *)opus_ogg_page.body,
			     opus_ogg_page.body_len);
  }
  return true;
#else
  Log(LOG_ERR,"unsupported audio format (no build support)");
  return false;
#endif  // HAVE_OPUS
}
예제 #18
0
파일: opus.c 프로젝트: brigittebigi/sppas
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;
}
예제 #19
0
int krad_opus_encoder_read (krad_opus_t *krad_opus, unsigned char *buffer, int *nframes) {

	int ready;
	int bytes;
	int resp;
	int s, c;

	while (krad_ringbuffer_read_space (krad_opus->ringbuf[krad_opus->channels - 1]) >= 512 * 4 ) {
		   
		for (c = 0; c < krad_opus->channels; c++) {

			krad_opus->ret = krad_ringbuffer_peek (krad_opus->ringbuf[c], (char *)krad_opus->samples[c], (512 * 4) );
			
			krad_opus->src_data[c].data_in = krad_opus->samples[c];
			krad_opus->src_data[c].input_frames = 512;
			krad_opus->src_data[c].data_out = krad_opus->resampled_samples[c];
			krad_opus->src_data[c].output_frames = 2048;
			krad_opus->src_error[c] = src_process (krad_opus->src_resampler[c], &krad_opus->src_data[c]);
			if (krad_opus->src_error[c] != 0) {
				failfast ("Krad Opus Encoder: src resampler error: %s\n", src_strerror(krad_opus->src_error[c]));
			}
			krad_ringbuffer_read_advance (krad_opus->ringbuf[c], (krad_opus->src_data[c].input_frames_used * 4) );
			krad_opus->ret = krad_ringbuffer_write (krad_opus->resampled_ringbuf[c],
										   (char *)krad_opus->resampled_samples[c],
										           (krad_opus->src_data[c].output_frames_gen * 4) );
		}
	}
	
	if (krad_opus->new_bitrate != krad_opus->bitrate) {
		krad_opus->bitrate = krad_opus->new_bitrate;
		resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE(krad_opus->bitrate));
		if (resp != OPUS_OK) {
			failfast ("Krad Opus Encoder: bitrate request failed %s\n", opus_strerror (resp));
		} else {
			printk  ("Krad Opus Encoder: set opus bitrate %d\n", krad_opus->bitrate);
		}
	}
	
	if (krad_opus->new_frame_size != krad_opus->frame_size) {
		krad_opus->frame_size = krad_opus->new_frame_size;
		printk ("Krad Opus Encoder: frame size is now %d\n", krad_opus->frame_size);		
	}
	
	if (krad_opus->new_complexity != krad_opus->complexity) {
		krad_opus->complexity = krad_opus->new_complexity;
		resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_COMPLEXITY(krad_opus->complexity));
		if (resp != OPUS_OK) {
			failfast ("Krad Opus Encoder: complexity request failed %s. \n", opus_strerror(resp));
		} else {
			printk ("Krad Opus Encoder: set opus complexity %d\n", krad_opus->complexity);
		}
	}	

	if (krad_opus->new_signal != krad_opus->signal) {
		krad_opus->signal = krad_opus->new_signal;
		resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_SIGNAL(krad_opus->signal));
		if (resp != OPUS_OK) {
			failfast ("Krad Opus Encoder: signal request failed %s\n", opus_strerror(resp));
		} else {
			printk ("Krad Opus Encoder: set opus signal mode %d\n", krad_opus->signal);
		}
	}
	
	if (krad_opus->new_bandwidth != krad_opus->bandwidth) {
		krad_opus->bandwidth = krad_opus->new_bandwidth;
		resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BANDWIDTH(krad_opus->bandwidth));
		if (resp != OPUS_OK) {
			failfast ("Krad Opus Encoder: bandwidth request failed %s\n", opus_strerror(resp));
		} else {
			printk ("Krad Opus Encoder: Set Opus bandwidth mode %d\n", krad_opus->bandwidth);
		}
	}
		
	ready = 1;
	
	for (c = 0; c < krad_opus->channels; c++) {
		if (krad_ringbuffer_read_space (krad_opus->resampled_ringbuf[c]) < krad_opus->frame_size * 4) {
			ready = 0;
		}
	}

	if (ready == 1) {

		for (c = 0; c < krad_opus->channels; c++) {
			krad_opus->ret = krad_ringbuffer_read (krad_opus->resampled_ringbuf[c],
										  (char *)krad_opus->resampled_samples[c],
										          (krad_opus->frame_size * 4) );
		}

		for (s = 0; s < krad_opus->frame_size; s++) {
			for (c = 0; c < krad_opus->channels; c++) {
				krad_opus->interleaved_resampled_samples[s * krad_opus->channels + c] = krad_opus->resampled_samples[c][s];
			}
		}

		bytes = opus_multistream_encode_float (krad_opus->encoder,
											   krad_opus->interleaved_resampled_samples,
											   krad_opus->frame_size,
											   buffer,
											   krad_opus->frame_size * 2);

		if (bytes < 0) {
			failfast ("Krad Opus Encoding failed: %s.", opus_strerror (bytes));
		}

		*nframes = krad_opus->frame_size;

		return bytes;
	}
	
	return 0;

}
예제 #20
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;
}
예제 #21
0
파일: encode.c 프로젝트: lmangani/baresip
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;
}
예제 #22
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);
  

}
예제 #23
0
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);
}
예제 #24
0
/*
 * 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;
}
예제 #25
0
/*
 * Open codec.
 */
static pj_status_t  codec_open( pjmedia_codec *codec,
				pjmedia_codec_param *attr )
{
    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
    int idx, err;

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

    pj_mutex_lock (opus_data->mutex);

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

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

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

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

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

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

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

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

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

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

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

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

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

    pj_mutex_unlock (opus_data->mutex);
    return PJ_SUCCESS;
}
예제 #26
0
파일: netjack.c 프로젝트: Barrett17/jack2
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);
}
예제 #27
0
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;
}
예제 #28
0
int
_v3_audio_encode(
        v3_handle v3h,
        /* pcm input */
        const uint8_t *pcm,
        uint32_t pcmlen,
        /* payload output */
        int16_t index,
        int16_t format,
        v3_coder *coder,
        uint8_t *data,
        uint32_t *datalen,
        /* optional args */
        uint8_t channels) {
    uint32_t maxdatalen;
    int ret = V3_OK;

    _v3_enter(v3h, __func__);

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

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

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

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

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

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

    _v3_leave(v3h, __func__);
    return ret;
}
예제 #29
0
파일: netsource.c 프로젝트: jackaudio/jack2
/**
 * 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);
    }
}
예제 #30
0
static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
	struct opus_context *context = NULL;
	int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
	int decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
	switch_codec_fmtp_t codec_fmtp;
	opus_codec_settings_t opus_codec_settings = { 0 };
    
	if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
		return SWITCH_STATUS_FALSE;
	}
    
	context->enc_frame_size = codec->implementation->actual_samples_per_second * (codec->implementation->microseconds_per_packet / 1000) / 1000;


	memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
	codec_fmtp.private_info = &opus_codec_settings;
	switch_opus_fmtp_parse(codec->fmtp_in, &codec_fmtp);

	/* Verify if the local or remote configuration are lowering maxaveragebitrate and/or maxplaybackrate */
	if ( opus_prefs.maxaveragebitrate && (opus_prefs.maxaveragebitrate < opus_codec_settings.maxaveragebitrate || !opus_codec_settings.maxaveragebitrate) ) {
		opus_codec_settings.maxaveragebitrate = opus_prefs.maxaveragebitrate;
	}
	if ( opus_prefs.maxplaybackrate && (opus_prefs.maxplaybackrate < opus_codec_settings.maxplaybackrate || !opus_codec_settings.maxplaybackrate) ) {
		opus_codec_settings.maxplaybackrate = opus_prefs.maxplaybackrate;
	}

	codec->fmtp_out = gen_fmtp(&opus_codec_settings, codec->memory_pool);

	if (encoding) {
		/* come up with a way to specify these */
		int bitrate_bps = OPUS_AUTO;
		int use_vbr = opus_prefs.use_vbr;
		int complexity = opus_prefs.complexity;
		int err;
		int samplerate = opus_codec_settings.samplerate ? opus_codec_settings.samplerate : codec->implementation->actual_samples_per_second;
        
		context->encoder_object = opus_encoder_create(samplerate,
													  codec->implementation->number_of_channels,
													  codec->implementation->number_of_channels == 1 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, &err);
        
        if (err != OPUS_OK) {
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err));
            return SWITCH_STATUS_GENERR;
        }
        

		/* Setting documented in "RTP Payload Format for Opus Speech and Audio Codec"  draft-spittka-payload-rtp-opus-03 */
		if( opus_codec_settings.maxaveragebitrate ) { /* Remote codec settings found in SDP "fmtp", we accept to tune the Encoder */
			opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate));
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder set bitrate based on maxaveragebitrate found in SDP [%dbps]\n", opus_codec_settings.maxaveragebitrate);
		} else {
			/* Default codec settings used, may have been modified by SDP "samplerate" */
			opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps));
			if (codec->implementation->actual_samples_per_second == 8000) {
				opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
				opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
			} else {
				opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
			}
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder set bitrate to local settings [%dbps]\n", bitrate_bps);
		}

		/* Another setting from "RTP Payload Format for Opus Speech and Audio Codec" */
		if ( opus_codec_settings.maxplaybackrate ) {
			if (opus_codec_settings.maxplaybackrate == 8000) {       /* Audio Bandwidth: 0-4000Hz  Sampling Rate: 8000Hz */
				opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
			} else if (opus_codec_settings.maxplaybackrate == 12000) { /* Audio Bandwidth: 0-6000Hz  Sampling Rate: 12000Hz */
				opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND));
			} else if (opus_codec_settings.maxplaybackrate == 16000) { /* Audio Bandwidth: 0-8000Hz  Sampling Rate: 16000Hz */
				opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
			} else if (opus_codec_settings.maxplaybackrate == 24000) { /* Audio Bandwidth: 0-12000Hz Sampling Rate: 24000Hz */
				opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
			} else if (opus_codec_settings.maxplaybackrate == 48000) { /* Audio Bandwidth: 0-20000Hz Sampling Rate: 48000Hz */
				opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
			}
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder set bandwidth based on maxplaybackrate found in SDP [%dHz]\n", opus_codec_settings.maxplaybackrate);
		}

		if (use_vbr) {
			opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr));
		}
		if (complexity) {
			opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity));
        }

		if (opus_codec_settings.useinbandfec) {
			opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(opus_codec_settings.useinbandfec));
		}
        
		if (opus_codec_settings.usedtx) {
			opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX(opus_codec_settings.usedtx));
		}
	}
	
	if (decoding) {
		int err;
        
		context->decoder_object = opus_decoder_create(codec->implementation->actual_samples_per_second,
													  codec->implementation->number_of_channels, &err);
        
		
		if (err != OPUS_OK) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err));
            
			if (context->encoder_object) {
				opus_encoder_destroy(context->encoder_object);
				context->encoder_object = NULL;
			}
            
			return SWITCH_STATUS_GENERR;
		}
        
	}
    
	codec->private_info = context;
    
	return SWITCH_STATUS_SUCCESS;
}