Trying to down-sample audio I am trying to downsample from $44100Hz$ to $8000Hz$, and I am not sure what I am doing wrong here.  $44100 / 8000$ is $5.5125$, so I am getting hung up a little on the fractional remainder which is causing my implementation to play back slightly slower than it is supposed to.  It seems that I need to somehow use the fractional remainder to compensate for this, but I am not sure how...

def downsample
  s = low_pass_filtered_signal_by_half_target_sample_rate
  samples_to_discard = (sample_rate.to_f / target_sample_rate).floor //   (44100.0 / 8000.0).floor

  s1_n = 0
  for (n = 0; n &lt; N; n++) {
     if (n % samples_to_discard == 0) {
       s1[s1_n] = averaged(n, samples_to_discard)
       s1_n += 1
    }
  }
end

def averaged(start_index, samples_to_discard)
  sum = 0
    for (n = start_index, n &lt; start_index + samples_to_discard; n++) {
      sum += s[n] || 0
    }
  sum / samples_to_discard
end
First you need to interpolate between samples rather than just retaining and discarding samples (which introduces horrible jitter noise during non-integer downsampling).

Then, if the original audio data contained spectrum around or above 4000 Hz (half the sample rate), you will need to low-pass filter before or in conjunction with the interpolation to the lower sample rate, or else you will get aliasing.

A good combined method of low-pass filtering plus interpolation is to use a windowed Sinc function as the interpolation kernel, where the Sinc is scaled to be the transform of an ideal "brick-wall" or rectangular filter with the appropriate low-pass cut-off frequency.  The width of the window on the scaled Sinc function will control the transition width of the frequency cut-off.