• ### how to change the frequency of a sine wave smoothly

I'm generating a control-level sine wave to be used for LFO like this:

I'm using the multiplication box on the right to control the frequency. This works, except that it creates horrible jolts in the waveform when you select a new frequency. I can see exactly why this happens--it's jumping to a point in the phase. The question is, how can I correct it?

So far I've tried:

1. smoothing the frequency using [line]. This makes it go crazy!
2. Muting the output until the new phase catches up. This is acceptable, but I'm hoping that there is a better solution.

This has to be done at control level, not line level. Any ideas?

• Posts 16 | Views 7119
• Instead of multiplying the results of the counter, what if you instead multiplied the increment? so you are adding 0.1(speed multiplier). Shouldn't that preserve the phase point and just change the rate of accumulation?

Unless you are using 0.1 every 50ms as a sort of time base or if that accumulation is coming from somewhere else in the patch...

• Thanks for the suggestion. In the system I'm building, there is going to be one counter sending data to many LFO units inside abstractions, so I had wanted to keep the counter stable. That being said, I can see how it could work. I could keep just the [metro] as central and then have each abstraction count and then calculate the waveform. It seems a bit wasteful to have so many counters working in parallel (there might be 50+), but I might do this if I can't find a better solution.

• I thought of another thing- you could sample the sine output when the speed changes and subtract or add that value to what you're inputting to the sine to preserve that phase point. Or preserve the phase point but still add the value you wanted to advance during that step.

Because the sin wraps the values in a certain way, it's possible to jump to a specific phase by subtracting the current output from the stream that's going to the input. Although this would require an extra [f ] object. or would it?

• wait, never mind. This isn't true, because outputs of the sine function are equal at multiple phases so it is not possible to work backwards.

Unless! you used a [wrap ] or modulo object, and fed that into the sin. you could preserve a value from 0 to 1 and feed that into the sin function

• @LiamG Is there a reason not to use [osc~] into [snapshot].... ?
David.

• @LarsXI , this is the kind of thing that I was thinking of, but I can't quite get my head around the mathematics of it. I think I would need to use an arcsine function. Can anybody help?

@whale-av , I'd rather stay away from line-level objects for the sake of economy. In some patches I'm using this abstraction over 50 times, and 50 instances of [osc~] add up.

• You could try to implement a stepped low-pass in the message domain, much like a counter. I've used that with luck for exponential interpolation between random values before. Make it run on the same bang as your counter.

This is a first order low-pass filter:

y[n] = y[n-1] + a * (x[n] - y[n-1])

a being the filter coefficient (lower values = slower filter).

Try this and let me know how it works: msg-lop.pd

Also, where and how did you implement the [line] object?

• I tried putting a [line] right after the frequency number box, so that it would smooth out the multiplier before the number stream went into the [sin] object. But this had the effect of giving a series of glitches rather than one. The result is quite interesting, but definitely not what I'm looking for.

I did find a solution to the problem by focusing on the line of numbers, before it reaches the [sin] object. Basically, if you can smooth it over so that the new slope carries on where the last one left off, there will be no loss of continuity in the sine wave. Here's the solution I found: samp.pd (don't ask me how it works though).

However, this solution is so much more complicated than @LarsXI's idea of simply changing the line increment that it doesn't really make much sense. I think I'll just go with that.

• @LiamG Efficiency-wise I have no idea..... but [smooth] is an abstraction that seems closer to what you need...... smooth_test.pd than [samp]
David.

• @whale-av Here is a simple idea that could be the most efficient....... maybe........
thingy.pd
The metro can be central, and you only need the one table.....
The higher the frequency the fewer the data points within a cycle, but with a fixed metro I cannot see how you can avoid that.
You could however just add a [line] with the grain you want, taking [\$1 50( to smooth the output, but it will not be a curve.
David.

• Here's the downstream method that uses a fractional phase system! I wonder if it is more computationally intensive that just doing multiple counters, or the other methods.

downstreamphase.pd

• @LiamG have you benchmark tested the CPU consumption of 50 sine waves? Cause [osc~] is a table look-up oscillator and it shouldn't consume too much CPU. If Pd can't handle 50 table look-up oscillators, then it's probably no good.
Haven't done this benchmark test, but I'm pretty sure it shouldn't be a problem.

• @alexandros I second that, as I have built a patch with 20480 [osc~] objects, that took a while to load, but ran whilst the frequencies of every [osc~] were being constantly changed by osc messages(glissandi).
With 40960 The patch had difficulty....... and took so long to load that I never tried a number in between.
Pd extended...... so 32-bit.
David.

• Well you might be right, but my audio patches tend to run heavy already and I don't want to stress them any further. I guess that I also just like doing things in the non-signal domain. LarsXI's first solution is quite simple and effective and only uses one more object than the [snapshot~] method would, so I think I'll be going with that!

• This post is deleted!
Posts 16 | Views 7119
Internal error.

Oops! Looks like something went wrong!