RS-MET
RS-MET copied to clipboard
I need a "spinning phasor" object to take FM and convert to PM.
Hey Robin, I just got this idea to solve a problem with modulating things with anti-aliased phasors (or sawtooths/ramps).
I need to use the rotation formula to rotate a signal in two or three dimensions, for example:
void rotate2D(double sin, double cos, double * X, double * Y)
{
double x = *X, y = *Y;
*X = x * cos - y * sin;
*Y = x * sin + y * cos;
}
So I need to derive a sin/cos out of a velocity of change of value rather than a fixed value/DC/phase value.
Imagine taking your hand and spinning a floating wheel. Now try to stop the wheel from spinning as fast as you can and make it spin the other direction. The speed of the movement of your hand hand represents frequency, and your strength represents ... force? torque? Now replace your hand with a sawtooth or a phasor. All we need to do is have a parameter for "how fast can the sawtooth stop/reverse the spinning of the wheel".
I'm trying to solve this problem:
My LFO is an anti-aliased saw and I want to control rotation. But the glitch in modulation of the "smoothed slope" causes the sound to click before rotation is set back to 0. If the anti-aliased saw could control a factor of rotation RATHER THAN the rotation value direction, the rotation glitch could be smoothed away.
the slope kinda represents speed of rotation or something, where... oh, maybe half of that spike (vertical-wise) represents negative (backwards) rotation as well.
This has potentially many uses! Pseudo-PM done this way could sound more interesting, more analog than standard PM. Edit: And you may ask: why not use the non-anti-aliased saw? I could, but non-anti-aliased waveforms are not desirable. Infinitely sharp edges are not good for audio rate modulation, they have unnecessary precision and harshness. Also, I want my LFOs to be just as good as a modulator as they are as an audio source. I am furthering my venture into "physically perfect" synthesizer, rather than digitally perfect (which is cold and ugly and harsh). Synthesizers should derive physical limitations from our natural world as inspiration, as much as possible. I don't want to separate LFOs from HFOs/standard oscillators.
i'm not sure if i get this right, but it almost sounds to me like you are talking about just smoothing the edge here. what's the difference to using a simple lowpass filter? i think, your graph with the spike (if that represents a force, hence an acceleration) and the smoothed out version of it, is what a lowpass would do. btw. integrating periodic bipolar spikes gives a sawtooth wave.
needless to say, however, that smoothing of course doesn't really anti-alias anything unless you use it together with oversampling
and what have sawtooth waves to do with rotations? they create circular motion (i.e. sines and cosines)
robin, a lowpass filter is the PROBLEM! The saw is lowpassed... it's anti-aliased. That being said, do you get it now or should I make some more graphs? π
Edit: The anti-alised sawtooth controls rotation value from -1 to 1, and jumps back to -1 non-instantly. That causes a spike of "extreme speed" back toward -1. That extreme speed is like taking a rotating wheel, reversing its direction of rotation extremely fast, and then back to forward motion extremely fast.
Solving this problem will be very useful for everything else we/you/I are working on!
Edit: Ok, simple explanation. Say you have an iterative oscillator like your exponential iterator..? Now you only have a frequency control.... what if you want to have a phase control? Well, you need to convert FM to PM.
wait wait wait...so you are using a sawtooth "phasor" for the phase-input of a sine wave, i.e. a sine-function, right (or maybe even some other wavshape)? when the phasor hits 1, it jumps back to 0 (or -1 whatever your conventions). ....and you picture this as the phasor turning around and going back in a very short amount of time? i don't really think that this is the right mental model for what the phasor does. you can just as well imagine it increasing forever. in that case, the periodicity of the sin-function would take over the role of resetting the phasor. the phasor just passes 1 ...but that value > 1 is the equivalent to some other value (shortly above 0). there is no turning back and then picking up forward speed again
it's like you are imagining a rotating wheel that can only rotate once and then has to be rewinded back in order to allow for another forward rotation. ...but it actually just continues to rotate forward
as far as the sine is concerned, 0.1 is the same (equivalent) input as 1.1. the 1.1 is just mapped back to 0.1 in order to avoid overflow and other nasty numerical things. it doesn't need to go back by reversing direction
it's like you are imagining a rotating wheel that can only rotate once and then has to be rewinded back in order to allow for another forward rotation. ...but it actually just continues to rotate forward
yes almost! it's better to imagine replacing the sawtooth with your hand. You HAVE to move your hand back up to push the wheel forward again. But then your hand must stay in contact with the wheel, and essentially "slip across" rather than your hand being an infinitely strong force that stops the wheel from spinning... or... something. Wow this kind of sounds like soft sync. The wheel could only turn / speed up /slow down efficiently if the speed of your hand is around the speed of the wheel. Go too fast and your hand slips off and doesn't increase the speed much. Go too slow and you just have a low speed.
....anyway, so would your suggestion be doing something where I only use a portion of the sawtooth (the non-glitched part) somehow?
i'm still totally confused. there is no "glitch" in the sawtooth and i don't know how to imagine to "replace the sawtooth with my hand". the sawtooth shape is actually just an artifact of our desire to avoid numerical overflow - otherwise it would just be an ever increasing linear function. i think, it's better to replace the sawtooth with that fucntion in your mental model. that would be more accurate. the sawtooth value does not "jump back" in the sense of moving back at infinite speed. it just disappears at the top and reappears at the bottom. we instantaneously map the value >1 to an equivalent value <1 . it's actually wrong to connect the two values with a vertical line
the sawtooth shape is not an artifact of a desire to avoid numerical flow, the sawtooth shape is the correct shape of a physically-limited saw within the increment of time of the digital computer that is simulating reality in 1/44100 steps of time.
But forget all that for a moment, the imperfect sawtooth shape produces a more pleasing sound because it is warmer and more physically limited/accurate for the limitation of time steps of the digital world.
I think you just have to experience the problem for yourself. Modulate stereo rotation in jerobeam mushroom with my sawtooth LFO. You will get ugly clicks. Then think about how to solve the issue.
Or forget everything I said again and focus on this one problem: Convert FM to PM. Take a frequency modulation signal and turn that into a phase modulation value/signal. This is a problem we should solve if we are going to use oscillators that don't have a phase input.
We want oscillators to function iteratively, that's how things oscillate in the real world. And this will lead to naturally-anti-aliased oscillators, better sound, better everything.
focus on this one problem: Convert FM to PM
the instantaneous phase of a signal is given by the integral (think: running sum) of the instantaneous frequency. so i guess, going back and forth between FM and PM involves integrating or differentiating the modulator signal (i.e. taking a running sum y[n] = y[n-1] + x[n] or a 1st difference y[n] = x[n] - x[n-1] in the discrete time domain). ...may need some more attention to detail, though
ok good! You have the problem in your head! That's all I need. I'll pay for your time working on this when I really need it solved. I'm going to release JB mushroom now and just allow the user to select non-aa saw.
just in case, maybe a diagram will help:
i think, we are on the right track with integration/differentiation:
https://moinsound.wordpress.com/2011/03/04/frequency-modulation-or-phase-modulation-synthesizer-technologies/
which boils down to 1st order lowpass/highpass filters applied to the modulator. a running sum is basically a 1st order lowpass with 0 cutoff frequency and a differentiator a highpass at fs/2 (in the simplest case, at least). however, i can imagine that the modulator needs some rescaling after filtering which should somehow track the modulator frequency
Hey Robin, remember this problem? I want you to work on it! PM to FM converter. I want to experiment with this as a way to put "physical limitations" on modulations, so we can have smoother modulation that doesn't break the sample rate limit causing harsh tones.
Oh, I remember what I wanted to do with this. I wanted to create a sinusoid generator which only has frequency as a parameter. It's also not reliable in tuning so I'd want to create a self-tuning process to get it in tune (which will need to be redone based on samplerate & oversampling).
something like:
s0 -= f * s1;
s1 += f * s0;
So it only has frequency and I need a PM to FM converter to do PM. AND it doesn't have to be perfect, I'm purposely interested in it not being perfect, and maybe we need a parameter for how imperfect, or how quickly frequency is allowed to change or something. I don't know what your end result will be so I don't know what parameters you will have.
With an imperfect phase modulated sinusoid generator, we can get an imperfect and possibly musical and anti-aliased sawtooth and other shapes which cannot be modulated so fast that it creates harsh tones. It could sound warm and the FM/PM would sound interesting. Basically, I want to create a simulated physical synth with physical limitations.
I could take this sinusoid generator and create analog-style filters like I do in Chaosfly/FMD. An entire synth could be built from that one simple sinusoid equation above.
We will also need this simple equation for filtering:
out = out * (1 - cut) + in * cut;
(already available)
And we need a soft clipper. Which you already made. But I wonder how we could continue this trend of physical modelling to create a clipper that is naturally antialiased and imperfect.
what is this update equation?
s0 -= f * s1;
s1 += f * s0;
is this supposed to be a recursive sine oscillator? this would have to be the cheapest update equation i have ever seen for such a thing. are you sure, this works? were does it come from?
equation comes from xoxos: https://www.kvraudio.com/forum/viewtopic.php?p=6686764#p6686764
he probably got it from somewhere
edit: yes it's a recursive sinusoid. it works. IIRC it doesn't have perfect tuning due to sample rate inaccuracy. But to solve that all you need to do is create a tuning map per midi key by measuring the frequency in and see what you get out. This is how Silent Way tunes analog synths.
Edit: Oh, according to the notes it becomes less sinusoid with higher frequencies. http://www.earlevel.com/main/2003/03/02/the-digital-state-variable-filter/
Man it would be nice if you could get your modular synth working so we could do all these experiments quickly π
So your mission is to create a kind of phase modulation version of that sine update equation with some kind of PM to FM conversion.
(Edit: And I want to use that PM to FM conversion in other places, so isolate it as its own thing)
it would be nice if you could get your modular synth working
yeahh. i just re-organized the modules in ToolChain, making an "Under Construction" section at the bottom where i have now included Liberty and moved a few of the other unfinished modules there, too. somehow i don't get sound out of it and the colors look weird but maybe i can get it to work soon. the main challenge was to get the whole software architecture working - but this is done and what remains is adding more atomic modules - a straightforward task of wrapping some bits of core dsp code into the liberty api, so to speak - but somehow i then didn't bother to add any more modules...
this simple recursive sine equation is interesting. i must experiment with it. my currently simplest sine oscillator is in class rsSineIterator:
RS_INLINE T getValue()
{
T tmp = a1*s1 - s2;
s2 = s1;
s1 = tmp;
return tmp;
}
...but this one is perfect. in terms of arithmetic operations, it's actually even simpler (1 mul, 1 sub vs 2 muls, 1 sub, 1 add) but is has more assignments and uses a temp. maybe i should performance-measure both.
btw - the filter i was recently talking about (with the supposedly perfect modulation response) is based on the rotation-matrix idea, too. but with a few tweaks to allow for non-resonant filters as well (some filters cannot be expressed as rotation matrix - but they can use another kind of 2x2 matrix)
So your mission is to create a kind of phase modulation version of that sine update equation with some kind of PM to FM conversion.
(Edit: And I want to use that PM to FM conversion in other places, so isolate it as its own thing)
i think, if only sine-waves are assumed, the task will be simpler than in the general case - but i also think, it could be interesting to solve the problem for the general case and then make a simplified version for the sine case. the thing is the integration/differentiation stuff is actually some sort of lowpass/highpass filter (possibly with some gain-compensation involved) in the general case whereas it might be simple first order allpass in the sine case (the derivative of a sine is a cosine and you can get that conversion with a properly tuned allpass - but only iff the input is a sine indeed)
I don't understand. Why would you solve it assuming sine-waves? That wouldn't get us anything new, except maybe something more efficient than sin(). Are you talking about if the modulation input is sine waves? That makes sense. But also, not so useful.
yes, i mean if the modulation signal (i.e. the modulator) is as sine wave. in this case, the conversion by differentiation (to cosine) is a simple allpass and likewise, the integration (to negative cosine) is the same allpass with sign inversion. otherwise, integrators and differentiators are perhaps a little more complicated - but probably not really very much - in the simplemost implementation, it may be just first order lowpass and highpass - but perhaps with some gain compensation which might become a bit tricky...but maybe not...we'll see
i'm currently making my wavetable-oscillator from straightliner available as source module in ToolChain. then i will combine 2 of them into a dual-oscillator with interactions - FM/PM/sync/etc. - then i have a good environment to experiment with FM
...as a side effect, we will then be able to throw together a basic subtractive synth directly in ToolChain...multiple source-modules in the chain just add their outputs to what's already there, the (basic) Ladder filter is already available, the breakpoint modulator as well - so ToolChain can be used as a sort of wireless modular synth soon.... :-)
edit: i will perhaps need to include a sort of simple gain module..to have a target parameter for an amp-envelope. but that's simple
But that stuff is boring! Unless you have some nice soft sync math, or feedback stuff. Oh, you were experimenting with feedback in the patch you posted recently so hopefully you have feedback on your mind.
Curious why you are joyful about this, I don't see the potential... maybe you are happy about being able to wire signals wherever you want? I mean... if I were you, I'd add a modulator source for the sound generators (not just the modulator modules, heck, add one for the filters output as well, everything should have a modulation source). Then you can wire things up a bit more modularly.
At the end of the day though I say forget toolchain and focus on Liberty modular!
forget about toolchain? it's my shell for everything else, including liberty. but i think, it's nice to have some (sub)modular features like the modulation system already available at the toolchain level, so it's already a bit more than just a chain of effects. but i currently don't really plan to go very far with that - as in letting every audio-source be used as mod-source as well - that would be too messy. but i like the idea of being able to throw together a basic monophonic subtractive synth with sources, filters and modulators already on the toolchain top-level. if you need polyphony and/or full modularity, go to liberty
but maybe at some point, i'll even allow for polyphony for the soucres/filters/modulators in toolchain itself....but that's no priority at the moment.
yeahhh...i think, liberty would actually also be a good environment to experiment with FM vs PM
i think, liberty would actually also be a good environment to experiment with FM vs PM
i will try to get liberty ready for work and then provide a sine-osc module with phase input and then create a PM patch and then try to emulate it using only the frequency input and filters. i think, passing the modulator signal through a differentiator before entering the frequency input should do the trick. likewise, using an integrator on the modulator in front of the PM input should emulate FM via PM. ...there might be some more obstacles, though - we'll see
Another use case for PM/FM converter: your resonator filters. If I replace my oscillators with resonator filters I might have an easy path to highly pingable filters with some overdrive capability.
Hmm, if you get Liberty working now I might actually setup Chaosfly in it and just go without having signal visualizers. Oh! Here's a solution, have many outputs out of Liberty and connect those outputs to VST audio visualizers!
And I need to know how to create modules for Liberty, I need a bunch of custom ones. Maybe I'll have to keep a personal repository for all my Liberty modules.
have many outputs out of Liberty and connect those outputs to VST audio visualizers!
for that, i would first have to figure out, how to let ToolChain itself have a dynamic number of outputs. something, that's on the ToDo list because i want to make my Linkwitz/Riley crossover available in ToolChain - and possibly the new crossover from multicomp (which itself will also have to be improved).
custom (atomic) modules...phew...i'll to refresh my grasp of the api that i wrote back then (fortunately, i took the code documentation seriously). from a quick look, it seems you need to subclass from romos::ModuleAtomic
but there are some things about the api that i'd like to change - for example, i have been using my own string class - i'd like to replace that with std::string. what kind of modules do you need? maybe they can themselves be realized meaningfully in a non-atomic way, given the right atomic modules
for example, i'm planning a tapped delay-module that has outputs for x[n-1], x[n-2],.... - a basic building block for filters. ...and a formula module to allow arbitrary N-input-M-output formulas (re-using the expression evaluator from func shaper) ...but maybe let's discuss this in the liberty thread...
Maybe I can ask you to add certain building blocks. Example would be the trisaw oscillator or resonator filters, signal crossfader for FM/PM (this is a crossfader that uses sin/cosin).
edit: oh trisaw oscillator needs FM and PM input
i think, i will make a TriSaw shaper into which you can feed input from a Phasor. this is more flexible. FM is the simply changing the frequency of the phasor and PM would mean to add something to the phasor's output before feeding it into the TriSawShaper...if i'm not mistaken
That's fine, it's less convenient, so we will need a feature where you create a container in Liberty, and you can duplicate that container, and a change to one of those containers updates the rest of the containers. "Macro Container"?
you can already create containers. either by putting a fresh container into the structure and going into it or by selecting a bunch of modules and "containerizing" the selection (all in the right-click menu). when you click on a container from it's parent module, you also have a "save container" option (maybe i should add it also to the menu when you click on an empty area, applying it to the container, we are currently inside of) and when you right-click on an empty area, you can load a container....but yeah - direct duplication would be more convenient
but if you change the container, only that one container changes? The container should reference the saved container file so that all containers referencing that file will be updated to reflect the changes.
ahh...now i understand what you mean some kind of aliasing or linking of a bunch of containers. but what has that to do with whether we have a TriSawOsc or TriSawShaper. the TriSawOsc is supposed to created from the TriSawShaper and a Phasor just once and for all and then used in the same, unchanged form everywhere - in the same way an atomic module would (this is why i didn't get what you mean at first)
yes, create it once, but for my purposes I may want to add more features like a convenient parameter for self-modulation. I want to create a whole Chaosfly Oscillator Unit which may have ever-growing number of features to make it easy to experiment with. I might build the soft clipper directly into the oscillator unit for example.
i've been just re-reading some document i printed out many years ago. this one:
http://argos.vu/wp-content/uploads/2016/05/Digital_Sound_Generation_1.pdf
on page 40, it says:
Even if an oscillator lacks immediate phase control, itβs still possible to add FM capabilities. As phase is the time integral of frequency, we may differentiate the modulator signal and add it to the frequency input
...the differentiator there looks weird. perhaps some sort of 2nd order differentiator? dunno. i may take a closer look when i'm back on monday
ahhh...it seems like it's just a first order lowpass before the actual differentiator (i was talking about the second one - the first one looks like what i would expect)
ok, i'll check out and probably won't be online until monday evening. c u
Move this to Discussion / Ideas