diff options
-rw-r--r-- | sound/rate.cpp | 29 | ||||
-rw-r--r-- | sound/rate.h | 50 | ||||
-rw-r--r-- | sound/resample.cpp | 67 |
3 files changed, 65 insertions, 81 deletions
diff --git a/sound/rate.cpp b/sound/rate.cpp index dcbd25b8a2..4c026adb83 100644 --- a/sound/rate.cpp +++ b/sound/rate.cpp @@ -55,19 +55,6 @@ typedef struct ratestuff } *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) @@ -104,7 +91,7 @@ int st_rate_start(eff_t effp, st_rate_t inrate, st_rate_t outrate) * Processed signed long samples from ibuf to obuf. * Return number of samples processed. */ -int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp) +int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { rate_t rate = (rate_t) effp->priv; st_sample_t *ostart, *oend; @@ -134,10 +121,9 @@ int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size out = ilast + (((icur - ilast) * rate->opos_frac) >> FRAC_BITS); /* output sample & increment position */ - + out = out * vol / 256; clampedAdd(*obuf++, out); #if 1 // FIXME: Hack to generate stereo output - clampedAdd(*obuf++, out); #endif @@ -151,14 +137,3 @@ the_end: 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); -} - diff --git a/sound/rate.h b/sound/rate.h index fb9ca40ad4..c84e33a2ad 100644 --- a/sound/rate.h +++ b/sound/rate.h @@ -14,11 +14,11 @@ #include "audiostream.h" typedef int16 st_sample_t; +typedef uint16 st_volume_t; typedef uint32 st_size_t; typedef uint32 st_rate_t; typedef struct { - bool used; byte priv[1024]; } eff_struct; typedef eff_struct *eff_t; @@ -57,64 +57,62 @@ static inline void clampedAdd(int16& a, int b) { // Resample (high quality) -int st_resample_getopts(eff_t effp, int n, char **argv); +int st_resample_getopts(eff_t effp, int n, const char **argv); int st_resample_start(eff_t effp, st_rate_t inrate, st_rate_t outrate); -int st_resample_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp); -int st_resample_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp); +int st_resample_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol); +int st_resample_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol); int st_resample_stop(eff_t effp); // Rate (linear filter, low quality) -int st_rate_getopts(eff_t effp, int n, char **argv); int st_rate_start(eff_t effp, st_rate_t inrate, st_rate_t outrate); -int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp); -int st_rate_stop(eff_t effp); +int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol); -#if 1 class RateConverter { protected: eff_struct effp; public: RateConverter() {} virtual ~RateConverter() {} - virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp) = 0; - virtual int drain(st_sample_t *obuf, st_size_t *osamp) = 0; + virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) = 0; + virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) = 0; }; class LinearRateConverter : public RateConverter { public: LinearRateConverter(st_rate_t inrate, st_rate_t outrate) { - st_rate_getopts(&effp, 0, NULL); st_rate_start(&effp, inrate, outrate); } - ~LinearRateConverter() { - st_rate_stop(&effp); + virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { + return st_rate_flow(&effp, input, obuf, osamp, vol); } - virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp) { - return st_rate_flow(&effp, input, obuf, osamp); - } - virtual int drain(st_sample_t *obuf, st_size_t *osamp) { + virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { return (ST_SUCCESS); } }; class ResampleRateConverter : public RateConverter { public: - ResampleRateConverter(st_rate_t inrate, st_rate_t outrate) { - st_resample_getopts(&effp, 0, NULL); + ResampleRateConverter(st_rate_t inrate, st_rate_t outrate, int quality) { + // FIXME: quality is for now a nasty hack. + // Valid values are 0,1,2,3 (everything else is treated like 0 for now) + const char *arg = 0; + switch (quality) { + case 1: arg = "-qs"; break; + case 2: arg = "-q"; break; + case 3: arg = "-ql"; break; + } + st_resample_getopts(&effp, arg ? 1 : 0, &arg); st_resample_start(&effp, inrate, outrate); } ~ResampleRateConverter() { st_resample_stop(&effp); } - virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp) { - return st_resample_flow(&effp, input, obuf, osamp); + virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { + return st_resample_flow(&effp, input, obuf, osamp, vol); } - virtual int drain(st_sample_t *obuf, st_size_t *osamp) { - return st_resample_drain(&effp, obuf, osamp); + virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { + return st_resample_drain(&effp, obuf, osamp, vol); } }; #endif - - -#endif diff --git a/sound/resample.cpp b/sound/resample.cpp index 825760236b..3bbd3d18ca 100644 --- a/sound/resample.cpp +++ b/sound/resample.cpp @@ -113,7 +113,7 @@ static long SrcEX(resample_t r, long Nx); /* * Process options */ -int st_resample_getopts(eff_t effp, int n, char **argv) { +int st_resample_getopts(eff_t effp, int n, const char **argv) { resample_t r = (resample_t) effp->priv; /* These defaults are conservative with respect to aliasing. */ @@ -262,37 +262,37 @@ int st_resample_start(eff_t effp, st_rate_t inrate, st_rate_t outrate) { * Processed signed long samples from ibuf to obuf. * Return number of samples processed. */ -int st_resample_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp) { +int st_resample_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { resample_t r = (resample_t) effp->priv; long i, k, last; - long Nout; // The number of bytes we effectively output + long Nout = 0; // The number of bytes we effectively output long Nx; // The number of bytes we will read from input long Nproc; // The number of bytes we process to generate Nout output bytes - #if 1 // FIXME: Hack to generate stereo output - *osamp >>= 1; + const long obufSize = *osamp / 2; +#else + const long obufSize = *osamp; #endif - /* constrain amount we actually process */ - fprintf(stderr,"Xp %d, Xread %d\n",r->Xp, r->Xread); + // Constrain amount we actually process + //fprintf(stderr,"Xp %d, Xread %d\n",r->Xp, r->Xread); // Initially assume we process the full X buffer starting at the filter // start position. Nproc = r->Xsize - r->Xp; -printf("FOO(1) Nproc %ld\n", Nproc); // Nproc is bounded indirectly by the size of output buffer, and also by // the remaining size of the Y buffer (whichever is smaller). - i = MIN(r->Ysize - r->Yposition, (long)*osamp); - if (Nproc * r->Factor >= i) - Nproc = (long)(i / r->Factor); - -printf("FOO(2) Nproc %ld\n", Nproc); + // We round up for the output buffer, because we want to generate enough + // bytes to fill it. + i = MIN((long)((r->Ysize - r->Yposition) / r->Factor), (long)ceil((obufSize - r->Yposition) / r->Factor)); + if (Nproc > i) + Nproc = i; // Now that we know how many bytes we want to process, we determine // how many bytes to read. We already have Xread bytes in our input // buffer, so we need Nproc - r->Xread more bytes. - Nx = Nproc - r->Xread + r->Xoff + r->Xp; // FIXME: Fingolfing thinks this is the correct thing, not what's in the next line! + Nx = Nproc - r->Xread + r->Xoff + r->Xp; // FIXME: Fingolfin thinks this is the correct thing, not what's in the next line! // Nx = Nproc - r->Xread; /* space for right-wing future-data */ if (Nx <= 0) { st_fail("resample: Can not handle this sample rate change. Nx not positive: %d", Nx); @@ -324,7 +324,7 @@ printf("FOO(3) Nproc %ld\n", Nproc); } if (r->quadr < 0) { /* exact coeff's method */ long creep; - Nout = SrcEX(r, Nproc); + Nout = SrcEX(r, Nproc) + r->Yposition; fprintf(stderr,"Nproc %d --> %d\n",Nproc,Nout); /* Move converter Nproc samples back in time */ r->t -= Nproc * r->b; @@ -339,7 +339,7 @@ printf("FOO(3) Nproc %ld\n", Nproc); } } else { /* approx coeff's method */ long creep; - Nout = SrcUD(r, Nproc); + Nout = SrcUD(r, Nproc) + r->Yposition; fprintf(stderr,"Nproc %d --> %d\n",Nproc,Nout); /* Move converter Nproc samples back in time */ r->Time -= Nproc; @@ -364,20 +364,31 @@ printf("FOO(3) Nproc %ld\n", Nproc); r->Xread = i; r->Xp = r->Xoff; -printf("osamp = %d, Nout = %ld\n", *osamp, Nout); - for (i = 0; i < Nout; i++) { - clampedAdd(*obuf++, (int)r->Y[i]); +printf("osamp = %ld, Nout = %ld\n", obufSize, Nout); + long numOutSamples = MIN(obufSize, Nout); + for (i = 0; i < numOutSamples; i++) { + int sample = (int)(r->Y[i] * vol / 256); + clampedAdd(*obuf++, sample); #if 1 // FIXME: Hack to generate stereo output - clampedAdd(*obuf++, (int)r->Y[i]); + clampedAdd(*obuf++, sample); #endif } - // At this point, we used *osamp bytes out of Nout available bytes in the Y buffer. - // If there are any bytes remaining, shift them to the start of the buffer, - // and update Yposition - - - *osamp = Nout; + // Move down the remaining Y bytes + for (i = numOutSamples; i < Nout; i++) { + r->Y[i-numOutSamples] = r->Y[i]; + } + if (Nout > numOutSamples) + r->Yposition = Nout - numOutSamples; + else + r->Yposition = 0; + + // Finally set *osamp to the number of samples we put into the output buffer +#if 1 // FIXME: Hack to generate stereo output + *osamp = numOutSamples * 2; +#else + *osamp = numOutSamples; +#endif return (ST_SUCCESS); } @@ -385,7 +396,7 @@ printf("osamp = %d, Nout = %ld\n", *osamp, Nout); /* * Process tail of input samples. */ -int st_resample_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp) { +int st_resample_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { resample_t r = (resample_t) effp->priv; long isamp_res, osamp_res; st_sample_t *Obuf; @@ -401,7 +412,7 @@ int st_resample_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp) { st_sample_t Osamp; Osamp = osamp_res; ZeroInputStream zero(isamp_res); - rc = st_resample_flow(effp, zero, Obuf, (st_size_t *) & Osamp); + rc = st_resample_flow(effp, zero, Obuf, (st_size_t *) & Osamp, vol); if (rc) return rc; /*fprintf(stderr,"DRAIN isamp,osamp (%d,%d) -> (%d,%d)\n", |