           H O M E - APOLLO181 INTRODUCTION PWM LED Dimmer Step Motor Controller Sound Generator: Part 1 Sound Generator: Part 2 Random Number Generator How to play sound with APOLLO181 (Part 2): the software

After having built a basic 4-bit Digital to Audio converter, in this section we compute algorithms that generate audible notes in the range of 350-3500 Hz, starting from sampled waveforms, digitized at 8000 samples per second and using 4 bits per sample, that is equal to generate a constant bit rate signal of 32 Kbit/s.

The first, simplest waveform is a ~1KHz pure unsigned sine wave, which I have plotted in MS Excel with -45 degrees phase shift, and digitized with 8 samples (that means 8kHz of sample rate), using 16 rounded integer levels (that means 4-bit accuracy). The following table returns the eight level values which I have calculated for each sample:

 Sample number Degrees D/A D/A binary 1 0 13 1101 2 45 15 1111 3 90 13 1101 4 135 8 1000 5 180 2 0010 6 225 0 0000 7 270 2 0010 8 315 8 1000

Graphs plotted in MS Excel     A sine wave, with -45° phase shift, digitized at 8x sample rate, with 4-bit level accuracy

The first algorithm in APOLLO181 is very simple: just output to "port 0" the eight 4-bit binary samples, one by one, as an infinite cycle. In order to get a ~1kHz frequency, I temporarily used the trick to slow down the clock rate on the board, without computing any delay routine. The audio tone was nice to my ears and sufficiently loud.

1)                    Load accumulator with binary 13

2)                    Output accumulator to Port 0

3)                    Goto 4)

4)                    Load accumulator with binary 15

5)                    Output accumulator to Port 0

6)                    Goto 7)

7)                    Load accumulator with binary 13

...

...  etc etc, for binary 8, 2, 0, 2

...

22)                  Load accumulator with binary 8

23)                  Output accumulator to Port 0

24)                  Goto 1) Captured by a FTT spectral analysis system A 4-bit ~1000 Hz sine wave, sampled at 8x rate, as it is reconstructed by Apollo181 DAC

How to invoke subprograms without Call/Return statements

As usual with APOLLO181, it is a bit of a challenge to write effective software in only 256 available memory locations . The major limitation is the no provision at all of calling subroutine instructions. Since the delay between samples must be identical, it would be a waste of memory writing the same delay routine many times, across the whole program.

Since in the next exercise we are going to produce a cycle of 32 different samples to reconstruct a complex periodic waveform, by using 256 Bytes of RAM we would need to write 32 nearly identical subprograms, each occupying maximum eight locations of memory (256/32=8), that generate the sample and compute the delay between two adjacent samples. This is not only impractical, but also impossible to perform.

The solution (source: Choosing and using 4 bit microcontrollers, by Philip McDowell, 1993, pg. 116) is making use of a table of jumps, where the return statement would be. The 'calling' section of code loads a progressive number into a dedicated register prior to jump to the 'subroutine', and at the end of the routine, this number is used as an index to a table of jumps. This means that every use of the routine must have an entry in the table, and this restricts the number of 'calls' to a maximum of sixteen for a 4-bit processor; in our case the maximum number of 'calls' is only eight, because APOLLO181's jump statement requires two instructions to be performed: the first to load the accumulator with the low-order nibble of the RAM location, and the second for the jump instruction itself, which contains the high-order nibble.

Thus, in our exercise, we will need to repeat the pseudo-call routines four times inside the main algorithm (32/8=4), that is wasteful, but anyway more efficient than writing thirty-two identical delay routines.

Here below you may find the structure of the algorithm for calling a subprogram many times, , by using a table of jumps without the use of Call/Return statements:

0)                                Return_index = 0

1)                                Load accumulator with sample n.1

2)                                Output accumulator to Port 0

3)                                Goto Delay_subroutine

4)                                Load accumulator with sample n.2

5)                                Output accumulator to Port 0

6)                                Goto Delay_subroutine

7)                                Load accumulator with sample n.3

8)

Delay_subroutine:        CalculateDelay

Increment Return_index

Goto Return_index

Return_index 1):          Goto 4)

Return_index 2):          Goto 7)

Return_index 3):          Goto ...

…                               …

Joseph Fourier, mathematician and physicist of the 18th century, realized that any signal, no matter what looks the shape of the waveform, can be expressed as the sum of sinusoidal waves at various amplitudes and frequencies.

Thus, theoretically, it is possible to synthesize and reproduce any complex sound from the combination of pure sinusoidal tones. This is the concept behind additive synthesis, which involves constructing a wide range of sounds by adding up multiple sine waves at different frequencies and amplitude.

Unfortunately, a person’s voice or natural sounds are so complicated that require a nearly infinite amount of data processing to be recreated accurately. In practice, of course, the sum of sinusoidal waves is truncated to a finite number of terms, in order to considerably reduce the computational load. C Major chord made up of three notes sounding simultaneously, transponed from C4 to C6 (at ~1kHz)

In this exercise we will compute an algorithm to play a major triad, that is a chord composed of three notes alone, played simultaneously.

In particular, we are going to synthesize a C Major chord, that is one of the most common chord, used in many songs. This chord is basic because it comprises only three notes: C, E, and G. These, physically, have frequencies in the ratio of 4:5:6 and when they are played together, the three notes blend very well and are pleasant to the human ear.

To simplify all calculations, from now on we will adopt the scientific scale, based on 'Middle C' having a frequency of 256 Hz. This is also known as the diatonic scale, that is an eight-note musical scale composed of seven pitches and a repeated octave.

The frequencies of the three notes in the C Major chord (starting at 'Middle C') are: C4= 256 Hz, E4= 320 Hz and G4= 384 Hz.

