Back Original

Mid-Side Processing in Jackdaw

Jackdaw is a free, keyboard-focused Digital Audio Workstation (DAW), currently in progress. Source code and a user manual are available on github.

The latest version of Jackdaw includes a new “Channel Mode” setting on all effects, which enables mid-side audio processing.

Mid-side processing

A stereo audio signal contains a Left channel and a Right channel. Differences between the two (along with appropriate loudspeaker placement or the use of headphones) give the overall sound a spatial quality that is not achievable with a single-channel mono signal.

In most stereo recordings, there’s a lot of overlap between the Left and Right channels. That overlap tends to sound as if it’s in the “middle” of a mix, where the non-overlap – the difference – sounds like it’s happening on one side or the other, or both.

It turns out to be very easy to extract two new signals from stereo L and R, where one represents the overlap, and the other represents the difference. These are the “Mid” and “Side” channels. The Mid and Side channels can just as easily be transformed back into stereo L and R.

Mid-side encoding:
M = (L + R) / 2
S = (L - R) / 2

Decoding:
L = M + S
R = M - S

(The division by two can happen in either step, but must happen somewhere.)

“Mid-side processing”, then, is any processing done on the mid-side encoding of a stereo signal, rather than on the original L and R channels.

Mid-side processing – especially mid-side EQ – is a common tool in music production, used to alter the stereo characteristics of a recording.

Mid-side EQ example: drums

Here’s a recording that came straight out of my e-drums:

I don’t like the way the hi-hat seems to be way off to the left compared to the kick and snare. But I don’t have access to a separate hi-hat track that I can simply pan over to the right; this is just a single WAV file!

Luckily, the hi-hat sound can be targeted in an EQ, because it is most prominently heard in a high-frequency band between 2kHz and 20kHz. Attenuating that frequency band in the Side channel and boosting it in the Mid channel effectively pans the band – and therefore, the hi-hat – toward the center of the stereo image.

(The snare occupies that high-frequency band too, but in this case that doesn’t matter too much, because the snare is already centered and has other characteristic frequencies as well.)

Here’s the same recording, after the mid-side treatment:

Jackdaw effect “channel modes”

“Mid-side EQ” is often shipped as its own effect. Instead of adding a whole new effect, I found it much easier (and ultimately more powerful) to implement mid-side encoding/decoding at the abstract Effect level. All effects in Jackdaw are capable of processing one or two channels – typically stereo L and R – but why not pass M and S through the effect instead?

The channel modes are as follows:

  1. Stereo
  2. L only
  3. R only
  4. Mid only
  5. Side only
  6. Mid-side

If the channel mode is one of Mid only, Side only, or Mid-side, the two stereo input L and R channels are encoded as Mid and Side before being sent through the effect.

In L only, R only, Mid only, and Side only modes, one of the two input channels is processed by the effect, and the other is bypassed. In Stereo and Mid-side modes, both channels are processed. Conventional mid-side processing is not achieved with Mid-side mode, but rather with two separate effects: one in Mid only and the other in Side only.

Stereo and Mid-side modes are equivalent for all effects that treat each of the two input channels independently: the Equalizer, FIR Filter, Saturation, and Compressor effects. The Reverb and Delay effects process the two output channels in tandem, and therefore will sound somewhat different in Mid-side mode.

Encoding / decoding

Every instance of a Jackdaw Effect belongs to an EffectChain, which is simply a sequence of effects. When a signal passing through an effect chain reaches an effect that requires mid-side encoding, the signal is mid-side-encoded, and the effect chain records the encoding state. Stereo decoding is then only done when:

Therefore, you can have an effect in Mid-only mode followed immediately by an effect in Side-only mode, and mid-side encoding/decoding will only be done once.

/* 'L' and 'R' are audio buffers (type float *) 
   'ec' is an EffectChain pointer
*/
for (int i=0; i<ec->num_effects; i++) {
    Effect *e = ec->effects[i];
    /* When `running_amp` is zero, effects that never produce sound from silence 
       are bypassed */
    bool running_amp_nonzero = fabs(running_amp) > amp_epsilon;
    if (e->active && (e->operate_on_empty_buf || running_amp_nonzero)) {
        e->has_proc_state = true;
        /* Macro checks if the effect's channel mode is one of `Mid only`,
           `Side only`, or `Mid-side` */
        if (!ec->mid_side_encoded && EFFECT_CH_MODE_DO_ENCODE(e->channel_mode)) {
            mid_side_encode(L, R, len);
            ec->mid_side_encoded = true;
        } else if (ec->mid_side_encoded && !EFFECT_CH_MODE_DO_ENCODE(e->channel_mode)) {
            mid_side_decode(L, R, len);
            ec->mid_side_encoded = false;
        }
        /* NULL ptr is passed when a channel is bypassed */
        if (e->channel_mode == EFFECT_CH_MODE_L || e->channel_mode == EFFECT_CH_MODE_MID) {
            running_amp = effect_buf_apply(e, L, NULL, len, running_amp);
        } else if (e->channel_mode == EFFECT_CH_MODE_R || e->channel_mode == EFFECT_CH_MODE_SIDE) {
            running_amp = effect_buf_apply(e, NULL, R, len, running_amp);
        } else {
            running_amp = effect_buf_apply(e, L, R, len, running_amp);
        }
    } else if (e->active && !running_amp_nonzero && e->has_proc_state) {
        /* Clear short timescale effect state (e.g. EQ filter state) 
           when the effect stops running. e->has_proc_state set to false */
        effect_silence(e);
    }
}
/* Before moving on, ensure channels are stereo L and R */
if (ec->mid_side_encoded) {
    mid_side_decode(L, R, len);
    ec->mid_side_encoded = false;
}

Mid-side EQ in Jackdaw

So, to create a “mid-side EQ” in Jackdaw you would:

  1. Add an EQ to the track (S-e)
  2. Set that EQ’s channel mode to Mid only
  3. Add a second EQ
  4. Set the second EQ’s channel mode to Side only

That’s it! It’s two separate effects instead of one, but the processing is exactly the same.

Here’s what it looks like to create the drum example from above:

The first EQ, which processes the Side channel, has a high shelf filter pulling down the high frequency range (the hi-hat). The second EQ, which process the Mid channel, brings those frequencies back up, but only in the middle.

Other mid-side effects

EQ is where mid-side processing is most useful, but it has been interesting to experiment with other effects as well. Adding saturation to the mid channel only seems to be a nice way to get some of the bite and warmth of the effect with less loss of clarity. Putting a delay line in Mid-side mode with a nonzero Stereo offset can create some interesting, unpredictable echo patterns.

I will soon add a general-purpose Amp / stereo effect, which will include things like swapping the two channels, and effect-level panning. In Mid-side mode, the pan control in this effect will allow you to directly adjust the M/S balance on a single slider. Swapping the channels will turn the mix “inside out”.

In case you missed it

Also in this update: Jackdaw reverb

Previous update: MIDI, synth, and more