PCM Wave time stretch

4

Write the smallest program performs a time stretch operation on a PCM Wave (.wav) file.

Rules:

  • Parameter input will by via whatever standard argument mechanism your language comes with, e.g. argv in C/C++, $_GET in PHP. Hard coded paths are not allowed.
  • First parameter will be a decimal value that represents the stretch coefficient. 1 means don't stretch, 2 means twice the length, 0.5 means half the length, 0.333 means one third the length. An example might be stretch.exe 1.5 c:\sound.wav
  • The time stretch operation does not need to perform pitch correction.
  • You must not drop samples to fit a compression (i.e. stretch < 1). You should use interpolation, weighted mean, or a similar method.
  • Assume a WAVE PCM file with a RIFF header.
  • Assume 16-bits per sample (bonus if your code works for 8-bit and 24-bit audio)
  • You must handle any number of audio channels.
  • You must at least handle 11025, 22050 and 44100Hz sample rates, though the ability to handle arbitrary rates would be a bonus! :)
  • Your output file must keep the same sample rate, sample size and channel count as the input file.
  • The output file must be named "stretch.wav"
  • You may not use any 3rd party libraries or built-in functions for audio processing. The parsing of the WAV file and the time stretch operation must be your own code.

On Windows, the C:\Windows\Media directory contains plenty of WAV files to test with.

Polynomial

Posted 2011-11-25T12:43:06.677

Reputation: 4 082

Answers

1

Ruby, 220 characters

s,n=$*
w=IO.binread(n).unpack r='s<*'
x=[];t=[g=0]*c=w[11]
w[u=22..-1].each_slice(c){|f|g+=v=1.0/s.to_f
c.times{|h|t[h]+=f[h]*v}
(c.times{|h|x<<=m=t[h]/g;t[h]-=m};g-=1)until 1>g}
w[u]=x;IO.binwrite'stretch.wav',w.pack(r)

This version works with ruby 1.9.3 with basic 16 bit files (e.g. no additional chunks) for any sample rate or number of channels.

Howard

Posted 2011-11-25T12:43:06.677

Reputation: 23 109