Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SQ #70

Closed
GWBasic opened this issue Aug 13, 2023 · 12 comments · Fixed by #73
Closed

Support SQ #70

GWBasic opened this issue Aug 13, 2023 · 12 comments · Fixed by #73

Comments

@GWBasic
Copy link
Owner

GWBasic commented Aug 13, 2023

For SQ: https://en.wikipedia.org/wiki/Stereo_Quadraphonic
https://en.wikipedia.org/wiki/Matrix_decoder#SQ_matrix,_%22Stereo_Quadraphonic%22,_CBS_SQ_(4:2:4)

Rear left: Right is (3/4)pi ahead
Rear center: 135 degrees difference between channels, right is 135 degrees forward relative to left
Rear right: Right is (1/4)pi behind

https://www.desmos.com/calculator/zimzev6yla

l: left back in left total
e: right back in right total
k: left back in right total
r: right back in right total

Bottom functions:

Rear center in left total
Rear center in right total

@GWBasic
Copy link
Owner Author

GWBasic commented Aug 13, 2023

Wrote a program to demonstrate phase differences in the rear channels. Output:

right rear to left rear
left_amplitude: 0, right_aplitude: 1; phase_difference: -1.5707964, amplitude: 1.4
left_amplitude: 0.1, right_aplitude: 0.9; phase_difference: -1.7921108, amplitude: 1.267754
left_amplitude: 0.2, right_aplitude: 0.8; phase_difference: -2.0607538, amplitude: 1.1544696
left_amplitude: 0.3, right_aplitude: 0.7; phase_difference: -2.38058, amplitude: 1.0662081
left_amplitude: 0.4, right_aplitude: 0.6; phase_difference: -2.7468014, amplitude: 1.0095544
left_amplitude: 0.5, right_aplitude: 0.5; phase_difference: -3.1415927, amplitude: 0.98994946
left_amplitude: 0.6, right_aplitude: 0.4; phase_difference: 2.7468016, amplitude: 1.0095544
left_amplitude: 0.7, right_aplitude: 0.3; phase_difference: 2.38058, amplitude: 1.0662081
left_amplitude: 0.8, right_aplitude: 0.2; phase_difference: 2.0607538, amplitude: 1.1544696
left_amplitude: 0.9, right_aplitude: 0.1; phase_difference: 1.7921109, amplitude: 1.2677538
left_amplitude: 1, right_aplitude: 0; phase_difference: 1.5707961, amplitude: 1.4

Basically:

  • When a tone is isolated to the right rear speaker, the phase difference is -90 degrees.
  • When a tone is isolated to the left rear speaker, the phase difference is 90 degrees.
  • When a tone is centered in the rear speakers, the phase difference is 180/-180 degrees

Basically, -90 -> -180 pans from rear right to rear center, and 90 -> 180 pans from rear left to rear center.

What I don't understand is how to handle phases -90 -> 0 -> 90. Do they pan from rear right to front right (or rear left to front left?)

@GWBasic
Copy link
Owner Author

GWBasic commented Aug 13, 2023

Experimented with pans from front to back:

left front to left rear
left_rear_amplitude: 0, left_front_amplitude: 1; phase_difference: 3.1415925, amplitude: 1
left_rear_amplitude: 0.1, left_front_amplitude: 0.9; phase_difference: 3.063971, amplitude: 0.97271806
left_rear_amplitude: 0.2, left_front_amplitude: 0.8; phase_difference: 2.9683468, amplitude: 0.9521576
left_rear_amplitude: 0.3, left_front_amplitude: 0.7; phase_difference: 2.8501358, amplitude: 0.9408214
left_rear_amplitude: 0.4, left_front_amplitude: 0.6; phase_difference: 2.7049654, amplitude: 0.9421178
left_rear_amplitude: 0.5, left_front_amplitude: 0.5; phase_difference: 2.5308666, amplitude: 0.96032774
left_rear_amplitude: 0.6, left_front_amplitude: 0.4; phase_difference: 2.3318088, amplitude: 1
left_rear_amplitude: 0.7, left_front_amplitude: 0.3; phase_difference: 2.1201706, amplitude: 1.0645432
left_rear_amplitude: 0.8, left_front_amplitude: 0.2; phase_difference: 1.91382, amplitude: 1.1546428
left_rear_amplitude: 0.9, left_front_amplitude: 0.1; phase_difference: 1.728213, amplitude: 1.2678871
left_rear_amplitude: 1, left_front_amplitude: 0; phase_difference: 1.5707961, amplitude: 1.4

right front to right rear
right_rear_amplitude: 0, right_front_amplitude: 1; phase_difference: 0, amplitude: 1
right_rear_amplitude: 0.1, right_front_amplitude: 0.9; phase_difference: -0.07762151, amplitude: 0.97271806
right_rear_amplitude: 0.2, right_front_amplitude: 0.8; phase_difference: -0.17324567, amplitude: 0.9521576
right_rear_amplitude: 0.3, right_front_amplitude: 0.7; phase_difference: -0.29145682, amplitude: 0.9408214
right_rear_amplitude: 0.4, right_front_amplitude: 0.6; phase_difference: -0.43662715, amplitude: 0.9421178
right_rear_amplitude: 0.5, right_front_amplitude: 0.5; phase_difference: -0.610726, amplitude: 0.96032774
right_rear_amplitude: 0.6, right_front_amplitude: 0.4; phase_difference: -0.80978364, amplitude: 1
right_rear_amplitude: 0.7, right_front_amplitude: 0.3; phase_difference: -1.0214219, amplitude: 1.0645432
right_rear_amplitude: 0.8, right_front_amplitude: 0.2; phase_difference: -1.2277725, amplitude: 1.1546428
right_rear_amplitude: 0.9, right_front_amplitude: 0.1; phase_difference: -1.4133795, amplitude: 1.2678871
right_rear_amplitude: 1, right_front_amplitude: 0; phase_difference: -1.5707964, amplitude: 1.4

What's strange is how the phase difference works. I suspect that my subtraction was backwards in right front to right rear

@GWBasic
Copy link
Owner Author

GWBasic commented Aug 13, 2023

Basically, the way that SQ works (with regard to phase) is that:

  1. In phase starts at the front
  2. As the phase difference goes to -90, the sound is isolated in the right rear
  3. When the phase difference is -180, the sound is between the rear channels
  4. When the phase difference is 90, the sound is isolated in the left rear
  5. When the phase returns to 180, the sound is in the front

The fact that out-of-phase can go to the front is odd. Normal matrixing doesn't "care" about the sign of the phase; -90 and +90 are treated the same, as is -180 and +180.

I still need to understand the amplitude changes.

@GWBasic
Copy link
Owner Author

GWBasic commented Aug 27, 2023

Re-did the phase chart:

right front to right rear
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.1; phase_difference: -0.069886, amplitude: 1.0724471, left_total_amplitude: 0.07, right_total_amplitude: 1.002447
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.2; phase_difference: -0.13909595, amplitude: 1.1497524, left_total_amplitude: 0.14, right_total_amplitude: 1.0097524
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.3; phase_difference: -0.20699221, amplitude: 1.2318121, left_total_amplitude: 0.21000001, right_total_amplitude: 1.0218121
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.4; phase_difference: -0.2730087, amplitude: 1.3184603, left_total_amplitude: 0.28, right_total_amplitude: 1.0384604
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.5; phase_difference: -0.3366748, amplitude: 1.409481, left_total_amplitude: 0.35, right_total_amplitude: 1.059481
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.6; phase_difference: -0.397628, amplitude: 1.5046198, left_total_amplitude: 0.42000002, right_total_amplitude: 1.0846198
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.7; phase_difference: -0.45561564, amplitude: 1.6035978, left_total_amplitude: 0.48999998, right_total_amplitude: 1.1135978
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.8; phase_difference: -0.51048833, amplitude: 1.7061238, left_total_amplitude: 0.56, right_total_amplitude: 1.1461239
left_front: 0; right_front: 1; left_rear: 0; right_rear: 0.9; phase_difference: -0.5621867, amplitude: 1.8119053, left_total_amplitude: 0.63, right_total_amplitude: 1.1819053
left_front: 0; right_front: 1; left_rear: 0; right_rear: 1; phase_difference: -0.610726, amplitude: 1.9206555, left_total_amplitude: 0.7, right_total_amplitude: 1.2206556
left_front: 0; right_front: 0.9; left_rear: 0; right_rear: 1; phase_difference: -0.6610432, amplitude: 1.8401754, left_total_amplitude: 0.7, right_total_amplitude: 1.1401753
left_front: 0; right_front: 0.8; left_rear: 0; right_rear: 1; phase_difference: -0.71883, amplitude: 1.7630146, left_total_amplitude: 0.7, right_total_amplitude: 1.0630145
left_front: 0; right_front: 0.7; left_rear: 0; right_rear: 1; phase_difference: -0.7853982, amplitude: 1.6899494, left_total_amplitude: 0.7, right_total_amplitude: 0.9899494
left_front: 0; right_front: 0.6; left_rear: 0; right_rear: 1; phase_difference: -0.8621701, amplitude: 1.6219544, left_total_amplitude: 0.7, right_total_amplitude: 0.9219544
left_front: 0; right_front: 0.5; left_rear: 0; right_rear: 1; phase_difference: -0.95054686, amplitude: 1.5602324, left_total_amplitude: 0.7, right_total_amplitude: 0.8602325
left_front: 0; right_front: 0.4; left_rear: 0; right_rear: 1; phase_difference: -1.0516503, amplitude: 1.5062258, left_total_amplitude: 0.7, right_total_amplitude: 0.8062258
left_front: 0; right_front: 0.3; left_rear: 0; right_rear: 1; phase_difference: -1.1659045, amplitude: 1.4615773, left_total_amplitude: 0.7, right_total_amplitude: 0.7615773
left_front: 0; right_front: 0.2; left_rear: 0; right_rear: 1; phase_difference: -1.2924967, amplitude: 1.428011, left_total_amplitude: 0.7, right_total_amplitude: 0.72801095
left_front: 0; right_front: 0.1; left_rear: 0; right_rear: 1; phase_difference: -1.4288993, amplitude: 1.4071068, left_total_amplitude: 0.7, right_total_amplitude: 0.70710677

right rear to left rear
left_front: 0; right_front: 0; left_rear: 0.1; right_rear: 1; phase_difference: -1.7701336, amplitude: 1.4069825, left_total_amplitude: 0.7034913, right_total_amplitude: 0.7034913
left_front: 0; right_front: 0; left_rear: 0.2; right_rear: 1; phase_difference: -1.9655875, amplitude: 1.4277254, left_total_amplitude: 0.7138627, right_total_amplitude: 0.7138627
left_front: 0; right_front: 0; left_rear: 0.3; right_rear: 1; phase_difference: -2.15371, amplitude: 1.4616429, left_total_amplitude: 0.73082143, right_total_amplitude: 0.73082143
left_front: 0; right_front: 0; left_rear: 0.4; right_rear: 1; phase_difference: -2.331809, amplitude: 1.5078461, left_total_amplitude: 0.75392306, right_total_amplitude: 0.75392306
left_front: 0; right_front: 0; left_rear: 0.5; right_rear: 1; phase_difference: -2.4980917, amplitude: 1.5652475, left_total_amplitude: 0.78262377, right_total_amplitude: 0.78262377
left_front: 0; right_front: 0; left_rear: 0.6; right_rear: 1; phase_difference: -2.6516354, amplitude: 1.6326665, left_total_amplitude: 0.81633323, right_total_amplitude: 0.81633323
left_front: 0; right_front: 0; left_rear: 0.7; right_rear: 1; phase_difference: -2.7922482, amplitude: 1.7089177, left_total_amplitude: 0.85445887, right_total_amplitude: 0.85445887
left_front: 0; right_front: 0; left_rear: 0.8; right_rear: 1; phase_difference: -2.9202783, amplitude: 1.7928748, left_total_amplitude: 0.8964374, right_total_amplitude: 0.89643735
left_front: 0; right_front: 0; left_rear: 0.9; right_rear: 1; phase_difference: -3.0364265, amplitude: 1.8835074, left_total_amplitude: 0.9417537, right_total_amplitude: 0.9417537
left_front: 0; right_front: 0; left_rear: 1; right_rear: 1; phase_difference: -3.1415927, amplitude: 1.9798989, left_total_amplitude: 0.9899494, right_total_amplitude: 0.98994946
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.9; phase_difference: 3.0364265, amplitude: 1.8835073, left_total_amplitude: 0.9417536, right_total_amplitude: 0.9417536
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.8; phase_difference: 2.9202783, amplitude: 1.7928747, left_total_amplitude: 0.89643735, right_total_amplitude: 0.89643735
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.7; phase_difference: 2.7922482, amplitude: 1.7089176, left_total_amplitude: 0.85445887, right_total_amplitude: 0.8544588
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.6; phase_difference: 2.6516356, amplitude: 1.6326665, left_total_amplitude: 0.81633323, right_total_amplitude: 0.81633323
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.5; phase_difference: 2.4980917, amplitude: 1.5652475, left_total_amplitude: 0.78262377, right_total_amplitude: 0.78262377
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.4; phase_difference: 2.3318093, amplitude: 1.5078461, left_total_amplitude: 0.75392306, right_total_amplitude: 0.75392306
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.3; phase_difference: 2.15371, amplitude: 1.4616429, left_total_amplitude: 0.73082143, right_total_amplitude: 0.73082143
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.2; phase_difference: 1.9655876, amplitude: 1.4277254, left_total_amplitude: 0.7138627, right_total_amplitude: 0.7138627
left_front: 0; right_front: 0; left_rear: 1; right_rear: 0.1; phase_difference: 1.7701335, amplitude: 1.4069825, left_total_amplitude: 0.7034913, right_total_amplitude: 0.7034913

