1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
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
|