PanAz levels on full width

Hello everyone,
I’m using PanAz to spread a signal all over an 8 channels system, and I’m struggling to get every channel to have the same signal level as the others.
From this little simple SynthDef:

    (
    SynthDef(\example,{arg pos = 0, width = 8, orientation = 0.5;
    			var sig;
    	sig = SinOsc.ar();
    	sig = PanAz.ar(8,sig, pos, 1, width, orientation);
    	Out.ar(0, sig);
    }).add;
    )
    y = Synth(\example);

I can see that the levels are lowered gradually when moving away from the channels 0-1 (see also the meter pic):
meters
How do I obtain all the channels to have the same signal level?
Thank you so much

Hey, I got curious and looked around in source files:
It looks like PanAz is unable to spread a signal equally to all channels. It is actually only able to spread it equally over two channels. Already from width=3 the underlying “sine” distribution becomes evident.

I wrote a function that basically compensates this sine curve, try it out:

Ndef(\testAz){
	var numOutputs = 8;
	var orientation = 0.5;
	var sin = SinOsc.ar();
	var pos = MouseX.kr(0,2);
	var width = MouseY.kr(1,8);
	
	var compensation = numOutputs.collect{|i|
		var chanpos = pos/2*numOutputs + (width/2) + orientation;
		var range = numOutputs/width;
		chanpos = (chanpos - i) / width;
		chanpos = chanpos - (range * floor(chanpos/range));
		Select.kr(chanpos>1,[
			sin(pi*chanpos).reciprocal,
			0
		])
	};
	
	PanAz.ar(numOutputs,sin,pos,1,width,orientation)*compensation.poll(1)

}.play

image
Compensation could be “compensated” as well (like 0.5*compensation) to retain the sine shape as much as you want.
It looks so hacky to me that I feel like I’m doing something stupid…
Maybe someone has done something like this already in an extension?

3 Likes

Thank you @elgiano for this hacky solution :slight_smile:
I may know why this is sound stupid to you, that’s because basically… it is!!
I mean, not your solution of course, but my will to use the PanAz UGen to actually spread the same mono signal to 8 ch speakers, it makes no sense at all!
I can obtain the exact same result with less effort duplicating 8 times the signal:

(
SynthDef(\example,{arg pos = 0, width = 8, orientation = 0.5;
var sig;
sig = SinOsc.ar();
Out.ar(0, sig.dup(8));
}).add;
)
y = Synth(\example);

Your answer was very cool and informative for the sake of curiosity and hacking things, but I think that in the end if anyone would like to have a mono signal spreaded to 8 ch, he/she better use .dup(8) or something similar :sweat_smile:

Sure you can dup the signal! Then you can’t “focus” it anymore to one channel or pan it around :frowning:, but if a static 8 channel duplication of your signal is what you want, of course just dup it!

Happy to have been helpful somehow :slight_smile:

Interesting, I know the idea of the sinusoidal scaling is to have equal power as you pan across a stereo pair - haven’t worked through what that means when the signal is being spread between more than 2 though… (assuming a circular orientation)

maybe a good time to break out MatLab and Faust…