예제 #1
0
/****************************************************************************
 * configurations
 */
static void systest_list_audio_devs()
{
    unsigned i, dev_count;
    pj_size_t len=0;
    pj_status_t status;
    test_item_t *ti;
    enum gui_key key;
    const char *title = "Audio Device List";

    ti = systest_alloc_test_item(title);
    if (!ti)
	return;

    PJ_LOG(3,(THIS_FILE, "Running %s", title));

    dev_count = pjmedia_aud_dev_count();
    if (dev_count == 0) {
	key = gui_msgbox(title,
			 "No audio devices are found", WITH_OK);
	ti->success = PJ_FALSE;
	pj_ansi_strcpy(ti->reason, "No device found");
	return;
    }

    pj_ansi_snprintf(ti->reason+len, sizeof(ti->reason)-len,
		     "Found %u devices\r\n", dev_count);
    len = strlen(ti->reason);

    for (i=0; i<dev_count; ++i) {
	pjmedia_aud_dev_info info;

	status = pjmedia_aud_dev_get_info(i, &info);
	if (status != PJ_SUCCESS) {
	    systest_perror("Error retrieving device info: ", status);
	    ti->success = PJ_FALSE;
	    pj_strerror(status, ti->reason, sizeof(ti->reason));
	    return;
	}

	pj_ansi_snprintf(ti->reason+len, sizeof(ti->reason)-len,
			 " %2d: %s [%s] (%d/%d)\r\n",
		          i, info.driver, info.name,
			  info.input_count, info.output_count);
	len = strlen(ti->reason);
    }

    ti->reason[len] = '\0';
    key = gui_msgbox(title, ti->reason, WITH_OK);
    PJ_UNUSED_ARG(key);

    ti->success = PJ_TRUE;
}
예제 #2
0
PJ_DEF(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index)
{
    pjmedia_snd_dev_info *oi = &g_sys.info[g_sys.info_counter];
    pjmedia_aud_dev_info di;

    g_sys.info_counter = (g_sys.info_counter+1) % PJ_ARRAY_SIZE(g_sys.info);

    if (pjmedia_aud_dev_get_info(index, &di) != PJ_SUCCESS)
	return NULL;

    pj_bzero(oi, sizeof(*oi));
    pj_ansi_strncpy(oi->name, di.name, sizeof(oi->name));
    oi->name[sizeof(oi->name)-1] = '\0';
    oi->input_count = di.input_count;
    oi->output_count = di.output_count;
    oi->default_samples_per_sec = di.default_samples_per_sec;

    return oi;
}
예제 #3
0
int main() {
    pj_init();
    pjmedia_aud_dev_index dev_idx;

    pjmedia_endpt *ep;

    pj_caching_pool cp;
    pj_caching_pool_init(&cp, 0, 1024);

    pjmedia_endpt_create(&cp.factory, NULL, 1, &ep);
    int dev_cnt;
    dev_cnt = pjmedia_aud_dev_count();
    printf("Got %d audio devices\n", dev_cnt);

    for (dev_idx=0; dev_idx < dev_cnt; ++dev_idx) {
        pjmedia_aud_dev_info info;
        CHECK(__FILE__, pjmedia_aud_dev_get_info(dev_idx, &info));
        printf("%d. %s (in=%d, out=%d)\n", dev_idx, info.name, info.input_count, info.output_count);
    }
    return 0;
}
예제 #4
0
static void list_devices(void)
{
    unsigned i;
    pj_status_t status;
    
    dev_count = pjmedia_aud_dev_count();
    if (dev_count == 0) {
	PJ_LOG(3,(THIS_FILE, "No devices found"));
	return;
    }

    PJ_LOG(3,(THIS_FILE, "Found %d devices:", dev_count));

    for (i=0; i<dev_count; ++i) {
	pjmedia_aud_dev_info info;

	status = pjmedia_aud_dev_get_info(i, &info);
	if (status != PJ_SUCCESS)
	    continue;

	PJ_LOG(3,(THIS_FILE," %2d: %s [%s] (%d/%d)",
	          i, info.driver, info.name, info.input_count, info.output_count));
    }
}
예제 #5
0
파일: sound_port.c 프로젝트: iamroger/voip
/*
 * Start the sound stream.
 * This may be called even when the sound stream has already been started.
 */
