Demand.kr(trigger, reset, demand rate Ugens)
Extrae elementos de uno o varios arrays con cierta periodicidad y con cierto orden.

La clase Demand trabaja siempre junto con otra clase de tipo demand rate. Estos Ugens se escriben siempre empezando con la letra D mayúscula. Por ejemplo Dbrown, Dgeom, Dseries, etc. Los demand rate Ugens definen los elementos de un array y la manera en que serán entregados cuando el Demand lo solicite. Esta entrega puede ser de varias formas como en secuencia, aleatoriamente, siguiendo un patrón aritmético o geométrico, etc. Demand puede trabajar con kr o con ar cuidando que el triger si es un Ugen sea del mismo rate (e.g. Demand.ar(Impulse.ar,..)

Los argumentos de Demand son:

trigger =  Puede ser una señal o un argumento que se modifica desde afuera. Cuando el trigger cambia de no positivo a positivo se extrae un elemento.

reset = Reinicia los Demand Ugens de modo que el siguiente elemento que se extraiga sea el primero de cada Ugen

Demand Ugens = Puede ser cualquiera de los demand rate Ugens como Dseq o Drand. Estos Ugens contienen los arrays de donde el Demand extrae los elementos. Cada Ugen se comporta de manera distinta el entregar los elementos de los arrays.

Veamos algunos demand rate Ugens:

Dseq(array, length)
Entrega en orden los elementos de un array un determinado número de veces.

array = array con los elementos en orden que se quieren entregar al Demand.

length = numero de repeticiones. Una repetición es la lectura de todo el array.

Ejemplo 1

Aqui creamos dos argumentos: t_trig para pedir un elemento nuevo del array y t_reset para reiniciar el Dseq. Es necesario usar este tipo de argumentos antecedidos por t_ para que funcione. En el tercer argumento del Demand ponemos un Dseq que nos entregará en secuencia los elementos de su array infinitas veces. El Demand está asignado a la variable freq que hace las veces de frecuencia para un SinOsc.

(
SynthDef(\Dseq, {|t_trig=1, t_reset=0, gate=1|
				 var freq, sig, env;
				 freq=Demand.kr(t_trig,t_reset,Dseq([0,2,4,6,7,9,11].midiratio,inf));
				 sig=SinOsc.ar(freq*300);
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

d=Synth(\Dseq)
d.set(\t_trig, 1)
d.set(\t_reset, 1)
d.set(\gate, 0)

Ejemplo 2

Ahora usamos una señal como trigger. La señal es un Impulse que pedirá un elemento al Dseq 2 veces por segundo. Dseq entregará los elementos de su array una sola vez.

(
SynthDef(\Dseq, {|gate=1|
				 var freq, sig, env;
				 freq=Demand.kr(Impulse.kr(7),0,Dseq([0,2,4,6,7,9,11].midiratio,1));
				 sig=SinOsc.ar(freq*300);
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

d=Synth(\Dseq)
d.set(\gate, 0)

Drand(array, length)
Entrega en orden aleatorio los elementos de un array un determinado número de veces.

array = array con los elementos  que se quieren entregar al Demand.

length = numero de elementos del array que se entregarán. Diferente de Dseq donde se cuentan las veces que se entrega todos los elementos. En Drand se cuenta elemento por elemento.

Ejemplo 3

Igual que el ejemplo 1 pero con Drand. Aqui el uso del t_reset es irrelevante ya que, al ser aleatorio el orden, no hay un primer elemento.

(
SynthDef(\Drand, {|t_trig=1, t_reset=0, gate=1|
				 var freq, sig, env;
				 freq=Demand.kr(t_trig,t_reset,Drand([0,2,4,6,7,9,11].midiratio,inf));
				 sig=SinOsc.ar(freq*300);
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

d=Synth(\Drand)
d.set(\t_trig, 1)
d.set(\t_reset, 1)
d.set(\gate, 0)

Ejemplo 4

Ahora usamos una señal como trigger. La señal es un Impulse que pedirá un elemento al Dseq 2 veces por segundo. Dseq entregará los elementos de su array una sola vez.

(
SynthDef(\Drand, {|gate=1|
				 var freq, sig, env;
				 freq=Demand.kr(Impulse.kr(2),0,Drand([0,2,4,6,7,9,11].midiratio,7));
				 sig=SinOsc.ar(freq*300);
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

d=Synth(\Drand)
d.set(\gate, 0)

Ejemplo 5

Se pueden poner otros demand rate Ugens como elementos del array de un demand rate Ugen

(
SynthDef(\DseqDseqDrand, {|gate=1|
				 var freq, sig, env;
				 freq=Demand.kr(Impulse.kr(8),0,Dseq([Dseq([1,0,1,2,1,0,1].midiratio,1), Drand												([12,9,-4,-9].midiratio,1)],inf));
				 sig=Blip.ar(freq*200, 2);
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

d=Synth(\DseqDseqDrand)
d.set(\gate, 0)

(
SynthDef(\DseqDseqDrand2, {|gate=1|
				 var freq, sig, env,armonicos;
				 freq=Demand.kr(Impulse.kr(8),0,Dseq([Dseq([1,0,1,2,1,0,1].midiratio,1), Drand([12,9,-4,-9].midiratio,1)],inf));
				 armonicos=Demand.kr(Impulse.kr(10),0,Dseq([4,2,3,4,5,6,7,8,9,10,11,12,13].pyramid,inf));
				 sig=Blip.ar(freq*200, armonicos);
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

z=Synth(\DseqDseqDrand2)
z.set(\gate,0)

///ejemplo del help de Demand
1*0.4
(
{
	var trig, seq;
	trig = Impulse.kr(12);
	seq = Drand([
		Dseq([4,1,0,2,2,0,1,2]),
		Dseq([1,0,0,0,2,1]),
		Dseq([4,1,0,1,1]),
		Dseq([4,4,0,0])], inf);
	trig = Demand.kr(trig, 0, seq * 0.4) * trig;
	{LPF.ar(PinkNoise.ar, 12000)}.dup * Decay.kr(trig, 0.5);
}.play;
)

Dswitch(array, index)
Posee un array de donde puede escoger a voluntad un elemento y mandarlo al Demand.

array = array con los elementos que se pueden entregar al Demand. Pueden ser números, demand rate Ugens o alguna otra Clase.

index = Indice del elemento del array que queremos entregar al Demand.

Ejemplo 6

Usamos un Dswitch para escoger diferentes patrones numéricos y asignarlos a la frecuencia de un Pulse. Creamos el argumento switch dentro del Synth para poder escoger el índice del array del Dswitch.

(
SynthDef(\Dswitch1, {|gate=1, switch=0|
				 var freq, sig, env;
				 freq=Demand.kr(Impulse.kr(8),0,Dswitch1([Dseq([0,2,4].midiratio,inf), Dseq([0,2,3].midiratio, inf), 1, MouseY.kr(2,1)], switch));
				 sig=Pulse.ar(freq*300)!2;
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

d=Synth(\Dswitch1)
d.set(\switch, 0) // mayor
d.set(\switch, 1) // menor
d.set(\switch, 2) // tonica
d.set(\switch, 3) // glissando
d.set(\gate, 0)

Ejemplo 7

Se puede utilizar el Demand con audio rate para generar ondas. Recuerden que el trigger debe tener audio rate también

Server.default = Server.internal = s
s.boot

Array.series(100,0,0.1).sin.plot

(
SynthDef(\caucasico, {|gate=1, freq=7033|
				 var sig, env;
				 sig=Demand.ar(Impulse.ar(freq), 0, Dseq(Array.series(600,0,0.1).sin,inf));
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

d=Synth(\caucasico)
d.set(\gate, 0)
d.plot

s.scope

(
SynthDef(\caucasico, {|gate=1, freq=2303|
				 var sig, env;
				 sig=Demand.ar(Impulse.ar(freq), 0, Dseq([0,-1,0.4,0.6,0.9,0.1,1,0.5],inf));
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

(
SynthDef(\caucasico, {|gate=1, freq=2303|
				 var sig, env;
				 sig=Demand.ar(Impulse.ar(freq), 0, Dseq(Array.geom(10,1,0.28).reverse.mirror,inf));
				 env=EnvGen.kr(Env.asr(0.01,1,1),gate,doneAction:2);
				 Out.ar(0,sig*env);
				 }).send(s)
)

q=Synth(\caucasico)
s.scope

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

s.boot

s.sendMsg("/b_allocRead",0,"sounds/perform.wav")
s.sendMsg("/b_allocRead",1,"sounds/timb.wav")
s.sendMsg("/b_allocRead",2,"sounds/holarescate.wav")

(
	SynthDef("os", {| gate=1, rate=1, beat=4|
		var sig, env,altura, seq, ritmo, seqr,buf,seqbuf,seqrvol,ritmovol;
			
			seqbuf=Drand([1,2,0], inf);
			 buf=Demand.ar(Impulse.ar(beat),0,seqbuf);
			 
			      seqr=Drand([1,2], inf);
					  ritmo=Demand.ar(Impulse.ar(beat),0,seqr);
					  
					  seqrvol=Drand([1,0,1,0,1,1,1,1,1], inf);
					  ritmovol=Demand.ar(Impulse.ar(beat),0,seqrvol);
					  
					  sig=PlayBuf.ar(1,buf,1,Impulse.ar(beat*ritmo),LFNoise2.kr(10,58200,59400));
					    sig=sig+RLPF.ar(sig,500,0.8);
					  
					      sig=sig*ritmovol;
					        env=EnvGen.ar(Env.adsr(0,0,1,0), gate, doneAction:2);
					         
					          Out.ar(0, sig*env*1);
					  }).send(s)
);

Synth(\os)