/* $Id: systest.c 4537 2013-06-19 06:47:43Z riza $ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include "systest.h"
#include "gui.h"

#define THIS_FILE "systest.c"

unsigned    test_item_count;
test_item_t test_items[SYSTEST_MAX_TEST];
char	    doc_path[PATH_LENGTH] = {0};
char	    res_path[PATH_LENGTH] = {0};
char	    fpath[PATH_LENGTH];

#define USER_ERROR  "User used said not okay"

static void systest_wizard(void);
static void systest_list_audio_devs(void);
static void systest_display_settings(void);
static void systest_play_tone(void);
static void systest_play_wav1(void);
static void systest_play_wav2(void);
static void systest_rec_audio(void);
static void systest_audio_test(void);
static void systest_latency_test(void);
static void systest_aec_test(void);
static void exit_app(void);

/* Menus */
static gui_menu menu_exit = { "Exit", &exit_app };

static gui_menu menu_wizard =  { "Run test wizard", &systest_wizard };
static gui_menu menu_playtn = { "Play Tone", &systest_play_tone };
static gui_menu menu_playwv1 = { "Play WAV File1", &systest_play_wav1 };
static gui_menu menu_playwv2 = { "Play WAV File2", &systest_play_wav2 };
static gui_menu menu_recaud  = { "Record Audio", &systest_rec_audio };
static gui_menu menu_audtest = { "Device Test", &systest_audio_test };
static gui_menu menu_calclat = { "Latency Test", &systest_latency_test };
static gui_menu menu_sndaec = { "AEC/AES Test", &systest_aec_test };

static gui_menu menu_listdev = { "View Devices", &systest_list_audio_devs };
static gui_menu menu_getsets = { "View Settings", &systest_display_settings };

static gui_menu menu_tests = { 
    "Tests", NULL, 
    10, 
    {
	&menu_wizard,
	&menu_audtest, 
	&menu_playtn,
	&menu_playwv1,
	&menu_playwv2,
	&menu_recaud,
	&menu_calclat,
	&menu_sndaec,
	NULL, 
	&menu_exit
    }
};

static gui_menu menu_options = { 
    "Options", NULL, 
    2, 
    {
	&menu_listdev,
	&menu_getsets,
    }
};

static gui_menu root_menu = { 
    "Root", NULL, 2, {&menu_tests, &menu_options} 
};

/*****************************************************************/

#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
PJ_INLINE(char *) add_path(const char *path, const char *fname)
{
    strncpy(fpath, path, PATH_LENGTH);
    strncat(fpath, fname, PATH_LENGTH);
    return fpath;
}
#else
#   define add_path(path, fname) fname
#endif

static void exit_app(void)
{
    systest_save_result(add_path(doc_path, RESULT_OUT_PATH));
    gui_destroy();
}


#include <pjsua-lib/pjsua.h>
#include <pjmedia_audiodev.h>

typedef struct systest_t
{
    pjsua_config	    ua_cfg;
    pjsua_media_config	    media_cfg;
    pjmedia_aud_dev_index   rec_id;
    pjmedia_aud_dev_index   play_id;
} systest_t;

static systest_t systest;
static char textbuf[600];

/* Device ID to test */
int systest_cap_dev_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
int systest_play_dev_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;

static void systest_perror(const char *title, pj_status_t status)
{
    char errmsg[PJ_ERR_MSG_SIZE];
    char themsg[PJ_ERR_MSG_SIZE + 100];

    if (status != PJ_SUCCESS)
	pj_strerror(status, errmsg, sizeof(errmsg));
    else
	errmsg[0] = '\0';
    
    strcpy(themsg, title);
    strncat(themsg, errmsg, sizeof(themsg)-1);
    themsg[sizeof(themsg)-1] = '\0';

    gui_msgbox("Error", themsg, WITH_OK);
}

test_item_t *systest_alloc_test_item(const char *title)
{
    test_item_t *ti;

    if (test_item_count == SYSTEST_MAX_TEST) {
	gui_msgbox("Error", "You have done too many tests", WITH_OK);
	return NULL;
    }

    ti = &test_items[test_item_count++];
    pj_bzero(ti, sizeof(*ti));
    pj_ansi_strcpy(ti->title, title);

    return ti;
}

