samer@34
|
1 % audio_sonifier - Create sonifier object
|
samer@34
|
2 %
|
samer@34
|
3 % audio_sonifier ::
|
samer@34
|
4 % nonneg ~ 'Duration of each note',
|
samer@34
|
5 % options {
|
samer@34
|
6 % transpose/0 :: int ~'pitch transposition in semitones';
|
samer@34
|
7 % gen /'sine' :: {'sine','blsquare'};
|
samer@34
|
8 % attack /5 :: nonneg ~'attack time in ms';
|
samer@34
|
9 % decay /200 :: nonneg ~'decay time in ms';
|
samer@34
|
10 % release/5 :: nonneg ~'release time in ms';
|
samer@34
|
11 % cutoff /0.4 :: nonneg ~'low pass cut-off as norm freq';
|
samer@34
|
12 % fs /11025 :: nonneg ~'sample rate'
|
samer@34
|
13 % }
|
samer@34
|
14 % => sonifier.
|
samer@34
|
15 %
|
samer@34
|
16 % sonifier ::=
|
samer@34
|
17 % seq(natural) ~'thing to sonify',
|
samer@34
|
18 % (void=>void) ~'action on finish'
|
samer@34
|
19 % => player.
|
samer@34
|
20 %
|
samer@34
|
21 % player ::= struct {
|
samer@34
|
22 % start :: void => void;
|
samer@34
|
23 % startq :: (nonneg,nonneg) => void;
|
samer@34
|
24 % stop :: void => void;
|
samer@34
|
25 % isrunning :: void => bool;
|
samer@34
|
26 % atend :: void => bool;
|
samer@34
|
27 % rewind :: void => void;
|
samer@34
|
28 % dispose :: void => void
|
samer@34
|
29 % }.
|
samer@34
|
30
|
samer@36
|
31 function f=audio_sonifier(dur,varargin)
|
samer@37
|
32 audio_info = options( ...
|
samer@34
|
33 'transpose',0,'gen','sine','fs',11025, 'cutoff',0.4, ...
|
samer@34
|
34 'attack',5,'decay',200,'release',5,varargin{:});
|
samer@34
|
35
|
samer@36
|
36 audio_info.lineout = lineout(1,audio_info.fs);
|
samer@34
|
37 f=@(seq,onfinish)sonify_audio(audio_info,dur,seq,onfinish);
|
samer@34
|
38 end
|
samer@34
|
39
|
samer@34
|
40 function player=sonify_audio(audio,dur,seq,onfinish)
|
samer@37
|
41 %disp('preparing audio signal.');
|
samer@34
|
42 sched = playaudio_async( ...
|
samer@34
|
43 sonify(seq,dur,audio_opts(audio)), audio.lineout, ...
|
samer@34
|
44 'defer',1,'its',2^31,'onfinish',@(a)onfinish());
|
samer@34
|
45
|
samer@34
|
46 player=cpfields({'stop','isrunning','atend','rewind','dispose'},...
|
samer@34
|
47 sched, struct(...
|
samer@34
|
48 'start', @()sched.startat(nows+1), ...
|
samer@34
|
49 'startq', @(q,o)sched.startat(o+quant(q,nows))));
|
samer@34
|
50 % 'wait', sig.wait));
|
samer@34
|
51
|
samer@37
|
52 %disp('audio playback ready to go.');
|
samer@34
|
53 end
|
samer@34
|
54
|
samer@34
|
55 function opts=audio_opts(A)
|
samer@34
|
56 c=@(t)round(A.fs*t/1000);
|
samer@37
|
57 opts=options('bpm',60, 'transpose',A.transpose-69, ...
|
samer@34
|
58 'env',envadr(c(A.attack),c(A.decay),c(A.release)), ...
|
samer@34
|
59 'gen',A.gen,'bl_cutoff',A.cutoff,'fs',A.fs,'buffer',0.125);
|
samer@34
|
60 end
|
samer@34
|
61
|