⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sound_port.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    return PJ_SUCCESS;
}


/*
 * Stop the sound device.
 * This may be called even when there's no sound device in the port.
 */
static pj_status_t stop_sound_device( pjmedia_snd_port *snd_port )
{
    /* Check if we have sound stream device. */
    if (snd_port->snd_stream) {
	pjmedia_snd_stream_stop(snd_port->snd_stream);
	pjmedia_snd_stream_close(snd_port->snd_stream);
	snd_port->snd_stream = NULL;
    }

    /* Destroy AEC */
    if (snd_port->ec_state) {
	pjmedia_echo_destroy(snd_port->ec_state);
	snd_port->ec_state = NULL;
    }

    return PJ_SUCCESS;
}


/*
 * Create bidirectional port.
 */
PJ_DEF(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool,
					     int rec_id,
					     int play_id,
					     unsigned clock_rate,
					     unsigned channel_count,
					     unsigned samples_per_frame,
					     unsigned bits_per_sample,
					     unsigned options,
					     pjmedia_snd_port **p_port)
{
    pjmedia_snd_port *snd_port;

    PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);

    snd_port = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_port);
    PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM);

    snd_port->rec_id = rec_id;
    snd_port->play_id = play_id;
    snd_port->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
    snd_port->options = options | DEFAULT_OPTIONS;
    snd_port->clock_rate = clock_rate;
    snd_port->channel_count = channel_count;
    snd_port->samples_per_frame = samples_per_frame;
    snd_port->bits_per_sample = bits_per_sample;

    *p_port = snd_port;


    /* Start sound device immediately.
     * If there's no port connected, the sound callback will return
     * empty signal.
     */
    return start_sound_device( pool, snd_port );

}

/*
 * Create sound recorder AEC.
 */
PJ_DEF(pj_status_t) pjmedia_snd_port_create_rec( pj_pool_t *pool,
						 int dev_id,
						 unsigned clock_rate,
						 unsigned channel_count,
						 unsigned samples_per_frame,
						 unsigned bits_per_sample,
						 unsigned options,
						 pjmedia_snd_port **p_port)
{
    pjmedia_snd_port *snd_port;

    PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);

    snd_port = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_port);
    PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM);

    snd_port->rec_id = dev_id;
    snd_port->dir = PJMEDIA_DIR_CAPTURE;
    snd_port->options = options | DEFAULT_OPTIONS;
    snd_port->clock_rate = clock_rate;
    snd_port->channel_count = channel_count;
    snd_port->samples_per_frame = samples_per_frame;
    snd_port->bits_per_sample = bits_per_sample;

    *p_port = snd_port;

    /* Start sound device immediately.
     * If there's no port connected, the sound callback will return
     * empty signal.
     */
    return start_sound_device( pool, snd_port );
}


/*
 * Create sound player port.
 */
PJ_DEF(pj_status_t) pjmedia_snd_port_create_player( pj_pool_t *pool,
						    int dev_id,
						    unsigned clock_rate,
						    unsigned channel_count,
						    unsigned samples_per_frame,
						    unsigned bits_per_sample,
						    unsigned options,
						    pjmedia_snd_port **p_port)
{
    pjmedia_snd_port *snd_port;

    PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);

    snd_port = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_port);
    PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM);

    snd_port->play_id = dev_id;
    snd_port->dir = PJMEDIA_DIR_PLAYBACK;
    snd_port->options = options | DEFAULT_OPTIONS;
    snd_port->clock_rate = clock_rate;
    snd_port->channel_count = channel_count;
    snd_port->samples_per_frame = samples_per_frame;
    snd_port->bits_per_sample = bits_per_sample;

    *p_port = snd_port;

    /* Start sound device immediately.
     * If there's no port connected, the sound callback will return
     * empty signal.
     */
    return start_sound_device( pool, snd_port );
}


/*
 * Destroy port (also destroys the sound device).
 */
PJ_DEF(pj_status_t) pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port)
{
    PJ_ASSERT_RETURN(snd_port, PJ_EINVAL);

    return stop_sound_device(snd_port);
}