/*****************************************************************************
 * test: play simple ringback tone and hear it 
 */
static void systest_play_tone(void)
{
    /* Ringtones  */
    #define RINGBACK_FREQ1	    440	    /* 400 */
    #define RINGBACK_FREQ2	    480	    /* 450 */
    #define RINGBACK_ON		    3000    /* 400 */
    #define RINGBACK_OFF	    4000    /* 200 */
    #define RINGBACK_CNT	    1	    /* 2   */
    #define RINGBACK_INTERVAL	    4000    /* 2000 */

    unsigned i, samples_per_frame;
    pjmedia_tone_desc tone[RINGBACK_CNT];
    pj_pool_t *pool = NULL;
    pjmedia_port *ringback_port = NULL;
    enum gui_key key;
    int ringback_slot = -1;
    test_item_t *ti;
    pj_str_t name;
    const char *title = "Audio Tone Playback Test";
    pj_status_t status;

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

    key = gui_msgbox(title,
		     "This test will play simple ringback tone to "
		     "the speaker. Please listen carefully for audio "
		     "impairments such as stutter. You may need "
		     "to let this test running for a while to "
		     "make sure that everything is okay. Press "
		     "OK to start, 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("ringback", 512, 512);
    samples_per_frame = systest.media_cfg.audio_frame_ptime * 
			systest.media_cfg.clock_rate *
			systest.media_cfg.channel_count / 1000;

    /* Ringback tone (call is ringing) */
    name = pj_str("ringback");
    status = pjmedia_tonegen_create2(pool, &name, 
				     systest.media_cfg.clock_rate,
				     systest.media_cfg.channel_count, 
				     samples_per_frame,
				     16, PJMEDIA_TONEGEN_LOOP, 
				     &ringback_port);
    if (status != PJ_SUCCESS)
	goto on_return;

    pj_bzero(&tone, sizeof(tone));
    for (i=0; i<RINGBACK_CNT; ++i) {
	tone[i].freq1 = RINGBACK_FREQ1;
	tone[i].freq2 = RINGBACK_FREQ2;
	tone[i].on_msec = RINGBACK_ON;
	tone[i].off_msec = RINGBACK_OFF;
    }
    tone[RINGBACK_CNT-1].off_msec = RINGBACK_INTERVAL;

    status = pjmedia_tonegen_play(ringback_port, RINGBACK_CNT, tone,
				  PJMEDIA_TONEGEN_LOOP);
    if (status != PJ_SUCCESS)
	goto on_return;

    status = pjsua_conf_add_port(pool, ringback_port, &ringback_slot);
    if (status != PJ_SUCCESS)
	goto on_return;

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

    key = gui_msgbox(title,
		     "Ringback tone should be playing now in the "
		     "speaker. Press OK to stop. ", WITH_OK);

    status = PJ_SUCCESS;

on_return:
    if (ringback_slot != -1)
	pjsua_conf_remove_port(ringback_slot);
    if (ringback_port)
	pjmedia_port_destroy(ringback_port);
    if (pool)
	pj_pool_release(pool);

    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encounter error when initializing "
		       "the tone generator: ", 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_strcpy(ti->reason, USER_ERROR);
    }
    return;
}

/* Util: create file player, each time trying different paths until we get
 * the file.
 */
static pj_status_t create_player(unsigned path_cnt, const char *paths[], 
				 pjsua_player_id *p_id)
{
    pj_str_t name;
    pj_status_t status = PJ_ENOTFOUND;
    unsigned i;

    for (i=0; i<path_cnt; ++i) {
	status = pjsua_player_create(pj_cstr(&name, paths[i]), 0, p_id);
	if (status == PJ_SUCCESS)
	    return PJ_SUCCESS;
    }
    return status;
}

/*****************************************************************************
 * test: play WAV file
 */
