Articles

A Basic Vocoder Tutorial, Part 4

In this tutorial series, we have created the heart of a vocoder using the MC system introduced in Max 8. The vocoder imbues a sound source (the carrier) with the drive of a second sound source (the exciter). We used MC to work with multiple channels of audio (e.g. 2 channels for stereo sound). Then within each channel, we used MC again to process each frequency band of audio for the two sources.

Vocoder_tutorial_4.zip
application/zip 5.97 KB
download the patches used in this tutorial

At the end of tutorial 3, we produced the patcher below, which is parameterized using Max for Live objects to make it easy to turn into a device.

In this patcher, and in this whole tutorial thus far, we've used a static "super saw" style synthesizer playing the note "A" for our carrier. While it isn't very dynamic or exciting it demonstrates the potential of the vocoder.

To take our vocoder to the next level, it is time to think about our options for better carrier signals.

This subject could easily fill a volume and is impossible to cover completely in this brief introduction. We will focus on two places to launch your journey...

1 - Classic Vocoder Synth

Max comes bundled with hundreds of example patchers that provide both inspiration and a place to find models for your own work. Many people don't realize what an incredible treasure trove exists in these examples and it is definitely under explored. One of these fabulous examples is the "Classic Vocoder" patch. You can find it in the menu bar under the Help item.

It looks like this:

All of the magic happens in the bpatcher above the ezdac~ object. Opening that patcher, taking it out of presentation mode, and unlocking it to edit, yields this:

The patcher uses send~ and receive~ rather than patch cords for the main audio, but it isn't too crazy to track down if we are patient:

  1. The center section at the bottom is just for outputting lists to display a visualization. It doesn't actually impact the audio.

  2. The area labeled "Excitation Source" is the synth for our carrier. That's what we are here for; we will come back to this in a moment.

  3. The bank of 15 abstractions on the left that are labeled "classic-channel" are the heart of the vocoder. Each channel implements a bandpass filter both the carrier and for the exciter (it actually doubles the filters up to get narrower bands with better separation) and uses the avg~ object for the envelope follower.

About that synth

Now that we have the lay of the land, we can steal the synth out of this vocoder and add it to our own with a quick copy and paste.

In this synth, zerox~ is used as a quick-and-dirty analysis of the input signal. More zero-crossings per period of time means higher frequencies, and really high frequencies are more likely with noisy sounds. An FFT or other analysis method could be more accurate, but this gets the job done and is computationally very light.

If the input signal is deemed to be noisy, then the synthesizer switches to become a noise source. Otherwise, it uses a rectangular wave from the train~ object. If a voice input is used, then the carrier tracks approximately with the human voice to produce noisy sounds for consonants and tones for vowels.

2 - Sidechain Source in Max for Live

A second option with which we may wish to experiment is providing an external synthesizer that is not of our own making. There are lots of ways to patch this up in Max: bring in another adc~, instantiate an instrument plug-in with the vst~ object, or use a Max for Live synth in the amxd~ object. If we want to use our vocoder inside of Live, then we can get the carrier to come in as a sidechain input.

Here are the modifications to our patcher:

We've made 3 modifications to our patch:

  1. We added a plugin~ object to get 4 channels of audio from the Live application — the first two channels are the inputs from the track (which we're using for the excitation source), while inputs 3 and 4 are used for the sidechain inputs (for the carrier source).

  2. We've replaced the ezdac~ object for an mc.plugout~ object. The mc.plugout~ object defaults to stereo on channels 1 and 2.

  3. We've moved all of the interface objects into the upper-left region of the patcher window, which will be displayed in our Max for Live device in Live, and we have also selected all of the other objects and patch cords and selected Hide on Lock... from the Object menu to hide those objects when we lock our patch. (Note: we could also have added the UI objects to the Presentation Layer of our patch, as well).

Then, to make it a Max for Live device, save it as a Project:

In the resulting Project window, you can export it as a Max for Live device:

Now you are ready to load your device into Live and provide any carrier you like; from clips, to the Wavetable Instrument, to anything else your heart desires.

Wrapping Up

In creating a basic vocoder, we've covered a lot of ground. We also have left a lot of ground uncovered. If you want some additional context and some ideas where you might take your vocoder explorations next, this video offers a great history and a number of examples:


I hope you've had as much fun following along as I've had in creating this series. As always, happy patching!

Learn More: See all the articles in this series

by Timothy Place on October 13, 2020

Lilli Wessling Hart's icon

Thanks for everything you've contributed to Cycling '74 over the last 15 years, Tim! We will all miss you tremendously, and look forward to our paths crossing in other ways.

Rob Ramirez's icon

Ah Tim P, the legend, going out on a high note with this series! We will miss you!

I highly recommend Dave Tompkins (featured in the video above) "How to Wreck a Nice Beach" for an incredibly entertaining dive into vocoder history and cultural subversions.

Michael Simonelli's icon

Hi I have a question about turning this into a max for live device.

I found this online from this link https://docs.cycling74.com/max8/vignettes/live_audiodevices: By convention, a Max for Live device gets all its audio from the Live application using the plugin~ object and sends its audio output using the plugout~ object. Audio input and output is limited to two channels.

Confused as to how the plugin~ object is supposed to work here. When I turn this into a max for live device and put it on an audio track it just mutes the signal. I'm newer to this and likely missing something. How do you assign a carrier and an excitation signal from inside of live when this is loaded as a max for live device? Any help would be appreciated!

MMa's icon

Great!

👽'tW∆s ∆lienz👽's icon

👨‍✈️Thank You For Your Service, Tim!🙌

Marcel Wierckx's icon

Crazy that this classic-vocoder patch, which I made as a grad student at McGill University way back in 1999, is still a popular topic. It's very humbling when an expert like Tim calls my work 'fabulous'; if that's the bar then words fall short to describe his amazing contributions to the Max community!

Jan G.'s icon

Hi Timothy, thanks a lot for the great Tutorial and the vocoder patch on page 4.

I took the time to test it and work my way through it,
and it seems there's some small things I don't completely understand.
Could be it's just small mistakes, or I am mistaking, but I noticed following things:

1) when firing up your patch max4live-made version of your patch, i notice that sound comes mainly from the right until i move the "attack" knob, then the left channel comes back alive as well. the same when i click the edit button in Live to open up the patch in max. everytime I do this, volume and sound change quite a bit.

2) the range (low/high) is reversed in your example (you put lows into high and vice versa). you can see this if you look for the mc.bands~ inlet comments. that might not be a problem, but the weird thing is: once i turn them around, into the "right" order (put a high limit in the lower and a low limit in the upper number box), the patch goes very very quiet, almost no sound, i have to boost a lot

3) when used with the limits in the "wrong" order (swapped), the patch is very loud, and it distorts

4) you also get a negative "ideal Q factor" (has to do with the swapped limits, i think)

5) for the Bandwidth, you write "makeup gain for the filter q (more gain to compensate when they are narrow, less gain when they overlap)". but, the documentation of mc.bands~ says, that lower BW numbers represent wider bands with more overlap. so you seem to be doing it exactly the other way round than either you say, or than the documentation says: you increase gain for lower BW values. btw, this is independent of the limit ranges (swapped or unswapped). maybe there's a reason for this? is the documentation wrong?

6) you provide a way to change the number of vocoder/bandpass channels. the documentation of mc.bands~ says, that once changes, the DSP has to restart in order for the channel number change to take effect. that's not entirely true, because i can observe changes when changing the channel number (in Max or as a max4live device in Live), but I never know what's going on exactly. seems all a bit weird, or at least i can't figure out what's happening here

I also have a quick question: Is there any guideline or rule of thumb for the number of vocoder channels? I thought, 40 might be better, but I can't really tell, it depends on the material. Sometimes, 8, 12 or 30 vocoder channels sound the best

thanks so much for providing help,
or maybe another user can help me out also,

all the best,
Jan