• ### Limiting amplitude on an LFO

Hello,

In the context of a MIDI to CV converter, I am trying to limit independantly the lower and upper points of a waveform. The reason for that is that when I play high pitches, the LFO added to the keyboard pitch makes the final value go over 1, creating a kind of high pitched plateau that I would like to avoid. On the other hand, I would like to allow the lower part of the LFO wave to continue its course, so the waveform would be asymetrical in a way, for example going from -1 to +0.2. I achieved this with different vline~ objects, by setting two \$ for posMax and negMax and it works fine. Here is the patch.

Variable LFO.pd

Now my issue with hat solution is that it doesn't play smoothly when adjusting the LFO rate, I suppose due to the fact that the different vline~ have to update while playing and they don't like it. Anyway, I am back to square one because playability and modulation possibility for the LFO speed is a must.

My math knowledge is not enough to figure out what kind of equation I should write to mathematically create the waveforms. Or maybe there is another way ? I went through the oscillators creation tutorial by Alexandro Drymonitis but couldn't find a way to adapt his patches so I could control the positive and negative parts of the waveforme independantly.

If anyone could put me in the right direction, it would be great.

Thank you.

• Posts 15 | Views 532
• most people make the error and use signalrate objects for their datarate LFOs - you seem to do it the other way round.

i would forget metro and use phasor~ as accumulator, and then all you need is a bit of arithmetics plus you can sum (mix) or multiply (AM, RM) layers of LFOs to get all kind of simple and complex waveforms.

for example cosine: _ *0.75 _ %1. _ cos
saw: _ *2. _ -1.
saw down: _ *-2. _ +1,
square: _ >=0.5 _ *2. _ -1.

tri is a bit more work, in pd i would use expr~

then sum : (a+b)/2
am : a(b)
rm : a((2b)-1)

• Thank you ! I managed to do what I wanted with the square oscillator. It was quite easy though because the positive and negative amplification of the wave were obvious. The other ones are quite close of those in the tutorial I found, so I will have to investigate more, it can't be that complicated. Anyway, here is the patch.

LFO square.pd

Now I have to wrap my head around the triangle one.

About data/signal rate objects, my first attempt was with osc~, but regarding my issue with waveforme values control, vline~ was the only solution I could come up with. I like the easy flexibility of vline~ as a function generator though. In the variable LFO patch, playing with the base rate multiplicators for example gives cool results coupled with curve adjustments. It is also cool to disconnect some vline~and not others. I will keep it for that. But for basic playability a mathematical oscillator is better for sure.

• you will sooner or later find out how to create a phasor~ patch which can be retriggered by an audio click and/or by a bang, in case you were thinking in that direction, it is all possible dont worry.

is there a split~ object in pd? otherwise you can use comparison operators with moses to split ranges.

and always use sliders or a scope to see what happens (it might also help you to find the formulas)

• Yes there is a split~ object but it is more about cutting a message with several values in it.

I can manage the selection of upper/lower parts of a waveform with <~ or >~ outputting 1 and 0 as gates. It works fine amplifying them separately, but it creates an abrupt breakpoint where the two offsetted parts meet in time. I also managed to get a kind of sine-ish waveform by adding a slew in the square LFO. It is wonky, but I like the sonic result. I also thought about offsetting the CV pitch itself to account for the range threshold. The fact is, the extremes of the full LFO modulation are not so tonal anymore so the accuracy of the main pitch isn't as important as the LFO range at that point if that makes sense.

I also have to try the LFO mixing as you suggested, it should be fun.

Here is the patch so far.

MidiCV OK v2.pd

• but it creates an abrupt breakpoint where the two offsetted parts meet in time. I also managed to get a kind of sine-ish waveform by adding a slew in the square LFO.

this can probably be avoided. the main cause for this is when you dont take care about matching the ranges exactly, for example when splitting into >= 0.5 and <= 0.5. - then at exactly 0.5 both gates are open and the two values get summed instead of alternated.

i´ve looked it up in my collection, here is tri:

``````expr (\$f1<0.25)*((\$f1*2)+0.5) + ((\$f1>=0.25)&&(\$f1<0.5))*(-(\$f1*2)+1.5) + ((\$f1>=0.5)&&(\$f1<0.75))*((-\$f1*2)+1.5) + (\$f1>=0.75)*((\$f1*2)-1.5)
``````
• okay this sucks, how do i get this forum to display an asterax?

• @Obineg You have to escape them (or at least the first and probably more if you want to print many)...... as they are used for text formatting.
It can get very messy.
Using x and explaining that it should be seen as * is probably easier...

BTW any reason not to use sigbinops [min~] and [max~] to satisfy the op requirement?
David.
[*~] [*~]

• escaping each of them sounds like a lot of work. i think one can guess that \$f12 was 1 times 2 - and the other are ones are not needed anyway.

yes, for signal expr~ you can use min(max()()), i copied this from my datarate max patch.

of course both is likewise difficult to read for a beginner.

outside of expr~ you might also be able to optimize the code further with pong and modulo.

but i like to start out verbose and linear, then optimize later.

he has yet to get rid of this snapshot nonsense.

• `code 4*5`

ah, found the code tag. but you already fixed my post.

• @Obineg I have modded your post above...... using the code box gives you the asterix..... no idea why it didn't work for you......
David.

• don't understand but maybe this helps:

[mtof] and [mtof~] conversion from midi-note-value to Hz

equation for linear mapping:

``````y = ( (c-d) / (a-b) ) * (x-a) + c
``````

where x is input
a-b input range
c-d output range.

triangle~

``````[phasor~]
[*~ 2]
[-~ 1]
[abs~]
``````

vanilla square~

``````[phasor~]
[-~ 0.5]
[*~ 1e+30]
[clip~ -1 1]
``````

splitting a signal at zero-crossing would be

[min~ 0] [max~ 0]

(there might occur aliasing at the output... if this is too noisy maybe oversample, and or filter it or use a bandlimited waveform)

• EDIT fixed the mapping equation

• TL;DR but I'm posing here a link to a tutorial I wrote long ago, on how to create VCOs (Voltage Controlled Oscillators) in Pd. http://drymonitis.me/wp-content/uploads/2016/02/making_VCOs_in_pure_data.pdf to whom it may concern.

• @alexandros Hello ! I have already found and read you tutorial. IThank you for doing that, it helped me understand some stuff.

Posts 15 | Views 532
Internal error.

Oops! Looks like something went wrong!