static void systest_play_wav(unsigned path_cnt, const char *paths[])
{
    pjsua_player_id play_id = PJSUA_INVALID_ID;
    enum gui_key key;
    test_item_t *ti;
    const char *title = "WAV File Playback Test";
    pj_status_t status;

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

    pj_ansi_snprintf(textbuf, sizeof(textbuf),
		     "This test will play %s file to "
		     "the speaker. Please listen carefully for audio "
		     "impairments such as stutter. Let this test run "
		     "for a while to make sure that everything is okay."
		     " Press OK to start, CANCEL to skip",
		     paths[0]);

    key = gui_msgbox(title, textbuf,
		     WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }

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

    /* WAV port */
    status = create_player(path_cnt, paths, &play_id);
    if (status != PJ_SUCCESS)
	goto on_return;

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

    key = gui_msgbox(title,
		     "WAV file should be playing now in the "
		     "speaker. Press OK to stop. ", WITH_OK);

    status = PJ_SUCCESS;

on_return:
    if (play_id != -1)
	pjsua_player_destroy(play_id);

    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we've encountered 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_strcpy(ti->reason, USER_ERROR);
    }
    return;
}

static void systest_play_wav1(void)
{
    const char *paths[] = { add_path(res_path, WAV_PLAYBACK_PATH),
			    ALT_PATH1 WAV_PLAYBACK_PATH };
    systest_play_wav(PJ_ARRAY_SIZE(paths), paths);
}

static void systest_play_wav2(void)
{
    const char *paths[] = { add_path(res_path, WAV_TOCK8_PATH),
			    ALT_PATH1 WAV_TOCK8_PATH};
    systest_play_wav(PJ_ARRAY_SIZE(paths), paths);
}


/*****************************************************************************
 * 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);
	}
    }
}


/****************************************************************************
 * test: audio system test
 */
static void systest_audio_test(void)
{
    enum {
	GOOD_MAX_INTERVAL = 5,
    };
    const pjmedia_dir dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
    pjmedia_aud_param param;
    pjmedia_aud_test_results result;
    pj_size_t textbufpos;
    enum gui_key key;
    unsigned problem_count = 0;
    const char *problems[16];
    char drifttext[120];
    test_item_t *ti;
    const char *title = "Audio Device Test";
    pj_status_t status;

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

    key = gui_msgbox(title,
		     "This will run an automated test for about "
		     "ten seconds or so, and display some "
		     "statistics about your sound device. "
		     "Please don't do anything until the test completes. "
		     "Press OK to start, or CANCEL to skip this test.",
		     WITH_OKCANCEL);
    if (key != KEY_OK) {
	ti->skipped = PJ_TRUE;
	return;
    }

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

    /* Disable sound device in pjsua first */
    pjsua_set_no_snd_dev();

    /* Setup parameters */
    status = pjmedia_aud_dev_default_param(systest.play_id, &param);
    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we had error in pjmedia_aud_dev_default_param()", status);
	pjsua_set_snd_dev(systest.rec_id, systest.play_id);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
	ti->reason[sizeof(ti->reason)-1] = '\0';
	return;
    }

    param.dir = dir;
    param.rec_id = systest.rec_id;
    param.play_id = systest.play_id;
    param.clock_rate = systest.media_cfg.snd_clock_rate;
    param.channel_count = systest.media_cfg.channel_count;
    param.samples_per_frame = param.clock_rate * param.channel_count * 
			      systest.media_cfg.audio_frame_ptime / 1000;

    /* Latency settings */
    param.flags |= (PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY | 
		    PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY);
    param.input_latency_ms = systest.media_cfg.snd_rec_latency;
    param.output_latency_ms = systest.media_cfg.snd_play_latency;

    /* Run the test */
    status = pjmedia_aud_test(&param, &result);
    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we encountered error with the test", status);
	pjsua_set_snd_dev(systest.rec_id, systest.play_id);
	ti->success = PJ_FALSE;
	pj_strerror(status, ti->reason, sizeof(ti->reason));
	ti->reason[sizeof(ti->reason)-1] = '\0';
	return;
    }

    /* Restore pjsua sound device */
    pjsua_set_snd_dev(systest.rec_id, systest.play_id);

    /* Analyze the result! */
    strcpy(textbuf, "Here are the audio statistics:\r\n");
    textbufpos = strlen(textbuf);

    if (result.rec.frame_cnt==0) {
	problems[problem_count++] = 
	    "No audio frames were captured from the microphone. "
	    "This means the audio device is not working properly.";
    } else {
	pj_ansi_snprintf(textbuf+textbufpos, 
			 sizeof(textbuf)-textbufpos,
			 "Rec : interval (min/max/avg/dev)=\r\n"
			 "         %u/%u/%u/%u (ms)\r\n"
			 "      max burst=%u\r\n",
			 result.rec.min_interval,
			 result.rec.max_interval,
			 result.rec.avg_interval,
			 result.rec.dev_interval,
			 result.rec.max_burst);
	textbufpos = strlen(textbuf);

	if (result.rec.max_burst > GOOD_MAX_INTERVAL) {
	    problems[problem_count++] = 
		"Recording max burst is quite high";
	}
    }

    if (result.play.frame_cnt==0) {
	problems[problem_count++] = 
	    "No audio frames were played to the speaker. "
	    "This means the audio device is not working properly.";
    } else {
	pj_ansi_snprintf(textbuf+textbufpos, 
			 sizeof(textbuf)-textbufpos,
			 "Play: interval (min/max/avg/dev)=\r\n"
			 "         %u/%u/%u/%u (ms)\r\n"
			 "      burst=%u\r\n",
			 result.play.min_interval,
			 result.play.max_interval,
			 result.play.avg_interval,
			 result.play.dev_interval,
			 result.play.max_burst);
	textbufpos = strlen(textbuf);

	if (result.play.max_burst > GOOD_MAX_INTERVAL) {
	    problems[problem_count++] = 
		"Playback max burst is quite high";
	}
    }

    if (result.rec_drift_per_sec) {
	const char *which = result.rec_drift_per_sec>=0 ? "faster" : "slower";
	unsigned drift = result.rec_drift_per_sec>=0 ? 
			    result.rec_drift_per_sec :
			    -result.rec_drift_per_sec;

	pj_ansi_snprintf(drifttext, sizeof(drifttext),
			"Clock drifts detected. Capture "
			"is %d samples/sec %s "
			"than the playback device",
			drift, which);
	problems[problem_count++] = drifttext;
    }

    if (problem_count == 0) {
	pj_ansi_snprintf(textbuf+textbufpos, 
			 sizeof(textbuf)-textbufpos,
			 "\r\nThe sound device seems to be okay!");
	textbufpos = strlen(textbuf);

	key = gui_msgbox("Audio Device Test", textbuf, WITH_OK);
    } else {
	unsigned i;

	pj_ansi_snprintf(textbuf+textbufpos,
			 sizeof(textbuf)-textbufpos, 
			 "There could be %d problem(s) with the "
			 "sound device:\r\n",
			 problem_count);
	textbufpos = strlen(textbuf);

	for (i=0; i<problem_count; ++i) {
	    pj_ansi_snprintf(textbuf+textbufpos,
			     sizeof(textbuf)-textbufpos, 
			     " %d: %s\r\n", i+1, problems[i]);
	    textbufpos = strlen(textbuf);
	}

	key = gui_msgbox(title, textbuf, WITH_OK);
    }

    ti->success = PJ_TRUE;
    pj_ansi_strncpy(ti->reason, textbuf, sizeof(ti->reason));
    ti->reason[sizeof(ti->reason)-1] = '\0';
}


/****************************************************************************
 * sound latency test
 */
