Ejemplo n.º 1
0
static pj_status_t avi_event_cb(pjmedia_event *event,
                                void *user_data)
{
    avi_port_t *ap = (avi_port_t *)user_data;

    switch (event->type) {
    case PJMEDIA_EVENT_WND_CLOSED:
        ap->is_quitting = PJ_TRUE;
        break;
    case PJMEDIA_EVENT_MOUSE_BTN_DOWN:
        if (ap->is_running) {
            pjmedia_vid_port_stop(ap->vid_port);
            if (ap->snd_port)
                pjmedia_aud_stream_stop(
                    pjmedia_snd_port_get_snd_stream(ap->snd_port));
        } else {
            pjmedia_vid_port_start(ap->vid_port);
            if (ap->snd_port)
                pjmedia_aud_stream_start(
                    pjmedia_snd_port_get_snd_stream(ap->snd_port));
        }
        ap->is_running = !ap->is_running;
        break;
    default:
        return PJ_SUCCESS;
    }

    /* We handled the event on our own, so return non-PJ_SUCCESS here */
    return -1;
}
Ejemplo n.º 2
0
static void record(unsigned rec_index, const char *filename)
{
    pj_pool_t *pool = NULL;
    pjmedia_port *wav = NULL;
    pjmedia_aud_param param;
    pjmedia_aud_stream *strm = NULL;
    char line[10], *dummy;
    pj_status_t status;

    if (filename == NULL)
	filename = WAV_FILE;

    pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), "wav",
			  1000, 1000, NULL);

    status = pjmedia_wav_writer_port_create(pool, filename, 16000, 
					    1, 320, 16, 0, 0, &wav);
    if (status != PJ_SUCCESS) {
	app_perror("Error creating WAV file", status);
	goto on_return;
    }

    status = pjmedia_aud_dev_default_param(rec_index, &param);
    if (status != PJ_SUCCESS) {
	app_perror("pjmedia_aud_dev_default_param()", status);
	goto on_return;
    }

    param.dir = PJMEDIA_DIR_CAPTURE;
    param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
    param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
    param.channel_count = PJMEDIA_PIA_CCNT(&wav->info);
    param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info);

    status = pjmedia_aud_stream_create(&param, &wav_rec_cb, NULL, wav,
				       &strm);
    if (status != PJ_SUCCESS) {
	app_perror("Error opening the sound device", status);
	goto on_return;
    }

    status = pjmedia_aud_stream_start(strm);
    if (status != PJ_SUCCESS) {
	app_perror("Error starting the sound device", status);
	goto on_return;
    }

    PJ_LOG(3,(THIS_FILE, "Recording started, press ENTER to stop"));
    dummy = fgets(line, sizeof(line), stdin);

on_return:
    if (strm) {
	pjmedia_aud_stream_stop(strm);
	pjmedia_aud_stream_destroy(strm);
    }
    if (wav)
	pjmedia_port_destroy(wav);
    if (pool)
	pj_pool_release(pool);
}
Ejemplo n.º 3
0
static void play_file(unsigned play_index, const char *filename)
{
    pj_pool_t *pool = NULL;
    pjmedia_port *wav = NULL;
    pjmedia_aud_param param;
    pjmedia_aud_stream *strm = NULL;
    char line[10], *dummy;
    pj_status_t status;

    if (filename == NULL)
	filename = WAV_FILE;

    pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), "wav",
			  1000, 1000, NULL);

    status = pjmedia_wav_player_port_create(pool, filename, 20, 0, 0, &wav);
    if (status != PJ_SUCCESS) {
	app_perror("Error opening WAV file", status);
	goto on_return;
    }

    status = pjmedia_aud_dev_default_param(play_index, &param);
    if (status != PJ_SUCCESS) {
	app_perror("pjmedia_aud_dev_default_param()", status);
	goto on_return;
    }

    param.dir = PJMEDIA_DIR_PLAYBACK;
    param.clock_rate = wav->info.clock_rate;
    param.samples_per_frame = wav->info.samples_per_frame;
    param.channel_count = wav->info.channel_count;
    param.bits_per_sample = wav->info.bits_per_sample;

    status = pjmedia_aud_stream_create(&param, NULL, &wav_play_cb, wav,
				       &strm);
    if (status != PJ_SUCCESS) {
	app_perror("Error opening the sound device", status);
	goto on_return;
    }

    status = pjmedia_aud_stream_start(strm);
    if (status != PJ_SUCCESS) {
	app_perror("Error starting the sound device", status);
	goto on_return;
    }

    PJ_LOG(3,(THIS_FILE, "Playback started, press ENTER to stop"));
    dummy = fgets(line, sizeof(line), stdin);

on_return:
    if (strm) {
	pjmedia_aud_stream_stop(strm);
	pjmedia_aud_stream_destroy(strm);
    }
    if (wav)
	pjmedia_port_destroy(wav);
    if (pool)
	pj_pool_release(pool);
}
Ejemplo n.º 4
0
/* Start sound */
static pj_status_t snd_start(unsigned flag)
{
    pj_status_t status;

    if (strm != NULL) {
    	app_perror("snd already open", PJ_EINVALIDOP);
    	return PJ_EINVALIDOP;
    }

    pjmedia_aud_dev_default_param(0, &param);
    param.channel_count = CHANNEL_COUNT;
    param.clock_rate = CLOCK_RATE;
    param.samples_per_frame = SAMPLES_PER_FRAME;
    param.dir = (pjmedia_dir) flag;
    param.ext_fmt.id = PJMEDIA_FORMAT_AMR;
    param.ext_fmt.bitrate = 12200;
    param.output_route = PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;

    status = pjmedia_aud_stream_create(&param, &rec_cb, &play_cb, NULL, &strm);
    if (status != PJ_SUCCESS) {
    	app_perror("snd open", status);
    	return status;
    }

    rec_cnt = play_cnt = 0;
    pj_gettimeofday(&t_start);

    pjmedia_delay_buf_reset(delaybuf);

    status = pjmedia_aud_stream_start(strm);
    if (status != PJ_SUCCESS) {
    	app_perror("snd start", status);
    	pjmedia_aud_stream_destroy(strm);
    	strm = NULL;
    	return status;
    }

    return PJ_SUCCESS;
}
Ejemplo n.º 5
0
PJ_DEF(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream)
{
    return pjmedia_aud_stream_start(stream->aud_strm);
}
Ejemplo n.º 6
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 )
{
    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;
}
Ejemplo n.º 7
0
PJ_DEF(pj_status_t) pjmedia_aud_test( const pjmedia_aud_param *param,
				      pjmedia_aud_test_results *result)
{
    pj_status_t status = PJ_SUCCESS;
    pjmedia_aud_stream *strm;
    struct test_data test_data;
    unsigned ptime, tmp;
    
    /*
     * Init test parameters
     */
    pj_bzero(&test_data, sizeof(test_data));
    test_data.param = param;
    test_data.result = result;

    test_data.pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(),
				    "audtest", 1000, 1000, NULL);
    pj_mutex_create_simple(test_data.pool, "sndtest", &test_data.mutex); 

    /*
     * Open device.
     */
    status = pjmedia_aud_stream_create(test_data.param, &rec_cb, &play_cb, 
				       &test_data, &strm);
    if (status != PJ_SUCCESS) {
        app_perror("Unable to open device", status);
	pj_pool_release(test_data.pool);
        return status;
    }


    /* Sleep for a while to let sound device "settles" */
    pj_thread_sleep(200);

    /*
     * Start the stream.
     */
    status = pjmedia_aud_stream_start(strm);
    if (status != PJ_SUCCESS) {
        app_perror("Unable to start capture stream", status);
	pjmedia_aud_stream_destroy(strm);
	pj_pool_release(test_data.pool);
        return status;
    }

    PJ_LOG(3,(THIS_FILE,
	      " Please wait while test is in progress (~%d secs)..",
	      (DURATION+SKIP_DURATION)/1000));

    /* Let the stream runs for few msec/sec to get stable result.
     * (capture normally begins with frames available simultaneously).
     */
    pj_thread_sleep(SKIP_DURATION);


    /* Begin gather data */
    test_data.running = 1;

    /* 
     * Let the test runs for a while.
     */
    pj_thread_sleep(DURATION);


    /*
     * Close stream.
     */
    test_data.running = 0;
    pjmedia_aud_stream_destroy(strm);
    pj_pool_release(test_data.pool);


    /* 
     * Gather results
     */
    ptime = param->samples_per_frame * 1000 / param->clock_rate;

    tmp = pj_math_stat_get_stddev(&test_data.capture_data.delay);
    result->rec.frame_cnt = test_data.capture_data.delay.n;
    result->rec.min_interval = DIV_ROUND(test_data.capture_data.delay.min, 1000);
    result->rec.max_interval = DIV_ROUND(test_data.capture_data.delay.max, 1000);
    result->rec.avg_interval = DIV_ROUND(test_data.capture_data.delay.mean, 1000);
    result->rec.dev_interval = DIV_ROUND(tmp, 1000);
    result->rec.max_burst    = DIV_ROUND_UP(result->rec.max_interval, ptime);

    tmp = pj_math_stat_get_stddev(&test_data.playback_data.delay);
    result->play.frame_cnt = test_data.playback_data.delay.n;
    result->play.min_interval = DIV_ROUND(test_data.playback_data.delay.min, 1000);
    result->play.max_interval = DIV_ROUND(test_data.playback_data.delay.max, 1000);
    result->play.avg_interval = DIV_ROUND(test_data.capture_data.delay.mean, 1000);
    result->play.dev_interval = DIV_ROUND(tmp, 1000);
    result->play.max_burst    = DIV_ROUND_UP(result->play.max_interval, ptime);

    /* Check drifting */
    if (param->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK) {
	int end_diff, start_diff, drift;

	end_diff = test_data.capture_data.last_timestamp -
		   test_data.playback_data.last_timestamp;
	start_diff = test_data.capture_data.first_timestamp-
		      test_data.playback_data.first_timestamp;
	drift = end_diff > start_diff? end_diff - start_diff :
		start_diff - end_diff;

	/* Allow one frame tolerance for clock drift detection */
	if (drift < (int)param->samples_per_frame) {
	    result->rec_drift_per_sec = 0;
	} else {
	    unsigned msec_dur;

	    msec_dur = (test_data.capture_data.last_timestamp - 
		       test_data.capture_data.first_timestamp) * 1000 /
		       test_data.param->clock_rate;

	    result->rec_drift_per_sec = drift * 1000 / msec_dur;

	}
    }

    return test_data.has_error? PJ_EUNKNOWN : PJ_SUCCESS;
}
Ejemplo n.º 8
0
static void pcap2wav(const pj_str_t *codec,
		     const pj_str_t *wav_filename,
		     pjmedia_aud_dev_index dev_id,
		     const pj_str_t *srtp_crypto,
		     const pj_str_t *srtp_key)
{
    const pj_str_t WAV = {".wav", 4};
    struct pkt
    {
	pj_uint8_t	 buffer[320];
	pjmedia_rtp_hdr	*rtp;
	pj_uint8_t	*payload;
	unsigned	 payload_len;
    } pkt0;
    pjmedia_codec_mgr *cmgr;
    const pjmedia_codec_info *ci;
    pjmedia_codec_param param;
    unsigned samples_per_frame;
    pj_status_t status;

    /* Initialize all codecs */
    T( pjmedia_codec_register_audio_codecs(app.mept, NULL) );

    /* Create SRTP transport is needed */
#if PJMEDIA_HAS_SRTP
    if (srtp_crypto->slen) {
	pjmedia_srtp_crypto crypto;

	pj_bzero(&crypto, sizeof(crypto));
	crypto.key = *srtp_key;
	crypto.name = *srtp_crypto;
	T( pjmedia_transport_srtp_create(app.mept, NULL, NULL, &app.srtp) );
	T( pjmedia_transport_srtp_start(app.srtp, &crypto, &crypto) );
    }
#else
    PJ_UNUSED_ARG(srtp_crypto);
    PJ_UNUSED_ARG(srtp_key);
#endif

    /* Read first packet */
    read_rtp(pkt0.buffer, sizeof(pkt0.buffer), &pkt0.rtp, 
	     &pkt0.payload, &pkt0.payload_len, PJ_FALSE);

    cmgr = pjmedia_endpt_get_codec_mgr(app.mept);

    /* Get codec info and param for the specified payload type */
    app.pt = pkt0.rtp->pt;
    if (app.pt >=0 && app.pt < 96) {
	T( pjmedia_codec_mgr_get_codec_info(cmgr, pkt0.rtp->pt, &ci) );
    } else {
	unsigned cnt = 2;
	const pjmedia_codec_info *info[2];
	T( pjmedia_codec_mgr_find_codecs_by_id(cmgr, codec, &cnt, 
					       info, NULL) );
	if (cnt != 1)
	    err_exit("Codec ID must be specified and unique!", 0);

	ci = info[0];
    }
    T( pjmedia_codec_mgr_get_default_param(cmgr, ci, &param) );

    /* Alloc and init codec */
    T( pjmedia_codec_mgr_alloc_codec(cmgr, ci, &app.codec) );
    T( pjmedia_codec_init(app.codec, app.pool) );
    T( pjmedia_codec_open(app.codec, &param) );

    /* Init audio device or WAV file */
    samples_per_frame = ci->clock_rate * param.info.frm_ptime / 1000;
    if (pj_strcmp2(wav_filename, "-") == 0) {
	pjmedia_aud_param aud_param;

	/* Open audio device */
	T( pjmedia_aud_dev_default_param(dev_id, &aud_param) );
	aud_param.dir = PJMEDIA_DIR_PLAYBACK;
	aud_param.channel_count = ci->channel_cnt;
	aud_param.clock_rate = ci->clock_rate;
	aud_param.samples_per_frame = samples_per_frame;
	T( pjmedia_aud_stream_create(&aud_param, NULL, &play_cb, 
				     NULL, &app.aud_strm) );
	T( pjmedia_aud_stream_start(app.aud_strm) );
    } else if (pj_stristr(wav_filename, &WAV)) {
	/* Open WAV file */
	T( pjmedia_wav_writer_port_create(app.pool, wav_filename->ptr,
					  ci->clock_rate, ci->channel_cnt,
					  samples_per_frame,
					  param.info.pcm_bits_per_sample, 0, 0,
					  &app.wav) );
    } else {
	err_exit("invalid output file", PJ_EINVAL);
    }

    /* Loop reading PCAP and writing WAV file */
    for (;;) {
	struct pkt pkt1;
	pj_timestamp ts;
	pjmedia_frame frames[16], pcm_frame;
	short pcm[320];
	unsigned i, frame_cnt;
	long samples_cnt, ts_gap;

	pj_assert(sizeof(pcm) >= samples_per_frame);

	/* Parse first packet */
	ts.u64 = 0;
	frame_cnt = PJ_ARRAY_SIZE(frames);
	T( pjmedia_codec_parse(app.codec, pkt0.payload, pkt0.payload_len, 
				&ts, &frame_cnt, frames) );

	/* Decode and write to WAV file */
	samples_cnt = 0;
	for (i=0; i<frame_cnt; ++i) {
	    pjmedia_frame pcm_frame;

	    pcm_frame.buf = pcm;
	    pcm_frame.size = samples_per_frame * 2;

	    T( pjmedia_codec_decode(app.codec, &frames[i], 
				    (unsigned)pcm_frame.size, &pcm_frame) );
	    if (app.wav) {
		T( pjmedia_port_put_frame(app.wav, &pcm_frame) );
	    }
	    if (app.aud_strm) {
		T( wait_play(&pcm_frame) );
	    }
	    samples_cnt += samples_per_frame;
	}

	/* Read next packet */
	read_rtp(pkt1.buffer, sizeof(pkt1.buffer), &pkt1.rtp,
		 &pkt1.payload, &pkt1.payload_len, PJ_TRUE);

	/* Fill in the gap (if any) between pkt0 and pkt1 */
	ts_gap = pj_ntohl(pkt1.rtp->ts) - pj_ntohl(pkt0.rtp->ts) -
		 samples_cnt;
	while (ts_gap >= (long)samples_per_frame) {

	    pcm_frame.buf = pcm;
	    pcm_frame.size = samples_per_frame * 2;

	    if (app.codec->op->recover) {
		T( pjmedia_codec_recover(app.codec, (unsigned)pcm_frame.size, 
					 &pcm_frame) );
	    } else {
		pj_bzero(pcm_frame.buf, pcm_frame.size);
	    }

	    if (app.wav) {
		T( pjmedia_port_put_frame(app.wav, &pcm_frame) );
	    }
	    if (app.aud_strm) {
		T( wait_play(&pcm_frame) );
	    }
	    ts_gap -= samples_per_frame;
	}
	
	/* Next */
	pkt0 = pkt1;
	pkt0.rtp = (pjmedia_rtp_hdr*)pkt0.buffer;
	pkt0.payload = pkt0.buffer + (pkt1.payload - pkt1.buffer);
    }
}
Ejemplo n.º 9
0
pj_status_t latency_checker::start(latency_config_t &config)
{
	pj_status_t result = PJ_EINVAL;
	if(m_pool == NULL)
	{
		m_dstate = 0;
		m_start_tone_time.u64 = 0;
		m_latency = 0;
		m_quality = 0;
		m_config = config;
		m_status_string[0] = 0;
		m_gain = new snd_agc("",30,1,32000,32000);
		m_idle_freq1_det = new tone_detector(m_config.clock_rate,IDLE_FREQ1);
		m_idle_freq2_det = new tone_detector(m_config.clock_rate,IDLE_FREQ2);
		m_active_freq1_det = new tone_detector(m_config.clock_rate,ACTIVE_FREQ1);
		m_active_freq2_det = new tone_detector(m_config.clock_rate,ACTIVE_FREQ2);

		init_generate_dual_tone(&m_idle_tone,m_config.clock_rate,IDLE_FREQ1,IDLE_FREQ2,32767);
		init_generate_dual_tone(&m_active_tone,m_config.clock_rate,ACTIVE_FREQ1,ACTIVE_FREQ2,32767);
		pj_log_set_level(0);
		pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_SENDER | PJ_LOG_HAS_TIME | PJ_LOG_HAS_MICRO_SEC);
		if(pj_init()==PJ_SUCCESS)
		{
			m_caching_pool = (pj_caching_pool *)malloc(sizeof(pj_caching_pool));
			pj_caching_pool_init( m_caching_pool, NULL, 0 );
			m_pool_factory=&m_caching_pool->factory;
			m_pool = pj_pool_create(m_pool_factory, "LATENCY NATIVE", 4000, 4000, NULL);
			pj_log_set_level(m_config.logs.level);
			pj_logging_init(m_pool);
			pj_logging_setLogToConsole(1);

			pj_logging_setFilename(m_config.logs.file_name);
			pj_logging_setMaxLogFiles(m_config.logs.max_files);
			pj_logging_setMaxLogFileSize(m_config.logs.max_file_size*1024*1024);
			pj_logging_start();

			pj_get_timestamp(&m_last_get_frame_time);

			m_lock = new PPJ_SemaphoreLock(m_pool,NULL,1,1);

			pjmedia_aud_subsys_init(m_pool_factory);
#if PJMEDIA_AUDIO_DEV_HAS_ANDROID
#if PJ_ANDROID_DEVICE==1
			pjmedia_aud_register_factory(&pjmedia_android_factory);
#endif
#if PJ_ANDROID_DEVICE==2
			pjmedia_aud_register_factory(&pjmedia_opensl_factory);
#endif
#if PJ_ANDROID_DEVICE==3
			pjmedia_aud_register_factory(&pjmedia_alsa_factory);
#endif
#endif

			pjmedia_aud_param params;
			params.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
			params.rec_id = 1;
			params.play_id = 6;
			params.clock_rate = m_config.clock_rate;
			params.channel_count = 1;
			params.samples_per_frame = m_config.min_frame_length*m_config.clock_rate/1000;
			params.bits_per_sample = 16;
			params.flags = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY | PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
			params.input_latency_ms = m_config.min_frame_length;
			params.output_latency_ms = m_config.min_frame_length;
			result = pjmedia_aud_stream_create(&params,&rec_cb_s,&play_cb_s,this,&m_aud_stream);

			if(result==PJ_SUCCESS)
			{
				result = pjmedia_aud_stream_start(m_aud_stream);
				if(result==PJ_SUCCESS)
				{


				}

			}
		}
	}

	if(result!=PJ_SUCCESS)
		internal_clean();
	return result;
}
Ejemplo n.º 10
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;
}