// Coded by astrobuf.
//
// A stereo panner
//
//  use 3dB law (sin/cos taper) constant power across the pan
//      6dB law (linear taper) equal volume across the pan in mono
//      4.5dB law is a compromise
//
// 
// Because as of Reaper 3.75 its pan is wonky.
// 
//  Reaper 3.x pan tapers feature request
//  - discussion:  http://forum.cockos.com/showthread.php?p=434029
//  - feature request:  http://forum.cockos.com/project.php?issueid=1860
//
//  - Reaper 4 prerelease discussion: 
//    http://forum.cockos.com/showthread.php?t=77296
//    http://forum.cockos.com/showthread.php?t=71905
//     http://forum.cockos.com/showthread.php?t=69730
//
//
// This pan is compatible with both stereo and mono sources. On 
// stereo sources, it skews and smoothly crushes the stereo field till
// on a hard pan the signal is equally mixed on one channel.
//
// Good for stereo or mono mixdowns.


desc:Skew Pan

slider1:0<-90,90,1>Pan
slider2:3.52183<0,6,0.00390625>Pan Law

@init

G11 = 1.0; G12 = 0.0;
G21 = 0.0; G22 = 1.0;


@slider

// map pan to radians
pan = -slider1 * $pi/180;

// map dB to scalar
dBgain = 10^((6-slider2)/20);
alpha = (dBgain-1)/(sqrt(2)-1); // Alpha in [0, 1]
gain = 1 + alpha*(sqrt(1+ (tan(pan))^2) - 1);
gain = 1/gain;

// Crush stereo width.
width = 1 - abs(tan(pan));

// Skew matrix
R11 = gain;             R12 = 0;
R21 = gain*tan(pan);    R22 = gain*width;


@block
// Smooth coefficients to avoid zipper noise during a sweep.
d11 = (R11 - G11) / samplesblock;
d12 = (R12 - G12) / samplesblock;
d21 = (R21 - G21) / samplesblock;
d22 = (R22 - G22) / samplesblock;

@sample

// Smooth the coefficients.
G11 += d11;
G12 += d12;
G21 += d21;
G22 += d22;

// M/S Conversion.
M = (spl0 + spl1) / 2;
S = (spl0 - spl1) / 2;

// Transform.
Mnew = M*G11 + S*G12;
Snew = M*G21 + S*G22;

// Convert back to L/R.
spl0 = Mnew + Snew;
spl1 = Mnew - Snew;