static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
			     unsigned *lat_sum, unsigned *lat_cnt, 
			     unsigned *lat_min, unsigned *lat_max)
{
    pjmedia_frame frm;
    short *buf;
    unsigned i, clock_rate, samples_per_frame;
    pj_size_t read, len;
    unsigned start_pos;
    pj_bool_t first;
    pj_status_t status;

    *lat_sum = 0;
    *lat_cnt = 0;
    *lat_min = 10000;
    *lat_max = 0;

    samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
    clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
    frm.buf = pj_pool_alloc(pool, samples_per_frame * 2);
    frm.size = samples_per_frame * 2;
    len = pjmedia_wav_player_get_len(wav);
    buf = pj_pool_alloc(pool, len + samples_per_frame);

    /* Read the whole file */
    read = 0;
    while (read < len/2) {
	status = pjmedia_port_get_frame(wav, &frm);
	if (status != PJ_SUCCESS)
	    break;

	pjmedia_copy_samples(buf+read, (short*)frm.buf, samples_per_frame);
	read += samples_per_frame;
    }

    if (read < 2 * clock_rate) {
	systest_perror("The WAV file is too short", PJ_SUCCESS);
	return -1;
    }

    /* Zero the first 500ms to remove loud click noises 
     * (keypad press, etc.)
     */
    pjmedia_zero_samples(buf, clock_rate / 2);

    /* Loop to calculate latency */
    start_pos = 0;
    first = PJ_TRUE;
    while (start_pos < len/2 - clock_rate) {
	int max_signal = 0;
	unsigned max_signal_pos = start_pos;
	unsigned max_echo_pos = 0;
	unsigned pos;
	unsigned lat;

	/* Get the largest signal in the next 0.7s */
	for (i=start_pos; i<start_pos + clock_rate * 700 / 1000; ++i) {
	    if (abs(buf[i]) > max_signal) {
		max_signal = abs(buf[i]);
		max_signal_pos = i;
	    }
	}

	/* Advance 10ms from max_signal_pos */
	pos = max_signal_pos + 10 * clock_rate / 1000;

	/* Get the largest signal in the next 800ms */
	max_signal = 0;
	max_echo_pos = pos;
	for (i=pos; i<pos+clock_rate * 8 / 10; ++i) {
	    if (abs(buf[i]) > max_signal) {
		max_signal = abs(buf[i]);
		max_echo_pos = i;
	    }
	}

	lat = (max_echo_pos - max_signal_pos) * 1000 / clock_rate;

#if 0
	PJ_LOG(4,(THIS_FILE, "Signal at %dms, echo at %d ms, latency %d ms",
		  max_signal_pos * 1000 / clock_rate,
		  max_echo_pos * 1000 / clock_rate,
		  lat));
#endif

	*lat_sum += lat;
	(*lat_cnt)++;
	if (lat < *lat_min)
	    *lat_min = lat;
	if (lat > *lat_max)
	    *lat_max = lat;

	/* Advance next loop */
	if (first) {
	    start_pos = max_signal_pos + clock_rate * 9 / 10;
	    first = PJ_FALSE;
	} else {
	    start_pos += clock_rate;
	}
    }

    return 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';
    }
}


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';
    }
}


/****************************************************************************
 * 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);

    ti->success = PJ_TRUE;
}

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);

}

/*****************************************************************/

int systest_init(void)
{
    pjsua_logging_config log_cfg;
    pj_status_t status = PJ_SUCCESS;

    status = pjsua_create();
    if (status != PJ_SUCCESS) {
	systest_perror("Sorry we've had error in pjsua_create(): ", status);
	return status;
    }

    pjsua_logging_config_default(&log_cfg);
    log_cfg.log_filename = pj_str(add_path(doc_path, LOG_OUT_PATH));

    pjsua_config_default(&systest.ua_cfg);
    pjsua_media_config_default(&systest.media_cfg);
    systest.media_cfg.clock_rate = TEST_CLOCK_RATE;
    systest.media_cfg.snd_clock_rate = DEV_CLOCK_RATE;
    if (OVERRIDE_AUD_FRAME_PTIME)
	systest.media_cfg.audio_frame_ptime = OVERRIDE_AUD_FRAME_PTIME;
    systest.media_cfg.channel_count = CHANNEL_COUNT;
    systest.rec_id = REC_DEV_ID;
    systest.play_id = PLAY_DEV_ID;
    systest.media_cfg.ec_tail_len = 0;
    systest.media_cfg.snd_auto_close_time = 0;

#if defined(OVERRIDE_AUDDEV_PLAY_LAT) && OVERRIDE_AUDDEV_PLAY_LAT!=0
    systest.media_cfg.snd_play_latency = OVERRIDE_AUDDEV_PLAY_LAT;
#endif

#if defined(OVERRIDE_AUDDEV_REC_LAT) && OVERRIDE_AUDDEV_REC_LAT!=0
    systest.media_cfg.snd_rec_latency = OVERRIDE_AUDDEV_REC_LAT;
#endif
	
    status = pjsua_init(&systest.ua_cfg, &log_cfg, &systest.media_cfg);
    if (status != PJ_SUCCESS) {
	pjsua_destroy();
	systest_perror("Sorry we've had error in pjsua_init(): ", status);
	return status;
    }

    status = pjsua_start();
    if (status != PJ_SUCCESS) {
	pjsua_destroy();
	systest_perror("Sorry we've had error in pjsua_start(): ", status);
	return status;
    }

    status = gui_init(&root_menu);
    if (status != 0)
	goto on_return;

    return 0;

on_return:
    gui_destroy();
    return status;
}


