• Home
  • About
  • Site Policies
  • Contact

Designing Sound

Art and technique of sound design

  • All Posts
  • Featured
  • News
  • Interviews
  • Reviews
  • Tutorials
  • Resources
    • VR Audio Resources
    • Independent SFX Libraries
    • Events Calendar
  • Series Archives
    • Featured Topics
    • Featured Sound Designers
    • Audio Implementation Greats
    • Exclusive Interviews
    • Behind the Art
    • Webinar/Discussion Group Recordings
    • Sunday Sound Thought
    • The Sound Design Challenge

Pure Data Wavetable Synth – Part 8

April 25, 2013 by Shaun Farley

Part08-01aDespite all of this, I’m still relatively new at Pure Data and the Max language. To those who chime in with corrections or clarifications in the comments, you are most appreciated! If you’re new to PD, make sure you check the comments section for clarifying info provided by generous souls.

We’re picking up steam here. The synthesizer is essentially done. What we’re doing in the last two projects is adding features to make it a little more fun. Today, we’ll be adding in a 3 stage filter section. We’re going to route our synthesizer output through a hi-pass filter, then a band-pass filter, and finally a low-pass filter. It will pass through each of them in series, but we’ll be able to turn the filters on and off. Just to make things a little extra interesting, we’ll incorporate an LFO into each filter to sweep the center frequency (which we’ll also be able to turn on and off). You’ve completed the previous seven tutorials…right? ;)

The awesome part of what we’re doing today is that the code for each filter section is nearly identical. The only filter we’ll have to make any significant changes to is the band-pass filter, and even those will be relatively minor. Let’s get started…but don’t forget to configure you MIDI controller before opening your patch.

Create a [toggle] and then use a “comment” to label it “High Pass”. We’re going to use this toggle to turn our filter on and off. Open it’s properties window and set the “send-symbol” to $0-filter1″. We’ll use that variable much later. Next, create a horizontal slider, and label it “Center Frequency”. Set its output range in “properties” to 0 to 2000, and assign “$0-filter1Freq” to it’s “send-symbol”. Create a number atom that you can put next to the slider, and set its “receive symbol” to the same variable (you may want to change the “size” too). This way we’ll know exactly where we’ve set our center frequency.Part08-02Before we apply this frequency to a high pass filter, let’s build our LFO generator. Thankfully, we can just reuse our “oscGenerator” abstraction patch. Create [oscGenerator] and place it in you patch a little ways below the horizontal slider you just created. Now create a vertical radio atom and change its “number” to “6”. While you’re in there, set the atom’s “receive-symbol” to “lfoInit”…we’ll come back to that as we finish up this stage of the filter section. Label the first five boxes (top to bottom) in the same order that you labeled the “Modulation Shape” selector we created for frequency and amplitude modulation. Label the final box, on the bottom, “LFO Off” and connect the vertical radio atom to the cold inlet of [oscGenerator]. Create a vertical slider and connect it to the hot inlet. Open the slider’s properties window and set the “bottom” and “top” values of “output-range” to “1” and “20” respectively. Label it “LFO Rate”.

Next, we need to think about the range of frequencies over which our LFO will be able to sweep the high-pass filter. I like the idea of being able to sweep over the entire range to which we’ve already assigned our filter with the horizontal slider (0 to 2000). Why don’t we drop a vertical slider with the “bottom” and “top” of the “output-range” set to that as well? Then connect it to the hot inlet of a new [*~] atom. I’m going to pause here, because there’s a potential problem with simply connecting [pd lfoGenerator1] to the cold inlet of [*~]. Our LFO is going to swing between -1 and 1. What happens if our range slider is outputting 1500…meaning that we’re multiplying by 1500? Well that means our output will swing between -1500 and +1500. If our center frequency is set anywhere below 1500, then we’re dropping below 0 Hz. We need to restrict the {range*LFO} value to remain positive. We’ll use the same math process that we did for the amplitude modulation…{(LFO output+1)*0.5}.

Part08-04Rather than use two atoms, one for “+ 1” and one for “* 0.5”, like we did last time, we’re going to use an atom that allows us to represent that process as an equation…[expr]. [expr] is another one of those atoms that can be used on data streams or signals. Since the output of [oscGenerator] is an audio signal, we’re going to use [expr~]. For the equation, we’re going to use the one I ended the last paragraph with…only substituting “LFO output” with the local variable “$v1” (the standard “$1” won’t work here, we need that extra little “v” in this application). PD follows standard mathematical orders of operation…everything in parentheses first, followed by multiplication or division, followed by addition or subtraction. Connect the output of [oscGenerator] to [expr~ ($v1+1)*0.5], and connect that [expr~] atom to the cold inlet of [*~].

Part08-05Now we’re going to want a way to stop this modulating signal if it the vertical radio selector is set to “LFO Off.” Let’s use [spigot~] again. Create that atom and place it below [*~], but don’t connect it yet. We need a way to send it a “0” value. We can rig this up with a [send] / [receive] pair and a Boolean atom. Open the properties of your vertical radio wave shape selector, and set its “send-symbol” to “$0-lfo1”. Now it not only passes the value to [oscGenerator], but also through that nice little variable. Remember that computers count from 0 up. On this selector, the value for “Sine” is “0”, and the value for “LFO Off” is “5”. We want our [spigot~] atom to let the audio flow whenever the value DOES NOT equal “5”. Create the atom [r $0-lfo1] then connect it to another new object atom, [!= 5]. [!=] is the opposite Boolean process of [==]. [!=] means “does not equal”, and will output a “1” whenever the incoming value does not match the argument. Connect the [!= 5] to the cold inlet of [spigot~], and connect the output of [*~] to the hot inlet.

Part08-06aWe’re still using tildes, because we’re still working math on an audio signal generated out of [oscGenerator]. Create the math atom [+~]. Connect the right outlet of [spigot~] to the cold inlet, and connect the “Center Frequency” slider we created (back at the beginning of this post) to the hot inlet. Remember, we can add numbers and signals. It simply means that the sum that is output will be a signal as well. At this point, we have our center frequency, and a LFO sweep to modulate that frequency. Now we need to actually produce our filter. PD has an atom for that…[hip~]! Its cold inlet receives the center frequency where it should begin the low cut, and it’s hot inlet receives a signal. However, we’ve got a small problem to deal with. Create [hip~] and drop it in your patch, but don’t make any connections yet. Examine the atom, and see if you can figure out what, exactly, the issue is.

Did you notice that the cold inlet is white? That means it needs the cut-off frequency in data form. We currently have it in signal, and need a way to convert it. Worry not, we have [snapshot~]! [snapshot~] takes a signal and converts it into a number whenever it receives a “bang”. What’s that you say? “Our signal is constantly changing because of the LFO”…? Correct, we need to be continuously outputting bangs to [snapshot~]. Do you remember the [metro] atom?

Here’s how we fix our issue. Create [snapshot~] and connect it to the outlet of [+~] and the cold inlet of [hip~]. Now, create [metro 1] (outputs a bang every millisecond, thanks to the argument “1”) and connect that to the inlet of [snapshot~] as well. Create a [loadbang] atom and connect it to the inlet of [metro 1], because we want [snapshot~] to always be working. It’s not a bad idea to have a manual [bang] as well, so create one of those and connect it to the inlet of [metro 1] as well. You can use either a button [bang] or a message atom [bang] here. I chose a message atom.Part08-07The only thing we’re missing now is our actual signal from the synthesizer. Look under [pd polytouchSynth], where you probably have a [dac~] at the moment. Click on the [dac~] atom…in “edit mode”, of course…and change it to [throw~ filter1]. Create its partner [catch~ filter1] and connect it to the hot inlet of [hip~].part08-08aThe only thing we need to finish off this first filter stage is a way to “bypass” the actual filter. Let’s turn to our dual [spigot~] solution once more. Create 2 of them; connecting one to the outlet of [catch~ filter] and the other to the outlet of [hip~]. Waaaay back in the beginning of this article, we created a [toggle] that’s passing its output over the variable “$0-filter1” (it was the very first thing we did). Create the atom [r $0-filter1] and connect it to the cold inlet on both [spigot~] atoms. Finally, create a new atom, [throw~ filter2], and connect the [spigot~] outlets to it (left outlet for the one directly connected to [catch~ filter~], and right outlet for the atom connected to [hip~]). We’ve got one last little thing to do in this filter stage. We set up the wave shape vertical radio selector to receive the symbol “lofInit”. We need to configure that to set the LFO off on opening the patch. Last time, we created the pair of atoms [loadbang] -> [; sustainInit 1]. Let’s edit that message atom. Add a “;” immediately after the 1, press enter/return, and then type lfoInit 5. Now it PD will set the LFO “off” whenever it loads this patch. [You can see my example of this edited atom under the “Load File” section.] Part08-09aHooray! We’ve finished the hi-pass filter. The rest of this is very much like cruising downhill! Copy everything we’ve done so far today (your entire hi-pass filter section, [toggle] to [throw~ filter2]) and paste it into your patch twice. Now we just need to do some minor updates. Relabel the middle stage [toggle] “Band Pass” and the third stage [toggle] “Low Pass”. We’re doing this now so that its easier to keep track of where we are, because we’re actually going to move to the “High Pass” stage first.

All we have to do here is a lot of renaming.

  • Open the [toggle]’s properties and change “$0-filter1” to “$0-filter3”
  • Open the horizontal slider’s properties and change “$0-filter1Freq” to “$0-filter3Freq”
  • Change the slider’s “left” and right “values” to “20000” and “5000” respectively
  • Open the number atom’s properties and change “$0-filter1Freq” to “$0-filter3Freq”
  • Change the equation in [expr~ ($v1+1)*0.5] to “($v1-1)*0.5″…on this one, we want it to only subtract.
  • Change [r $0-lfo1] to [r $0-lfo3]
  • Change [hip~] to [lop~]
  • Change [catch~ filter1] to [catch~ filter3]
  • Change [r $0-filter1] to [r $0-filter3]
  • Change [throw~ filter2] to [throw~ output]

Your hi-pass filter is done! Let’s turn back to the band-pass filter now. We’re going to start out with many of the same changes, but we don’t actually need to make all of them:

  • Open the [toggle]’s properties and change “$0-filter1” to “$0-filter2”
  • Open the horizontal slider’s properties and change “$0-filter1Freq” to “$0-filter2Freq”
  • Change the slider’s “left” and “right values to “1000” and “10000” respectively
  • Open the number atom’s properties and change “$0-filter1Freq” to “$0-filter2Freq”
  • Delete the [expr~ ($v1+1)*0.5] atom…we don’t need it here
  • Change [r $0-lfo1] to [r $0-lfo2]
  • Delete the [loadbang], [bang], [metro 1], and [snapshot~]…we won’t need these either
  • Change [catch~ filter1] to [catch~ filter2]
  • Change [r $0-filter1] to [r $0-filter2]
  • Change [throw~ filter2] to [throw~ filter3]

Your “Band Pass” section should now look like this.Part08-10aPD actually has a band-pass function that accepts a variable signal built right into it…[vcf~] (“voltage controlled filter”). We’re going to use that here instead of the basic [bp~] (band-pass) filter atom. Were we to use [bp~], we’d have to stick with the previously used [metro 1] -> [snapshot~] method. Click on [hip~] and change it to [vcf~]. [catch~ filter2] should maintain its connection at the hot inlet. The middle inlet, which is also a signal inlet, can take our center frequency signal. Connect the outlet of [+~] directly to this inlet. [hip~] and [lop~] are fixed Q filters; [vcf~] is not. The other cold inlet…the white, data, inlet…accepts a value for Q. We’ll place a new horizontal slider in the patch, and label it “Filter Q”. Open the slider’s properties window. Set its range from 0 to 5 (or set the “right” value differently if you like…it’s up to you), and set the “send-symbol” to $0-bpQ”. Create [r $0-bpQ] and connect it to the right most inlet of [vcf~]. Now our band-pass filter is done as well!Part08-11aThe only thing we have left to do is get the audio back out of the computer again. At the bottom of the “Low Pass” stage, we changed the [throw~] argument to “output”. We’re setting ourselves up for the next, and final article, with that. For now, create [catch~ output], and connect a new [dac~] atom to it. If you want a final comparison reference, use the image at the head of this article.

Stick a fork in it…we’re done for the day! When we finish up the project for good next time, we’ll be adding an anti-aliasing filter and the ability to record sounds directly to the hard drive from this patch. In the meantime, play around and have some fun with your fully functional synth patch!

Filed Under: featured, tutorials Tagged With: dsp, dsp 2013, dsp environments, featured, open source, puredata, synthesis, synthesizer, tools, tutorial, wavetable synth project

