Mathematically Ramp down a sinewave to 0 or switch frequencies

In summary: You might consider halving the amplitude until it’s reallly small like 1/256 of the original value picking 1/256 as a convenient value for basically eight steps to silence.
  • #1
btb4198
572
10
How do Mathematically Ramp down a sinewave to 0 or switch frequencies without causing a clicking sound?
I wrote code to play a sinewave but when I stop the sound I can hear a clicking sound. I tried to slowly ramp down the Amplitude, but that seem to only work for some Combination of frequencies and amplitudes.

here is what I have:

Naudio play code:
public override int Read(byte[] buffer, int offset, int sampleCount)
        {

            if (position == 0 && onetimeflag == false )
            {
                n2 = 0;
                onetimeflag = true;
            }

            if(stopflag == true && Amplitude > 0 )
            {
                Amplitude = Math.Round(Amplitude - 0.01,2);
            }

            if ((n2 >= BufferLength || stopflag == true) && lastvalue == 0 )
            {
          

                return -1;
            }
 for (int i = 0; i < (sampleCount / 4); i++)
            {
              
                    temp1 = (float)(Amplitude * Math.Sin(2D * Math.PI * RightFrequencyOutPut * n2 / 44100D));
                    Frequency_switch = true;
                    n2++;
                }
                lastvalue = temp1;
                byte[] bytes = BitConverter.GetBytes(temp1);
                buffer[i * 4 + 0] = bytes[0];
                buffer[i * 4 + 1] = bytes[1];
                buffer[i * 4 + 2] = bytes[2];
                buffer[i * 4 + 3] = bytes[3];
                tempSample++;
              
            }
            return sampleCount;
        }
 
Technology news on Phys.org
  • #2
Also, I am using the C# library NAudio. Anyhow I know there has to be a Mathematically way of not producing a clicking sound and a Mathematically way of smoothly switching between frequencies.
is there an Equation to do this?
 
  • #3
I’m sure you can create a function to do it. However, there is no one function that does this ramping down.

You might consider halving the amplitude until it’s reallly small like 1/256 of the original value picking 1/256 as a convenient value for basically eight steps to silence.

Db wise this will subtract 6db from the signal at each step.
 
  • #4
You will get a click if there is a step at the transition.
Switch the sinewave on or off at a zero crossing.
To change between two sinewaves, switch when they have equal values and the derivatives have the same sign.
 
  • Like
Likes berkeman, Filip Larsen, jedishrfu and 1 other person
  • #5
  • #6
  • #7
Baluncore said:
You will get a click if there is a step at the transition.
Switch the sinewave on or off at a zero crossing.
To change between two sinewaves, switch when they have equal values and the derivatives have the same sign.
is there a mathematically way to know when numbers I will cross from 0 on ?
 
  • #8
btb4198 said:
is there a mathematically way to know when numbers I will cross from 0 on ?
That will depend on how you generate your sinewave, and how it is stored.
The sign ± will change at each zero crossing.

You could generate the data in a separate array, search that array backwards for the last change of sign, and then copy the part you need, up to the final zero, into the Naudio buffer.

You might be able to read the data in, and change the length of, a Naudio buffer.
 
  • #9
btb4198 said:
Is there a way to make it fade out when you click a button ?
Yes, you call the BeginFadeOut method in the button's click event handler. How much C# programming have you done? What is your end goal? Dealing with button clicks and sound events is something that is handled well by most game engines and you may be better off using one of these appropriate for your platform than trying to create something from scratch.
 
  • #10
