|Colin Muir Dorward|
Posted on 15 May 2021, 08:06 PMHow do we achieve this?
I'd love to hear solutions on EFM, or any links to other, outside sources of info.
I know there are many youtube tutorials, but it's difficult to locate a good one that doesn't ramble too much.
Edit: I found the useful document I had lost, which I believe will answer my question
Posted on 15 May 2021, 11:55 PMModulate a square wave carrier with a sawtooth wave Modulator with a Phase offset of 32 (or 96). Modulator output level controls the pulse width -- narrowed pulse with higher output level. Using HarshSquare wave #24 for the carrier and ESS sawtooth wave #27 will give the classic analog result, but be aware it will alias in the upper registers, and Key volume scaling the Modulatior enough to help the aliasing messes up the PWM depth; and the HarshSquare as a carrier aliases on its own.
You can also 'build from scratch' with sine waves - here's a short example video done on an SY99 https://www.youtube.com/watch?v=q3fQDePuaS8
Since the base square wave is built from sine waves with one feedback loop, and the saw wave from another sine wave with a feedback loop, that SY99 example allows for keyscaling to control the aliasing in the upper registers and keeping essentially constant PWM depth.
The Essence only has one feedback, so it gets a little sloppy and less accurate due to the 'stock' saw waves aren't quite right, and the frequency drift with Multiplier/Ratio messes it up as well. You'll need a down sloping saw wave like ESS sawtooth, but you have to edit it and smooth it once or twice; then instead of simultaneously patching into both the Carrier and Modulator making the square wave like the SY99 example, you patch it directly to the Multile/Ratio 2.0 Modulator, but then through another Operator set to zero freq with a sine wave at a level and patch that modulator to the Carrier.
So, here's an example for Essence: Set Op2 carrier, sine, Mult 1.0; Op1 modulator patched into Op2, sine, Mult 2.0, level about 36, feedback about 66. Op3 modulator, patched to Op2, Zero frequency, level 32; Op4 modulator, patched to Op1, smoothed version of Ess sawtooth, Mult 1.0 phase=32. Volume will control pulse width, best from 0-33 or so. Can now use Key Volume Scale on Ops 1, 3, 4 to kill the aliasing on the upper notes and keep the PWM depth. Setting Op3 phase = 5 helps a little as well. The use EG, LFO AM etc to control Op4 for PWM
Try it out, I'll upload an example voice later
|Colin Muir Dorward|
Posted on 16 May 2021, 12:24 AMHey Manny, thanks for this tutorial. I'll have a go at this.
What I've done in the meantime is simply sum two saw wavs, one with a very slight detune and/or pitch modulation. It certainly sounds more PWMish than doing two detuned saws on an analog, but maybe I'm still missing something. This was from that document I linked earlier, which describes the method pretty well. I tried several different pitch modulations and detune combos, including using a micro pitch envelope. Each way seems to sound a bit different.
Edit: thinking through this "detune" method I tried and realizing that at some point those two saws are going to line up, and make a SAWx2. PWM never makes a saw shape, so I guess that needs to be corrected somehow.
2nd Edit: I realized I forgot to invert the second saw, that aught to fix it.
3rd Edit: This method does more of a Reese bass, where the PWM rate increases as you go up the keyboard. I tried to correct that by using modmatrix with notenumber reducing detune amount. However, I can't quite trim it out, since I'd need to scale the detune amount logarithmically (is that possible?) but even with linear scaling the result is pretty sweet since you get the varying PWM rate but not as extreme as in a Reese type.
|Colin Muir Dorward|
Posted on 16 May 2021, 07:09 AMManny, I've implemented your method, and it seems to be working, but it's not quite the PWM sound I was expecting. I wonder if I've done something wrong. I don't really grasp how it's working so definitely could have messed it up!
Posted on 16 May 2021, 08:28 AMColin,
I've uploaded two example patches, one using Modulation Index (i.e. modulator level) to achieve the PWM and the other using phase offset via frequency drift (detuning).
Some background -- the phase type of PWM obtained by detuning two sawtooth waves with one phase inverted (the Reese technique you refer to ?) is an old modular analog trick when you had oscillators that didn't directly implement PWM, which subsequently became and old ROMpler trick with "Saw" and "Ramp" waves. Techically it is not true PWM as it's not directly controllable, meaning you typically can't set the inital Pulse width, or the total PWM depth amount via LFO, EG, Velocity, a CC etc... You just get the narrowing from square to thin at a rate based on the detune with a fixed depth. You've noticed the issue with the speed doubling every octave from the detune effect. Some instruments/VST's offer a fixed Hz detune mode along with the standard Cents detune, which means the rate is unchanged with pitch.
The index technique is the proper way for true PWM where you can set the inital Pulse width, and the total PWM depth amount via LFO, EG, Velocity, & CC's. This is what I show in my video I linked to previously. Yamaha's FM (PM) implementation is, for lack of a better phrase, 'mathematically pure' so it works extremely well in truly modeling real PWM.
The Essence FM engine differs from Yamaha's and can't quite get the accuracy of the PWM modeling without some aliasing and/or phase drift issues, but it does do a pretty good job.
The two voices I attached are Manny Phase PWM and Manny Index PWM showing the two different techniques. If you deconstruct Manny Index PWM, you'll see it using Ops 5&6 with the ESS satwooth and HarshSquare waves. The LFO controls the AM of Op6 for the PWM depth, You can turn off/down the LFO AM amount and then use the Op6 EG as well, and blend etc. It totally nails the modeling of PWM, but starting above middle C aliasing distortion becomes an issue.
Mute Op5, unmute Op2 to hear the Essence's version of the SY99's 'build from scratch' method. You'll note that is sounds slightly different and not as accurate as the SY99 version, and that's due to the single feedback in the Essence and using a smoothed version of the ESS sawtooth wave (I use 2 loops in the SY99, all sines). Add in the OP drift in the Essence with different Multiple settings and a different feedback gain structure comapred to Yamaha's, the overall result really good but just noticeably off a bit harmonically. The two stacks are detuned from one another, so unmute Ops 2 and 5 together for the '2 oscillator' sound
Deconstructing Manny Phase PWM, using this technique I've set it up for the most amount of control you can get out of it. I use up Op 5 as an LFO to do the PWM, and you can change the speed with the Freq Fine and the depth with decreasing the Level of Op5 -- note 42 is the maximum depth, any larger and it just folds back and doesn't change the 'thinness'. You can change the inital Pulse Width by changing the phase of Op4 . The default value of 64 gives square wave (50%) , and setting to 32 gives 42%, 96=75% etc. Kinda cool to set to 0 to hear it star at "DC Voltage" then gradually come in. Unfortuantely an octave above middle C the aliasing distortion starts really badly.
EDIT - Oops! The Phase of Op 5 in Manny Index PWM should be set to 10, not 0 (to play nice when both Ops 2 and 5 are unmuted). Sorry about that!
|Colin Muir Dorward|
Posted on 16 May 2021, 07:35 PMThanks for this!
Fantastic learning resource. I don't understand how the index method works yet but working my way through it.
As for the phase method, your program is pretty close to mine, but you've made some improvements.
One thing I'm struggling to fully comprehend is the use of zero-rate OPs. Do you have any words for me on this?
Posted on 16 May 2021, 11:49 PMColin,
The most useful explanation of zero frequency Operators is they more or less function as wave shapers and phase shifters of the sum/product of all the Operators that feed into them. It all is dependent on the waveform of the zero freq Operator and phase setting, and whether that zero freq Operator is a carrier, or if it is a modulator that then feeds into another Operator.
You may have noticed in the Manny Phase PWM example voice, both Ops 1 & 4 are the ESS sawtooth wave, Op 2 is a zero freq sine wave, phase =0, so it is basically just acting like an Amp for Op1. Op 3 also is zero freq sine wave, but phase = 64, so it is inverting the phase of Op 4 while again acting like an Amp. This creates two identical saw waves, with phase inverted from the other. Now if the Modulator Ops phase were the same, the result would be essential null and the waves cancel out, "DC Voltage" in analog PWM terms. So to get the sound and the inital pulse width that you can hear, you need to change the initial phase of one of the Saws, and the phase = width. Meaning, setting Op 4 phase = 64 gives a square wave as 64 is 50% of 127; similarly setting phase = 32 would give 24% pulse as 32/127 = 25%
Op 5 is phase shifting Op4 in real time as an LFO. The Op 5 is the depth of the modulation, the Freq fine is the rate of the modulation. The phase sets at what inital depth I want the modulation to start at -- with the triangle wave I'm using, 32 would be Maximum, 96 would be minimum, though it would be scaled by the EG. I use the EG to create the longer inital square wave portion. If you want, set the OP rate = 0, phase = 32, then start changing the EG shape to control the PWM depth.
Note, the Level of Ops 1 & 4 also act like an amp for volume up until a modulation index of 1, which seems to be a level of about 32 on the Essence. After that it doesn't get louder just starts shaping the wave, not unlike wavefolding. You can control the volume envelope with either the EG on the Modualtor Ops 1 & 4 or Carrier Ops 2 & 3, but for best signal to noise quality, I always leave the Modulator Ops with full-on envelopes and use the Carrier Ops EG for my Amp EG.
Posted on 17 May 2021, 01:50 AMTo expand on the "Index" method, the approach is to use Operators to build a square wave Carrier and saw wave Modulator. The example voice Manny Index PWM shows how it can be done with only 2 Operators, using Op 5 as the square wave Carrier and Op 6 as the saw wave modulator with Op 6 phase = 32. As you increase the Level of Op 6 modulating Op 5, the square wave of Op 5 with start to get narrower (NOTE, in the example voice I actually set Op 6 phase = 42 and Op 5 should be set = 10 for the Op 5-6 stack to 'play nice' with the Ops 1-4 stack when un-muted as noted previously in this thread). Again, I'm using the LFO AMD of Op 6 for the pulse modulation
Now, it is good to note that it matters which type of sawtooth wave you use - rising or falling - to make the phase modulation index math work correctly. It has to be a falling sawtooth, which by most is also known as a Ramp wave. In contrast to the a rising sawtooth shape version traditionally referred to as the classic Sawtooth wave. If you change Op 6 to be either Saw1 or Saw2 you'll hear that you no longer get the PWM, regardless of the phase for Op 6 and the Level. The math is just wrong to model PWM with a (rising) Saw wave. You have to use the falling Ramp wave
Side note -- when you use Saw2 with a phase = 64, turn the level up to like 50-60, you'll hear that's the math to model Oscillator Hard Sync, which maybe I'll get into sometime in the future 😉
Anyway, there are two issues with the 2 Op construct. OnNe is the very limited ability to create dynamic modulations - you basically get the pulse width and no other timbral control. The second is that there is significant upper range aliasing that comes with using the HarshSquare wave Carrier. You could use the regular Square wave for Carrier Op 5, and set up two different voice versions split in a Patch with the HarshSquare version playing the lower keys and regular Square version in the upper keys, but that's a pain and you still have limited timbral control.
Thus, in the Ops 1-4 stack I decised to build a square wave form scratch, using Ops 2 &1, that way I can smoothly roll out the aliasing in the upper registers using the Key Volume Scale on Op 1. Now I can also use Op 1 level, velocity sensitivy and the EG to create dynamic and/or evolving brightness of the square/pulse wave ! SO I set up the usual Op 1 as the Modualtor as I need the feedbck loop to itself, set of multiple/ratio 2.0, and it is patched to modulate Carrier Op 2 sine wave, multiple 1.0. Next we need to modulate our square wave with the ramp sawtooth.
Ideally I would use a modulator feedbacking to itself with multiple/ratio of 1.0 for the saw (Ramp) wave, but I don't have a second feedback loop to do it. So, I'm using a smoothed version of the Ess sawtooth wave called MF saw2. Since the square wave is being created by both Ops 1 & 2, the "Pulse Width" Modulator, for which I used Op 4, needs to be patched to both Ops 1 & 2. Then as before the level of Op 4 controls the width of the pulse. (NOTE: rather than directly patching Op 4 to Op 2, I patched it through Op 3 set as a zero frequency Sine wave, then patched Op 3 to Op 2. This lowers a bite the amount of Op 4 getting to Op 2, which was done to trim out the behavior of the Essence's engine a bit, but you can do it the other way as well)
I've attached some more example patches/voices. Compare the Patches Manny PhaseAtkPWM and Manny IndexAtkPWM To hear how much more dynamic the Index approach is ! The patch MannyIndxPhsDynaStr layers voices using both methods.
|Colin Muir Dorward|
Posted on 21 May 2021, 08:49 PMManny, just seeing now that you added a second post, fantastic! I'll be reading through this a few more times yet. 👍
I'm still pretty stuck on zero-frequency OPs. I can't seem to predict how they work or use them in an intuitive way. I've been looking for educational resources on the subject but the volume of junky, elementary tutorials really clutters the search. Do you have any suggested readings? I'm not a maths guy so that route is unfortunately a long ways away for me!