예제 #1
0
// helper for creating call-recorder
static void create_recorder(pjsua_call_info ci)
{
	// specify target file
	pj_str_t rec_file = pj_str(app_cfg.record_file);
	pj_status_t status = PJ_ENOTFOUND;
	
	log_message("Creating recorder ... ");
	
	// Create recorder for call
	status = pjsua_recorder_create(&rec_file, 0, NULL, 0, 0, &rec_id);
	if (status != PJ_SUCCESS) error_exit("Error recording answer", status);
	
	// connect active call to call recorder
	pjsua_conf_port_id rec_port = pjsua_recorder_get_conf_port(rec_id);		
	pjsua_conf_connect(ci.conf_slot, rec_port);
	
	log_message("Done.\n");
}
예제 #2
0
static void systest_aec_test(void)
{
    const char *ref_wav_paths[] = { add_path(res_path, WAV_PLAYBACK_PATH),
				    ALT_PATH1 WAV_PLAYBACK_PATH };
    pjsua_player_id player_id = PJSUA_INVALID_ID;
    pjsua_recorder_id writer_id = PJSUA_INVALID_ID;
    enum gui_key key;
    test_item_t *ti;
    const char *title = "AEC/AES Test";
    unsigned last_ec_tail = 0;
    pj_status_t status;
    pj_str_t tmp;

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

    key = gui_msgbox(title,
		     "This test will try to find whether the AEC/AES "
		     "works good on this system. Test will play a file "
		     "while recording from mic. The recording will be "
		     "played back later so you can check if echo is there. "
		     "Press OK to start.",
		     WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }

    /* Save current EC tail */
    status = pjsua_get_ec_tail(&last_ec_tail);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Set EC tail setting to default */
    status = pjsua_set_ec(PJSUA_DEFAULT_EC_TAIL_LEN, 0);
    if (status != PJ_SUCCESS)
	goto on_return;

    /*
     * Create player and recorder
     */
    status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths,
			   &player_id);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(1,(THIS_FILE, status, "Error opening WAV file %s",
		     WAV_PLAYBACK_PATH));
	goto on_return;
    }

    status = pjsua_recorder_create(
                 pj_cstr(&tmp, add_path(doc_path, AEC_REC_PATH)), 0, 0, -1,
                 0, &writer_id);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(1,(THIS_FILE, status, "Error writing WAV file %s",
		     AEC_REC_PATH));
	goto on_return;
    }

    /*
     * Start playback and recording.
     */
    pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0);
    pj_thread_sleep(100);
    pjsua_conf_connect(0, pjsua_recorder_get_conf_port(writer_id));

    /* Wait user signal */
    gui_msgbox(title, "AEC/AES test is running. Press OK to stop this test.",
	       WITH_OK);

    /*
     * Stop and close playback and recorder
     */
    pjsua_conf_disconnect(0, pjsua_recorder_get_conf_port(writer_id));
    pjsua_conf_disconnect(pjsua_player_get_conf_port(player_id), 0);
    pjsua_recorder_destroy(writer_id);
    pjsua_player_destroy(player_id);
    player_id = PJSUA_INVALID_ID;
    writer_id = PJSUA_INVALID_ID;

    /*
     * Play the result.
     */
    status = pjsua_player_create(
                 pj_cstr(&tmp, add_path(doc_path, AEC_REC_PATH)),
                 0, &player_id);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(1,(THIS_FILE, status, "Error opening WAV file %s", AEC_REC_PATH));
	goto on_return;
    }
    pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0);

    /* Wait user signal */
    gui_msgbox(title, "We are now playing the captured audio from the mic. "
		      "Check if echo (of the audio played back previously) is "
		      "present in the audio. The recording is stored in "
		      AEC_REC_PATH " for offline analysis. "
		      "Press OK to stop.",
		      WITH_OK);

    pjsua_conf_disconnect(pjsua_player_get_conf_port(player_id), 0);

    key = gui_msgbox(title,
		     "Did you notice any echo in the recording?",
		     WITH_YESNO);


