This pretty much works:
(
var width = Window.screenBounds.width;
var channels = 2;
var wc = width * channels, wc2 = wc * 2;
var shift = (wc2 * 0.9).round(2).asInteger;
var index = 0;
d = FloatArray.newClear(wc2);
v = SoundFileView(nil, Rect(800, 200, 500, 400)).front
.alloc(width * 2, 2)
.gridOn_(false);
OSCdef(\recSummary, { |msg|
var chan = msg[3..];
chan = (chan ++ chan.neg).as(FloatArray);
d.overWrite(chan, index);
index = index + (channels * 2);
if(index >= wc2) {
// shift everything left
d.overWrite(d[shift..], 0);
d.overWrite(FloatArray.fill(shift, 0), wc2 - shift);
index = wc2 - shift;
defer { v.setData(d, startFrame: 0, channels: channels) };
} {
defer { v.set(index div: 2, chan) };
};
}, '/recSummary', s.addr);
a = {
var sig = SoundIn.ar(Array.series(channels, 0, 1));
var trig = Impulse.ar(32); // speed of updates
var sampleCount = Phasor.ar(trig, 1, 1, 10e34, 1);
// using FOS here as an integrator
// because Integrator's coefficient is control rate only
var runningSum = FOS.ar(sig.squared, DC.ar(1), DC.ar(0), Delay1.ar(trig) <= 0);
var rms = (runningSum / sampleCount).sqrt;
SendReply.ar(trig, '/recSummary', rms);
// RecordBuf.ar( /* you fill in this part */ );
sig * 0.1
}.play;
v.onClose = { a.release; OSCdef(\recSummary).free };
)
PS I think you absolutely do not want to ~b.loadToFloatArray
an hour’s worth of audio every half second. Really, don’t do this.
EDIT: Replaced the synth, after finding a trick to do the RMS at audio rate. Now it reports a higher (more accurate) level.
hjh