samer@34: % audio_sonifier - Create sonifier object samer@34: % samer@34: % audio_sonifier :: samer@34: % nonneg ~ 'Duration of each note', samer@34: % options { samer@34: % transpose/0 :: int ~'pitch transposition in semitones'; samer@34: % gen /'sine' :: {'sine','blsquare'}; samer@34: % attack /5 :: nonneg ~'attack time in ms'; samer@34: % decay /200 :: nonneg ~'decay time in ms'; samer@34: % release/5 :: nonneg ~'release time in ms'; samer@34: % cutoff /0.4 :: nonneg ~'low pass cut-off as norm freq'; samer@34: % fs /11025 :: nonneg ~'sample rate' samer@34: % } samer@34: % => sonifier. samer@34: % samer@34: % sonifier ::= samer@34: % seq(natural) ~'thing to sonify', samer@34: % (void=>void) ~'action on finish' samer@34: % => player. samer@34: % samer@34: % player ::= struct { samer@34: % start :: void => void; samer@34: % startq :: (nonneg,nonneg) => void; samer@34: % stop :: void => void; samer@34: % isrunning :: void => bool; samer@34: % atend :: void => bool; samer@34: % rewind :: void => void; samer@34: % dispose :: void => void samer@34: % }. samer@34: samer@36: function f=audio_sonifier(dur,varargin) samer@37: audio_info = options( ... samer@34: 'transpose',0,'gen','sine','fs',11025, 'cutoff',0.4, ... samer@34: 'attack',5,'decay',200,'release',5,varargin{:}); samer@34: samer@36: audio_info.lineout = lineout(1,audio_info.fs); samer@34: f=@(seq,onfinish)sonify_audio(audio_info,dur,seq,onfinish); samer@34: end samer@34: samer@34: function player=sonify_audio(audio,dur,seq,onfinish) samer@37: %disp('preparing audio signal.'); samer@34: sched = playaudio_async( ... samer@34: sonify(seq,dur,audio_opts(audio)), audio.lineout, ... samer@34: 'defer',1,'its',2^31,'onfinish',@(a)onfinish()); samer@34: samer@34: player=cpfields({'stop','isrunning','atend','rewind','dispose'},... samer@34: sched, struct(... samer@34: 'start', @()sched.startat(nows+1), ... samer@34: 'startq', @(q,o)sched.startat(o+quant(q,nows)))); samer@34: % 'wait', sig.wait)); samer@34: samer@37: %disp('audio playback ready to go.'); samer@34: end samer@34: samer@34: function opts=audio_opts(A) samer@34: c=@(t)round(A.fs*t/1000); samer@37: opts=options('bpm',60, 'transpose',A.transpose-69, ... samer@34: 'env',envadr(c(A.attack),c(A.decay),c(A.release)), ... samer@34: 'gen',A.gen,'bl_cutoff',A.cutoff,'fs',A.fs,'buffer',0.125); samer@34: end samer@34: