«f0 sound detector» by redFrik

on 31 Dec'11 10:58 in

automatically record sound into buffers - with playback

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
//f0 sound detector - automatically record sound into buffers - with playback - originally written for av-programming udk class ws2011/12
(
z= 16;	//number of buffers in b
l= 2;	//length of buffers in seconds
x= false;	//mute recording
s.latency= 0.05;
s.waitForBoot{
	var detectorSynth, recorderSynths, responder;
	SynthDef(\f0SoundDetector, {|thresh= 0.075, time= 0.2|
		var input= SoundIn.ar;
		var off= DetectSilence.ar(input, thresh, time);
		var on= 1-off;				//invert
		var cnt= PulseCount.ar(on)%z+1;	//buffer index counter
		var changed= HPZ1.ar(on).abs>0;	//trigger
		SendTrig.ar(changed, 0, on*cnt);	//0= rec off, >0 rec start index
	}).add;
	SynthDef(\f0SoundRecorder, {|buf, t_trig= 0|
		var src= DelayN.ar(SoundIn.ar, 0.1, 0.1);	//compensate for detector latency
		RecordBuf.ar(src, buf, loop: 0, trigger: t_trig);
	}).add;
	SynthDef(\f0SoundPlayer, {|out= 0, buf, pan= 0, amp= 0.1, atk= 0.01, rel= 0.1, gate= 1, speed= 1|
		var env= EnvGen.ar(Env.asr(atk, amp, rel), gate, doneAction:2);
		var src= PlayBuf.ar(1, buf, speed, loop:1);
		Out.ar(out, Pan2.ar(src*env, pan));
	}).add;
	s.sync;
	b= {Buffer.alloc(s, s.sampleRate*l)}.dup(z);	//mono buffer
	s.sync;
	responder= OSCFunc({|m|
		var index= m[3].asInteger;
		if(x.not, {						//if not muted
			if(index>=1, {
				("recording"+index).postln;
				recorderSynths[index-1].set(\t_trig, 1);	//start sound recording
			}, {
				if(index==0, {
					"recording stopped".postln;
				});
			});
		});
	}, \tr, s.addr);
	detectorSynth= Synth(\f0SoundDetector);
	recorderSynths= b.collect{|x| Synth(\f0SoundRecorder, [\buf, x])};
	CmdPeriod.doOnce({b.do{|x| x.free}; responder.free});
	s.sync;
	Pdef(\pattern1).clear;
	Pdef(\pattern1).play(quant:1);
	Pdef(\pattern1, Pbind(
		\instrument, \f0SoundPlayer,
		\index, Pn(Pshuf((0..(z-1)), 4)),	//index selector, scramble every 4th time
		\buf, Pfunc({|ev| b[ev.index]}),
		\amp, 0.8,
		\dur, Pseq([0.25, 0.25, 0.5, 1], inf),
		\pan, Pwhite(-0.8, 0.8, inf),
		\speed, Prand([1, 1.2], inf)
	));
};
)

/*
x= true;	//mute recording (stop collecting more)
x= false;	//unmute
*/

/*
(	//rewite the playback as it is running
Pdef(\pattern1, Pbind(
	\instrument, \f0SoundPlayer,
	\index, Pseq((0..(z-1)), inf),	//index selector, played in order
	\buf, Pfunc({|ev| b[ev.index]}).trace,
	\amp, 0.8,
	\dur, Prand([0.25, 0.5, 1, 2, Pn(0.125, 4)], inf),
	\pan, Pwhite(-0.8, 0.8, inf),
	\speed, Prand([1, 1.25, 1.5, 1.75, 0.75, 0.5], inf)*Prand([1, -1], inf)	//back and forth
));
)
Pdef(\pattern1).stop
*/
descendants
«Re: f0 sound detector» by foxparse (private)
«dckvuraajy» by anonymous (private)
full graph
raw 2574 chars (focus & ctrl+a+c to copy)
reception
comments
tedorsc user 23 Jan'13 06:53

can easily imagine this as a core of an installation.

J. Simon van der Walt user 23 Aug'14 11:12

I don't get this bit: \index, Pn(Pshuf((0..(z-1)), 4)), \buf, Pfunc({|ev| b[ev.index]}),

Why not just: \buf, Pn(Pshuf((0..(z-1)), 4)),

Fredrik Olofsson user 25 Aug'14 16:29

true. that's left over code from older more advanced examples. so a bit more complicated than needed, but it's often good to have a separate index key like this so that you can do different things depending on which buffer the event is using (ie which 'index' key is currently selected).

consider this where the playback speed is mapped to which buffer that's playing...

¨¨¨ Pdef(\pattern1, Pbind( \instrument, \f0SoundPlayer, \index, Pn(Pshuf((0..(z-1)), 4)), //index selector, scramble every 4th time \buf, Pfunc({|ev| b[ev.index]}), \amp, 0.8, \dur, 0.25, \pan, Pwhite(-0.8, 0.8, inf), \speed, Pfunc({|ev| ev.index.postln.linexp(0, z-1, 0.5, 1.5)}) )); ´´´