﻿ Sine Wave Synthesis Part 1 - Theory and Simulation  Android Sine Wave Synthesis

Part 1 - Theory and Simulation

Preceding tutorials in this series:

Tutorials in that series that follow:

Limitations of PCM when synthesizing  waveforms

This is the first in set of tutorials that looks at synthesizing a sine wave within Android and follows on from the technology primer on pulse code modulation.

Before getting into the programming, it worth setting out how we will achieve the task and undertake some simulation to test the theory.

A sine wave can be reproduced using the following formula:

y(t)= Asin(2ϖft+φ)

A represents the peak amplitude, f represents the frequency, t represents time and φ represents phase in radians. t can be our periodic sampling time and y(t) will be our sample or quantized value. If we use the fact that periodic time is the inverse of the sample rate or:

periodic time=1/(sample rate)

then we can adapt this formula for programming.

Before doing that is it worth looking at the Android AudioTrack class. AudioTrack allows the playback of PCM data and we can set various parameters depending on the application. PCM data can be extracted from a .WAV file and then each sample can be added to an array or, as in our case, we calculate the samples mathematically and add them to the array. We have two streaming options with AudioTrack, we can stream continuous data for playback or calculate explicitly one period of a sine wave and repeat the pattern. As the sine wave is regular and predicable, then this is the approach I will take. This approach is less processor intensive, but we have to make sure we calculate exactly one period or we will end up with distortion. The last parameter we need to consider for now is the amplitude. Since we are using 16 bit PCM we will choose 32767. In the previous tutorial the lowest quantization value was set to 0. It is more convenient and intuitive to set the quantization value of zero mid-way between the highest and lowest quantization value. We therefore, represent the 16 bit PCM quantization levels as -32767 to +32767.

The pseudo code below sets out how we will achieve the task. 2 x ϖ will be one constant. We can simply multiply ϖ by 2 or take the arctangent of 1 and multiple it by 8. I'll choose the latter.

Constants

•  twopi = 8 * arctan (1)
•  sampleRate = 44100 /*maximum supported by AudioTrack
•  amp = 32767

Variables

• Frequency /* to be input by the user
• I = 0 /*index for samples counts initially zero
• samples[] /* array of signed integers to hold the samples
• phase = 0 /* phase angle in radian and starting at zero

We will set a for loop to increment and calculate the following in each loop:

• samples[i] = amp * sin(phase)
• phase = phase +  (twopi * frequency / sampleRate)

It quite straightforward to input these formulae into a spreadsheet and test the theory. I have done this with a spreadsheet you can download in open document format. The screenshot below shows that we generate a good sine wave at 1000 Hz. You can modify the frequency and sample rate in this model as see how the fidelity quickly diminishes as you increase frequency. This is evident well within the audible range. This is expected as we only take two samples per period at 20 KHz and end up with something that looks like a saw-tooth wave. For many people, they cannot hear these higher frequencies or they are well attenuated. Therefore, for many purposes 44.1 KHz will be fine. However, to increases the fidelity you will need a sample rate well above the Nyquist Rate. Try changing the sample rate in the model to 5,644,800 Hz (Used in some professional DSD recorders) and set the frequency to 20 KHz. The result is a high fidelity sine wave.

Now we are ready to program.

Download the sine wave simulator in OpenDoument format.   