static pj_status_t start_sound_device( pj_pool_t *pool,
				       pjmedia_snd_port *snd_port )
{
    pjmedia_aud_rec_cb snd_rec_cb;
    pjmedia_aud_play_cb snd_play_cb;
    pjmedia_aud_param param_copy;
    pj_status_t status;

    /* Check if sound has been started. */
    if (snd_port->aud_stream != NULL)
	return PJ_SUCCESS;

    PJ_ASSERT_RETURN(snd_port->dir == PJMEDIA_DIR_CAPTURE ||
		     snd_port->dir == PJMEDIA_DIR_PLAYBACK ||
		     snd_port->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK,
		     PJ_EBUG);

    /* Get device caps */
    if (snd_port->aud_param.dir & PJMEDIA_DIR_CAPTURE) {
	pjmedia_aud_dev_info dev_info;

	status = pjmedia_aud_dev_get_info(snd_port->aud_param.rec_id, 
					  &dev_info);
	if (status != PJ_SUCCESS)
	    return status;

	snd_port->aud_caps = dev_info.caps;
    } else {
	snd_port->aud_caps = 0;
    }

    /* Process EC settings */
    pj_memcpy(&param_copy, &snd_port->aud_param, sizeof(param_copy));
    if (param_copy.flags & PJMEDIA_AUD_DEV_CAP_EC) {
	/* EC is wanted */
	if ((snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) == 0 &&
            (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC))
        {
	    /* Device supports EC */
	    /* Nothing to do */
	} else {
	    /* Application wants to use software EC or device
             * doesn't support EC, remove EC settings from
	     * device parameters
	     */
	    param_copy.flags &= ~(PJMEDIA_AUD_DEV_CAP_EC |
				  PJMEDIA_AUD_DEV_CAP_EC_TAIL);
	}
    }

    /* Use different callback if format is not PCM */
    if (snd_port->aud_param.ext_fmt.id == PJMEDIA_FORMAT_L16) {
	snd_rec_cb = &rec_cb;
	snd_play_cb = &play_cb;
    } else {
	snd_rec_cb = &rec_cb_ext;
	snd_play_cb = &play_cb_ext;
    }

    /* Open the device */
    status = pjmedia_aud_stream_create(&param_copy,
				       snd_rec_cb,
				       snd_play_cb,
				       snd_port,
				       &snd_port->aud_stream);

    if (status != PJ_SUCCESS)
	return status;

    /* Inactivity limit before EC is suspended. */
    snd_port->ec_suspend_limit = AEC_SUSPEND_LIMIT *
				 (snd_port->clock_rate / 
				  snd_port->samples_per_frame);

    /* Create software EC if parameter specifies EC and
     * (app specifically requests software EC or device
     * doesn't support EC). Only do this if the format is PCM!
     */
    if ((snd_port->aud_param.flags & PJMEDIA_AUD_DEV_CAP_EC) &&
	((snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC)==0 ||
         (snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) != 0) &&
	param_copy.ext_fmt.id == PJMEDIA_FORMAT_PCM)
    {
	if ((snd_port->aud_param.flags & PJMEDIA_AUD_DEV_CAP_EC_TAIL)==0) {
	    snd_port->aud_param.flags |= PJMEDIA_AUD_DEV_CAP_EC_TAIL;
	    snd_port->aud_param.ec_tail_ms = AEC_TAIL;
	    PJ_LOG(4,(THIS_FILE, "AEC tail is set to default %u ms",
				 snd_port->aud_param.ec_tail_ms));
	}
	    
	status = pjmedia_snd_port_set_ec(snd_port, pool, 
					 snd_port->aud_param.ec_tail_ms,
					 snd_port->prm_ec_options);
	if (status != PJ_SUCCESS) {
	    pjmedia_aud_stream_destroy(snd_port->aud_stream);
	    snd_port->aud_stream = NULL;
	    return status;
	}
    }

    /* Start sound stream. */
    if (!(snd_port->options & PJMEDIA_SND_PORT_NO_AUTO_START)) {
	status = pjmedia_aud_stream_start(snd_port->aud_stream);
    }
    if (status != PJ_SUCCESS) {
	pjmedia_aud_stream_destroy(snd_port->aud_stream);
	snd_port->aud_stream = NULL;
	return status;
    }

    return PJ_SUCCESS;
}
예제 #6
0
static void systest_display_settings(void)
{
    pjmedia_aud_dev_info di;
    pj_size_t len = 0;
    enum gui_key key;
    test_item_t *ti;
    const char *title = "Audio Settings";
    pj_status_t status;

    ti = systest_alloc_test_item(title);
    if (!ti)
	return;

    PJ_LOG(3,(THIS_FILE, "Running %s", title));

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Version: %s\r\n",
		     pj_get_version());
    len = strlen(textbuf);

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Test clock rate: %d\r\n",
		     systest.media_cfg.clock_rate);
    len = strlen(textbuf);

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Device clock rate: %d\r\n",
		     systest.media_cfg.snd_clock_rate);
    len = strlen(textbuf);

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Aud frame ptime: %d\r\n",
		     systest.media_cfg.audio_frame_ptime);
    len = strlen(textbuf);

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Channel count: %d\r\n",
		     systest.media_cfg.channel_count);
    len = strlen(textbuf);

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Audio switching: %s\r\n",
	    (PJMEDIA_CONF_USE_SWITCH_BOARD ? "Switchboard" : "Conf bridge"));
    len = strlen(textbuf);

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Snd buff count: %d\r\n",
		     PJMEDIA_SOUND_BUFFER_COUNT);
    len = strlen(textbuf);

    /* Capture device */
    status = pjmedia_aud_dev_get_info(systest.rec_id, &di);
    if (status != PJ_SUCCESS) {
	systest_perror("Error querying device info", status);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
	return;
    }

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len,
		     "Rec dev : %d (%s) [%s]\r\n",
		     systest.rec_id,
		     di.name,
		     di.driver);
    len = strlen(textbuf);

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len,
		     "Rec  buf : %d msec\r\n",
		     systest.media_cfg.snd_rec_latency);
    len = strlen(textbuf);

    /* Playback device */
    status = pjmedia_aud_dev_get_info(systest.play_id, &di);
    if (status != PJ_SUCCESS) {
	systest_perror("Error querying device info", status);
	return;
    }

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len,
		     "Play dev: %d (%s) [%s]\r\n",
		     systest.play_id,
		     di.name,
		     di.driver);
    len = strlen(textbuf);

    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len,
		     "Play buf: %d msec\r\n",
		     systest.media_cfg.snd_play_latency);
    len = strlen(textbuf);

    ti->success = PJ_TRUE;
    pj_ansi_strncpy(ti->reason, textbuf, sizeof(ti->reason));
    ti->reason[sizeof(ti->reason)-1] = '\0';
    key = gui_msgbox(title, textbuf, WITH_OK);
    PJ_UNUSED_ARG(key); /* Warning about unused var */
}
예제 #7
0
/* Application init */
static pj_status_t app_init()
{
    unsigned i, count;
    pj_status_t status;

    /* Redirect log */
    pj_log_set_log_func((void (*)(int,const char*,int)) &log_writer);
    pj_log_set_decor(PJ_LOG_HAS_NEWLINE);
    pj_log_set_level(3);

    /* Init pjlib */
    status = pj_init();
    if (status != PJ_SUCCESS) {
    	app_perror("pj_init()", status);
    	return status;
    }

    pj_caching_pool_init(&cp, NULL, 0);

    /* Init sound subsystem */
    status = pjmedia_aud_subsys_init(&cp.factory);
    if (status != PJ_SUCCESS) {
    	app_perror("pjmedia_snd_init()", status);
        pj_caching_pool_destroy(&cp);
    	pj_shutdown();
    	return status;
    }

    count = pjmedia_aud_dev_count();
    PJ_LOG(3,(THIS_FILE, "Device count: %d", count));
    for (i=0; i<count; ++i) {
    	pjmedia_aud_dev_info info;
    	pj_status_t status;

    	status = pjmedia_aud_dev_get_info(i, &info);
    	pj_assert(status == PJ_SUCCESS);
    	PJ_LOG(3, (THIS_FILE, "%d: %s %d/%d %dHz",
    		   i, info.name, info.input_count, info.output_count,
    		   info.default_samples_per_sec));
    	
	unsigned j;

	/* Print extended formats supported by this audio device */
	PJ_LOG(3, (THIS_FILE, "   Extended formats supported:"));
	for (j = 0; j < info.ext_fmt_cnt; ++j) {
	    const char *fmt_name = NULL;
	    
	    switch (info.ext_fmt[j].id) {
	    case PJMEDIA_FORMAT_PCMA:
		fmt_name = "PCMA";
		break;
	    case PJMEDIA_FORMAT_PCMU:
		fmt_name = "PCMU";
		break;
	    case PJMEDIA_FORMAT_AMR:
		fmt_name = "AMR-NB";
		break;
	    case PJMEDIA_FORMAT_G729:
		fmt_name = "G729";
		break;
	    case PJMEDIA_FORMAT_ILBC:
		fmt_name = "ILBC";
		break;
	    case PJMEDIA_FORMAT_PCM:
		fmt_name = "PCM";
		break;
	    default:
		fmt_name = "Unknown";
		break;
	    }
	    PJ_LOG(3, (THIS_FILE, "   - %s", fmt_name));
	}
    }

    /* Create pool */
    pool = pj_pool_create(&cp.factory, THIS_FILE, 512, 512, NULL);
    if (pool == NULL) {
    	app_perror("pj_pool_create()", status);
        pj_caching_pool_destroy(&cp);
    	pj_shutdown();
    	return status;
    }

    /* Init delay buffer */
    status = pjmedia_delay_buf_create(pool, THIS_FILE, CLOCK_RATE,
				      SAMPLES_PER_FRAME, CHANNEL_COUNT,
				      0, 0, &delaybuf);
    if (status != PJ_SUCCESS) {
    	app_perror("pjmedia_delay_buf_create()", status);
        //pj_caching_pool_destroy(&cp);
    	//pj_shutdown();
    	//return status;
    }

    return PJ_SUCCESS;
}
예제 #8
0
static void show_dev_info(unsigned index)
{
#define H   "%-20s"
    pjmedia_aud_dev_info info;
    char formats[200];
    pj_status_t status;

    if (index >= dev_count) {
	PJ_LOG(1,(THIS_FILE, "Error: invalid index %u", index));
	return;
    }

    status = pjmedia_aud_dev_get_info(index, &info);
    if (status != PJ_SUCCESS) {
	app_perror("pjmedia_aud_dev_get_info() error", status);
	return;
    }

    PJ_LOG(3, (THIS_FILE, "Device at index %u:", index));
    PJ_LOG(3, (THIS_FILE, "-------------------------"));

    PJ_LOG(3, (THIS_FILE, H": %u (0x%x)", "ID", index, index));
    PJ_LOG(3, (THIS_FILE, H": %s", "Name", info.name));
    PJ_LOG(3, (THIS_FILE, H": %s", "Driver", info.driver));
    PJ_LOG(3, (THIS_FILE, H": %u", "Input channels", info.input_count));
    PJ_LOG(3, (THIS_FILE, H": %u", "Output channels", info.output_count));
    PJ_LOG(3, (THIS_FILE, H": %s", "Capabilities", decode_caps(info.caps)));

    formats[0] = '\0';
    if (info.caps & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) {
	unsigned i;

	for (i=0; i<info.ext_fmt_cnt; ++i) {
	    char bitrate[32];

	    switch (info.ext_fmt[i].id) {
	    case PJMEDIA_FORMAT_L16:
		strcat(formats, "L16/");
		break;
	    case PJMEDIA_FORMAT_PCMA:
		strcat(formats, "PCMA/");
		break;
	    case PJMEDIA_FORMAT_PCMU:
		strcat(formats, "PCMU/");
		break;
	    case PJMEDIA_FORMAT_AMR:
		strcat(formats, "AMR/");
		break;
	    case PJMEDIA_FORMAT_G729:
		strcat(formats, "G729/");
		break;
	    case PJMEDIA_FORMAT_ILBC:
		strcat(formats, "ILBC/");
		break;
	    default:
		strcat(formats, "unknown/");
		break;
	    }
	    sprintf(bitrate, "%u", info.ext_fmt[i].det.aud.avg_bps);
	    strcat(formats, bitrate);
	    strcat(formats, " ");
	}
    }
    PJ_LOG(3, (THIS_FILE, H": %s", "Extended formats", formats));

#undef H
}
예제 #9
0
/*
 * Start the sound stream.
 * This may be called even when the sound stream has already been started.
 */