/*
 * Retrieve the sound stream associated by this sound device port.
 */
PJ_DEF(pjmedia_snd_stream*) pjmedia_snd_port_get_snd_stream(
						pjmedia_snd_port *snd_port)
{
    PJ_ASSERT_RETURN(snd_port, NULL);
    return snd_port->snd_stream;
}


/*
 * Enable AEC
 */
PJ_DEF(pj_status_t) pjmedia_snd_port_set_ec( pjmedia_snd_port *snd_port,
					     pj_pool_t *pool,
					     unsigned tail_ms,
					     unsigned options)
{
    pjmedia_snd_stream_info si;
    pj_status_t status;

    /* Sound must be opened in full-duplex mode */
    PJ_ASSERT_RETURN(snd_port && 
		     snd_port->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK,
		     PJ_EINVALIDOP);

    /* Sound port must have 16bits per sample */
    PJ_ASSERT_RETURN(snd_port->bits_per_sample == 16,
		     PJ_EINVALIDOP);

    /* Destroy AEC */
    if (snd_port->ec_state) {
	pjmedia_echo_destroy(snd_port->ec_state);
	snd_port->ec_state = NULL;
    }

    snd_port->aec_tail_len = tail_ms;

    if (tail_ms != 0) {
	unsigned delay_ms;

	status = pjmedia_snd_stream_get_info(snd_port->snd_stream, &si);
	if (status != PJ_SUCCESS)
	    si.rec_latency = si.play_latency = 0;

	delay_ms = (si.rec_latency + si.play_latency) * 1000 /
		   snd_port->clock_rate;
	status = pjmedia_echo_create(pool, snd_port->clock_rate, 
				    snd_port->samples_per_frame, 
				    tail_ms, delay_ms,
				    options, &snd_port->ec_state);
	if (status != PJ_SUCCESS)
	    snd_port->ec_state = NULL;
	else
	    snd_port->ec_suspended = PJ_FALSE;
    } else {
	PJ_LOG(4,(THIS_FILE, "Echo canceller is now disabled in the "
			     "sound port"));
	status = PJ_SUCCESS;
    }

    return status;
}


/* Get AEC tail length */
PJ_DEF(pj_status_t) pjmedia_snd_port_get_ec_tail( pjmedia_snd_port *snd_port,
						  unsigned *p_length)
{
    PJ_ASSERT_RETURN(snd_port && p_length, PJ_EINVAL);
    *p_length =  snd_port->ec_state ? snd_port->aec_tail_len : 0;
    return PJ_SUCCESS;
}



/*
 * Connect a port.
 */
PJ_DEF(pj_status_t) pjmedia_snd_port_connect( pjmedia_snd_port *snd_port,
					      pjmedia_port *port)
{
    pjmedia_port_info *pinfo;

    PJ_ASSERT_RETURN(snd_port && port, PJ_EINVAL);

    /* Check that port has the same configuration as the sound device
     * port.
     */
    pinfo = &port->info;
    if (pinfo->clock_rate != snd_port->clock_rate)
	return PJMEDIA_ENCCLOCKRATE;

    if (pinfo->samples_per_frame != snd_port->samples_per_frame)
	return PJMEDIA_ENCSAMPLESPFRAME;

    if (pinfo->channel_count != snd_port->channel_count)
	return PJMEDIA_ENCCHANNEL;

    if (pinfo->bits_per_sample != snd_port->bits_per_sample)
	return PJMEDIA_ENCBITS;

    /* Port is okay. */
    snd_port->port = port;
    return PJ_SUCCESS;
}


/*
 * Get the connected port.
 */
PJ_DEF(pjmedia_port*) pjmedia_snd_port_get_port(pjmedia_snd_port *snd_port)
{
    PJ_ASSERT_RETURN(snd_port, NULL);
    return snd_port->port;
}


/*
 * Disconnect port.
 */
PJ_DEF(pj_status_t) pjmedia_snd_port_disconnect(pjmedia_snd_port *snd_port)
{
    PJ_ASSERT_RETURN(snd_port, PJ_EINVAL);

    snd_port->port = NULL;

    return PJ_SUCCESS;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -