Android Sine Wave Synthesis

Part 1 -

Preceding tutorials in this series:

Tutorials in that series that follow:

- Part 2 -
Project Framework - Part 3 -
PlayWave.java Class Constructor - Part 4 -
PlayWave.java Methods - Part 5 -
MainActivity and Testing - Part 6 -
Using a Scope and Limits

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-

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-

Now we are ready to program.

Download the sine wave simulator in OpenDoument format.

Download Download the Project files