View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

MixingBoard

Home   How To   Code Pool   Public Library   Theory   Events



A dynamically allocated graphic mixing board for SC3 Server. MixerChannels allow programmatic control of level and panning and can be used as simple audio processors without having to put them in a MixingBoard. MixerSends (pre- and post-fader) allow signal routing comparable to DAW software. The graphic MixingBoard allows realtime control of level, panning, audio routing, and dynamic creation/destruction of sends from the gui.

Installation instructions are in the tarball. Class files, help files and synthdefs are provided. Below is copied the code example demonstrating what this puppy can do.

MixingBoard.tar

	// mixer example

s = Server.internal; s.boot;

// wait for server to boot, then execute all the following code chunks

(
z = MixerChannel.new("Master", s, 2, 2);	// master fader -- created first to illustrate
									// automatic correction of order of execution

c = 6;	// 6 channels

	// each channel is 1 -> 2, ready for postsends; note random panning
	// outbus:z directs output to master fader; order of execution is corrected at this time
m = Array.fill(c, { arg i; MixerChannel.new(i.asString, s, 1, 2, 
    level: 0, pan: 1.0.rand2, postSendReady:true, outbus:z) });

n = MixerChannel.new("comb", s, 2, 2, outbus:z);	// mixer for comb filter

	// make mixingboard with default skin
	// note that last arguments can be a mixture of single MixerChannels or collections
b = MixingBoard.new("mixer demo", nil, m, n, z);
)

b.skin.layout_(\horizontal);	// completely redraws with new layout
b.skin.layout_(\vertical);

	// use color to highlight master fader
z.mcgui.color1_(Color.blue).color2_(Color.red);

(
i = Instr([\test, \pulser], {
    arg s_freq = 440, p_freq = 1;
    var trig, env;
    trig = Dust.kr(p_freq);
    env = EnvGen.ar(Env.perc(0.01, 0.5), trig);
    Pulse.ar(s_freq, 0.25, env);
}, #[[20, 20000, \exponential, 0.1], [0.01, 50, \linear, 0.01]]);

	// make patches to play different pitches with different repeats
p = Array.fill(c, { Patch.new(i, [(50.0.rand + 20).midicps, 3.0.rand + 0.1]) });

m.do({ arg mm, i; mm.play(p.at(i)) });	// play patches on corresponding mixerchannels
	// you won't hear anything b/c the levels are 0, but the ugens on the server should jump

SynthDef.new("delaytest2", {
    arg inbus, outbus;
    var combfreq;
    combfreq = SinOsc.ar(0.2, 0, 300, 500);	// LFO
    Out.ar(outbus, CombN.ar(In.ar(inbus, 2), 2,
        [combfreq.reciprocal, (combfreq+1).reciprocal]));
}).load(s);

	// standard synthdef names can be played by mixerchannel, too
	// array for arguments may be omitted!
	// defer allows time for synthdef to be loaded
{ n.play("delaytest2", \inbus, n.inbus.index); nil }.defer(0.5);
	// still no sound b/c nothing's playing to delaytest
)

// watch the mixingboard as the sends register in the gui
(
	// create post-fader sends
	// also insures correct order of execution
x = Array.fill(c, { arg i; MixerPostSend.new(m.at(i), n, 0) });
)

// schedule level increases for mixers and sends
(
Routine.new({
    var index, i;
    index = Array.series(c, 0, 1);	// indices to mixerchannels
    { index.size > 0 }.while({
	        i = index.choose;
	        m.at(i).levelTo(0.4, 10.0.rand + 8);	// fade in over random time
	        index.remove(i);
	        (5.0.rand + 2.0).yield;		// wait
    });
    nil.yield;
}).play;

Routine.new({
    var index, i;
    12.yield;		// wait 12 seconds before starting
    index = Array.series(c, 0, 1);	// indices to mixerchannels
    { index.size > 0 }.while({
	        i = index.choose;
	        x.at(i).levelTo(0.4, 10.0.rand + 8);	// fade in over random time
	        index.remove(i);
	        (5.0.rand + 2.0).yield;		// wait
    });
    nil.yield;
}).play;
)

	// turn all channels off and cycle thru, one by one
	// this proves that all sends are working and going thru the comb filter
(
m.do({ arg mm; mm.level = 0 });

Routine.new({
    m.do({
	        arg mm;
	        mm.level = 0.5;
	        2.wait;
	        mm.level = 0;
    });
    nil.yield;
}).play;
)

// use the board to play with panning and level
// changing the master fader level adjusts all sound, as you'd expect
// try turning comb all the way off--unprocessed sound continues
// adjust send level faders to change comb response for the individual channels

// now you can stop everything using the mixingboard object (or by closing the board window)
// watch the ugens go to zero!
b.free;