Stereo signal balancer


Equal power panning balances two channels. By panning from left (pos=0) to right (pos=1) you are decrementing the level of the left channel from 1 to 0 taking the square root of the linear scaling factor, while at the same time incrementing the level of the right channel from 0 to 1 using the same curve. In the center position (pos=0.5) this results in a level for both channels of sqrt(0.5) (~=0.707 or -3dB). The output of panstereo remains a stereo signal. This is a port of Supercollider's Balance2 ugen.


kpan is defined between 0 (left) and 1 (right) to make it coherent with opcodes like pan2, which also use this range. This differs from the original implementation in Supercollider, which uses a pan value of -1 to 1. Notice that even if kpan is a scalar (k-) variable, it is interpolated internaly to prevent discontinuities ("zipper" noise).


aoutL, aoutR panstereo aL, aR, kpan, klevel=1


  • aL: left input
  • aR: right input
  • kpan: panning position, between 0 (left) and 1 (right)
  • klevel: control rate level input (defaults to 1)


  • aoutL: left output
  • aoutR: right output

Execution Time

  • Performance



sr     = 44100
ksmps  = 64
nchnls = 2
0dbfs  = 1

opcode panst, aa, aak
  a0, a1, kpos xin
    aL,  aR  pan2 a0, kpos
    aL1, aR1 pan2 a1, kpos
    aL += aL1
    aR += aR1
    xout aL, aR

instr 1
  anoise = pinker() * 0.5
  aL = reson(anoise, 2000, 200, 2)
  aR = reson(anoise, 1000, 200, 2)
  ; aR oscili 0.1, 1000
  kpan = lfo:k(0.5, 0.1) + 0.5
  println "kpan: %.3f", kpan
  aL, aR panstereo aL, aR, kpan, 1
  outs aL, aR

instr 2
  anoise = pinker() * 0.5
  aL = reson(anoise, 2000, 10, 2)
  aR = reson(anoise, 400, 10, 2)
  ; aR oscili 0.1, 1000
  kpan invalue "pan"
  aL, aR panstereo aL, aR, kpan, 1
  outs aL, aR



i2 0.1 100

 <bgcolor mode="nobackground">
 <bsbObject type="BSBKnob" version="2">
  <mouseControl act="">continuous</mouseControl>
  <randomizable group="0">false</randomizable>

See also


Eduardo Moguillansky, 2021