Asymmetrical Stereo Widener

Dear all,

I have an unusual idea to manipulate the stereo soundstage width of selected audio tracks in “asymmetrical” way → I would like to extend the left side of the soundstage more strongly then the right one. To give you a better impression why do I need it, I have prepared a picture (see attached picture).

I am sitting in the car on the driver seat (on the left side), but the center of the soundstage is either located in the center of the dashboard (see attached picture Var.C → left and right half of the soundstage is distributed symmetrically), or it is panned left above the steering wheel (Var.B → left part of the soundstage is squeezed and the right side is stretched).
I prefer the second option (Var.B) and try to compensate the squeezing on the left side through asymmetrical widening of the soundstage → extending the left side (as showed on the picture).

I am a absolute beginner in Audacity, but I found already something, what in my opinion, could be used as a base/starting point for my desire. 
I found the following Nyquest plug-in „Stereo Widener“ from David R.Sky

It offers three parameters, which control the widening of the soundstage:

  1. Inverted signal volume: [-48 dB - -6 dB, default -18 dB]
  2. Pan position: [0 (center) to -100 (opposite channel), default 0]
  3. Time offset: [0 - 20 ms, default 0] - applying an offset can enhance the illusion.

My idea is:

A) (the optimum solution) request the parameter 1. and 2. individually fort he left and right chanel, and process them individually according to the specified parameters

B) (medium solution) request an additional parameter 4. “Asymmetry factor” (e.g. from -5=L to +5=R), which will be considered during the processing of the plug-in

C) (simplified solution) implement an fixed „Asymmetry factor” directly in the plugin code (I would try to get the right value through testing)

Unfortunately I am not a programmer and I am not able to modify David’s code myself, but I have a “suspicion” that it must be done somewhere in the Stereo-Butterfly-Function section of the code or few rows further.

here is the code:

;nyquist plug-in
;version 1
;type process
;name “Stereo Widener…”
;action “Widening stereo audio…”
;info “by David R. Sky\nReleased under terms of GNU Public License\n-Pan: -100=opposite channel, 0=center”

;control vol “Inverted signal volume - db” int “” -18 -48 -6
;control p “Pan position” int “” 0 -100 0
;control offset “Time offset - ms” int “” 0 0 20

#| Stereo Widener by David R. Sky, October 18, 2004
Updated March 19, 2006
Thanks to David Walsh and Monty of the Audacity-users list
for discussion and explanation of how to widen stereo.

Should work properly for both North American and European
audacity-Nyquist -
N American uses . for decimal
European uses , for decimal
so calculations are done using floating whole numbers
(see two setf statements)

A stereo widener creates the illusion that your speakers are
further apart than they really are. Stereo widening results depend
on distance of your speakers from each other, the plug-in settings,
and your location in relation to the speakers.

This stereo widener works by inverting both left and right channels
of stereo audio to some degree, then panning those inverted signals
somewhere between the center pan position and the opposite channel.
A time offset of up to 20ms can be applied to enhance the illusion.


  1. Inverted signal volume
    From -48db (minimum volume) to -6db (maximum volume), default

  2. Pan position
    From 0 (center) to -100 (opposite channel), default 0.

  3. Time offset
    From 0 to 20ms, default 0ms.

; Stereo Butterfly function - used to
; change the width of the stereo field.
(defun butterfly (sound width)
(sum (mult (aref sound 0) (sum width 1) 0.5)
(mult (aref sound 1) (sum width -1) -0.5))
(sum (mult (aref sound 1) (sum width 1) 0.5)
(mult (aref sound 0) (sum width -1) -0.5))))

; convert arguments to floating values
(setf offset (/ (float offset) (float 1000)))
(setf p (/ (float p) (float 100)))

; applying stereo widener
(if (arrayp s)
(sim (cue s)
(at-abs offset
(cue (butterfly (mult -1 (db-to-linear vol) s) p))))

(format nil “You must apply the stereo widener to stereo audio.”)

Is anybody of you willing to support my crazy idea and to adopt the code to the specified needs?

BTW: any better solution or suggestion are welcome

Thanks in advance

The “Channel Mixer” plug-in allows you to set the left/right channels independently:

Thank you so much for your quick response!
I have looked on that and I guess I can add an 16th option:

(1 (list 50 50 50 50)) ; Average
(2 (list 100 0 100 0)) ; Both Left
(3 (list 0 100 0 100)) ; Both Right
(4 (list 70 30 30 70)) ; Extra Narrow
(5 (list 85 15 15 85)) ; Narrow Stereo
(6 (list 100 -30 -30 100)) ; Wide Stereo
(7 (list 100 -60 -60 100)) ; Extra Wide
(8 (list 50 50 -50 50)) ; Centre to Left
(9 (list 50 -50 50 50)) ; Centre to Right
(10 (list 0 100 100 0)) ; Swap Left/Right
(11 (list 100 -100 -100 100)) ; Vocal Remover L/R invert
(12 (list 100 -100 100 -100)) ; Vocal Remover mono
(13 (list -100 0 0 100)) ; Invert Left
(14 (list 100 0 0 -100)) ; Invert Right
(15 (list 50 50 50 -50)) ; Mid-Side Decode
(16 (list 100 -60 0 100)) ; Stretched to Left

and check/play with the value (16 (list 100 -60 0 100))

If you have any further Idea or hint, how to modify the code in “stereo Widener” (I wold like to test both plug-ins) you are still welcome!

The effect should remember its last used settings, so you may not need to modify it at all - just use the text/slider controls.

You could try changing the “butterfly” code to something like this:

(defun butterfly (sound width-left width-right) 
    (sum (mult (aref sound 0) (sum width-left 1) 0.5)
         (mult (aref sound 1) (sum width-left -1) -0.5))
    (sum (mult (aref sound 1) (sum width-right 1) 0.5)
         (mult (aref sound 0) (sum width-right -1) -0.5))))

Then, instead of having the “vol” and “p” controls, use “width-left” and “width-right” controls.

The only real differences between “Stereo Widener” and “Channel Mixer” are:

  1. Channel Mixer provides total control for any left/right mix, whereas Stereo Widener provides a subset of combinations for the specific purpose of “widening”.
  2. Stereo Widener allows you to add a delay to the processed part of the signal so as to “synthesize” wider stereo. (personally I prefer the “Pseudo Stereo” effect for this job:

Once again, thank you so much for your support, it is a pleasure to work in this collaborativeway.
I have understood your point with Stereo widener and stay with/focus on channel mixer. I will let you know if it works :slight_smile:

I have severe doubts that any of those widening schemes will work.
You’re in essence trying to compensate a phase difference (arrival time) with an intensity alteration.
Asymmetric changes have unwanted side effects because L/R and M/S are so much interwoven. The 'S’ide channel had actually to be manipulated by wave shaping the displacement. However, this results in distortion because of the re-transformation to L+R.
On the other hand, mixing together different amounts of LR for both channels results in a rotation and not in skewing, squeezing or stretching.
That are just my spontaneous thoughts and I’m glad to be proven wrong.


Like you Robert, I have some doubt about how effective this will be, but it’s an interesting experiment and I suspect that some degree of (subjective) improvement will be possible. I’ll be interested to hear how mister cool gets on.

Hi, thanks for sharing your thoughts.
I am aware, that this is not really a perfect solution. I understand, that this kind of manipulation will lead to some distortions, but you have to know, that my car is not the “most quiet one”. This means, that the absolute cleanest, undistorted sound has not the highest priority. My priority is more soundstage oriented. I use a little bit sophisticated car audio setup based on DSP, and I tried already many things including experiments with time delays and phase differences. Here is an overview of this setup (it is in German, but the pictures are selfexplanatory)

Now it is the time for next challenge: to optimize the the first piece in the complete audio chain: the source → the music.
This is a kind of experiment (I call it brain-jogging).
If it works, I am happy with improved music reproduction.
If it does not work, I am happy too, I have learned a much :slight_smile:

I will keep you informed

Robert states:
“…Asymmetric changes have unwanted side effects because L/R and M/S are so much interwoven. The 'S’ide channel had actually to be manipulated by wave shaping the displacement. However, this results in distortion because of the re-transformation to L+R.
On the other hand, mixing together different amounts of LR for both channels results in a rotation and not in skewing, squeezing or stretching…”

What does it mean M/S
What does it mean S’ide channel
What does it mean … results in a rotation

M=Mono or mid channel = L+R/2 = all that is common to both channels
S= side channel or width and position of the mono channel=L-R/2
It is interesting to apply effects–e.g. limiter, compressor–in this “domain” before the inverse transformation.

The so called rotation is rather a conceptional thing. The rotation axis is perpendicular to the horizontal plane between the speakers.
In the channel mixer, there are presets for 90 ° rotations (e.g. “Center to Left”).
Coincidently, it is also the transformation from L/R to M/S
See also Karaoke, Rotation, Panning & more

If I read your article correctly (I understand perfectly German), you’ve already incorporated some delays in the DSP.
Therefore, the center should already be adjustable to stay right in front.
I can not say how stereo widening will affect the sound, especially when the width goes over 100 %.
Keep us updated.


First of all, sorry for my poor English, which hinders me to express my thoughts and ideas precisely.

Let’s go back to Roberts answers.

Yes, all drivers in my car are perfectly time aligned through time response measurement and time delays applied in DSP.
I am not trying to adjust the position of the center → I did it already and works perfectly (exactly above the steering wheel). What I try to achieve is to extend the soundstage beyond the physical speaker location.

In the meantime I did some testing with different values and made the following “observations”

  1. Applying this asymmetrical modification in fact do “rotate” the soundstage (as Robert stated), but do not really extend the soundstage
  2. The rotation is perceived in the opposite direction then expected (at home and in the car)
  • 100 -60 0 100 sounds more “rightish”
  • 100 0 -60 100 sounds more “leftish”
  1. The precision of the stereo localization is decreased → more fuzzy
  2. The weight, the pressure in the low and mid frequencies is lost, it sounds a little bit “bloodless”

I will continue with some experiments, including applying time delay (like in the Stereo Widener), but in the meantime I have the following idea and question: is it possible to limit this channel mixer modifications to specified bandwidth and keep the rest untouched? Here is an example, what I mean:

  • Get S(L) = L-R
  • Filter S(L) to frequencies > 1kHz (just as example)
  • Invert S(L)
  • Add inverted S(L) to R
    The same for the right channel

This would prevent the loosing the “weight”

Any thoughts/comments are welcome

Here another question
Does anybody knows how the Q Sound recording technic works? I have a great CD from Roger Waters “Amused to death” which is recorded with this special effects

and since I bought this CD, I am totally impressed by this 3D spatial reproduction. This is what I would like to achieve and what I am heading for 

Bass frequencies are particularly prone to “phase cancellation” when stereo. For this reason, bass frequencies are often mixed to mono and placed centre in the mix of stereo recordings. (this is also why multi-speaker systems often have just one sub-bass speaker).

The easiest way to handle this would be to split the recording into two tracks before widening. Apply a low-pass filter to one of the tracks and mix to mono, and pass a complimentary high-pass filter to the other and widen as required.

To do this:

  1. Duplicate the track (Ctrl+D)
  2. Example filters for the two tracks using the Nyquist prompt effect:
;12 dB per octave high-pass
(setf hz 200)  ;This is the crossover frequency, set as required
(highpass2 *track* hz)

;12 dB per octave low-pass filter (mono)
(setf hz 200)  ;must be the same as the high-pass filter
(setf gain 0.5)  ;If the bass is already mono, this will be right, otherwise you can increase this a little
(let ((sig (diff *track* (highpass2 *track* hz))))  ;complimentary filter
  (mult gain (sum (aref sig 0)(aref sig 1))))  ;mix to mono

You could of course build this into the same effect as the widener/channel mixer, which would allow you to do the whole thing on one (stereo) track.
For example, if you have defined functions for:
(widen sig)
(lowpass-mono sig)
(highpass sig)
where “sig” is the audio signal that is sent to the function, then you could have something like:

(sum (widen (highpass *track*))
     (lowpass-mono *track*))

It’s certainly one of my favourite records.
I remember some 20 years back, I rode with a friend to a Pink Floyd concert in Lausanne (Switzerland) and “Amused to death” played a couple of times–David + co wouldn’t have approved that. We both were regularly fooled when the sound of an overtaking “new Ferrari car” appeared in the playback. We were gazing out the window like two synchronous swimmers…

As I understand it, the Q system is a post production suite of algorithms, not a recording technique.
(BTW, Waters’ last CD won a Grammy for best surround sound.)
Thus, you could simply include a Q processor in your chain as a secondary DSP unit.
However, that’s not much fun and probably not too cheap either.

Have you listened to the demo sounds they provide on the site in your car?
Analyzing these demos is quite interesting.
I use “Vocal Reduction and Isolation” for such tasks as it let’s you split the stereo sound into three channels and gives also some hints under the “Analyze” entry.

For instance, the voices in the jet demo can be selected and analyzed:

In normal stereo, the voice is panned hard left (-95 %) and the correlation is 5 %.
Stereo width is around 97 %.

The Q-processed voice is in the middle and the correlation around -82 % (nearly the same in both channels, but inverted).
And the stereo width? Well, a mere 297 %… 8-O

The code for measuring the stereo width (paste it into the Nyquist prompt and save it as a user preset under manage, if you want to reuse it)

;; Steve's stereo width measure
(let* ((mono (s-abs (mult 0.5 (sum (aref *track* 0)(aref *track*  1)))))
      (vr (s-abs (diff  (aref *track* 0)(aref *track* 1))))
      (a (/ (peak (integrate mono) ny:all) len))
      (b (/ (peak (integrate vr) ny:all) len)))
   (setq *float-format* "%3.2f")
     ((= 0 a)(format nil "Chance of Success: Nil (silent)."))
     ((= 0 b)(format nil "Chance of Success: Nil (mono)."))
     (T (format nil "Stereo Width: ~a %" (* 50 (/ b a))))))

And why does it sound leftish? Because the right side is delayed.

I can approximate this effect by:

  • Applying my hilbert filter which gives a phase shift of 90 ° L to R over all frequencies.
  • Preset “Extra wide” from the channel mixer

“Analyze” (VRaI) gives:
Pan position: 0.00182967
The left and right channels are correlated by about -88 %.
Stereo width: 379 %…

PS. the hilbert filter is similar to a delay but it wraps the phases around. It might give less comb effects, but I haven’t analysed that.

In general, the quality of the virtual Q system is very depending on the position of the head with regard to the speakers. I can make the voice wander by simply moving the head forward and back.
The question is now how this will work in your car where we have an additional delay for the left speakers and the angles are quite different in comparison to the usual 60 ° spread.