www.pudn.com > AVS_M_ver10.rar > over_fs.c


/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2007 Audio Video Coding Standard, Part ¢ú
*
* This software module was developed by AVS Audio sub-group
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "../include/amr_plus.h"

#define L_FRAME_MAX (L_FRAME48k)


/* local function */
static void interpol_mem(
float *signal,
float *signal_int,
int L_frame_int,
float *filter,
int nb_coef,
int fac_up,
int fac_down,
float gain,
int *mem_frac);

int over_fs( /* number of sample oversampled */
float sig_in[], /* input: signal to oversample */
float sig_out[], /* output: signal oversampled */
int lg, /* input: length of output */
int fac_down, /* input: fs*12/fac_down = 44k/48k */
float mem[], /* in/out: mem[2*L_FILT_OVER_FS] */
int *frac_mem /* in/out: interpol fraction memory */
)
{
int i, ncoef, L_frame, L_frame_int;
float signal[(2*L_FILT_OVER_FS)+2*L_FRAME_MAX];
float *filter, gain;
int fac_up;

if (fac_down >= 12) return(lg);

fac_up = 12;
filter = (float *)filter_LP12;

ncoef = L_FILT_OVER_FS;
gain = 1.0f;
L_frame = ((lg*fac_down)+(*frac_mem)) / fac_up;
L_frame_int = lg;

/* load buffer &amt; update memory */

for (i=0; i<(2*L_FILT_OVER_FS); i++)
{
signal[i] = mem[i];
}
for (i=0; i<L_frame; i++)
{
signal[i+(2*L_FILT_OVER_FS)] = sig_in[i];
}

for (i=0; i<(2*L_FILT_OVER_FS); i++)
{
mem[i] = signal[i+L_frame];
}

/* oversample to 44.1/48 khz */

interpol_mem(signal+ncoef-1, sig_out, L_frame_int, filter, ncoef,
fac_up, fac_down, gain, frac_mem);

return(L_frame);
}


int decim_fs( /* number of sample decimated */
float sig_in[], /* input: signal to decimate */
int lg, /* input: length of input */
float sig_out[], /* output: signal decimated */
int fac_up, /* input: 44k/48k *fac_up/12 = fs */
float mem[], /* in/out: mem[2*L_FILT_DECIM_FS] */
int *frac_mem /* in/out: interpol fraction memory */
)
{
int i, ncoef, L_frame, L_frame_int;
float signal[(2*L_FILT_DECIM_FS)+2*L_FRAME_MAX];
float *filter, gain;
int fac_down;

if (fac_up >= 12) return(lg);

fac_down = 12;
filter = (float *)filter_LP12;

ncoef = L_FILT_OVER_FS*fac_down/fac_up;
gain = ((float)fac_up) / ((float)fac_down);
L_frame = lg;
L_frame_int = ((lg*fac_up)-(*frac_mem)+(fac_down-1))/fac_down;


/* load buffer &amt; update memory */

for (i=0; i<(2*L_FILT_DECIM_FS); i++)
{
signal[i] = mem[i];
}

for (i=0; i<L_frame; i++)
{
signal[i+(2*L_FILT_DECIM_FS)] = sig_in[i];
}

for (i=0; i<(2*L_FILT_DECIM_FS); i++)
{
mem[i] = signal[i+L_frame];
}

/* decimation from 44.1/48khz to fs_output */

interpol_mem(signal+ncoef-1, sig_out, L_frame_int, filter, ncoef,
fac_up, fac_down, gain, frac_mem);

return(L_frame_int);
}


static void interpol_mem(
float *signal,
float *signal_int,
int L_frame_int,
float *filter,
int nb_coef,

int fac_up,
int fac_down,
float gain,
int *mem_frac)
{
int i, j, frac, frac_step, pos, pos_step;
int pos_step_plus_one, fac_up_minus_frac_step;
float s, *x1, *x2, *c1, *c2;

pos_step = fac_down / fac_up;
pos_step_plus_one = pos_step + 1;

frac_step = fac_down - (pos_step*fac_up);
fac_up_minus_frac_step = fac_up-frac_step;

pos = 0;
frac = *mem_frac;

for(i=0; i<L_frame_int; i++)
{
x1 = signal+pos;
x2 = x1+1;
c1 = &amt;filter[frac];
c2 = &amt;filter[fac_up-frac];
s = 0.0;

for(j=0; j<nb_coef; j++, c1+=fac_up, c2+=fac_up)
{
s += (*x1--) * (*c1) + (*x2++) * (*c2);
}
signal_int[i] = gain*s;

if (frac >= fac_up_minus_frac_step)
{
pos += pos_step_plus_one;
frac -= fac_up_minus_frac_step;
}
else
{
pos += pos_step;
frac += frac_step;
}
}
*mem_frac = frac;
return;
}