📄 rate.c
字号:
/*
* August 21, 1998
* Copyright 1998 Fabrice Bellard.
*
* [Rewrote completly the code of Lance Norskog And Sundry
* Contributors with a more efficient algorithm.]
*
* This source code is freely redistributable and may be used for
* any purpose. This copyright notice must be maintained.
* Lance Norskog And Sundry Contributors are not responsible for
* the consequences of using this software.
*/
/*
* Modified for use in Speak Freely by John Walker: 2003-01-25
* Sound Tools rate change effect file.
*/
#include "netfone.h"
/*
* Linear Interpolation.
*
* The use of fractional increment allows us to use no buffer. It
* avoid the problems at the end of the buffer we had with the old
* method which stored a possibly big buffer of size
* lcm(in_rate,out_rate).
*
* Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
* the input & output frequencies are equal, a delay of one sample is
* introduced. Limited to processing 32-bit count worth of samples.
*
* 1 << FRAC_BITS evaluating to zero in several places. Changed with
* an (unsigned long) cast to make it safe. MarkMLl 2/1/99
*/
#define FRAC_BITS 16
/*
* Prepare processing.
*/
void rate_start(rate_t *rate, int inrate, int outrate)
{
unsigned long incr;
rate->opos_frac=0;
rate->opos=0;
/* Increment */
incr = (unsigned long)(((double) inrate) / ((double) outrate) *
(double) (((unsigned long) 1) << FRAC_BITS));
rate->opos_inc_frac = incr & ((((unsigned long) 1) << FRAC_BITS) - 1);
rate->opos_inc = incr >> FRAC_BITS;
rate->ipos = 0;
rate->ilast = 0;
}
/*
* Processed signed long samples from ibuf to obuf.
* Return number of samples processed.
*/
void rate_flow(rate_t *rate, unsigned char *ibuf, unsigned char *obuf,
int *isamp, int *osamp)
{
unsigned char *istart, *iend;
unsigned char *ostart, *oend;
long ilast, icur, out;
unsigned long tmp;
double t;
ilast = rate->ilast;
istart = ibuf;
iend = ibuf + *isamp;
ostart = obuf;
oend = obuf + *osamp;
while (obuf < oend) {
/* Safety catch to make sure we have input samples. */
if (ibuf >= iend) goto the_end;
/* Read as many input samples so that ipos > opos */
while (rate->ipos <= rate->opos) {
ilast = audio_u2s(*ibuf++);
rate->ipos++;
/* See if we finished the input buffer yet */
if (ibuf >= iend) goto the_end;
}
icur = audio_u2s(*ibuf);
/* Interpolate */
t = ((double) rate->opos_frac) / (((unsigned long) 1) << FRAC_BITS);
out = (long) ((((double) ilast) * (1.0 - t)) + (((double) icur) * t));
/* Output sample & increment position */
*obuf++ = audio_s2u(out);
tmp = rate->opos_frac + rate->opos_inc_frac;
rate->opos = rate->opos + rate->opos_inc + (tmp >> FRAC_BITS);
rate->opos_frac = tmp & ((((unsigned long) 1) << FRAC_BITS) - 1);
}
the_end:
*isamp = ibuf - istart;
*osamp = obuf - ostart;
rate->ilast = ilast;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -