Tutorials

Synth-Building with Max/MSP #2

This series of tutorials first appeared on my CreativeSynth.com website between 2001 and 2002. Due to their popularity (especially amongst new Max users), I have moved them to the Cycling74.com website. Read the introduction.

In the last article, we created a simple synthesizer using basic Max and MSP objects. The biggest problem with that synth was the last ov output control - and an annoying thump in the output whenever a new key was struck. In this, the second article, we will correct some of these problems - and open some new doors.

Tutorial Series

Creating cs.synth_02

cs.synth_02, shown below, is a slightly modified version of the original cs.synth_01. If you'd like to download the patch and the supporting object, you can get it here. This synth has a few new options.

First off, the output section has been changed slightly to include a clip~ object. This allows us to prevent sending the sound card anything greater that the normal -1.0 to 1.0 range. This object will clip the audio to that range, and will keep us away from unwanted distortion and clipping at the outputs. This is a good practice, and will be expanded upon in future articles.

The second, and more important, change is the section labeled "Envelope/VCA Stuff". This section, which only contained simple divider and multiplication object. Now, we are given two controls (for attack and release time), and everything is funneled through an object called ddg.velamp. This object is an encapsulation of some more meaty logic.

ddg.velamp.zip
application/zip 1.30 KB
Download now

Let's pop open the ddg.velamp object and see what is in there...

This object takes three inputs - the note velocity, an attack time and a release time. On the other end, it outputs an envelope signal (you can tell it's a signal by the "fuzzy" patch cable). In between the inputs and outputs, we have to determine trigger and release points, create an envelope and create a velocity-scaled output.

The pink section is a simple evaluation of attack or release events. When a velocity value is input, it is checked to determine if it is greater than zero. In Max world, velocity of 0 is a note-off (or release), while a note-on is greater than 0 (i.e., the attack event). Using a route object, a bang is triggered from the appropriate output.

The green section is the setup for the envelope. First, you will see that the incoming attack and release time values are multiplied by 20 to stretch them out. In the synth patch itself, we are using the default 0-to-127 range for the dial objects. With this multiplication, we will now have ranges from 0 to 2540 ms.

Next, the attack and release values are used to create messages to be sent to the line~ object. The format of a line~ message is "level", where time is optional (and defaults to 0 ms). On the left side of this section, we are setting up a message that will "zero out" the level, then build it up to 1.0 at the selected rate. In line~ terms, this is two separate messages. So, we create a message box that contains two messages, using the comma (,) delimiter.

The funny message that is constructed is a convoluted way of getting the message "0., 1. " to the next message box. This is made somewhat more complicated by the difficulty in creating a message with a comma in it. In order to pass a comma in the message, we need to use the "" slash in front of the comma. Also, make sure that there is a space on both sides of the "," combo - otherwise the slash will be included as part of the prior or next message.

This message "sets" a message box that will be "banged" by the next incoming note-on message. A corollary is available for the note-off, but doesn't have to set up the dual message - and is therefore much simpler. Try to carefully follow this patch to understand this routing.

The output of the line~ object is a ramping signal that runs from the last setting to the new setting. In order to use this output, as well as to still maintain velocity control, we need to scale the line~ output by the incoming velocity. To do this, we capture the note-on velocity (by ignoring note-offs), scale it using the divide (/) object, then multiply the line~ output by this value. In this way, the output of this sub-patcher will be sensitive to envelope settings as well as velocity.

The final step is the use of the rampsmooth~ object. This object is super valuable - it prevents ramped values (like amplitude envelopes) from changing too quickly. any signal (even our simple sine wave) will thump if the attack or release times occur too quickly. This object will help alleviate thumping by smoothing any change over a specified number of samples. There is still the opportunity for thumps - especially if you are driving the outputs very hard. But, in general, a simple rampsmooth~ strapped across a line~'s output will help create a more controllable envelope.

In the main patch, you can see that the velocity, attack time and release times are routed to the ddg.velamp object, and the output is sent to a multiplication (*~) object for output scaling. In this way, we maintain all of the VCA-style control of the original synth, with the new attack and decay times.

Next in the series - basic filtering.

Go to #3: Basic Filtering

[ddg]
Darwin Grosse
7/29/2001

by Darwin Grosse on August 20, 2007

Creative Commons License
ialuna5's icon

Hello,

I am trying to follow this tutorial in order to understand some things. Would you please let me know about the ddg.velamp object. Which is that object in Max 6?

Thank you!

ialuna5's icon

Thank you.

So, another question. I can open it directly with max and then copy it. But I tried adding it to externals and Max did not recognize through the option/filepreferences nor file/install. I tried a couple of folders: max-externals and msp-externals, and leaving it in a folder by its own. Neither way could I get the program to read them. Is the way of copy paste the only way? Or is there something I am missing?

Thanks a lot!

Roman Thilenius's icon

i may be in /externals, but i does not have to be, because it is a patcher.

and ... patchers do not load by starting them ... you must restart max/msp after placing them _somewhere_ in the search path to make them available.

-110

stringtapper's icon

That's because ddg.velamp is an *abstraction* and not an *external*.

Here's what you should do:

Open that version of ddg.velamp that you downloaded and copy the contents.

Then open a new patcher and paste those contents inside it.

Save that patch as ddg.velamp.

Put the new patch "ddg.velamp.maxpat" into a folder within your Max search path (Options>File Preferences… to set custom folders).

Delete that old ddg.velamp just to be safe, reboot Max and then open a new patch, make a new object and type "deg.velamp" and it should show up in the autocompletion as an abstraction (with the 'P' symbol to the left of it).

ialuna5's icon

Thank you guys. It works fine now.

Appreciated!

Grant Atkinson's icon

Hi Darwin, I've noticed that your ddg.velamp object has had some changes made and now incorporates the adsrmoog~ abstraction/sub-patch. I've been trying to wrap my head around the maths involved with this sub-patch, as it has changed somewhat to your tutorial here. Is there any possibility of having an addendum made to this tutorial covering these changes and perhaps the maths behind these objects. Apologies for what is probably really simple, maths has never been a strong suit and this would be helpful imo. Thanks.