diff dsp/synth/audio_sonifier.m @ 34:c75bb62b90a9

Imported audio synthesis tools.
author samer
date Sun, 20 Jan 2013 19:05:05 +0000
parents
children 9e7be347b3a0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsp/synth/audio_sonifier.m	Sun Jan 20 19:05:05 2013 +0000
@@ -0,0 +1,67 @@
+% audio_sonifier - Create sonifier object
+%
+% audio_sonifier ::
+%    nonneg ~ 'Duration of each note',
+%    options {
+%       transpose/0    :: int    ~'pitch transposition in semitones';
+%       gen    /'sine' :: {'sine','blsquare'};
+%       attack /5      :: nonneg ~'attack time in ms';
+%       decay  /200    :: nonneg ~'decay time in ms';
+%       release/5      :: nonneg ~'release time in ms';
+%       cutoff /0.4    :: nonneg ~'low pass cut-off as norm freq';
+%       fs     /11025  :: nonneg ~'sample rate'
+%    }
+% => sonifier.
+%
+% sonifier ::= 
+%   seq(natural) ~'thing to sonify', 
+%   (void=>void) ~'action on finish' 
+% => player.
+%
+% player ::= struct {
+%    start     :: void => void;    
+%    startq    :: (nonneg,nonneg) => void;    
+%    stop      :: void => void;
+%    isrunning :: void => bool;
+%    atend     :: void => bool;
+%    rewind    :: void => void;
+%    dispose   :: void => void
+% }.
+
+function f=audio_sonifier(device,dur,varargin)
+	audio_info = prefs( ...
+				'transpose',0,'gen','sine','fs',11025, 'cutoff',0.4, ...
+				'attack',5,'decay',200,'release',5,varargin{:});
+
+	if isempty(device)
+		audio_info.lineout = lineout(1,audio_info.fs);
+	else
+		audio_info.lineout = device;
+		audio_info.fs = rate(device);
+	end
+
+	f=@(seq,onfinish)sonify_audio(audio_info,dur,seq,onfinish);
+end
+
+function player=sonify_audio(audio,dur,seq,onfinish)
+	disp('preparing audio signal.');
+	sched  = playaudio_async( ...
+		sonify(seq,dur,audio_opts(audio)), audio.lineout, ...
+		'defer',1,'its',2^31,'onfinish',@(a)onfinish());
+
+	player=cpfields({'stop','isrunning','atend','rewind','dispose'},...
+		sched, struct(...
+			'start',  @()sched.startat(nows+1), ...
+			'startq', @(q,o)sched.startat(o+quant(q,nows))));
+%			'wait',   sig.wait));
+
+	disp('audio playback ready to go.');
+end
+
+function opts=audio_opts(A)
+	c=@(t)round(A.fs*t/1000);
+	opts=prefs('bpm',60, 'transpose',A.transpose-69, ...
+		'env',envadr(c(A.attack),c(A.decay),c(A.release)), ...
+		'gen',A.gen,'bl_cutoff',A.cutoff,'fs',A.fs,'buffer',0.125);
+end
+