Monitoring Audio Bus Volume

Hi,

For GUI monitoring of audio buses I use an old class by Yvan Volochine, modified a little here to work with current SC.

Here is the class, YVBusMeter:

// original code by Yvan Volochine
// fixes for Swing and multichannel by Marije Baalman
// fixes for SC 3.13 by blindmanonacid

// TODO:
// - add a decay to the vu-s (Amplitude.kr's release param?) -> thx Blackrain
// - separate GUI from this code

YVBusMeter {
	var <meterGui, s, w;
	var <name, <coord;
	var <bus;
	var <responder, <meterSynth, <defName;

	*new { |win, bus, coordinates|
		if (win.notNil and: {bus.notNil}, {
			^super.new.init(win, bus, coordinates)
		}, {
			Error(" args").throw
		})
	}

	free {
		try{
			responder.free;
			meterSynth.free;
		}
	}

	init { |win, b, coordinates|
		s      = Server.default;
		coord  = coordinates ?? [10, 10, 10, 160];
		w      = win;
		//name   = ("vu_" ++ Date.localtime.stamp).asSymbol;
		name   = ("/vu_" ++ UniqueID.next).asSymbol;
		bus   = b;
		this.drawMeter;
		CmdPeriod.doOnce{ this.free };
	}


	drawMeter {
		this.addSynth;
		meterGui = LevelIndicator(w, Rect(*coord));
		meterGui.drawsPeak = true;
		this.addOscResponder;
	}

	addOscResponder {

		responder = OSCFunc({ arg msg;
			{
				if(meterGui.notNil, {
					meterGui.value_(msg[3].ampdb.linlin(-40, 0, 0, 1))
					    .peakLevel_(msg[4].ampdb.linlin(-40, 0, 0, 1))
					    .warning_(0.75)
					    .critical_(0.95)
				})
			}.defer; // FIXME
		}, name, s.addr).add;

		w.onClose_({ this.free })
	}

	addSynth {
		s.waitForBoot {
			defName = "forMeter_"++ UniqueID.next;
			SynthDef( defName, {
				|busid=0|
				var imp, delimp, snd, id;
				snd    = In.ar(busid, bus.numChannels);
				imp    = Impulse.kr(10); // change polling interval
				delimp = Delay1.kr(imp);
				// measure rms and Peak
				SendReply.kr(
					imp,
					name,
					[Amplitude.kr(snd, 0.01, 0.5), K2A.ar(Peak.ar(snd, delimp).lag(0, 3))]
				)
			}).send(s);
			s.sync;
			meterSynth = Synth.new( defName, [\busid, bus.index], s, \addToTail);
		}
	}

}

And here is some example code:


(
w= Window("busmeter", Rect(0, 0, 200, 400));
g= Bus.audio(s, 1);
YVBusMeter.new(w, g, [20, 20, 160, 360]); // (window, Bus, [left, top, hsize, vsize])
w.front;
)
b= Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
(
x = SynthDef(\help_Buffer, { arg out = 0, bufnum;
	Out.ar( [0, 1, g],
        PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 1)
    )
}).play(s,[\bufnum, b]);
)
x.free; b.free;
1 Like