Rather than jumping into Coding with both feet, why not consider what's needed first. You have FSK here (frequency shift keying). That can be achieved as smoothly as you want. If you are synthesising sine wave samples using
A(t) = A0(sin(ωt))
and slowly change the value of ω from one frequency to the next then you will have samples of a continuous curve. The varying values of ω (call them ω(t')) can be varied over as long a range of t' as you want. That ω(t') function need not be linear but it can follow, say, a raised cos shape (easy to code for). That will result in very narrow sidebands with frequency spacing of around 1/(transition time). That's about as good as you could get.
 
  • #11
sophiecentaur said:
If you are synthesising sine wave samples using A(t) = A0(sin(ωt)) and slowly change the value of ω from one frequency to the next then you will have samples of a continuous curve.
Careful, if you are varying ## \omega ## I think you need ## A(t) = A_0 \sin \left ( \omega \left ( t - 2 \pi \left \lfloor \frac{t}{2 \pi} \right \rfloor \right ) \right) ##
 
  • #12
You vary omega values with time in a straight sine wave formula. I haven’t time to search for a ref but look up a definition of fm.
The steps in t will be equal. Omega is varied over a period covering many carrier cycles if you want to avoid a click.
The coding would be easy enough.
PS
@pbuk that formula is wrong / incomplete. The bit in the brackets is zero)
 
Last edited:
  • #13
sophiecentaur said:
The coding would be easy enough.
Yes, it's easier to code than to write it in ## \LaTeX ## but if you don't make the correction I indicated then you will get ## \sin ( (\omega + \delta \omega) (t + \delta t)) ## instead of ## \sin ( \omega (t + \delta t)+ \delta t \delta \omega)) ##: consider the impact of the ## t \delta \omega ## term when t is, say, 10 seconds.
 
  • #14
pbuk said:
Yes, it's easier to code than to write it in ## \LaTeX ## but if you don't make the correction I indicated then you will get ## \sin ( (\omega + \delta \omega) (t + \delta t)) ## instead of ## \sin ( \omega (t + \delta t)+ \delta t \delta \omega)) ##: consider the impact of the ## t \delta \omega ## term when t is, say, 10 seconds.
I have used t for the carrier and t' for the modulation waveform. That's sloppy and I should have pointed out that ω is a function of time like:
ω(t) = ω0(1+rt)

Also sloppy but r is the desired rate of change of ω and would be Δω/ transition time for a linear slide in frequency and it applied just during the transition period. r can be modified to reduce the bandwidth ('clicks')

(I usually fail with Latex so I tend to use the lazy verbal alternative for anything complicated. Mea culpa)
 
  • #15
The math could be avoided by programming a state machine as a DDS, to generate the buffer content step by step. That way the frequency and amplitude could be changed in real time, at rates specified in the numerical control registers.
https://en.wikipedia.org/wiki/Direct_digital_synthesis
 
  • Like
Likes sophiecentaur and pbuk
  • #16
Baluncore said:
The math could be avoided by programming a state machine as a DDS, to generate the buffer content step by step. That way the frequency and amplitude could be changed in real time, at rates specified in the numerical control registers.
https://en.wikipedia.org/wiki/Direct_digital_synthesis
Thanks for shaking us out of the hole we have dropped into - in real time digital signal processing there is no time to be calculating the sine of anything, we use lookup tables. And we don't need to worry about the detail of this anyway when we write an application because we use a library, in this case NAudio.

Note that in order to play a tone with a different frequency in NAudio, like most simple sound libraries, you stop playing one tone (with a call to BeginFadeOut) and start playing another one (with a call to BeginFadeIn).
 
  • #17
pbuk said:
Thanks for shaking us out of the hole we have dropped into - in real time digital signal processing there is no time to be calculating the sine of anything, we use lookup tables. And we don't need to worry about the detail of this anyway when we write an application because we use a library, in this case NAudio.

Note that in order to play a tone with a different frequency in NAudio, like most simple sound libraries, you stop playing one tone (with a call to BeginFadeOut) and start playing another one (with a call to BeginFadeIn).
Last nights I was discussing just this approach but in a totally different context. Machines exist that will perform all sorts of functions and the risk is going too far down the “just get it done” route.
Using a look up table is not essentially different from calculating sin(c) except you need to have some grasp of what a sine function means.
That is unless you want Mr Google to do all your thinking for you and then we end up in the tyrany of the machine. Democracy will die. (Over dramatic? Are you sure?)
 
  • #18
pbuk said:
(with a call to BeginFadeOut) and start playing another one (with a call to BeginFadeIn).
That could involve a variation in level and not necessarily the minimal phase disturbance. Doing it as quickly as possible would not be best (and cleanest) achieved this way because the phase progression between tones is not defined.
Proper synthesis can specify the precise transition. A library of functions may or may not have the required best function built in.
 
  • Like
Likes Baluncore
  • #19
pbuk said:
Note that in order to play a tone with a different frequency in NAudio, like most simple sound libraries, you stop playing one tone (with a call to BeginFadeOut) and start playing another one (with a call to BeginFadeIn).
That is a significant limitation of Naudio.
Fade_in and fade_out prevent changing the generated frequency on the fly without an amplitude step. The transition between the two sine waves will have an unknown phase difference during the transition.

A DDS employs a phase accumulator. Frequency is the rate of change of phase. Loading the frequency control register will immediately change the frequency, without any transient step in amplitude or phase.

At audio sample rates it matters little whether you use a lookup table or evaluate sine( phase ).
 
  • #20
sophiecentaur said:
That could involve a variation in level and not necessarily the minimal phase disturbance.
Baluncore said:
That is a significant limitation of Naudio.
Hey, don't shoot the messenger - NAudio is the OP's choice, not mine. But given the limitations exposed in this post I think they have more significant issues to address than the choice of audio library.
 
  • #21
  • #22
By necessity, shifting from a sinewave of a specific amplitude to anything else will involved the generation of other frequency components during the transition.

My strategy would be to minimize those other components.

So, in a loop that varies t, you calculate
. amplitude = Asin(Bt).
At the start of the transition (t0), you split this into two constructively interfering sine waves of slightly different pitch - with the difference represented by D:
. amplitude = (A/2)( sin(Bt+D(t-t0)) + sin(Bt-D(t-t0)) )
which can also be written:
. amplitude = Asin(Bt)cos(D(t-t0))
Once the D(t-t0) term reaches pi/2 use:
. amplitude = 0

If you are transitioning from one tone (A,B) to another (E,F), I would recommend treating them independently:
. amplitude = Asin(Bt)cos(D(t-t0)) + Esin(Ft)sin(D(t-t0)) . . . [for D(t-t0) from 0 to pi/2]
 

FAQ: Mathematically Ramp down a sinewave to 0 or switch frequencies

What is the purpose of mathematically ramping down a sinewave to 0 or switching frequencies?

The purpose of mathematically ramping down a sinewave to 0 or switching frequencies is to gradually decrease the amplitude of a signal or change its frequency over time. This can be used in various applications such as signal processing, audio engineering, and electronic circuit design.

How does one mathematically ramp down a sinewave?

To mathematically ramp down a sinewave, one can use a mathematical function or algorithm to gradually decrease the amplitude of the signal over time. This can be achieved using techniques such as amplitude modulation, frequency modulation, or pulse width modulation.

What is the purpose of switching frequencies?

The purpose of switching frequencies is to change the frequency of a signal, which can have various effects depending on the application. For example, in audio engineering, switching frequencies can create different sounds or filter out unwanted frequencies. In electronic circuit design, switching frequencies can be used to control the timing of signals.

How does one switch frequencies in a sinewave?

To switch frequencies in a sinewave, one can use a frequency mixer or oscillator circuit that can generate different frequencies. This can also be achieved using digital signal processing techniques, where the sinewave is sampled and the frequency is manipulated through digital algorithms.

What are some common applications of mathematically ramping down a sinewave or switching frequencies?

Some common applications of mathematically ramping down a sinewave or switching frequencies include audio effects such as tremolo, vibrato, and ring modulation in music production, frequency shifting and filtering in signal processing, and frequency control in electronic circuits such as oscillators and filters.

Similar threads

Replies
16
Views
3K
Replies
5
Views
5K
Replies
4
Views
1K
Replies
4
Views
7K
Replies
14
Views
3K
Replies
1
Views
1K
Replies
1
Views
2K
Back
Top