# Algorithm to pan audio

I'm looking for a way to pan the PCM audio I have. At the moment the audio is in a stereo format and I would like to pan it to the desired side (or more/less to a side).

I've recently figured out how to do mixing here so I guess it would be something similar (adding stuff to each other and such). What I was thinking is to add the audio data from one side to the other side.
For example if I were to pan hard left, I'd get the data from the right channel and add it to the left channel. I would then set the right channel to a constant value so that it would be silent.

Am I thinking in the right way or am I missing something obvious?

• Did you searched thoroughly? I.e. for that?
– jojek
Feb 23 '15 at 16:16
• I did. But I did not manage to find that. Thank you! Feb 24 '15 at 9:40

The basic technique to place a mono source in stereo is called constant power panning.

If you want to place a mono source at angle $$\theta$$ you can just use $$A_\mathrm{amp}$$ and $$B_\mathrm{amp}$$ as amplitudes for your channels:

$$A_\mathrm{amp} = \frac{\sqrt{2}}{2} (\cos{\theta} + \sin{\theta})$$

$$B_\mathrm{amp} = \frac{\sqrt{2}}{2} (\cos{\theta} - \sin{\theta})$$

Typically $$\theta$$ ranges from $$-45^{\circ}$$ to $$45^{\circ}$$ with $$0^{\circ}$$ being the center.

Hope, that helps.

Reference: Roads, Curtis (1996). The Computer Music Tutorial. Cambridge: The MIT Press, pp. 457–461.

You can put it in code directly. E.g. if you use Python and you have mono audio in a numpy array, you can convert it into stereo by a given angle like this:

def panner(x, angle):
"""
pan a mono audio source into stereo
x is a numpy array, angle is the angle in radiants
"""
left = np.sqrt(2)/2.0 * (np.cos(angle) - np.sin(angle)) * x
right = np.sqrt(2)/2.0 * (np.cos(angle) + np.sin(angle)) * x
return np.dstack((left,right))[0]


You can use it like panner(np.array([1,2,3]), np.radians(20)). (Of course [1,2,3] is a quite pointless audiobuffer.)

• I think I can give this a try. I don't really dee how I should create this in code but I'll see what I can do. Thanks! Feb 25 '15 at 12:33
• I have added some code for you. Feb 25 '15 at 13:25
• Does this work when the source is stereo? Sep 10 '16 at 2:35
• Not exactly sure about this, so this answer is rather a guess: I suppose it depends how the stereo panning has been done. If you deal with intensity stereophony, I think it will apply well. Just make the channels having their respective relative amplitudes. If you deal with other things, like time-of-arrival stereophony, it may not work at all. But you could try it out nevertheless. Sep 13 '16 at 22:00
• I just tried it for a mixer to pan stereo signals and it works perfectly, thanks a lot! For stereo you have to multiply the left sample with Bamp and the right sample with Aamp. When panned dead center the volume of the input will drop, you will only reach the input volume with hard left/right pans. Which I find quite useful because panning the signal won't make it peak.
– Tox
Jan 26 '20 at 17:40

I just wanted to point out that if you're planning to use these formulas in your code, you can get the exact same results with fewer calculations by using an angle $\theta$ between 0 and 90 degrees and simply calculating $A_{amp} = \sin(\theta)$ and $B_{amp} = \cos(\theta)$.

You may have run across these before (they seem to be more commonly referenced in my searches for Equal or Constant Power Panning), and thought the formulas above would give you a different curve. They sure do look different, but the curves are the same.

For a stereo file, if pan is not centered you just need to keep one channel same while attenuating the other side linearly.