The ratio of E to C is 5/4 (or 1,25). The ratio of G to C is 6/4= 3/2 (or 1,5) and the ratio of G to E is  6/5 (or 1,2). Since the ratio between every note can be expressed as the ratio of two small whole numbers, and the frequencies of the notes are equally distant from each other, they all sound pleasant together; hence the entire major triad is consonant.

The resulting waveform of  C+E+G, sum of sinusoids, is like:

C + E + G = sin(x) + sin(5/4 x) + sin(3/2 x)

where:

C4 = sin (2πf t)

E4 = sin (5/4 * 2πf t)

G4 = sin (3/2 * 2πf t)

and f = 256 Hz.

Since the period of  C is 2π, the period of E is 4/3π and the period of G is 8/5π, the resulting period of the sum C+E+G is 8π (that is the lowest common multiple of 2π, 4/3π and 8/5π). This means that the period of the C Major chord is 4 times (8π / 2π = 4) the period of the lowest note in the chord (i.e. four times the period of C4 note).

Since frequency is equal to the reciprocal of the period, the fundamental frequency for the C Major chord is one fourth the frequency of the lowest note in the chord, that's one fourth of C4: thus, in the C Major chord the fundamental frequency is missing from the tone and there is no spectral energy at that frequency.

The fundamental missing frequency for the C Major chord results to be 256/4= 64 Hz: of course if we need to digitize such a chord with 8kHz sample rate, we would need 8000/64= 125 different samples to reconstruct it.

Since we have only 256 bytes of RAM available for the program, we have to transpose the C Major chord two octaves up: by transposing sound two octaves up (that means four times the frequency) we need only one fourth of the number of samples while maintaining constant the sampling rate.

The frequencies of the three notes in the transposed C Major chord (starting now at 'Top C') are: C6= 1024 Hz, E6= 1280 Hz and G6= 1536 Hz, and the resulting chord has a missing fundamental frequency of 1024/4= 256 Hz.

Since in the C Major chord, the fundamental frequency has no spectral energy, the chord can be anyway reproduced by APOLLO181, even if the small speaker cannot reproduce sounds lower than 350 Hz.

In order to digitize such a chord using a sampling rate of 8000 Hz, we need now to generate only 8000/256 ~ 32 different samples useful to reconstruct the whole tone.

Graphs plotted in MS Excel     C Major Chord is synthetized by adding together bit-by-bit the samples of the 3 notes

Due to the lack of hardware resources, all the cumbersome calculations and the digital additive synthesis were made outside APOLLO181, under MS Excel. The algorithm is limited only to read the samples already stored in the program memory and issue them cyclically to the DAC, with the proper delay.

In particular I plotted for several periods each of the three sinusoids in MS Excel with +30 degrees phase shift, and I digitized, with an Excel formula, each period of the slowest wave (~1KHz sine wave) into eight samples (that means 8kHz of sample rate), by using sixteen rounded integer levels (that means 4-bit accuracy). I digitized the other two waves with the same sample rate, so, at the end, all the samples of the three waves last the same time and result synchronous. I then added together bit-by-bit the level of the corresponding samples, till covering a full period of the waveform. In fact, we have seen that the resulting wave is still periodic, with period equal to four periods of the slowest wave. For each sample I then divided the result of the sum by 3 and then I rounded it to an integer, in order to normalize the level to a 4-bit precision (that means that the peak amplitude of the level of any sample, so of the entire resulting waveform, cannot exceed binary 15).

The following table shows all the 32 samples (=8 samples*4 periods) which I have calculated:

 Sample number Degrees D/A D/A binary Sample number Degrees D/A D/A binary 1 0 11 1011 17 720 9 1001 2 45 15 1111 18 765 10 1010 3 90 12 1100 19 810 9 1001 4 135 5 0101 20 855 7 0111 5 180 2 0010 21 900 6 0110 6 225 4 0100 22 945 7 0111 7 270 8 1000 23 990 7 0111 8 315 11 1011 24 1035 6 0110 9 360 10 1010 25 1080 5 0101 10 405 8 1000 26 1125 7 0111 11 450 7 0111 27 1170 11 1011 12 495 8 1000 28 1215 12 1100 13 540 8 1000 29 1260 9 1001 14 585 6 0110 30 1305 3 0011 15 630 5 0101 31 1350 0 0000 16 675 6 0110 32 1395 4 0100

Graphs plotted in MS Excel     The resulting C6+E6+G6 Chord is still a periodic wave, that can be digitized with 32 samples

 Captured by a FTT spectral analysis system C6+E6+G6 Chord, sampled at 8x rate, 4-bit accuracy, as it is reconstructed by Apollo181 DAC

Here you can listen to APOLLO181 C Major chord outcome and below the page you may check the full program.

PLAY APOLLO181 reconstructed chord

Sound reconstruction: a pencil-paper method

The last exercise is easy and practical. The waveform of a single tone of a real violin was recorded and printed on a paper. After that, with the use of a special grid 32x16, it was sampled with a red pencil. The 32 samples, having each 4-bit accuracy, were loaded into APOLLO181 RAM and played by using the same algorithm as was used before.

Here you can listen to the true tone of the original violin first and, after a brief pause, to APOLLO181 playing the same but reconstructed tone.

PLAY VIOLIN tone comparison

A part the natural vibrato timbre, characteristic envelope modulation of the real violin’s waveform, the two tones sound very similar to the human ear.     A real violin was recorded and digitized by hand using 32 samples with 4-bit precision

 Captured by a FTT spectral analysis system The violin waveform, sampled at 8x rate, as it is reconstructed by Apollo181 DAC     