int systest_set_dev(int cap_dev, int play_dev)
{
    systest.rec_id = systest_cap_dev_id = cap_dev;
    systest.play_id = systest_play_dev_id = play_dev;
    return pjsua_set_snd_dev(cap_dev, play_dev);
}

static void systest_wizard(void)
{
    PJ_LOG(3,(THIS_FILE, "Running test wizard"));
    systest_list_audio_devs();
    systest_display_settings();
    systest_play_tone();
    systest_play_wav1();
    systest_rec_audio();
    systest_audio_test();
    systest_latency_test();
    systest_aec_test();
    gui_msgbox("Test wizard", "Test wizard complete.", WITH_OK);
}


int systest_run(void)
{
    gui_start(&root_menu);
    return 0;
}

void systest_save_result(const char *filename)
{
    unsigned i;
    pj_oshandle_t fd;
    pj_time_val tv;
    pj_parsed_time pt;
    pj_ssize_t size;
    const char *text;
    pj_status_t status;

    status = pj_file_open(NULL, filename, PJ_O_WRONLY | PJ_O_APPEND, &fd);
    if (status != PJ_SUCCESS) {
	pj_ansi_snprintf(textbuf, sizeof(textbuf),
			 "Error opening file %s",
			 filename);
	systest_perror(textbuf, status);
	return;
    }

    text = "\r\n\r\nPJSYSTEST Report\r\n";
    size = strlen(text);
    pj_file_write(fd, text, &size);

    /* Put timestamp */
    pj_gettimeofday(&tv);
    if (pj_time_decode(&tv, &pt) == PJ_SUCCESS) {
	pj_ansi_snprintf(textbuf, sizeof(textbuf),
			 "Time: %04d/%02d/%02d %02d:%02d:%02d\r\n",
			 pt.year, pt.mon+1, pt.day,
			 pt.hour, pt.min, pt.sec);
	size = strlen(textbuf);
	pj_file_write(fd, textbuf, &size);
    }

    pj_ansi_snprintf(textbuf, sizeof(textbuf),
		     "Tests invoked: %u\r\n"
		     "-----------------------------------------------\r\n",
		     test_item_count);
    size = strlen(textbuf);
    pj_file_write(fd, textbuf, &size);

    for (i=0; i<test_item_count; ++i) {
	test_item_t *ti = &test_items[i];
	pj_ansi_snprintf(textbuf, sizeof(textbuf),
			 "\r\nTEST %d: %s %s\r\n",
			 i, ti->title,
			 (ti->skipped? "Skipped" : (ti->success ? "Success" : "Failed")));
	size = strlen(textbuf);
	pj_file_write(fd, textbuf, &size);

	size = strlen(ti->reason);
	pj_file_write(fd, ti->reason, &size);

	size = 2;
	pj_file_write(fd, "\r\n", &size);
    }


    pj_file_close(fd);

    pj_ansi_snprintf(textbuf, sizeof(textbuf),
		     "Test result successfully appended to file %s",
		     filename);
    gui_msgbox("Test result saved", textbuf, WITH_OK);
}

void systest_deinit(void)
{
    gui_destroy();
    pjsua_destroy();
}

