aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2003-07-24 21:26:00 +0000
committerMax Horn2003-07-24 21:26:00 +0000
commit09263a1febc4ff1adf69d81bf4d225340484df02 (patch)
tree4bd791723477857f51c1d0714a0d63cd605b26a7
parent1622ac31dafee837cb3011c558dfcd93c5bb1ca6 (diff)
downloadscummvm-rg350-09263a1febc4ff1adf69d81bf4d225340484df02.tar.gz
scummvm-rg350-09263a1febc4ff1adf69d81bf4d225340484df02.tar.bz2
scummvm-rg350-09263a1febc4ff1adf69d81bf4d225340484df02.zip
added volume support; some cleanup; provided exactly as many samples as were requested in the 'resample' algorithm (if possible)
svn-id: r9180
-rw-r--r--sound/rate.cpp29
-rw-r--r--sound/rate.h50
-rw-r--r--sound/resample.cpp67
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",