diff options
author | Max Horn | 2003-07-24 17:46:38 +0000 |
---|---|---|
committer | Max Horn | 2003-07-24 17:46:38 +0000 |
commit | b9d380bba43b25e1654b320a42b05499c060656c (patch) | |
tree | a882712c93b94c0e984c801f1a6ff8bcee515a40 /sound/rate.cpp | |
parent | becd70d243d456af9595ae0cc37e72b1489736c5 (diff) | |
download | scummvm-rg350-b9d380bba43b25e1654b320a42b05499c060656c.tar.gz scummvm-rg350-b9d380bba43b25e1654b320a42b05499c060656c.tar.bz2 scummvm-rg350-b9d380bba43b25e1654b320a42b05499c060656c.zip |
new files, based on SoX (http://sox.sf.net): better resampling code. Note that my mixer.cpp changes are on purpose not yet in CVS since they are not complete. Only reasons I checkin these files is that it's much more comfortable to have CVS, since I need to rewrite parts of resample.cpp now (I already have lots of modifications in). Also expect more OO in the future
svn-id: r9176
Diffstat (limited to 'sound/rate.cpp')
-rw-r--r-- | sound/rate.cpp | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/sound/rate.cpp b/sound/rate.cpp new file mode 100644 index 0000000000..bde477647a --- /dev/null +++ b/sound/rate.cpp @@ -0,0 +1,164 @@ +/* +* 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. +*/ + +/* + * Sound Tools rate change effect file. + */ + +#include "rate.h" + +#include <math.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 + * + * Replaced all uses of floating point arithmetic by fixed point + * calculations (Max Horn 2003-07-18). + */ + +#define FRAC_BITS 16 + +/* Private data */ + +typedef struct ratestuff +{ + unsigned long opos_frac; /* fractional position of the output stream in input stream unit */ + unsigned long opos; + + unsigned long opos_inc_frac; /* fractional position increment in the output stream */ + unsigned long opos_inc; + + unsigned long ipos; /* position in the input stream (integer) */ + + st_sample_t ilast; /* last sample in the input stream */ +} *rate_t; + +/* + * Process options + */ +int st_rate_getopts(eff_t effp, int n, char **argv) +{ + if (n) { + st_fail("Rate effect takes no options."); + return (ST_EOF); + } + + return (ST_SUCCESS); +} + +/* + * Prepare processing. + */ +int st_rate_start(eff_t effp, st_rate_t inrate, st_rate_t outrate) +{ + rate_t rate = (rate_t) effp->priv; + unsigned long incr; + + if (inrate == outrate) { + st_fail("Input and Output rates must be different to use rate effect"); + return (ST_EOF); + } + + if (inrate >= 65536 || outrate >= 65536) { + st_fail("rate effect can only handle rates < 65536"); + return (ST_EOF); + } + + rate->opos_frac = 0; + rate->opos = 0; + + /* increment */ + incr = (inrate << FRAC_BITS) / outrate; + + rate->opos_inc_frac = incr & ((1UL << FRAC_BITS) - 1); + rate->opos_inc = incr >> FRAC_BITS; + + rate->ipos = 0; + + rate->ilast = 0; + return (ST_SUCCESS); +} + +/* + * Processed signed long samples from ibuf to obuf. + * Return number of samples processed. + */ +int st_rate_flow(eff_t effp, InputStream &input, st_sample_t *obuf, st_size_t *osamp) +{ + rate_t rate = (rate_t) effp->priv; + st_sample_t *ostart, *oend; + st_sample_t ilast, icur, out; + unsigned long tmp; + + ilast = rate->ilast; + + ostart = obuf; + oend = obuf + *osamp; + + while (obuf < oend && !input.eof()) { + + /* read as many input samples so that ipos > opos */ + while (rate->ipos <= rate->opos) { + ilast = input.read(); + rate->ipos++; + /* See if we finished the input buffer yet */ + + if (input.eof()) + goto the_end; + } + + icur = input.peek(); + + /* interpolate */ + out = ilast + (((icur - ilast) * rate->opos_frac) >> FRAC_BITS); + + /* output sample & increment position */ + + clampedAdd(*obuf++, out); + #if 1 // FIXME: Hack to generate stereo output + + clampedAdd(*obuf++, out); + #endif + + tmp = rate->opos_frac + rate->opos_inc_frac; + rate->opos = rate->opos + rate->opos_inc + (tmp >> FRAC_BITS); + rate->opos_frac = tmp & ((1UL << FRAC_BITS) - 1); + } + +the_end: + *osamp = obuf - ostart; + rate->ilast = ilast; + return (ST_SUCCESS); +} + +/* + * Do anything required when you stop reading samples. + * Don't close input file! + */ +int st_rate_stop(eff_t effp) +{ + /* nothing to do */ + return (ST_SUCCESS); +} + |