⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plc_common.c

📁 一个开源的sip源代码
💻 C
字号:
/* $Id: plc_common.c 1266 2007-05-11 15:14:34Z bennylp $ */
/* 
 * Copyright (C) 2003-2007 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 <pj/assert.h>
#include <pj/pool.h>
#include <pj/string.h>


static void* plc_replay_create(pj_pool_t*, unsigned c, unsigned f);
static void  plc_replay_save(void*, pj_int16_t*);
static void  plc_replay_generate(void*, pj_int16_t*);

extern void* pjmedia_plc_steveu_create(pj_pool_t*, unsigned c, unsigned f);
extern void  pjmedia_plc_steveu_save(void*, pj_int16_t*);
extern void  pjmedia_plc_steveu_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*);
};


#if defined(PJMEDIA_HAS_STEVEU_PLC) && PJMEDIA_HAS_STEVEU_PLC!=0
static struct plc_alg plc_steveu =
{
    &pjmedia_plc_steveu_create,
    &pjmedia_plc_steveu_save,
    &pjmedia_plc_steveu_generate
};
#endif


static struct plc_alg plc_replay =
{
    &plc_replay_create,
    &plc_replay_save,
    &plc_replay_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);

    if (0)
	;
#if defined(PJMEDIA_HAS_STEVEU_PLC) && PJMEDIA_HAS_STEVEU_PLC!=0
    else if (clock_rate == 8000)
	plc->op = &plc_steveu;
#endif
    else
	plc->op = &plc_replay;

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


//////////////////////////////////////////////////////////////////////////////
/*
 * Simple replay based plc
 */
struct replay_plc
{
    unsigned	size;
    unsigned	replay_cnt;
    pj_int16_t *frame;
};


static void* plc_replay_create(pj_pool_t *pool, unsigned clock_rate, 
			       unsigned samples_per_frame)
{
    struct replay_plc *o;

    PJ_UNUSED_ARG(clock_rate);

    o = PJ_POOL_ALLOC_T(pool, struct replay_plc);
    o->size = samples_per_frame * 2;
    o->replay_cnt = 0;
    o->frame = (pj_int16_t*) pj_pool_zalloc(pool, o->size);

    return o;
}

static void plc_replay_save(void *plc, pj_int16_t *frame)
{
    struct replay_plc *o = (struct replay_plc*) plc;

    pj_memcpy(o->frame, frame, o->size);
    o->replay_cnt = 0;
}

static void plc_replay_generate(void *plc, pj_int16_t *frame)
{
    struct replay_plc *o = (struct replay_plc*) plc;
    unsigned i, count;
    pj_int16_t *samp;

    ++o->replay_cnt;

    if (o->replay_cnt < 16) {
	pj_memcpy(frame, o->frame, o->size);
    

	count = o->size / 2;
	samp = o->frame;
	for (i=0; i<count; ++i)
	    samp[i] = (pj_int16_t)(samp[i] >> 1);
    } else {
	pj_bzero(frame, o->size);
    }
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -