comment Save and load WAV sound files. Analyze frequencies. {w,rate}=loadwave(filename); loads a WAV file. w=loadwave(filename); loads a WAV file. r is saved to defaultrate. savewave(filename,v[,rate,bits]); saves a WAV file. analyze(v[,fmin,fmax,rate,points]); plots the frequencies of v mapsound(w,[,dt,fmin,fmax,simpl,rate]); show the sound history soundsec(n[,rate]); generates t values for n seconds. Default sample rate is 22050 or the sample rate of the last read WAV file. endcomment defaultrate=22050; function soundsec (n,rate=0) ## Return n seconds of t parameter. global defaultrate; if rate==0; rate=defaultrate; endif; return 0:2*pi/rate:2*n*pi; endfunction function savewave (filename,v,rate=0,bits=16) ## Save a vector of sound data in WAV format. ## Return the length of the sample in seconds. ## If rate=0, the default sampling rate is taken. ## bits may be 8 or 16. global defaultrate; if rate==0; rate=defaultrate; endif; open(filename,"wb"); write("RIFF"); if bits==8; n=cols(v); putlongword(n+37); write("WAVEfmt "); putlongword(16); putword(1); putword(1); putlongword(rate); putlongword(rate); putword(1); putword(8); write("data"); putlongword(n); m=max(abs(v)); vv=v/m*64+128; putuchar(vv); putchar(0); elseif bits==16; n=cols(v); putlongword(2*n+36); write("WAVEfmt "); putlongword(16); putword(1); putword(1); putlongword(rate); putlongword(2*rate); putword(2); putword(16); write("data"); putlongword(2*n); m=max(abs(v)); vv=v/m*64*256; putword(vv); else error("Bits must be 8 or 16"); endif close(); return cols(v)/rate; endfunction function loadwave (filename) ## Read a WAV file. ## The sample rate is stored to defaultrate. global defaultrate; open(filename,"rb"); if getstring(4)<>"RIFF"; error("No Wave file!"); endif; getlongword(); .. This is the total file length minus 8 if getstring(8)<>"WAVEfmt "; error("No Wave file!"); endif; offset=getlongword(); .. ??? Is always 16, sometimes 18 getword(); .. ??? Is always 1. if (getword()<>1); error("Stereo sample!"); endif; rate=getlongword(); getlongword(); byte=getword(); bits=getword(); if offset>16; getuchar(offset-16); endif; if getstring(4)<>"data"; error("No Wave file!"); endif; if byte==1; w=getuchar(getlongword()); elseif byte==2; w=getword(getlongword()/2); else error("Not 8 or 16 bit!"); endif; if cols(w)>0; w=w-sum(w)/cols(w); w=w/max(abs(w)); endif; close(); defaultrate=rate; return w; endfunction function analyze (w,fmin=10,fmax=1500,rate=0,points=8192) ## Make a frequency plot of the signal w with sampling rate. ## The data must be at least points long. ## The maximal frequency plotted will be fmax, the minimal fmin. global defaultrate; if rate==0; rate=defaultrate; endif; v=w[1:points]; f=abs(fft(v)); i=fmin/rate*points:fmax/rate*points; setplot(fmin,fmax,0,max(f[i])); fr=i/points*rate; xplot(fr,f[i]); return ""; endfunction function mapsound (w,dt=0.1,fmin=100,fmax=1500,simpl=1,rate=0) ## Plots a sound map for a sound. ## It does FFT at time increments dt. ## rate is the sampling rate. ## simpl points are collected for speed reasons. n=cols(w); global defaultrate; if rate==0; rate=defaultrate; endif; dp=dt*rate; points=2^floor(log(dp)/log(2)); ind=fmin/rate*points/simpl:fmax/rate*points/simpl; f=abs(fft(w[1:points])); f=sum(redim(f,points/simpl,simpl))'; M=f[ind]; i=1; repeat i=i+dp; if i+points>n; break; endif; f=abs(fft(w[i:i+points-1])); f=sum(redim(f,points/simpl,simpl))'; M=M_f[ind]; end; setplot(fmin,fmax,0,n/rate); density(-M,0.99); xplot(); return "" endfunction