Reputation: 5
What I'm trying to do is have a smooth transition from sine wave with a given set of values to another wave with a different value without introducing a kink into the sin wave. I'm at the fringes of my Maths knowledge so it anyone has any idea how to achieve this it would be greatly appreciated. I have looked at other questions and I have a gut feeling the answer is in a signal processing question.. phase vs time, instead of speed (or frequency) vs time. Just not sure how to adapt it to suit my code.
This link (bottom of the page) shows a working example of showing a waveform continously changing on the fly without any jumps in the wave when you change the value page link
Its all to generate the wing beats of a butterfly in after effects (which uses javascript) by changing the y axis angle on a graphic of a wing.
I used this formula: amplitude * Math.sin(time*speed)+bias
It all works fine until I need to change any of the key values amplitude, speed and bias. The animation has a jump in it or a flicker. I found some graph representations of what's happening, but not quite sure how to fix it in the code to create a smooth transition.
This image shows one of the kinks I'm getting
This image shows another kink in the wave
This image shows the smooth transition of what I'm trying to achieve
Many thanks for your time and any feedback you may have.
Upvotes: 0
Views: 508
Reputation: 16
@Meeesta I was looking to create an effect similar to the mathisfun example you shared. I was successful by adjusting my usual formula/approach to generate the wave. So rather than:
y = Math.sin(elapsedTime + frequency) * amplitude); // Don't do this for this scenario
Instead I do this on each update step (pseudo code):
// y value
phase -= frequency * deltaTime;
y = Math.sin(phase) * amplitude;
// x value
waveSpeed = frequency * wavelength * deltaTime;
x -= waveSpeed; // do this for each point in your wave line to shift the wave left
Here is a working example.
I am not sure the math is 100% accurate in terms of the wave form generated but the effect is right and it's close enough for my purposes.
Upvotes: 0
Reputation: 1
The best approach is to use the Waveform effect and experiment with the settings.
Upvotes: -1
Reputation: 9857
The best way to do so, for me, is to add a phase increment whenever a new sample is generated. When the amplitude or frequency changes, there would a "smooth transition".
Pseudo code:
int i = 0;
do {
// Calculate phase increment
phaseIncrement = 2 * M_PI * frequency / sampleRate;
// Generate sample
float sample = sin(phase);
// Update phase
phase = fmod((float) (phase + phaseIncrement), (float) (2 * M_PI));
// Convert sample to 32-bit integer
int16_t outputSample = sample * INT16_MAX;
// Write output to stdout
fwrite(&outputSample, sizeof(int16_t), 1, stdout);
} while (++i != signalLength * sampleRate);
Upvotes: 0
Reputation: 1908
Your objective of creating a 'smooth' transition is not a well defined mathematical description. To simply make the wave form continuous and correctly ascending or descending during the transition, one simple way would be to wait for the next time the waveform is zero and then change the amplitude and frequency instantaneously at that point in time, and calculate a new phase P.
For example, suppose your wave form is
f(t) = a*sin(w*t + p)
and at time t_0 such that w*t_0 + p = n*pi, you want the amplitude a to change to A, the radians per second to change from w to W, then you need to calculate a new P so they join up at t = t_0.
n = ceil((w*t + p)/pi)
t_0 = (n*pi - p) / w
P = n*pi - W*t_0
so for t >= t_0
f(t) = A*sin(W*t + P)
Upvotes: 1