on_return:
    if (player_id != PJSUA_INVALID_ID)
	pjsua_player_destroy(player_id);
    if (writer_id != PJSUA_INVALID_ID)
	pjsua_recorder_destroy(writer_id);

    /* Wait until sound device closed before restoring back EC tail setting */
    while (pjsua_snd_is_active())
	pj_thread_sleep(10);
    pjsua_set_ec(last_ec_tail, 0);


    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encountered an error: ", status);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
    } else if (key == KEY_YES) {
	ti->success = PJ_FALSE;
	if (!ti->success) {
	    pj_ansi_strcpy(ti->reason, USER_ERROR);
	}
    } else {
	char msg[200];

	pj_ansi_snprintf(msg, sizeof(msg), "Test succeeded.\r\n");

	ti->success = PJ_TRUE;
	pj_ansi_strncpy(ti->reason, msg, sizeof(ti->reason));
	ti->reason[sizeof(ti->reason)-1] = '\0';
    }
}
예제 #3
0
static void systest_latency_test(void)
{
    const char *ref_wav_paths[] = { add_path(res_path, WAV_TOCK8_PATH), ALT_PATH1 WAV_TOCK8_PATH };
    pj_str_t rec_wav_file;
    pjsua_player_id play_id = PJSUA_INVALID_ID;
    pjsua_conf_port_id play_slot = PJSUA_INVALID_ID;
    pjsua_recorder_id rec_id = PJSUA_INVALID_ID;
    pjsua_conf_port_id rec_slot = PJSUA_INVALID_ID;
    pj_pool_t *pool = NULL;
    pjmedia_port *wav_port = NULL;
    unsigned lat_sum=0, lat_cnt=0, lat_min=0, lat_max=0;
    enum gui_key key;
    test_item_t *ti;
    const char *title = "Audio Latency Test";
    pj_status_t status;

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

    key = gui_msgbox(title,
		     "This test will try to find the audio device's "
		     "latency. We will play a special WAV file to the "
		     "speaker for ten seconds, then at the end "
		     "calculate the latency. Please don't do anything "
		     "until the test is done.", WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }
    key = gui_msgbox(title,
		     "For this test to work, we must be able to capture "
		     "the audio played in the speaker (the echo), and only"
		     " that audio (i.e. you must be in relatively quiet "
		     "place to run this test). "
		     "Press OK to start, or CANCEL to skip.",
		     WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }

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

    status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths,
			   &play_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    play_slot = pjsua_player_get_conf_port(play_id);

    rec_wav_file = pj_str(add_path(doc_path, WAV_LATENCY_OUT_PATH));
    status = pjsua_recorder_create(&rec_wav_file, 0, NULL, -1, 0, &rec_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    rec_slot = pjsua_recorder_get_conf_port(rec_id);

    /* Setup the test */
    //status = pjsua_conf_connect(0, 0);
    status = pjsua_conf_connect(play_slot, 0);
    status = pjsua_conf_connect(0, rec_slot);
    status = pjsua_conf_connect(play_slot, rec_slot);


    /* We're running */
    PJ_LOG(3,(THIS_FILE, "Please wait while test is running (~10 sec)"));
    gui_sleep(10);

    /* Done with the test */
    //status = pjsua_conf_disconnect(0, 0);
    status = pjsua_conf_disconnect(play_slot, rec_slot);
    status = pjsua_conf_disconnect(0, rec_slot);
    status = pjsua_conf_disconnect(play_slot, 0);

    pjsua_recorder_destroy(rec_id);
    rec_id = PJSUA_INVALID_ID;

    pjsua_player_destroy(play_id);
    play_id = PJSUA_INVALID_ID;

    /* Confirm that echo is heard */
    gui_msgbox(title,
	       "Test is done. Now we need to confirm that we indeed "
	       "captured the echo. We will play the captured audio "
	       "and please confirm that you can hear the 'tock' echo.",
	       WITH_OK);

    status = pjsua_player_create(&rec_wav_file, 0, &play_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    play_slot = pjsua_player_get_conf_port(play_id);

    status = pjsua_conf_connect(play_slot, 0);
    if (status != PJ_SUCCESS)
	goto on_return;

    key = gui_msgbox(title,
		     "The captured audio is being played back now. "
		     "Can you hear the 'tock' echo?",
		     WITH_YESNO);

    pjsua_player_destroy(play_id);
    play_id = PJSUA_INVALID_ID;

    if (key != KEY_YES)
	goto on_return;

    /* Now analyze the latency */
    pool = pjsua_pool_create("latency", 512, 512);

    status = pjmedia_wav_player_port_create(pool, rec_wav_file.ptr, 0, 0, 0, &wav_port);
    if (status != PJ_SUCCESS)
	goto on_return;

    status = calculate_latency(pool, wav_port, &lat_sum, &lat_cnt,
			       &lat_min, &lat_max);
    if (status != PJ_SUCCESS)
	goto on_return;

on_return:
    if (wav_port)
	pjmedia_port_destroy(wav_port);
    if (pool)
	pj_pool_release(pool);
    if (play_id != PJSUA_INVALID_ID)
	pjsua_player_destroy(play_id);
    if (rec_id != PJSUA_INVALID_ID)
	pjsua_recorder_destroy(rec_id);

    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encountered an error: ", status);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
    } else if (key != KEY_YES) {
	ti->success = PJ_FALSE;
	if (!ti->success) {
	    pj_ansi_strcpy(ti->reason, USER_ERROR);
	}
    } else {
	char msg[200];
	pj_size_t msglen;

	pj_ansi_snprintf(msg, sizeof(msg),
			 "The sound device latency:\r\n"
			 " Min=%u, Max=%u, Avg=%u\r\n",
			 lat_min, lat_max, lat_sum/lat_cnt);
	msglen = strlen(msg);

	if (lat_sum/lat_cnt > 500) {
	    pj_ansi_snprintf(msg+msglen, sizeof(msg)-msglen,
			     "The latency is huge!\r\n");
	    msglen = strlen(msg);
	} else if (lat_sum/lat_cnt > 200) {
	    pj_ansi_snprintf(msg+msglen, sizeof(msg)-msglen,
			     "The latency is quite high\r\n");
	    msglen = strlen(msg);
	}

	key = gui_msgbox(title, msg, WITH_OK);

	ti->success = PJ_TRUE;
	pj_ansi_strncpy(ti->reason, msg, sizeof(ti->reason));
	ti->reason[sizeof(ti->reason)-1] = '\0';
    }
}
예제 #4
0
/*****************************************************************************
 * test: record audio
 */
static void systest_rec_audio(void)
{
    const pj_str_t filename = pj_str(add_path(doc_path, WAV_REC_OUT_PATH));
    pj_pool_t *pool = NULL;
    enum gui_key key;
    pjsua_recorder_id rec_id = PJSUA_INVALID_ID;
    pjsua_player_id play_id = PJSUA_INVALID_ID;
    pjsua_conf_port_id rec_slot = PJSUA_INVALID_ID;
    pjsua_conf_port_id play_slot = PJSUA_INVALID_ID;
    pj_status_t status = PJ_SUCCESS;
    const char *title = "Audio Recording";
    test_item_t *ti;

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

    key = gui_msgbox(title,
		     "This test will allow you to record audio "
		     "from the microphone, and playback the "
		     "audio to the speaker. Press OK to start recording, "
		     "CANCEL to skip.",
		     WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }

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

    pool = pjsua_pool_create("rectest", 512, 512);

    status = pjsua_recorder_create(&filename, 0, NULL, -1, 0, &rec_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    rec_slot = pjsua_recorder_get_conf_port(rec_id);

    status = pjsua_conf_connect(0, rec_slot);
    if (status != PJ_SUCCESS)
	goto on_return;

    key = gui_msgbox(title,
		     "Recording is in progress now, please say "
		     "something in the microphone. Press OK "
		     "to stop recording", WITH_OK);

    pjsua_conf_disconnect(0, rec_slot);
    rec_slot = PJSUA_INVALID_ID;
    pjsua_recorder_destroy(rec_id);
    rec_id = PJSUA_INVALID_ID;

    status = pjsua_player_create(&filename, 0, &play_id);
    if (status != PJ_SUCCESS)
	goto on_return;

    play_slot = pjsua_player_get_conf_port(play_id);

    status = pjsua_conf_connect(play_slot, 0);
    if (status != PJ_SUCCESS)
	goto on_return;

    key = gui_msgbox(title,
		     "Recording has been stopped. "
		     "The recorded audio is being played now to "
		     "the speaker device, in a loop. Listen for "
		     "any audio impairments. Press OK to stop.",
		     WITH_OK);

on_return:
    if (rec_slot != PJSUA_INVALID_ID)
	pjsua_conf_disconnect(0, rec_slot);
    if (rec_id != PJSUA_INVALID_ID)
	pjsua_recorder_destroy(rec_id);
    if (play_slot != PJSUA_INVALID_ID)
	pjsua_conf_disconnect(play_slot, 0);
    if (play_id != PJSUA_INVALID_ID)
	pjsua_player_destroy(play_id);
    if (pool)
	pj_pool_release(pool);

    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encountered an error: ", status);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
    } else {
	key = gui_msgbox(title, "Is the audio okay?", WITH_YESNO);
	ti->success = (key == KEY_YES);
	if (!ti->success) {
	    pj_ansi_snprintf(textbuf, sizeof(textbuf),
			     "You will probably need to copy the recorded "
			     "WAV file %s to a desktop computer and analyze "
			     "it, to find out whether it's a recording "
			     "or playback problem.",
			     WAV_REC_OUT_PATH);
	    gui_msgbox(title, textbuf, WITH_OK);
	    pj_ansi_strcpy(ti->reason, USER_ERROR);
	}
    }
}