left front to left rear
left_front: 0.1; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 1.7126932, amplitude: 1.4071068, left_total_amplitude: 0.70710677, right_total_amplitude: 0.7
left_front: 0.2; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 1.8490958, amplitude: 1.428011, left_total_amplitude: 0.72801095, right_total_amplitude: 0.7
left_front: 0.3; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 1.975688, amplitude: 1.4615773, left_total_amplitude: 0.7615773, right_total_amplitude: 0.7
left_front: 0.4; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 2.0899422, amplitude: 1.5062258, left_total_amplitude: 0.8062258, right_total_amplitude: 0.7
left_front: 0.5; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 2.1910458, amplitude: 1.5602324, left_total_amplitude: 0.8602325, right_total_amplitude: 0.7
left_front: 0.6; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 2.2794223, amplitude: 1.6219544, left_total_amplitude: 0.9219544, right_total_amplitude: 0.7
left_front: 0.7; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 2.3561943, amplitude: 1.6899494, left_total_amplitude: 0.9899494, right_total_amplitude: 0.7
left_front: 0.8; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 2.4227624, amplitude: 1.7630146, left_total_amplitude: 1.0630145, right_total_amplitude: 0.7
left_front: 0.9; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 2.4805493, amplitude: 1.8401754, left_total_amplitude: 1.1401753, right_total_amplitude: 0.7
left_front: 1; right_front: 0; left_rear: 1; right_rear: 0; phase_difference: 2.5308666, amplitude: 1.9206555, left_total_amplitude: 1.2206556, right_total_amplitude: 0.7
left_front: 1; right_front: 0; left_rear: 0.9; right_rear: 0; phase_difference: 2.5794058, amplitude: 1.8119053, left_total_amplitude: 1.1819053, right_total_amplitude: 0.63
left_front: 1; right_front: 0; left_rear: 0.8; right_rear: 0; phase_difference: 2.6311042, amplitude: 1.7061238, left_total_amplitude: 1.1461239, right_total_amplitude: 0.56
left_front: 1; right_front: 0; left_rear: 0.7; right_rear: 0; phase_difference: 2.685977, amplitude: 1.6035978, left_total_amplitude: 1.1135978, right_total_amplitude: 0.48999998
left_front: 1; right_front: 0; left_rear: 0.6; right_rear: 0; phase_difference: 2.7439644, amplitude: 1.5046198, left_total_amplitude: 1.0846198, right_total_amplitude: 0.42000002
left_front: 1; right_front: 0; left_rear: 0.5; right_rear: 0; phase_difference: 2.8049178, amplitude: 1.409481, left_total_amplitude: 1.059481, right_total_amplitude: 0.35
left_front: 1; right_front: 0; left_rear: 0.4; right_rear: 0; phase_difference: 2.8685837, amplitude: 1.3184603, left_total_amplitude: 1.0384604, right_total_amplitude: 0.28
left_front: 1; right_front: 0; left_rear: 0.3; right_rear: 0; phase_difference: 2.9346004, amplitude: 1.2318121, left_total_amplitude: 1.0218121, right_total_amplitude: 0.21000001
left_front: 1; right_front: 0; left_rear: 0.2; right_rear: 0; phase_difference: 3.0024965, amplitude: 1.1497524, left_total_amplitude: 1.0097524, right_total_amplitude: 0.14
left_front: 1; right_front: 0; left_rear: 0.1; right_rear: 0; phase_difference: 3.0717065, amplitude: 1.0724471, left_total_amplitude: 1.002447, right_total_amplitude: 0.07

Basically, the problem is that phase <0 or >1.7126932 is somehow steered. But, phases 1.7126932 <-> 3.0364265 have two different positions. At that point, whichever amplitude is higher determines how to steer.

Weird

@GWBasic
Copy link
Owner Author

GWBasic commented Sep 3, 2023

Tried upmixing a sample SQ file that I found online.

One thing I realized: When a sound is isolated in the right or left speaker, the noise in the other channel results in a random phase in the other channel, and thus random steering of the sound. This will especially be clear when upmixing recordings from noisy sources, like vinyl.

What I've decided to do is add a sn setting as an option. When either channel is quieter than the quietest steered sound, the phase difference will be overridden to 0.

To keep this simple, the option will merely be the "minimum steered amplitude," expressed as an amplitude. It will default to 1/100th: 0.01.

Note: Sample formula to calculate loudness in SPL.
Amplitude: 1
Demoninator: 1/2^23
20 * Math.log10(1/0.00000011920929)

@GWBasic
Copy link
Owner Author

GWBasic commented Sep 16, 2023

Marked experimental: At the time I don't fully understand the issues with SQ.

@GWBasic GWBasic linked a pull request Sep 16, 2023 that will close this issue
@GWBasic
Copy link
Owner Author

GWBasic commented Nov 19, 2023

It appears that:

  • When the amplitudes are approximately equal, the pan is to the rear. Phase difference should be used to pan between the two rear speakers
  • If left is louder, the pan is to the left. Phase difference should be used to steer between front and back
  • If right is louder, the pan is to the right. Phase difference should be used to steer between front and back

@GWBasic GWBasic reopened this Nov 19, 2023
@GWBasic
Copy link
Owner Author

GWBasic commented Nov 26, 2023

I suspect that the test tones that I've been working with are "mono compatible" instead of the default SQ test tones. (See how there are two different matrixes described at https://en.wikipedia.org/wiki/Stereo_Quadraphonic#Usage)

I'm now going to generate my own test tones according to both matrixes, and then support both matrixes.

@GWBasic
Copy link
Owner Author

GWBasic commented Nov 27, 2023

I wrote my own test tone generator, but I'm not sure if the tones are generated correctly.

Right-mid is played in both front speakers. Right rear comes out the front speaker.

I will try an alternate approach to the test tone generator.

@GWBasic
Copy link
Owner Author

GWBasic commented Dec 10, 2023

The problems are that, in #84:

  • left_to_right is always 0 in panner_and_writer.rs
  • panner_and_writer.rs only looks at left_to_right in 5.1. It ignores it in quad

This is blocked on fixing #84

@GWBasic
Copy link
Owner Author

GWBasic commented Feb 4, 2024

Switched back to the phase-based technique.

Currently I need to add some amplitude adjustments based on position.

@GWBasic
Copy link
Owner Author

GWBasic commented Feb 4, 2024

Currently left in an experimental state, if this is fixed, it will be in #87

@GWBasic GWBasic closed this as completed Feb 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant