Generating sines and decaying sines
Theory
The goal of this algorithm is to produce a series of values \(s_i=\sin\left(2\pi\frac{if}{f_s}\right)\), where \(f\) is the desired frequency of the sine wave, \(f_s\) is the sampling frequency, and \(i\ge 0\) is an integer. If this series of values is fed into a DAC at \(f_s\) samples per second, then the output of the DAC would be a sine wave with a frequency of \(f\).
Recall that \(e^{j\theta}=\cos\theta + j\sin\theta\), where \(j\) is the imaginary unit. Thus, if we can compute the value of \(e^{2\pi j\frac{if}{f_s}}\), we would have not only \(s_i=\sin\left(2\pi\frac{if}{f_s}\right)\), but also \(c_i=\cos\left(2\pi\frac{if}{f_s}\right)\). Note that: $$ \frac{c_{i+1}+js_{i+1}}{c_i + js_i} = \frac{e^{2\pi j\frac{\left(i+1\right)f}{f_s}}}{e^{2\pi j\frac{if}{f_s}}} = e^{2\pi j\frac{f}{f_s}} $$ $$ c_{i+1}+js_{i+1} = \left(c_{i}+js_{i}\right) e^{2\pi j\frac{f}{f_s}} $$ If we let \(c_0=k\) and \(s_0=0\), then we will get a sine and cosine wave with amplitude \(k\). Furthermore, if the frequency and sample rate are known ahead of time, the real and imaginary parts of \(e^{2\pi j\frac{f}{f_s}}\) can be precomputed, allowing for more efficient evaluation: $$ c_{i+1}+js_{i+1} = \left(c_{i}+js_{i}\right) \left(C + jS\right) $$Limited precision
Theoretically, we can repeat the above recursive step infinitely many times and the sine wave will still have the same amplitude. However, since the precision of the stored value of \(s_i\) and \(c_i\) is limited, precision loss will cause the sine wave to either decay or grow exponentially. Suppose \(s_i\), \(c_i\), \(S\), and \(C\) are stored as \(n\)-bit signed integers. This means that these values must be scaled up by a factor of \(2^{n-1}\) in order to take advantage of all of the bits we have. In order for the iterative formula to still be true, we must divide each value by \(2^{n-1}\) $$ \frac{c_{i+1}}{2^{n-1}}+j\frac{s_{i+1}}{2^{n-1}} = \left(\frac{c_{i}}{2^{n-1}}+j\frac{s_{i}}{2^{n-1}}\right) \left(\frac{C}{2^{n-1}} + j\frac{S}{2^{n-1}}\right) $$ $$ c_{i+1}+js_{i+1} = \frac{\left(c_{i}+js_{i}\right) \left(C + jS\right)}{2^{n-1}} $$ The division by \(2^{n-1}\) can be efficiently implemented as a bitshift.Complex multiplication
Normally, multiplying two complex numbers would require four multiplications. However, there is a trick that can be used to reduce this to three multiplications: $$ \begin{aligned} c_{i+1}+js_{i+1} &= \frac{\left(c_{i}+js_{i}\right) \left(C + jS\right)}{2^{n-1}} \\ &=\frac{\left(c_iC - s_iS\right) + \left(c_iS + s_iC\right)j}{2^{n-1}} \\ &=\frac{\left(c_iC + s_iC - s_iS - s_iC\right) + \left(c_iS - c_iC + c_iC + s_iC\right)j}{2^{n-1}} \\ &=\frac{\left(C\left(c_i + s_i\right) - s_i\left(C + S\right)\right) + \left(C\left(c_i + s_i\right) - c_i\left(C - S\right)\right)j}{2^{n-1}} \end{aligned}$$ Instead of requiring four multiplications and two additions, complex multiplication only requires three multiplications and three additions. The values of \(C + S\) and \(C - S\) can also be precomputed.Analysis
As the algorithm runs, loss of precision will cause the sine wave to decrease or increase in amplitude. This is because the magnitude of \(C + Sj\) is not necessarily equal to \(2^{n-1}\). This will cause the magnitude of \(c_i + s_ij\) to change by a factor of \(\frac{\sqrt{C^2+S^2}}{2^{n-1}}\) per step. For given values of \(C\) and \(S\), we expect the amplitude to have changed by a factor of \(\left(\frac{\sqrt{C^2+S^2}}{2^{n-1}}\right)^{i}\). Since the elapsed time is equal to the sample number \(i\) divided by the sampling rate, the exponential decay or growth rate is \(f_s\ln\left(\frac{\sqrt{C^2+S^2}}{2^{n-1}}\right)\). This effect can also be exploited by deliberately increasing or decreasing the values of \(S\) and \(C\). For example, a decaying sine could be used to emulate a bell sound.
With every step of the algorithm, we expect the phase of \(c_i + s_ij\) to increase by the phase of \(C + Sj\), which is equal to \(\arctan\frac{S}{C}\). Since this happens \(f_s\) times per second, the frequency is \(f=\frac{\omega}{2\pi}=\frac{f_s\arctan\frac{S}{C}}{2\pi}\)
Calculator
Use this calculator to determine and compare values of \(C\) and \(S\) for a given expected frequency and decay rate.Precision:
Sampling frequency:
Frequency:
Decay rate: (negative for decay, positive for growth)
Value of S | |||
0 | 0 | ||
Value of C | 0 | ||
0 |
Comments
Post a Comment