/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * 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 
 */

/* See http://trac.pjsip.org/repos/wiki/MeasuringSoundLatency on
 * how to use this program.
 */

#include <pjmedia.h>
#include <pjlib.h>

#include <stdio.h>

#define THIS_FILE   "lacency.c"


/* Util to display the error message for the specified error code  */
static int app_perror( const char *sender, const char *title, 
		       pj_status_t status)
{
    char errmsg[PJ_ERR_MSG_SIZE];

    PJ_UNUSED_ARG(sender);

    pj_strerror(status, errmsg, sizeof(errmsg));

    printf("%s: %s [code=%d]\n", title, errmsg, status);
    return 1;
}

/*
 * Find out latency
 */
static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav)
{
    pjmedia_frame frm;
    short *buf;
    unsigned i, samples_per_frame, read, len;
    unsigned start_pos;
    pj_status_t status;

    unsigned lat_sum = 0,
	     lat_cnt = 0,
	     lat_min = 10000,
	     lat_max = 0;

    samples_per_frame = PJMEDIA_PIA_SPF(&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 = 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 * PJMEDIA_PIA_SRATE(&wav->info)) {
	puts("Error: too short");
	return -1;
    }

    start_pos = 0;
    while (start_pos < len/2 - PJMEDIA_PIA_SRATE(&wav->info)) {
	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 + PJMEDIA_PIA_SRATE(&wav->info) * 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 * PJMEDIA_PIA_SRATE(&wav->info) / 1000;

	/* Get the largest signal in the next 500ms */
	max_signal = 0;
	max_echo_pos = pos;
	for (i=pos; i<pos+PJMEDIA_PIA_SRATE(&wav->info)/2; ++i) {
	    if (abs(buf[i]) > max_signal) {
		max_signal = abs(buf[i]);
		max_echo_pos = i;
	    }
	}

	lat = (max_echo_pos - max_signal_pos) * 1000 / PJMEDIA_PIA_SRATE(&wav->info);
	
#if 0
	printf("Latency = %u\n", lat);
#endif

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

	/* Advance next loop */
	start_pos += PJMEDIA_PIA_SRATE(&wav->info);
    }

    printf("Latency average = %u\n", lat_sum / lat_cnt);
    printf("Latency minimum = %u\n", lat_min);
    printf("Latency maximum = %u\n", lat_max);
    printf("Number of data  = %u\n", lat_cnt);
    return 0;
}


/*
 * main()
 */
int main(int argc, char *argv[])
{
    enum { NSAMPLES = 160, COUNT=100 };
    pj_caching_pool cp;
    pj_pool_t *pool;
    pjmedia_port *wav;
    pj_status_t status;


    /* Verify cmd line arguments. */
    if (argc != 2) {
	puts("Error: missing argument(s)");
	puts("Usage: latency REV.WAV");
	return 1;
    }

    pj_log_set_level(0);

    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);

    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "wav",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    status = pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE, 
				  &pjmedia_strerror);
    pj_assert(status == PJ_SUCCESS);

    /* Wav */
    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
					      argv[1],	/* file to play	    */
					      0,	/* use default ptime*/
					      0,	/* flags	    */
					      0,	/* default buffer   */
					      &wav	/* returned port    */
					      );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, argv[1], status);
	return 1;
    }

    status = calculate_latency(pool, wav);
    if (status != PJ_SUCCESS)
	return 1;

    status = pjmedia_port_destroy( wav );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    pj_pool_release( pool );
    pj_caching_pool_destroy( &cp );
    pj_shutdown();

    /* Done. */
    return 0;
}

