Online File
Rick Aster: Professional SAS Programming Shortcuts: Contents
%* Tempo ; %LET BPM = 120; %* Sampling frequency. ; %LET FS = 44100; %* Samples per 8th note. ; %LET N = %EVAL(&FS.*60/(&BPM.*2)); data work.audio (keep=value); set work.midinote; * Compute note frequency from MIDI note number. ; freq = 440*(2**((pitch - 69)/12)); * Compute volume from velocity. ; notevolume = velocity/1024; do sampleclock = 1 to &N.; value = 0; if notevolume > 0 then do; * Elapsed time since beginning of note. ; time = (sampleclock - 0.5)/(&FS.); * Compute volume envelope. ; select ; when (sampleclock < (&N.)*.01) env = sampleclock/((&N.)*.01); when (sampleclock < (&N.)*.67) env = 1; when (sampleclock < (&N.)*.6899) env = ((&N.)*.69 - sampleclock)/((&N.)*.02); otherwise env = .005*((&N.) - sampleclock)/((&N.)*.31); end; * Compute sample value. ; wavevalue = sin(time*2*constant('pi')*freq); floatvalue = 32768*wavevalue*notevolume*env; * Dither to form integer value. ; value = floorz(floatvalue); fraction = floatvalue - value; ditherbit = rand('uniform') <= fraction; value = value + ditherbit; * Clip to 16 bits. ; value = 32767 min value max -32767; end; output; end; run;