static pj_status_t start_sound_device( pj_pool_t *pool,
				       pjmedia_snd_port *snd_port )
{
    int i;float f;
    pjmedia_aud_rec_cb snd_rec_cb;
    pjmedia_aud_play_cb snd_play_cb;
    pjmedia_aud_param param_copy;
    pj_status_t status;

    /* Check if sound has been started. */
    if (snd_port->aud_stream != NULL)
	return PJ_SUCCESS;

    PJ_ASSERT_RETURN(snd_port->dir == PJMEDIA_DIR_CAPTURE ||
		     snd_port->dir == PJMEDIA_DIR_PLAYBACK ||
		     snd_port->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK,
		     PJ_EBUG);

    /* Get device caps */
    if (snd_port->aud_param.dir & PJMEDIA_DIR_CAPTURE) {
	pjmedia_aud_dev_info dev_info;

	status = pjmedia_aud_dev_get_info(snd_port->aud_param.rec_id, 
					  &dev_info);
	if (status != PJ_SUCCESS)
	    return status;

	snd_port->aud_caps = dev_info.caps;
    } else {
	snd_port->aud_caps = 0;
    }

    /* Process EC settings */
    pj_memcpy(&param_copy, &snd_port->aud_param, sizeof(param_copy));
    if (param_copy.flags & PJMEDIA_AUD_DEV_CAP_EC) {
	/* EC is wanted */
	if ((snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) == 0 &&
            (snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC))
        {
	    /* Device supports EC */
	    /* Nothing to do */
	} else {
	    /* Application wants to use software EC or device
             * doesn't support EC, remove EC settings from
	     * device parameters
	     */
	    param_copy.flags &= ~(PJMEDIA_AUD_DEV_CAP_EC |
				  PJMEDIA_AUD_DEV_CAP_EC_TAIL);
	}
    }

    /* Use different callback if format is not PCM */
    if (snd_port->aud_param.ext_fmt.id == PJMEDIA_FORMAT_L16) {
	snd_rec_cb = &rec_cb;
	snd_play_cb = &play_cb;
    } else {
	snd_rec_cb = &rec_cb_ext;
	snd_play_cb = &play_cb_ext;
    }

    /* Open the device */
    status = pjmedia_aud_stream_create(&param_copy,
				       snd_rec_cb,
				       snd_play_cb,
				       snd_port,
				       &snd_port->aud_stream);

    if (status != PJ_SUCCESS)
	return status;

    /* Inactivity limit before EC is suspended. */
    snd_port->ec_suspend_limit = AEC_SUSPEND_LIMIT *
				 (snd_port->clock_rate / 
				  snd_port->samples_per_frame);

    /* Create software EC if parameter specifies EC and
     * (app specifically requests software EC or device
     * doesn't support EC). Only do this if the format is PCM!
     */
    if ((snd_port->aud_param.flags & PJMEDIA_AUD_DEV_CAP_EC) &&
	((snd_port->aud_caps & PJMEDIA_AUD_DEV_CAP_EC)==0 ||
         (snd_port->prm_ec_options & PJMEDIA_ECHO_USE_SW_ECHO) != 0) &&
	param_copy.ext_fmt.id == PJMEDIA_FORMAT_PCM)
    {
	if ((snd_port->aud_param.flags & PJMEDIA_AUD_DEV_CAP_EC_TAIL)==0) {
	    snd_port->aud_param.flags |= PJMEDIA_AUD_DEV_CAP_EC_TAIL;
	    snd_port->aud_param.ec_tail_ms = AEC_TAIL;
	    PJ_LOG(4,(THIS_FILE, "AEC tail is set to default %u ms",
				 snd_port->aud_param.ec_tail_ms));
	}
	    
	status = pjmedia_snd_port_set_ec(snd_port, pool, 
					 snd_port->aud_param.ec_tail_ms,
					 snd_port->prm_ec_options);
	if (status != PJ_SUCCESS) {
	    pjmedia_aud_stream_destroy(snd_port->aud_stream);
	    snd_port->aud_stream = NULL;
	    return status;
	}
    }

    /* Start sound stream. */
    if (!(snd_port->options & PJMEDIA_SND_PORT_NO_AUTO_START)) {
	status = pjmedia_aud_stream_start(snd_port->aud_stream);
    }
    if (status != PJ_SUCCESS) {
	pjmedia_aud_stream_destroy(snd_port->aud_stream);
	snd_port->aud_stream = NULL;
	return status;
    }

#ifdef MY_SAVE_FILE_SEND
      if (fd_save !=NULL)
	fclose(fd_save);
      fd_save = fopen("/sdcard/send_data.pcm","wb");
      if (fd_save == NULL) PJ_LOG(1,(THIS_FILE, "open /sdcard/send_data.pcm failed!"));
#endif

#ifdef MY_SAVE_FILE_BEFORE_SPEEX
      if (fd_bfspeex != NULL)
	fclose(fd_bfspeex);
      fd_bfspeex = fopen("/sdcard/send_data_bfspeex.pcm","wb");
      if (fd_bfspeex == NULL) PJ_LOG(1,(THIS_FILE, "open /sdcard/send_data_bfspeex.pcm failed!"));
#endif

	if (pjmedia_audio_use_speex_ns == PJ_TRUE)
                        PJ_LOG(4,(THIS_FILE,"pjmedia_audio_use_speex_ns:true"));
	else
                        PJ_LOG(4,(THIS_FILE,"pjmedia_audio_use_speex_ns:false"));
                if (pjmedia_audio_use_speex_ns == PJ_TRUE){
                        if (snd_port->speex_st){
                PJ_LOG(4,(THIS_FILE, "speex noise suppress destroy"));
                speex_preprocess_state_destroy(snd_port->speex_st);
                        }
                        PJ_LOG(4,(THIS_FILE, "speex noise suppress start"));
      snd_port->speex_st =speex_preprocess_state_init(snd_port->samples_per_frame,snd_port->clock_rate);
      i=1;
      speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_DENOISE, &i);
      i=0;
      speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_AGC, &i);
      i=8000;
      speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
      i=0;
      speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_DEREVERB, &i);
      f=.0;
      speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
      f=.0;
      speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
	#if 0
	int vad = 1;   
	int vadProbStart = 80;   
	int vadProbContinue = 65;   
	speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_VAD, &vad); //静音检测   
	speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_PROB_START , &vadProbStart); //Set probability required for the VAD to go from silence to voice    
	speex_preprocess_ctl(snd_port->speex_st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &vadProbContinue);
	#endif
		}

    return PJ_SUCCESS;
}