Designing Sound in SuperCollider/DTMF

26: DTMF dialling tones

edit
(
// This data structure (like a "hashtable" or "associative array" in other languages) 
// maps from a phone key to a pair of frequencies in Hz. 
// We can push these frequencies to a synth.
~tbl = IdentityDictionary[
	$1 -> [[697, 1209]],
	$2 -> [[770, 1209]],
	$3 -> [[852, 1209]],
	$4 -> [[697, 1336]],
	$5 -> [[770, 1336]],
	$6 -> [[852, 1336]],
	$7 -> [[697, 1477]],
	$8 -> [[770, 1477]],
	$9 -> [[852, 1477]],
	$* -> [[697, 1633]],
	$0 -> [[770, 1633]],
	$# -> [[852, 1633]],
	$A -> [[941, 1209]],
	$B -> [[941, 1336]],
	$C -> [[941, 1477]],
	$D -> [[941, 1633]]
];

// Here we define a SynthDef which plays a single "number" at a time.
// Note that our strategy here is a bit different from the PD code in the book:
//   there, a single pair of sine-wave oscillators was re-used for each number,
//   whereas here, we create (and later free) an individual synth for each number.
SynthDef(\dtmf, {|freq=#[770, 1633], out=0, amp=0.2, gate=1|
	var son, env;
	son = SinOsc.ar(freq, 0, amp).sum;
	env = EnvGen.ar(Env.asr(0.001, 1, 0.001), gate, doneAction: 2);
	Out.ar(out, Pan2.ar(son * env * amp));
}).add;
)

// Check that it works:
x = Synth(\dtmf) // create
x.set(\gate, 0)  // free

(
// This pattern generates a random "phone number" and dials it
Pbind(
	\instrument, \dtmf,
	\dur, 0.2, // or for more "human" timing, try   Pwhite(0.2, 0.5, inf)
	\sustain, 0.15,
	\amp, 0.3,
	\freq, Prand(~tbl.asArray, 13)
).play;
)

(
// You could even dial a specific number:
Pbind(
	\instrument, \dtmf,
	\dur, 0.2, // or for more "human" timing, try   Pwhite(0.2, 0.5, inf)
	\sustain, 0.15,
	\amp, 0.3,
	\freq, Pseq("012827743866".collectAs({|digit| ~tbl[digit] }, Array))
).play;
)