/* $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 
 */
#include <pjmedia/wsola.h>
#include <pjmedia/circbuf.h>
#include <pjmedia/errno.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/math.h>
#include <pj/pool.h>

/*
 * This file contains implementation of WSOLA using PJMEDIA_WSOLA_IMP_WSOLA
 * or PJMEDIA_WSOLA_IMP_NULL
 */
#define THIS_FILE   "wsola.c"

/*
 * http://trac.pjsip.org/repos/ticket/683:
 *  Workaround for segfault problem in the fixed point version of create_win()
 *  on ARM9 platform, possibly due to gcc optimization bug.
 *
 *  For now, we will use linear window when floating point is disabled.
 */
#ifndef PJMEDIA_WSOLA_LINEAR_WIN
#   define PJMEDIA_WSOLA_LINEAR_WIN    (!PJ_HAS_FLOATING_POINT)
#endif


#if 0
#   define TRACE_(x)	PJ_LOG(4,x)
#else
#   define TRACE_(x)
#endif

#if 0
#   define CHECK_(x)	pj_assert(x)
#else
#   define CHECK_(x)
#endif


#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA) || \
    (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA_LITE)

/*
 * WSOLA implementation using WSOLA
 */

/* Buffer size including history, in frames */
#define FRAME_CNT	6

/* Number of history frames in buffer */
#define HIST_CNT	1.5

/* Template size, in msec */
#define TEMPLATE_PTIME	PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC

/* Hanning window size, in msec */
#define HANNING_PTIME	PJMEDIA_WSOLA_DELAY_MSEC

/* Number of frames in erase buffer */
#define ERASE_CNT	((unsigned)3)

/* Minimum distance from template for find_pitch() of expansion, in frames */
#define EXP_MIN_DIST	0.5

/* Maximum distance from template for find_pitch() of expansion, in frames */
#define EXP_MAX_DIST	HIST_CNT

/* Duration of a continuous synthetic frames after which the volume 
 * of the synthetic frame will be set to zero with fading-out effect.
 */
#define MAX_EXPAND_MSEC	PJMEDIA_WSOLA_MAX_EXPAND_MSEC


/* Buffer content:
 *
 *  +---------+-----------+--------------------+
 *  | history | min_extra | more extra / empty |
 *  +---------+-----------+--------------------+
 *  ^         ^           ^                    ^
 * buf    hist_size   min_extra            buf_size
 * 
 * History size (hist_size) is a constant value, initialized upon creation.
 *
 * min_extra size is equal to HANNING_PTIME, this samples is useful for 
 * smoothening samples transition between generated frame & history 
 * (when PLC is invoked), or between generated samples & normal frame 
 * (after lost/PLC). Since min_extra samples need to be available at 
 * any time, this will introduce delay of HANNING_PTIME ms.
 *
 * More extra is excess samples produced by PLC (PLC frame generation may 
 * produce more than exact one frame).
 *
 * At any particular time, the buffer will contain at least (hist_size + 
 * min_extra) samples.
 *
 * A "save" operation will append the new frame to the end of the buffer,
 * return the frame from samples right after history and shift the buffer
 * by one frame.
 *
 */

/* WSOLA structure */
struct pjmedia_wsola
{
    unsigned		 clock_rate;	    /* Sampling rate.		    */
    pj_uint16_t		 samples_per_frame; /* Samples per frame (const)    */
    pj_uint16_t		 channel_count;	    /* Channel countt (const)	    */
    pj_uint16_t		 options;	    /* Options.			    */

    pjmedia_circ_buf	*buf;		    /* The buffer.		    */
    pj_int16_t		*erase_buf;	    /* Temporary erase buffer.	    */
    pj_int16_t		*merge_buf;	    /* Temporary merge buffer.	    */

    pj_uint16_t		 buf_size;	    /* Total buffer size (const)    */
    pj_uint16_t		 hanning_size;	    /* Hanning window size (const)  */
    pj_uint16_t		 templ_size;	    /* Template size (const)	    */
    pj_uint16_t		 hist_size;	    /* History size (const)	    */

    pj_uint16_t		 min_extra;	    /* Minimum extra (const)	    */
    unsigned		 max_expand_cnt;    /* Max # of synthetic samples   */
    unsigned		 fade_out_pos;	    /* Last fade-out position	    */
    pj_uint16_t		 expand_sr_min_dist;/* Minimum distance from template 
					       for find_pitch() on expansion
					       (const)			    */
    pj_uint16_t		 expand_sr_max_dist;/* Maximum distance from template 
					       for find_pitch() on expansion
					       (const)			    */

#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0
    float		*hanning;	    /* Hanning window.		    */
#else
    pj_uint16_t		*hanning;	    /* Hanning window.		    */
#endif

    pj_timestamp	 ts;		    /* Running timestamp.	    */

};

#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA_LITE)

/* In this implementation, waveform similarity comparison is done by calculating
 * the difference of total level between template frame and the target buffer 
 * for each template_cnt samples. The smallest difference value assumed to be 
 * the most similar block. This seems to be naive, however some tests show
 * acceptable results and the processing speed is amazing.
 *
 * diff level = (template[1]+..+template[n]) - (target[1]+..+target[n])
 */
static pj_int16_t *find_pitch(pj_int16_t *frm, pj_int16_t *beg, pj_int16_t *end, 
			 unsigned template_cnt, int first)
{
    pj_int16_t *sr, *best=beg;
    int best_corr = 0x7FFFFFFF;
    int frm_sum = 0;
    unsigned i;

    for (i = 0; i<template_cnt; ++i)
	frm_sum += frm[i];

    for (sr=beg; sr!=end; ++sr) {
	int corr = frm_sum;
	int abs_corr = 0;

	/* Do calculation on 8 samples at once */
	for (i = 0; i<template_cnt-8; i+=8) {
	    corr -= (int)sr[i+0] +
		    (int)sr[i+1] +
		    (int)sr[i+2] +
		    (int)sr[i+3] +
		    (int)sr[i+4] +
		    (int)sr[i+5] +
		    (int)sr[i+6] +
		    (int)sr[i+7];
	}

	/* Process remaining samples */
	for (; i<template_cnt; ++i)
	    corr -= (int)sr[i];

	abs_corr = corr > 0? corr : -corr;

	if (first) {
	    if (abs_corr < best_corr) {
		best_corr = abs_corr;
		best = sr;
	    }
	} else {
	    if (abs_corr <= best_corr) {
		best_corr = abs_corr;
		best = sr;
	    }
	}
    }

    /*TRACE_((THIS_FILE, "found pitch at %u", best-beg));*/
    return best;
}

#endif

#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0
/*
 * Floating point version.
 */

#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA)

static pj_int16_t *find_pitch(pj_int16_t *frm, pj_int16_t *beg, pj_int16_t *end, 
			 unsigned template_cnt, int first)
{
    pj_int16_t *sr, *best=beg;
    double best_corr = 0;

    for (sr=beg; sr!=end; ++sr) {
	double corr = 0;
	unsigned i;

	/* Do calculation on 8 samples at once */
	for (i=0; i<template_cnt-8; i += 8) {
	    corr += ((float)frm[i+0]) * ((float)sr[i+0]) + 
		    ((float)frm[i+1]) * ((float)sr[i+1]) + 
		    ((float)frm[i+2]) * ((float)sr[i+2]) + 
		    ((float)frm[i+3]) * ((float)sr[i+3]) + 
		    ((float)frm[i+4]) * ((float)sr[i+4]) + 
		    ((float)frm[i+5]) * ((float)sr[i+5]) + 
		    ((float)frm[i+6]) * ((float)sr[i+6]) + 
		    ((float)frm[i+7]) * ((float)sr[i+7]);
	}

	/* Process remaining samples. */
	for (; i<template_cnt; ++i) {
	    corr += ((float)frm[i]) * ((float)sr[i]);
	}

	if (first) {
	    if (corr > best_corr) {
		best_corr = corr;
		best = sr;
	    }
	} else {
	    if (corr >= best_corr) {
		best_corr = corr;
		best = sr;
	    }
	}
    }

    /*TRACE_((THIS_FILE, "found pitch at %u", best-beg));*/
    return best;
}

#endif

static void overlapp_add(pj_int16_t dst[], unsigned count,
			 pj_int16_t l[], pj_int16_t r[],
			 float w[])
{
    unsigned i;

    for (i=0; i<count; ++i) {
	dst[i] = (pj_int16_t)(l[i] * w[count-1-i] + r[i] * w[i]);
    }
}

static void overlapp_add_simple(pj_int16_t dst[], unsigned count,
				pj_int16_t l[], pj_int16_t r[])
{
    float step = (float)(1.0 / count), stepdown = 1.0;
    unsigned i;

    for (i=0; i<count; ++i) {
	dst[i] = (pj_int16_t)(l[i] * stepdown + r[i] * (1-stepdown));
	stepdown -= step;
    }
}

static void create_win(pj_pool_t *pool, float **pw, unsigned count)
{
    unsigned i;
    float *w = (float*)pj_pool_calloc(pool, count, sizeof(float));

    *pw = w;

    for (i=0;i<count; i++) {
	w[i] = (float)(0.5 - 0.5 * cos(2.0 * PJ_PI * i / (count*2-1)) );
    }
}

#else	/* PJ_HAS_FLOATING_POINT */
/*
 * Fixed point version.
 */
#define WINDOW_BITS	15
enum { WINDOW_MAX_VAL = (1 << WINDOW_BITS)-1 };

#if (PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA)

static pj_int16_t *find_pitch(pj_int16_t *frm, pj_int16_t *beg, pj_int16_t *end, 
			 unsigned template_cnt, int first)
{
    pj_int16_t *sr, *best=beg;
    pj_int64_t best_corr = 0;

    
    for (sr=beg; sr!=end; ++sr) {
	pj_int64_t corr = 0;
	unsigned i;

	/* Do calculation on 8 samples at once */
	for (i=0; i<template_cnt-8; i+=8) {
	    corr += ((int)frm[i+0]) * ((int)sr[i+0]) + 
		    ((int)frm[i+1]) * ((int)sr[i+1]) + 
		    ((int)frm[i+2]) * ((int)sr[i+2]) +
		    ((int)frm[i+3]) * ((int)sr[i+3]) +
		    ((int)frm[i+4]) * ((int)sr[i+4]) +
		    ((int)frm[i+5]) * ((int)sr[i+5]) +
		    ((int)frm[i+6]) * ((int)sr[i+6]) +
		    ((int)frm[i+7]) * ((int)sr[i+7]);
	}

	/* Process remaining samples. */
	for (; i<template_cnt; ++i) {
	    corr += ((int)frm[i]) * ((int)sr[i]);
	}

	if (first) {
	    if (corr > best_corr) {
		best_corr = corr;
		best = sr;
	    }
	} else {
	    if (corr >= best_corr) {
		best_corr = corr;
		best = sr;
	    }
	}
    }

    /*TRACE_((THIS_FILE, "found pitch at %u", best-beg));*/
    return best;
}

#endif


static void overlapp_add(pj_int16_t dst[], unsigned count,
			 pj_int16_t l[], pj_int16_t r[],
			 pj_uint16_t w[])
{
    unsigned i;

    for (i=0; i<count; ++i) {
	dst[i] = (pj_int16_t)(((int)(l[i]) * (int)(w[count-1-i]) + 
	                  (int)(r[i]) * (int)(w[i])) >> WINDOW_BITS);
    }
}

static void overlapp_add_simple(pj_int16_t dst[], unsigned count,
				pj_int16_t l[], pj_int16_t r[])
{
    int step = ((WINDOW_MAX_VAL+1) / count), 
	stepdown = WINDOW_MAX_VAL;
    unsigned i;

    for (i=0; i<count; ++i) {
	dst[i]=(pj_int16_t)((l[i] * stepdown + r[i] * (1-stepdown)) >> WINDOW_BITS);
	stepdown -= step;
    }
}

#if PJ_HAS_INT64 && !PJMEDIA_WSOLA_LINEAR_WIN
/* approx_cos():
 *   see: http://www.audiomulch.com/~rossb/code/sinusoids/ 
 */
static pj_uint32_t approx_cos( pj_uint32_t x )
{
    pj_uint32_t i,j,k;

    if( x == 0 )
	return 0xFFFFFFFF;

    i = x << 1;
    k = ((x + 0xBFFFFFFD) & 0x80000000) >> 30;
    j = i - i * ((i & 0x80000000)>>30);
    j = j >> 15;
    j = (j * j + j) >> 1;
    j = j - j * k;

    return j;
}
#endif	/* PJ_HAS_INT64 && .. */

static void create_win(pj_pool_t *pool, pj_uint16_t **pw, unsigned count)
{
    
    unsigned i;
    pj_uint16_t *w = (pj_uint16_t*)pj_pool_calloc(pool, count, 
						  sizeof(pj_uint16_t));

    *pw = w;

    for (i=0; i<count; i++) {
#if PJ_HAS_INT64 && !PJMEDIA_WSOLA_LINEAR_WIN
	pj_uint32_t phase;
	pj_uint64_t cos_val;

	/* w[i] = (float)(0.5 - 0.5 * cos(2.0 * PJ_PI * i / (count*2-1)) ); */

	phase = (pj_uint32_t)(PJ_INT64(0xFFFFFFFF) * i / (count*2-1));
	cos_val = approx_cos(phase);

	w[i] = (pj_uint16_t)(WINDOW_MAX_VAL - 
			      (WINDOW_MAX_VAL * cos_val) / 0xFFFFFFFF);
#else
	/* Revert to linear */
	w[i] = (pj_uint16_t)(i * WINDOW_MAX_VAL / count);
#endif
    }
}

#endif	/* PJ_HAS_FLOATING_POINT */

/* Apply fade-in to the buffer.
 *  - fade_cnt is the number of samples on which the volume
 *       will go from zero to 100%
 *  - fade_pos is current sample position within fade_cnt range.
 *       It is zero for the first sample, so the first sample will
 *	 have zero volume. This value is increasing.
 */
static void fade_in(pj_int16_t buf[], int count,
		    int fade_in_pos, int fade_cnt)
{
#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0
    float fade_pos = (float)fade_in_pos;
#else
    int fade_pos = fade_in_pos;
#endif

    if (fade_cnt - fade_pos < count) {
	for (; fade_pos < fade_cnt; ++fade_pos, ++buf) {
	    *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt);
	}
	/* Leave the remaining samples as is */
    } else {
	pj_int16_t *end = buf + count;
	for (; buf != end; ++fade_pos, ++buf) {
	    *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt);
	}
    }
}

/* Apply fade-out to the buffer. */
static void wsola_fade_out(pjmedia_wsola *wsola, 
			   pj_int16_t buf[], int count)
{
    pj_int16_t *end = buf + count;
    int fade_cnt = wsola->max_expand_cnt;
#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0
    float fade_pos = (float)wsola->fade_out_pos;
#else
    int fade_pos = wsola->fade_out_pos;
#endif

    if (wsola->fade_out_pos == 0) {
	pjmedia_zero_samples(buf, count);
    } else if (fade_pos < count) {
	for (; fade_pos; --fade_pos, ++buf) {
	    *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt);
	}
	if (buf != end)
	    pjmedia_zero_samples(buf, (unsigned)(end - buf));
	wsola->fade_out_pos = 0;
    } else {
	for (; buf != end; --fade_pos, ++buf) {
	    *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt);
	}
	wsola->fade_out_pos -= count;
    }
}


PJ_DEF(pj_status_t) pjmedia_wsola_create( pj_pool_t *pool, 
					  unsigned clock_rate,
					  unsigned samples_per_frame,
					  unsigned channel_count,
					  unsigned options,
					  pjmedia_wsola **p_wsola)
{
    pjmedia_wsola *wsola;
    pj_status_t status;

    PJ_ASSERT_RETURN(pool && clock_rate && samples_per_frame && p_wsola,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(clock_rate <= 65535, PJ_EINVAL);
    PJ_ASSERT_RETURN(samples_per_frame < clock_rate, PJ_EINVAL);
    PJ_ASSERT_RETURN(channel_count > 0, PJ_EINVAL);

    /* Allocate wsola and initialize vars */
    wsola = PJ_POOL_ZALLOC_T(pool, pjmedia_wsola);
    wsola->clock_rate= (pj_uint16_t) clock_rate;
    wsola->samples_per_frame = (pj_uint16_t) samples_per_frame;
    wsola->channel_count = (pj_uint16_t) channel_count;
    wsola->options = (pj_uint16_t) options;
    wsola->max_expand_cnt = clock_rate * MAX_EXPAND_MSEC / 1000;
    wsola->fade_out_pos = wsola->max_expand_cnt;

    /* Create circular buffer */
    wsola->buf_size = (pj_uint16_t) (samples_per_frame * FRAME_CNT);
    status = pjmedia_circ_buf_create(pool, wsola->buf_size, &wsola->buf);
    if (status != PJ_SUCCESS) {
	PJ_LOG(3, (THIS_FILE, "Failed to create circular buf"));
	return status;
    }

    /* Calculate history size */
    wsola->hist_size = (pj_uint16_t)(HIST_CNT * samples_per_frame);

    /* Calculate template size */
    wsola->templ_size = (pj_uint16_t)(TEMPLATE_PTIME * clock_rate * 
				      channel_count / 1000);
    if (wsola->templ_size > samples_per_frame)
	wsola->templ_size = wsola->samples_per_frame;

    /* Calculate hanning window size */
    wsola->hanning_size = (pj_uint16_t)(HANNING_PTIME * clock_rate * 
				        channel_count / 1000);
    if (wsola->hanning_size > wsola->samples_per_frame)
	wsola->hanning_size = wsola->samples_per_frame;

    pj_assert(wsola->templ_size <= wsola->hanning_size);

    /* Create merge buffer */
    wsola->merge_buf = (pj_int16_t*) pj_pool_calloc(pool, 
						    wsola->hanning_size,
						    sizeof(pj_int16_t));

    /* Setup with PLC */
    if ((options & PJMEDIA_WSOLA_NO_PLC) == 0) {
	wsola->min_extra = wsola->hanning_size;
	wsola->expand_sr_min_dist = (pj_uint16_t)
				    (EXP_MIN_DIST * wsola->samples_per_frame);
	wsola->expand_sr_max_dist = (pj_uint16_t)
				    (EXP_MAX_DIST * wsola->samples_per_frame);
    }

    /* Setup with hanning */
    if ((options & PJMEDIA_WSOLA_NO_HANNING) == 0) {
	create_win(pool, &wsola->hanning, wsola->hanning_size);
    }

    /* Setup with discard */
    if ((options & PJMEDIA_WSOLA_NO_DISCARD) == 0) {
	wsola->erase_buf = (pj_int16_t*)pj_pool_calloc(pool, samples_per_frame *
						       ERASE_CNT,
						       sizeof(pj_int16_t));
    }

    /* Generate dummy extra */
    pjmedia_circ_buf_set_len(wsola->buf, wsola->hist_size + wsola->min_extra);

    *p_wsola = wsola;
    return PJ_SUCCESS;

}

PJ_DEF(pj_status_t) pjmedia_wsola_destroy(pjmedia_wsola *wsola)
{
    /* Nothing to do */
    PJ_UNUSED_ARG(wsola);

    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pjmedia_wsola_set_max_expand(pjmedia_wsola *wsola,
						  unsigned msec)
{
    PJ_ASSERT_RETURN(wsola, PJ_EINVAL);
    wsola->max_expand_cnt = msec * wsola->clock_rate / 1000;
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pjmedia_wsola_reset( pjmedia_wsola *wsola,
					 unsigned options)
{
    PJ_ASSERT_RETURN(wsola && options==0, PJ_EINVAL);
    PJ_UNUSED_ARG(options);

    pjmedia_circ_buf_reset(wsola->buf);
    pjmedia_circ_buf_set_len(wsola->buf, wsola->hist_size + wsola->min_extra);
    pjmedia_zero_samples(wsola->buf->start, wsola->buf->len); 
    wsola->fade_out_pos = wsola->max_expand_cnt;

    return PJ_SUCCESS;
}


static void expand(pjmedia_wsola *wsola, unsigned needed)
{
    unsigned generated = 0;
    unsigned rep;

    pj_int16_t *reg1, *reg2;
    unsigned reg1_len, reg2_len;

    pjmedia_circ_buf_pack_buffer(wsola->buf);
    pjmedia_circ_buf_get_read_regions(wsola->buf, &reg1, &reg1_len, 
				      &reg2, &reg2_len);
    CHECK_(reg2_len == 0);

    for (rep=1;; ++rep) {
	pj_int16_t *start, *templ;
	unsigned dist;

	templ = reg1 + reg1_len - wsola->hanning_size;
	CHECK_(templ - reg1 >= wsola->hist_size);

	start = find_pitch(templ, 
			   templ - wsola->expand_sr_max_dist, 
			   templ - wsola->expand_sr_min_dist,
			   wsola->templ_size, 
			   1);

	/* Should we make sure that "start" is really aligned to
	 * channel #0, in case of stereo? Probably not necessary, as
	 * find_pitch() should have found the best match anyway.
	 */

	if (wsola->options & PJMEDIA_WSOLA_NO_HANNING) {
	    overlapp_add_simple(wsola->merge_buf, wsola->hanning_size, 
			        templ, start);
	} else {
	    /* Check if pointers are in the valid range */
	    CHECK_(templ >= wsola->buf->buf &&
		   templ + wsola->hanning_size <= 
		   wsola->buf->buf + wsola->buf->capacity);
	    CHECK_(start >= wsola->buf->buf &&
		   start + wsola->hanning_size <= 
		   wsola->buf->buf + wsola->buf->capacity);

	    overlapp_add(wsola->merge_buf, wsola->hanning_size, templ, 
			 start, wsola->hanning);
	}

	/* How many new samples do we have */
	dist = (unsigned)(templ - start);

	/* Not enough buffer to hold the result */
	if (reg1_len + dist > wsola->buf_size) {
	    pj_assert(!"WSOLA buffer size may be to small!");
	    break;
	}

	/* Copy the "tail" (excess frame) to the end */
	pjmedia_move_samples(templ + wsola->hanning_size, 
			     start + wsola->hanning_size,
			     dist);

	/* Copy the merged frame */
	pjmedia_copy_samples(templ, wsola->merge_buf, wsola->hanning_size);

	/* We have new samples */
	reg1_len += dist;
	pjmedia_circ_buf_set_len(wsola->buf, reg1_len);

	generated += dist;

	if (generated >= needed) {
	    TRACE_((THIS_FILE, "WSOLA frame expanded after %d iterations", 
		    rep));
	    break;
	}
    }
}


static unsigned compress(pjmedia_wsola *wsola, pj_int16_t *buf, unsigned count,
			 unsigned del_cnt)
{
    unsigned samples_del = 0, rep;

    for (rep=1; ; ++rep) {
	pj_int16_t *start, *end;
	unsigned dist;

	if (count <= wsola->hanning_size + del_cnt) {
	    TRACE_((THIS_FILE, "Not enough samples to compress!"));
	    return samples_del;
	}

	// Make start distance to del_cnt, so discard will be performed in
	// only one iteration.
	//start = buf + (frmsz >> 1);
	start = buf + del_cnt - samples_del;
	end = start + wsola->samples_per_frame;

	if (end + wsola->hanning_size > buf + count) {
	    end = buf+count-wsola->hanning_size;
	}

	CHECK_(start < end);

	start = find_pitch(buf, start, end, wsola->templ_size, 0);
	dist = (unsigned)(start - buf);

	if (wsola->options & PJMEDIA_WSOLA_NO_HANNING) {
	    overlapp_add_simple(buf, wsola->hanning_size, buf, start);
	} else {
	    overlapp_add(buf, wsola->hanning_size, buf, start, wsola->hanning);
	}

	pjmedia_move_samples(buf + wsola->hanning_size, 
			     buf + wsola->hanning_size + dist,
			     count - wsola->hanning_size - dist);

	count -= dist;
	samples_del += dist;

	if (samples_del >= del_cnt) {
	    TRACE_((THIS_FILE, 
		    "Erased %d of %d requested after %d iteration(s)",
		    samples_del, del_cnt, rep));
	    break;
	}
    }

    return samples_del;
}



PJ_DEF(pj_status_t) pjmedia_wsola_save( pjmedia_wsola *wsola, 
					pj_int16_t frm[], 
					pj_bool_t prev_lost)
{
    unsigned buf_len;
    pj_status_t status;

    buf_len = pjmedia_circ_buf_get_len(wsola->buf);

    /* Update vars */
    wsola->ts.u64 += wsola->samples_per_frame;

    /* If previous frame was lost, smoothen this frame with the generated one */
    if (prev_lost) {
	pj_int16_t *reg1, *reg2;
	unsigned reg1_len, reg2_len;
	pj_int16_t *ola_left;

	/* Trim excessive len */
	if ((int)buf_len > wsola->hist_size + (wsola->min_extra<<1)) {
	    buf_len = wsola->hist_size + (wsola->min_extra<<1);
	    pjmedia_circ_buf_set_len(wsola->buf, buf_len);
	}

	pjmedia_circ_buf_get_read_regions(wsola->buf, &reg1, &reg1_len, 
					  &reg2, &reg2_len);

	CHECK_(pjmedia_circ_buf_get_len(wsola->buf) >= 
	       (unsigned)(wsola->hist_size + (wsola->min_extra<<1)));

	/* Continue applying fade out to the extra samples */
	if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) {
	    if (reg2_len == 0) {
		wsola_fade_out(wsola, reg1 + reg1_len - (wsola->min_extra<<1),
			       (wsola->min_extra<<1));
	    } else if ((int)reg2_len >= (wsola->min_extra<<1)) {
		wsola_fade_out(wsola, reg2 + reg2_len - (wsola->min_extra<<1),
			       (wsola->min_extra<<1));
	    } else {
		unsigned tmp = (wsola->min_extra<<1) - reg2_len;
		wsola_fade_out(wsola, reg1 + reg1_len - tmp, tmp);
		wsola_fade_out(wsola, reg2, reg2_len);
	    }
	}

	/* Get the region in buffer to be merged with the frame */
	if (reg2_len == 0) {
	    ola_left = reg1 + reg1_len - wsola->min_extra;
	} else if (reg2_len >= wsola->min_extra) {
	    ola_left = reg2 + reg2_len - wsola->min_extra;
	} else {
	    unsigned tmp;

	    tmp = wsola->min_extra - reg2_len;
	    pjmedia_copy_samples(wsola->merge_buf, reg1 + reg1_len - tmp, tmp);
	    pjmedia_copy_samples(wsola->merge_buf + tmp, reg2, reg2_len);
	    ola_left = wsola->merge_buf;
	}

	/* Apply fade-in to the frame before merging */
	if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) {
	    unsigned count = wsola->min_extra;
	    int fade_in_pos;

	    /* Scale fade_in position based on last fade-out */
	    fade_in_pos = wsola->fade_out_pos * count /
			  wsola->max_expand_cnt;

	    /* Fade-in it */
	    fade_in(frm, wsola->samples_per_frame,
		    fade_in_pos, count);
	}

	/* Merge it */
	overlapp_add_simple(frm, wsola->min_extra, ola_left, frm);

	/* Trim len */
	buf_len -= wsola->min_extra;
	pjmedia_circ_buf_set_len(wsola->buf, buf_len);

    } else if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0 &&
	       wsola->fade_out_pos != wsola->max_expand_cnt) 
    {
	unsigned count = wsola->min_extra;
	int fade_in_pos;

	/* Fade out the remaining synthetic samples */
	if (buf_len > wsola->hist_size) {
	    pj_int16_t *reg1, *reg2;
	    unsigned reg1_len, reg2_len;

	    /* Number of samples to fade out */
	    count = buf_len - wsola->hist_size;

	    pjmedia_circ_buf_get_read_regions(wsola->buf, &reg1, &reg1_len, 
					      &reg2, &reg2_len);

	    CHECK_(pjmedia_circ_buf_get_len(wsola->buf) >= 
		   (unsigned)(wsola->hist_size + (wsola->min_extra<<1)));

	    /* Continue applying fade out to the extra samples */
	    if (reg2_len == 0) {
		wsola_fade_out(wsola, reg1 + reg1_len - count, count);
	    } else if (reg2_len >= count) {
		wsola_fade_out(wsola, reg2 + reg2_len - count, count);
	    } else {
		unsigned tmp = count - reg2_len;
		wsola_fade_out(wsola, reg1 + reg1_len - tmp, tmp);
		wsola_fade_out(wsola, reg2, reg2_len);
	    }
	}

	/* Apply fade-in to the frame */
	count = wsola->min_extra;

	/* Scale fade_in position based on last fade-out */
	fade_in_pos = wsola->fade_out_pos * count /
		      wsola->max_expand_cnt;

	/* Fade it in */
	fade_in(frm, wsola->samples_per_frame,
		fade_in_pos, count);

    }

    wsola->fade_out_pos = wsola->max_expand_cnt;

    status = pjmedia_circ_buf_write(wsola->buf, frm, wsola->samples_per_frame);
    if (status != PJ_SUCCESS) {
	TRACE_((THIS_FILE, "Failed writing to circbuf [err=%d]", status));
	return status;
    }

    status = pjmedia_circ_buf_copy(wsola->buf, wsola->hist_size, frm, 
				   wsola->samples_per_frame);
    if (status != PJ_SUCCESS) {
	TRACE_((THIS_FILE, "Failed copying from circbuf [err=%d]", status));
	return status;
    }

    return pjmedia_circ_buf_adv_read_ptr(wsola->buf, wsola->samples_per_frame);
}


PJ_DEF(pj_status_t) pjmedia_wsola_generate( pjmedia_wsola *wsola, 
					    pj_int16_t frm[])
{
    unsigned samples_len, samples_req;
    pj_status_t status = PJ_SUCCESS;

    CHECK_(pjmedia_circ_buf_get_len(wsola->buf) >= wsola->hist_size + 
	   wsola->min_extra);

    /* Calculate how many samples in the buffer */
    samples_len = pjmedia_circ_buf_get_len(wsola->buf) - wsola->hist_size;

    /* Calculate how many samples are required to be available in the buffer */
    samples_req = wsola->samples_per_frame + (wsola->min_extra << 1);
    
    wsola->ts.u64 += wsola->samples_per_frame;

    if (samples_len < samples_req) {
	/* Expand buffer */
	expand(wsola, samples_req - samples_len);
	TRACE_((THIS_FILE, "Buf size after expanded = %d", 
		pjmedia_circ_buf_get_len(wsola->buf)));
    }

    status = pjmedia_circ_buf_copy(wsola->buf, wsola->hist_size, frm, 
				   wsola->samples_per_frame);
    if (status != PJ_SUCCESS) {
	TRACE_((THIS_FILE, "Failed copying from circbuf [err=%d]", status));
	return status;
    }

    pjmedia_circ_buf_adv_read_ptr(wsola->buf, wsola->samples_per_frame);

    /* Apply fade-out to the frame */
    if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) {
	wsola_fade_out(wsola, frm, wsola->samples_per_frame);
    }

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_wsola_discard( pjmedia_wsola *wsola, 
					   pj_int16_t buf1[],
					   unsigned buf1_cnt, 
					   pj_int16_t buf2[],
					   unsigned buf2_cnt,
					   unsigned *del_cnt)
{
    PJ_ASSERT_RETURN(wsola && buf1 && buf1_cnt && del_cnt, PJ_EINVAL);
    PJ_ASSERT_RETURN(*del_cnt, PJ_EINVAL);

    if (buf2_cnt == 0) {
	/* The whole buffer is contiguous space, straight away. */
	*del_cnt = compress(wsola, buf1, buf1_cnt, *del_cnt);
    } else {
	PJ_ASSERT_RETURN(buf2, PJ_EINVAL);

	if (buf1_cnt < ERASE_CNT * wsola->samples_per_frame &&
	    buf2_cnt < ERASE_CNT * wsola->samples_per_frame &&
	    wsola->erase_buf == NULL)
	{
	    /* We need erase_buf but WSOLA was created with 
	     * PJMEDIA_WSOLA_NO_DISCARD flag.
	     */
	    pj_assert(!"WSOLA need erase buffer!");
	    return PJ_EINVALIDOP;
	}

	if (buf2_cnt >= ERASE_CNT * wsola->samples_per_frame) {
	    /* Enough space to perform compress in the second buffer. */
	    *del_cnt = compress(wsola, buf2, buf2_cnt, *del_cnt);
	} else if (buf1_cnt >= ERASE_CNT * wsola->samples_per_frame) {
	    /* Enough space to perform compress in the first buffer, but then
	     * we need to re-arrange the buffers so there is no gap between 
	     * buffers.
	     */
	    unsigned max;

	    *del_cnt = compress(wsola, buf1, buf1_cnt, *del_cnt);

	    max = *del_cnt;
	    if (max > buf2_cnt)
		max = buf2_cnt;

	    pjmedia_move_samples(buf1 + buf1_cnt - (*del_cnt), buf2, max);

	    if (max < buf2_cnt) {
		pjmedia_move_samples(buf2, buf2+(*del_cnt), 
				     buf2_cnt-max);
	    }
	} else {
	    /* Not enough samples in either buffers to perform compress. 
	     * Need to combine the buffers in a contiguous space, the erase_buf.
	     */
	    unsigned buf_size = buf1_cnt + buf2_cnt;
	    pj_int16_t *rem;	/* remainder */
	    unsigned rem_cnt;

	    if (buf_size > ERASE_CNT * wsola->samples_per_frame) {
		buf_size = ERASE_CNT * wsola->samples_per_frame;
		
		rem_cnt = buf1_cnt + buf2_cnt - buf_size;
		rem = buf2 + buf2_cnt - rem_cnt;
		
	    } else {
		rem = NULL;
		rem_cnt = 0;
	    }

	    pjmedia_copy_samples(wsola->erase_buf, buf1, buf1_cnt);
	    pjmedia_copy_samples(wsola->erase_buf+buf1_cnt, buf2, 
				 buf_size-buf1_cnt);

	    *del_cnt = compress(wsola, wsola->erase_buf, buf_size, *del_cnt);

	    buf_size -= (*del_cnt);

	    /* Copy back to buffers */
	    if (buf_size == buf1_cnt) {
		pjmedia_copy_samples(buf1, wsola->erase_buf, buf_size);
		if (rem_cnt) {
		    pjmedia_move_samples(buf2, rem, rem_cnt);
		}
	    } else if (buf_size < buf1_cnt) {
		pjmedia_copy_samples(buf1, wsola->erase_buf, buf_size);
		if (rem_cnt) {
		    unsigned c = rem_cnt;
		    if (c > buf1_cnt-buf_size) {
			c = buf1_cnt-buf_size;
		    }
		    pjmedia_copy_samples(buf1+buf_size, rem, c);
		    rem += c;
		    rem_cnt -= c;
		    if (rem_cnt)
			pjmedia_move_samples(buf2, rem, rem_cnt);
		}
	    } else {
		pjmedia_copy_samples(buf1, wsola->erase_buf, buf1_cnt);
		pjmedia_copy_samples(buf2, wsola->erase_buf+buf1_cnt, 
				     buf_size-buf1_cnt);
		if (rem_cnt) {
		    pjmedia_move_samples(buf2+buf_size-buf1_cnt, rem,
				         rem_cnt);
		}
	    }
	    
	}
    }

    return (*del_cnt) > 0 ? PJ_SUCCESS : PJ_ETOOSMALL;
}


#elif PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_NULL
/*
 * WSOLA implementation using NULL
 */

struct pjmedia_wsola
{
    unsigned samples_per_frame;
};


PJ_DEF(pj_status_t) pjmedia_wsola_create( pj_pool_t *pool, 
					  unsigned clock_rate,
					  unsigned samples_per_frame,
					  unsigned channel_count,
					  unsigned options,
					  pjmedia_wsola **p_wsola)
{
    pjmedia_wsola *wsola;

    wsola = PJ_POOL_ZALLOC_T(pool, struct pjmedia_wsola);
    wsola->samples_per_frame = samples_per_frame;

    PJ_UNUSED_ARG(clock_rate);
    PJ_UNUSED_ARG(channel_count);
    PJ_UNUSED_ARG(options);

    *p_wsola = wsola;

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_wsola_destroy(pjmedia_wsola *wsola)
{
    PJ_UNUSED_ARG(wsola);
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_wsola_reset( pjmedia_wsola *wsola,
					 unsigned options)
{
    PJ_UNUSED_ARG(wsola);
    PJ_UNUSED_ARG(options);

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_wsola_save( pjmedia_wsola *wsola, 
					pj_int16_t frm[], 
					pj_bool_t prev_lost)
{
    PJ_UNUSED_ARG(wsola);
    PJ_UNUSED_ARG(frm);
    PJ_UNUSED_ARG(prev_lost);

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_wsola_generate( pjmedia_wsola *wsola, 
					    pj_int16_t frm[])
{
    pjmedia_zero_samples(frm, wsola->samples_per_frame);
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_wsola_discard( pjmedia_wsola *wsola, 
					   pj_int16_t buf1[],
					   unsigned buf1_cnt, 
					   pj_int16_t buf2[],
					   unsigned buf2_cnt,
					   unsigned *del_cnt)
{
    CHECK_(buf1_cnt + buf2_cnt >= wsola->samples_per_frame);

    PJ_UNUSED_ARG(buf1);
    PJ_UNUSED_ARG(buf1_cnt);
    PJ_UNUSED_ARG(buf2);
    PJ_UNUSED_ARG(buf2_cnt);

    *del_cnt = wsola->samples_per_frame;

    return PJ_SUCCESS;
}

#endif	/* #if PJMEDIA_WSOLA_IMP.. */


