Free Max/MSP Synths and a Favor (really long, sorry...)

robenkleene's icon

Hi there,

I'll start out by saying, yes is an absolutely massive post, so I apologize in advance for that. I didn't want to spam the forum by breaking it into a bunch of smaller posts (But I'd be happy to do that if people are interested, and would prefer I do it that way). I know I am asking a lot of people to even read this whole thing, but I thought it didn't hurt to try. In case you are wondering, the synths will always remain free and available with the full source downloadable. So any help people are willing to offer, that ends up with a fix, will always be freely available to the Max community.

So, I've made a couple of synthesizers in Max that I thought people might be interested in and they've got some bugs that I am hoping someone might be able to give me some advice on. The two synthesizers are called SimpleSynth and BeatBox.

# Here is a screenshot of SimpleSynth's interface
http://www.1percenter.com/wp-content/uploads/dropbox/simplesynth.png

# Here is a screenshot of BeatBox's interface
http://www.1percenter.com/wp-content/uploads/dropbox/beatbox.png

# An archive containing both synthesizers can be downloaded here.
http://www.1percenter.com/wp-content/uploads/dropbox/dfdsynths.zip

(Note that this is the first time I've released a patch as an archive, so if there is a better way to do this, let me know. I didn't want to build them as collectives, since I think it is easier to navigate the subpatches this way.)

Both can be built as VSTi's (or try the pre-built VSTis in the archive)

# A brief description of both synthesizers

Both synthesizers were created with the goal of recreating "typical" synthesizers. I.e. the most common implementation of the most common features of two types synthesizers. The goal wasn't to create something new, but to create something as standard as possible. To do this I used a combination of reverse engineering and consulting signal flow diagrams and documentation for various synthesizers (when I could find them). I know that using Max/MSP to create something "typical" isn't the normal approach, so I'll respond to that here with the following: Basically the idea is to have a base synthesizer that you can expand (or reduce) however you want, without having to worry about reinventing the wheel.

# A brief description of SimpleSynth, a basic subtractive Synthesizer

SimpleSynth is actually partial remake of a Synth called SCB Synth, which came free with Fred Welsh's excellent book "Welsh's Synthesizer Cookbook: Analog Synthesizer Programming." What Fred Welsh did was take the averages of the parameter values of many different Synthesizers, to create the "ultimate average synthesizer". Unfortunately the SCB Synth is Windows only, so I couldn't use it, which was the original catalyst for this project. I have a *ton* of great presets programmed into my version of this synth from the above mentioned book (which I highly recommend). But I removed them for now because the author of the book clearly put a lot of work into making them (and he seems to be self-published) and I don't want to "publish" them in the Synth without his permission. I left in a few as examples of what the synth can do.

# A brief description of BeatBox, a subtractive synthesizer that specializes in drum sounds

BeatBox is my own design. For BeatBox I consulted Sound on Sound tutorials and some books I have on sound design, then charted out the signal flows of how various drum sounds are synthesized. Then I figured out what the simplest feature set possible was that would allow for as many as possible of these signal flows to be used. The feature set turned out very similar to another well known commercial synth, so I used that one as a reference point. Unfortunately, BeatBox's presets were made by me :) , and I ran out of steam pretty quickly. I spent about 30 minutes on the bass drum and about 5 on the snare and 1 minute on high hat (which is absolutely terrible, actually just filtered noise works *much* better...). But there is an excellent guide to programming another drum synth available freely online that is almost verbatim applicable to this synth. I suspect someone will be able to connect the dots and figure out what it is, but I don't want to link to it for various reasons...

# On to the bugs...

So I've got some bugs that are an order of magnitude more difficult for me to figure out then anything I've encountered up to this point. This is because they appear inconsistently. If anyone has any advice on nailing down this kind of bug I'd be very interested in hearing about it. My debugging approach basically consists of inserting number boxes and scope~s and look at things when a note is playing. So when a bug only happens in one voice, deep in a poly~, while a stream of notes is being processed, I am lost.

Bug #1: SimpleSynth occasionally gets stuck notes

I am guessing that the cause of this is related to the adsr~. In particular, I suspect that the adsr~ occasionally doesn't receive note off messages, and as a result, just holds the sustain indefinitely. No idea how to fix this since the velocity of the note offs is pretty much sent directly to the adsr~. It might be related to how poly~ routes note offs to voices? Or does Max just occasionally "miss" note offs?

Bug #2: BeatBox occasionally doesn't make a sound on note ons

This could be caused either by Max/MSP not receiving a note on. Or possibly from my "edge~" based voice muting management. If, for some reason, this edge~ got triggered immediately after a note on, then the voice would be muted without playing the sound.

# All the following bugs are related to sound quality, and so fall under the general category of eliminating pops, clicks and distortion.

Bug #3: Sometimes there are pops and snaps when a note first plays

Both synths sometimes get a pop when a new note first starts playing, this can almost always be removed by raising the attack time, but I am hoping there is another fix for two reasons. 1. The amount that the attack has to be raised depends on the parameters of the current patch, therefore raising the minimum attack time (which would be a good catch-all fix) would reduce the flexibility of patches that can handle a much lower attack time. 2. These pops are inconsistent, i.e. even with the same parameters settings sometimes playing a note pops, sometimes it doesn't, therefore hopefully there is a way to get it to always play the way with no pop.

Bug #4: Occasionally sound gets distorted

Occasionally there are minor (but still annoying) pops and clicks that happen when a sound is playing. But, on top of that, there is sometimes more serious distortion. I sometimes get a sound that is best described as "digital distortion". In general this seems to happen when more when more stuff is going on at once. It could be related to CPU usage, but it doesn't seem to correlate directly to CPU. I.e. sometimes the CPU usage is high without distortion and sometimes it is low with distortion. I actually suspect they aren't directly related, and the correlation simply comes from more sounds happening at once means it is more likely to be happening to one of the sounds playing. Ableton Live (the environment I've been testing in) definitely has a hard CPU limit of around 70% and if you get near that amount serious distortion happens. But what I am describing can happen even with the CPU below 20%.

Bug #5: Sometimes, even without pops and clicks, two of the same note played after each other just sound "different" from each other

Things just vary if you play a note over and over again in strange ways. Sometimes the volume is a little different and sometimes the tone is slightly different. I suspect that the tone difference may have to do with the two oscillators drifting into slightly different sync states in relation to each other. This is particularly vexing since it seems so easy to fix. If I could just revert an oscillator to it's base state (the state it is in when it is loaded, before it has been used) each time a voice gets muted that would be great. But I haven't figured out a way to do that. Also, I think the volume issue is something different. It seems that all the MSP objects just behave slightly different each time they are triggered for a new voice based on whatever they were doing the last time they were used for a voice. If I could just reset all the MSP objects at once to their initial state on mute that would most likely solve all these variation problems...

# Finally for anyone interested in taking a look, a few notes:

1. All of the stuff right below each interface labelled "interface logic" is *really* hairy. Right now I think this works bug free, but it practically cost me my soul to get it working. I couldn't figure out a way to nicely have Max handle linking a number box and a slider and a the VST midi CC stuff *AND* have some knobs be scaled (i.e. one "tick" on a knob/slider can vary in the amount it changes a parameter, which provides fine control at one end of a knob/slider and coarse control at the other (the adsr knobs use this for example)). Anyway this code could definitely be written better, but none of it (as far as I can tell) is important for any of the bugs I am trying to fix.

2. You'll want to make a few things visible on lock if you want to poke around. In particular, I wouldn't try playing a note until the "load defaults" button has been clicked. Presets recall is also really useful (and can be used instead of the load defaults button), and there is some other obvious stuff you'll know to make visible.

3. As I said previously these can be built into VSTis.

4. As far as reproducing the above bugs, just hitting notes tends not to make them come out easily. But if you make a few one bar loops, each triggering a different instance of the synth, then they'll show themselves quickly.

Well that is that. We'll see how it goes. I know I am asking a lot but I've gotten some absolutely fantastic help when I've posted before, so it is worth a shot. Hopefully some other people will also think that this would be valuable to have be freely available for the Max community and are willing to lend a hand!

Thanks in advance!!
-Roben

SteveDaDark's icon

I took a good look at everything, but a lot of it is beyond me. I wonder if anyone else can help?

robenkleene's icon

Thanks for taking a look Steve, I appreciate it. I've been working on it myself for awhile now and I've realized I could have commented a lot of things much better *cough*or at all*cough*.

If you have any suggestions of ways I can make it easier for people understand how it works, I'd love to hear them.

Right now the stuff that I think is really hard to get are the pattr's and everything in the interface logic section. These are both ridiculously complicated for what they do but I couldn't figure out simpler ways to get the results I wanted.

I've been working on Bug #2 myself and I've made some progress. I realized quickly the solution I had in there would never have worked, so I've now replaced it with a different solution. The new solution isn't working yet, but it is close.

The source of the problem is now that the three envelopes in BeatBox sometimes don't trigger all at the same time. So if I can figure out a way to always trigger the three envelopes at exactly the same time (perhaps by triggering the envelopes with Signals as opposed to ints?) then I think that will solve that problem. Also of note is that both Bugs #3 and #5 are (most likely) at least partially caused by this same envelope triggering issue. So it is possible if I solve this, then that will only leave bugs #4 and #1 (and for some reason I haven't been able to reproduce bug #1, so that might be fixed as well, but I am not convinced yet).

Thanks again for taking a look!

-Roben

SteveDaDark's icon

Roben,

Just to let you know that my last post was a bit of a lie... i only looked at your subtractive synth, I forgot about the other one, sorry.

I understood the pattrs. For me I dont like them, i have never used them before. Do they carry anything more than an integer?

I figured if you are only sending values to the 'soundengine' i might as well use send and recieve objects. Your logic interface map looks just the same without them.

Anyway I spent a while doing that, but now I cant get the damn thing to work. What is it that the pattrs do that the send and recieve objects dont do?

I also understand most of everything else (in the subtractive synth), and I cant seem to get my head around the bugs you have.

Those clicks are really annoying, the only way to remove them is upping the attack on the amp env. Have you found a working solution to that yet? Maybe you should try putting a delay (of a few ms) on the ampenv?

I know you are interested in getting fixes for your bugs... but I dont think I have the knowledge right now to help. I am interested in learning though, and I might be able to help as I learn more about your code. Will you keep me posted?

SteveDaDark's icon

Oh by the way, so I could understand everything better, I removed all objects referenced to pluggo so I could get a clearer picture of the 'raw' synth,

robenkleene's icon

Howdy Steve,

The one and only reason I used pattr's instead of send/receive pairs is that send/receive pairs will send to a receive *in another patch*. Which means if you have three instances of the same synth loaded into VST host, changing a knob on one instance would send the change to the sound engines of all three instances. (That is my understanding anyway, I never actually tested that.)

With that said, I can't think of any reason that replacing the pattrs with send/receives wouldn't work perfectly when only a single instance is running.

Regarding the clicks in the attack phase, yeah I know that is really annoying. I haven't really decided what I am going to do about that yet. At this point I've pretty much determined that everything is working properly with that and I just choose a minimum attack that is too low. Right now the minimum attack is .1ms which is really low. I got that value from Simpler (the ableton live instrument). Simpler also has a click if the attack is set too low (although it is more subtle). It is worth noting that Ableton Live's new synthesizer Analog (which has very similar features to SimpleSynth) has minimum attack of 5ms. Setting SimpleSynth to 5ms for the attack seems to get rid of the click, so I think I might just make the new minimum 5ms. I am not going to do that right away though because I have about 100 presets programmed into the current versions, which I am not ready to redo yet :) .

Pasted below is a simple patch that proves that the click appears even with a really simple setup. I am not sure I understood your idea about adding a delay to the ampenv, did you mean delaying triggering the amp envelope?

Thanks for the interest and ideas!

Max Patch
Copy patch and select New From Clipboard in Max.

SteveDaDark's icon

Hi Roben,

Maybe all subtractive synthesizers compensate for that fatal click somehow. I noticed that it is more evident when you have a sine wave activated. From what I remember in physics, sine waves tend to create a click when you dont start from a frequency of 0. Also this reminds me of working in logic pro when I cut off an audio file early, it makes that fatal click sound as well.

I will still be looking at your patch and let you know what else I think!

-Steve

SteveDaDark's icon

Just a small perhaps insignificant question.. do you not use the percent2way in the subtractive patch at all? (still trying to get my head round things)

SteveDaDark's icon

Oh and about the delay i mentioned previously. I saw a synth before that inputted a del object before an amp envelope patch that I assumed was to remove clips, and to give the end user the illusion they are working from 0 attack, even though this would be staggered due to the delay.

p.s i will try and post all in one go next time!

roger.carruthers's icon

if you're talking about Pluggo's, then you can use
Plugsend/Plugreceive with '---' (or is it '--'?)
prepended to the name, eg Plugsend ---foo. This makes
the send/ local to that instance of the plug,
cheers
Roger
receive
--- Roben Kleene wrote:

>
> Howdy Steve,
>
> The one and only reason I used pattr's instead of
> send/receive pairs is that send/receive pairs will
> send to a receive *in another patch*. Which means if
> you have three instances of the same synth loaded
> into VST host, changing a knob on one instance would
> send the change to the sound engines of all three
> instances. (That is my understanding anyway, I never
> actually tested that.)
>

robenkleene's icon

Re "Maybe all subtractive synthesizers compensate for that fatal click somehow." Yeah, I am guessing that they just raise the minimum attack until a click isn't audible. I am not sure though, I don't have access to very many Synths that give you a value for the attack in seconds (most are just dials that don't show a corresponding value). But I'd be curious if there are any out there that give an attack as low as .1ms without a click.

Re "percent2way" No, I don't think there are any of those in SimpleSynth. Percent2way is for dials that go from -100% to 100%. I believe that was a new dial type I made for BeatBox.

Re the "delay", so that means it is essentially the same thing as increasing the minimum attack? (By adding to the minimum attack, without the users knowledge, behind the scenes). (The reason I am still confused is that if a delay is used before the left inlet of the adsr~ then that wouldn't really be adding to the attack, it would just delay the start of the attack a little later. Which I *think* would still result in a click, but I am not sure.)

robenkleene's icon

Thanks for the tip Roger, I did not know about that! I still think Max/MSP could use a non-global send/receive implementation. I think it was right to use the pattrs here, because I still like to have the option of running multiple instances in the runtime. But there are definitely situations where that pluggo tip would get the job done and be much easier than using the pattrs.

SteveDaDark's icon

Thats exactly what i mean. Well in my opinion if we are talking about tiny millisecond delays here, then your going to want to keep the attack effect in sync with the D S and R as far as 'uniformity' goes. In theory if you delay the signal before it reaches the patch then it shouldnt click. If your still having problems just adjust the min level of the attack, I mean no one is going to appreciate those clicks.