[icecast] question on downsampling

jaromil
Fri, 06 Aug 2004 14:22:38 -0000

On Thu, Oct 18, 2001 at 09:48:11AM +0300, Akos Maroy wrote:

> 2. Downsample in DarkIce, by simple means. For example, from 44.1kHz ->
> 22.05kHz, simply send one sample for every two imput samples, taking
> their average value. This shouldn't result in large computing overhead,
> and I could also do it for vorbis.
>
> As there are people on the list more clever than me, I'd like to know
> what downsides are there for point 2?

you can have a look into the resampling code of MuSE, in particular
audioproc.cpp which contains different procedures for resampling while
mixing (for better efficiency, we don't want to process all the bytes
twice, better do both operations in once). the core algorithm plays with
resolution by doing bitshift of array indexes, resulting in a better
interpolation than the procedure you describe here.

i.e:

int mixxx_stereo_22(int *dest, short *chan, int num, float volume) {
  int c, off,tnum = (num<<1);
  int delta = (num << 16) / tnum;
  for(c=0,off=0;c<tnum;c++, off += delta)
    dest[c] = (int) (dest[c] + (chan[off >> 16]*volume));

this resamples 22 to 44 while also adding it to the mixing buffer dest[].

alltough there are more exact ways to do it, this looks to me the better
compromise in performance and accuracy.

i found this algo into the speed resampling plugin of xmms, by
jammet-at-lionking.org, which originally was formulated to resample at any
frequency:

#define DO_PITCH(type, length, newlength, buffer, newbuffer) \
{ \
   int delta = (length << 16) / newlength, i, off; \
   type *ptr = (type *)buffer, *newptr = (type *)newbuffer; \
   for(i = 0, off = 0; i < newlength; i++, off += delta) \
      *newptr++ = ptr[off >> 16]; \
}

by using this you just need to calculate lenght proportions into your
resampling.

greetings


--
jaromil //dyne.org - GPG fingerprint and ___id____
6EEE 4FB2 2555 7ACD 8496  AB99 E2A2 93B4 6C62 4800