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


static void* plc_wsola_create(pj_pool_t*, unsigned c, unsigned f);
static void  plc_wsola_save(void*, pj_int16_t*);
static void  plc_wsola_generate(void*, pj_int16_t*);

/**
 * This struct is used internally to represent a PLC backend.
 */
struct plc_alg
{
    void* (*plc_create)(pj_pool_t*, unsigned c, unsigned f);
    void  (*plc_save)(void*, pj_int16_t*);
    void  (*plc_generate)(void*, pj_int16_t*);
};


static struct plc_alg plc_wsola =
{
    &plc_wsola_create,
    &plc_wsola_save,
    &plc_wsola_generate
};


struct pjmedia_plc
{
    void	    *obj;
    struct plc_alg  *op;
};


/*
 * Create PLC session. This function will select the PLC algorithm to
 * use based on the arguments.
 */
PJ_DEF(pj_status_t) pjmedia_plc_create( pj_pool_t *pool,
					unsigned clock_rate,
					unsigned samples_per_frame,
					unsigned options,
					pjmedia_plc **p_plc)
{
    pjmedia_plc *plc;

    PJ_ASSERT_RETURN(pool && clock_rate && samples_per_frame && p_plc,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);

    PJ_UNUSED_ARG(options);

    plc = PJ_POOL_ZALLOC_T(pool, pjmedia_plc);

    plc->op = &plc_wsola;
    plc->obj = plc->op->plc_create(pool, clock_rate, samples_per_frame);

    *p_plc = plc;

    return PJ_SUCCESS;
}


/*
 * Save a good frame to PLC.
 */
PJ_DEF(pj_status_t) pjmedia_plc_save( pjmedia_plc *plc,
				      pj_int16_t *frame )
{
    PJ_ASSERT_RETURN(plc && frame, PJ_EINVAL);
 
    plc->op->plc_save(plc->obj, frame);
    return PJ_SUCCESS;
}


/*
 * Generate a replacement for lost frame.
 */
PJ_DEF(pj_status_t) pjmedia_plc_generate( pjmedia_plc *plc,
					  pj_int16_t *frame )
{
    PJ_ASSERT_RETURN(plc && frame, PJ_EINVAL);
    
    plc->op->plc_generate(plc->obj, frame);
    return PJ_SUCCESS;
}


//////////////////////////////////////////////////////////////////////////////
/*
 * Packet loss concealment based on WSOLA
 */
struct wsola_plc
{
    pjmedia_wsola   *wsola;
    pj_bool_t	     prev_lost;
};


static void* plc_wsola_create(pj_pool_t *pool, unsigned clock_rate, 
			      unsigned samples_per_frame)
{
    struct wsola_plc *o;
    unsigned flag;
    pj_status_t status;

    PJ_UNUSED_ARG(clock_rate);

    o = PJ_POOL_ZALLOC_T(pool, struct wsola_plc);
    o->prev_lost = PJ_FALSE;

    flag = PJMEDIA_WSOLA_NO_DISCARD;
    if (PJMEDIA_WSOLA_PLC_NO_FADING)
	flag |= PJMEDIA_WSOLA_NO_FADING;

    status = pjmedia_wsola_create(pool, clock_rate, samples_per_frame, 1,
				  flag, &o->wsola);
    if (status != PJ_SUCCESS)
	return NULL;

    return o;
}

static void plc_wsola_save(void *plc, pj_int16_t *frame)
{
    struct wsola_plc *o = (struct wsola_plc*) plc;

    pjmedia_wsola_save(o->wsola, frame, o->prev_lost);
    o->prev_lost = PJ_FALSE;
}

static void plc_wsola_generate(void *plc, pj_int16_t *frame)
{
    struct wsola_plc *o = (struct wsola_plc*) plc;
    
    pjmedia_wsola_generate(o->wsola, frame);
    o->prev_lost = PJ_TRUE;
}