Comments

  1. Olivia says

    April 26, 2013 at 12:08 am

    You don’t look so new to the language…. nice to see PD articles here.

    • Shaun Farley says

      April 26, 2013 at 1:21 am

      I’m a fast learner. ;) It helps that this isn’t the first “programming language” that I’ve worked in. There are definitely places for improvement/increased efficiency within the code of these tutorials though. Some of those points are intentional…as it allowed me to introduce more methods and atoms…but there are just as many that are due to my “upper-level-novice” experience. Glad you’re enjoying them.

  2. Oliver says

    April 27, 2013 at 7:22 am

    Hi, again your tutorials are relly awesome, thanks a lot !!

    I would like to ask, if you can also serve the patches for each tut. I know the idea is to go through all the tutorials and fix errors yourself, but last time I got stucked and instead of 2 hours debugging, I would have liked to use a working patch and continue with the next tutorial …

    Cheers,
    Oliver

    • Shaun Farley says

      April 27, 2013 at 12:28 pm

      I plan to put up the finished patches only, Oliver. There will be a download link in the last article. You can at least use that to compare against your patches if you’re having issues.

  3. Tom Biddle says

    December 28, 2013 at 1:33 am

    Hi there, just trying to follow this but where it says

    “Open the
    [+ Toggle Item]
    ‘s properties and change “$0-filter1″ to “$0-filter2″”

    it doesn’t actually open anything up. Turned my adblocker off and nothing came of it. Anything you can think of?

  4. Tom Biddle says

    December 28, 2013 at 1:35 am

    oops, I’m being really thick, ignore that lol

Social Media

  • Twitter
  • YouTube

Posts By Month

#sounddesign on Twitter

#sounddesign

tunepocketTunePocket Music@tunepocket·
26 May 2020

Download royalty free gunshot sound effects, incl. one shot gun sounds, gun cocking sounds, gunshot with silencer, machine guns, and more #gunshot #sfx #sounddesign #videoediting #gamedev #royaltyfree https://t.co/bTTDQkveKF

Reply on Twitter 1265206307927162880Retweet on Twitter 1265206307927162880Like on Twitter 1265206307927162880Twitter 1265206307927162880
Reel2MReel2Media@Reel2M·
26 May 2020

At Reel2Media we are harnessing the power of smart speaker technology, to deliver cutting edge skills that solve problems and add value. To find out more, click here https://t.co/VAAw7vTW1V #sounddesign #smartspeaker #alexaskill #amazonalexa

Reply on Twitter 1265206269255847936Retweet on Twitter 1265206269255847936Like on Twitter 1265206269255847936Twitter 1265206269255847936
SoniKSoundLibSoniK Sound Library@SoniKSoundLib·
26 May 2020

Listen to #soundcloud preview of our next release! #np https://t.co/S3bxxrnqrh #audiopost #soundlibrary #soundediting #sounddesign #ambisonics #spatial #surround #ambience #roomtones

Reply on Twitter 1265204382779559936Retweet on Twitter 12652043827795599361Like on Twitter 12652043827795599361Twitter 1265204382779559936
asoundeffectA Sound Effect@asoundeffect·
26 May 2020

Want to know what the independent sound effects community has been up to? Hear the very latest SFX libraries here: https://t.co/OUBM2SqMoP #sounddesign #soundeffects #soundlibraries #indieSFX #gameaudio #filmsound #filmmaking #gamedev #indiedev #indiefilm

Reply on Twitter 1265199255838511105Retweet on Twitter 1265199255838511105Like on Twitter 1265199255838511105Twitter 1265199255838511105
OblikLinesOblik Lines@OblikLines·
26 May 2020

Working on new tracks with many instances of Misty Valley ! ⁠
Misty Valley is free for all NI Reaktor users⁠
You can get it here: https://t.co/bb53Gtkw5e

#reaktor6 #reaktor #nativeinstruments #synths #vst #sounddesign #virtualinstrument #musicproducer #obliklines #mistyvalley

Reply on Twitter 1265198647307907073Retweet on Twitter 1265198647307907073Like on Twitter 1265198647307907073Twitter 1265198647307907073
Load More...

Copyright Info

All content on Designing Sound is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

Copyright © 2023 · Magazine Pro Theme on Genesis Framework · WordPress · Log in