I recently found this implementation for widening a stereo signal by Michael Gruhn.


I've implemented this myself as follows:

void Voice::WidenTheStereoImage( double *a_dInputBufferLeft, double *a_dInputBufferRight, double *a_dOutputBufferLeft, double *a_dOutputBufferRight size_t a_zBufferSize, double a_dWidth){
double dTemp = 1/(1.0 + a_dWidth);
double dCoefficientM = 1.0 * dTemp;
double dCoefficientS = a_dWidth * 0.5;
double dValueM = 0.0;
double dValueS = 0.0;

for(size_t i = 0; i < a_zBufferSize; i++)
    dValueM = (a_dInputBufferLeft[i] + a_dInputBufferRight[i]) * dCoefficientM;
    dValueS = (a_dInputBufferRight[i] - a_dInputBufferLeft[i]) * dCoefficientS;

    a_dOutputBufferLeft[i] = dValueM - dValueS;
    a_dOutputBufferRight[i] = dValueM + dValueS;


When I apply this function to any signal I get nothing resembling a widened stereo version of the input. I've tried applying values from 1 to 4 as the Width and it just sounds distorted.

I'm wondering if this code example is only part of the implementation. I can't see how one side of the signal is delayed in the above which seems (to me) to be a critical element of stereo widening?

Also I would think that the output of this signal would be required to be mixed with the original input? Are these correct assumptions?

Can someone explain what this code is doing and what I must do to get a stereo widening effect from it?

  • $\begingroup$ Have you read the code snippet and tried to understand what it does? It's simple enough $\endgroup$ – Jazzmaniac Aug 6 '16 at 10:16

This code is splitting a stereo signal with left and right components into a stereo signal with mid and side components, scaling the mid and side components and converting back to left and right components.

To convert left (L) and right (R) stereo into mid (M and side (S):

$$ M = \frac{L + R}{2} $$ $$ S = \frac{L - R}{2} $$

And back:

$$ L = M + S $$ $$ R = M - S $$

The code is scaling the M and S before converting back to L and R. This is a fairly common approach to stereo widening. To widen you reduce M (the bit of signal in common to L and R) and/or increase S (the bit of signal that is the difference between L and R). The less the difference between L and R in the first place, the less effective this technique is i.e. it won't work if L and R are the same (i.e. mono sent to two channels). To widen when L and R are the same generally starts with delaying one channel by a small amount (but is a bit of a psycho-acoustic hack).

As to why your sound is distorted is another matter. It is most likely that you are scaling so that L and R are outside the range of values that can be played back over a speaker. Normally digital audio samples are in the range -1 to 1 so if you scale the samples beyond this range you will get clipping/saturation.

You won't need to mix it back with the original signal. The concept of dry/wet would be pointless as the stereo width is fully controlling the amount of effect applied to the original audio.

| improve this answer | |
  • $\begingroup$ The other thing to keep in mind is not to test your audio processing code on on an mp3 (or other compressed format) as the side component of them is grainy as hell and may trick you into thinking it's not working. $\endgroup$ – keith Aug 6 '16 at 18:42
  • $\begingroup$ No worries Keith. I was putting a two channel mono signal through it and now I understand thats why it wasn't working. I've read various information on the net stating that slight attenuation coupled with a small time shift (1 or 2 samples??) would give a better result. My synth produces a mono signal. I've thought about increasing the phase of the right channel by 90 degrees but this is really just the delay hack you described above. Any recommendations on how to approach a solution? $\endgroup$ – cixelsyd Aug 6 '16 at 18:53
  • $\begingroup$ I'd ask in KVR Production Techniques forum how to create a stereo effect from a mono signal - you might get some good advice from a pro mixing engineer how they do it and make it sound good, then you could convert their effects chain into code. It's not something I've looked into in great detail so I can't advise you I'm afraid, there's a slim chance someone here will know some research on the subject that may prove interesting if you're lucky, so you might want to ask another question on SO on the off chance. $\endgroup$ – keith Aug 6 '16 at 19:16
  • $\begingroup$ Just off the top of my head, looking into how early reflections are approximated in a reverb could be a fruitful area of investigation (or a wild goose chase!) but the maths and code will be complicated compared to simply delaying a channel, but the results should be a lot better. $\endgroup$ – keith Aug 6 '16 at 19:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.