Audio signal is generated by software and internal MCU peripherals. There is no dedictated sound controler in PIC peripherals, but some other resources are used instead. As the consequence to this compromise, audio output signal is pure binary (square wave), just like in the old computers and game consoles. To make the sound more pleasant, there is the passive, first order low-pass RC filter (R15-R19 and C9). There are five audio channels, each of them controlled by software. On-off, tone frequency and two-step volume control is supported. Three channels are typically used for music, one is for Jack's sound effects and one for his enemies sound effects.

The most convenient peripheral for audio signal generating is OC (output Compare), which is preset to Center-Aligned PWM mode. Unfortunately, there are only four OC channels in PIC24EP512GP202 (or any other 28-pin PIC MCU), and one of them is already used in horizontal sync generator, so we have only three for audio application. They are used for music.

The remaining two audio channels (sound effects) are created using TX units from UART1 and UART2 peripherals. TX buffers (U1TXREG and U2TXREG) are permanently loaded with 10101010s, so the whole transmited sequence, including Start and Stop bits, contains 0101010101s, repeated endlessly. BRG (Baud Rate Generator) determines the frequency, and On-Off is obtained by remapping Peripheral Pin Select to TX out or Port Latch.

In the Menu (or Pause) page, each channel is adjusted to Off, Low and High volume. The only difference which determines volume level, is OD (Open Drain) bit in ODCx register.

Music (or effect) script contains of 4-byte groups. First byte is for tone channel #1, then goes tone channel #2, tone channel #3 and duration (in 17.86 ms steps, which is equivqlent to 56 Hz, same as VGA vertical frequency). The table on the bottom is for tone pitch bytes (red numbers, 1-75), showing corresponding tones (blue, A2-B8) and frequencies (black, 110-7920 Hz). If the tone byte contains 0, it is pause (no tone on that channel), and if it contains 99, it is "no change" (previous tone continues). All table members must contain four bytes. Table terminator contains 0,0,0,255 and then follows one-word address (low endian) with new table which shall be executed. So "0,0,0,255" is opcode "jump" and the following word is jump address.

For sound effects, script contains 2-byte members. The first one is the tone pitch, and the second one is pitch in 17.86 ms steps (56 Hz). Terminator contains two zero bytes. There is no loop address like in the music script, as sound effects should be executed only once for each game event. Pause is represented as 0 (followed by pause duration byte which is >0), and there is no "equal" byte, as this is monotone effects table.

There are two global variables, named music.shift and effects.shift, they are used as global pitch shifters, for final frequency adjustment in one-tone steps. By default, they are 8 and 6. respectively.

The first example is for the part of Jumping Jack main theme (pp is pause and it equals to 00, ee means "equal" and it equals to 99 in the table), and the second one is sound effect for Jack's jump:

.byte pp,19,38,11
.byte pp,ee,pp,1
.byte pp,21,38,12
.byte 14,24,41,12
.byte 14,21,ee,12
.byte pp,pp,ee,12
.byte 14,21,ee,23
.byte pp,pp,ee,1
.byte 14,21,38,12
.byte pp,19,ee,12
.byte pp,21,ee,12
.byte pp,24,41,24
.byte pp,19,38,12
.byte pp,21,41,12
.byte pp,24,ee,24
.byte pp,19,43,12
.byte pp,21,42,12
.byte 14,24,ee,12
.byte 14,21,ee,12
.byte pp,pp,ee,12
  .byte 29,2
.byte 30,2
.byte 31,2
.byte 32,1
.byte 33,1
.byte 34,1
.byte 35,1
.byte 36,1
.byte 0,0
1 A2 110 Hz 13 A3 220 Hz 25 A4 440 Hz 37 A5 880 Hz 49 A6 1760 Hz 61 A7 3520 Hz 73 A8 7040 Hz
2 A#2 117 Hz 14 A#3 233 Hz 26 A#4 466 Hz 38 A#5 932 Hz 50 A#6 1865 Hz 62 A#7 3729 Hz 74 A#8 7459 Hz
3 B2 123 Hz 15 B3 245 Hz 27 B4 494 Hz 39 B5 988 Hz 51 B6 1976 Hz 63 B7 3951 Hz 75 B8 7902 Hz
4 C3 130 Hz 16 C4 262 Hz 28 C5 523 Hz 40 C6 1046 Hz 52 C7 2093 Hz 64 C8 4186 Hz      
5 C#3 139 Hz 17 C#4 279 Hz 29 C#5 558 Hz 41 C#6 1117 Hz 53 C#7 2233 Hz 65 C#8 4467 Hz      
6 D3 147 Hz 18 D4 294 Hz 30 D5 587 Hz 42 D6 1175 Hz 54 D7 2349 Hz 66 D8 4699 Hz      
7 D#3 156 Hz 19 D#4 311 Hz 31 D#5 622 Hz 43 D#6 1244 Hz 55 D#7 2489 Hz 67 D#8 4978 Hz      
8 E3 165 Hz 20 E4 330 Hz 32 E5 659 Hz 44 E6 1318 Hz 56 E7 2637 Hz 68 E8 5274 Hz      
9 F3 175 Hz 21 F4 349 Hz 33 F5 698 Hz 45 F6 1397 Hz 57 F7 2794 Hz 69 F8 5588 Hz      
10 F#3 185 Hz 22 F#4 370 Hz 34 F#5 740 Hz 46 F#6 1480 Hz 58 F#7 2960 Hz 70 F#8 5920 Hz      
11 G3 196 Hz 23 G4 392 Hz 35 G5 784 Hz 47 G6 1568 Hz 59 G7 3136 Hz 71 G8 6272 Hz      
12 G#3 208 Hz 24 G#4 415 Hz 36 G#5 831 Hz 48 G#6 1661 Hz 60 G#7 3322 Hz 72 G#8 6645 Hz      


Note: Special credits go to Marko Antonić, who made the arrangements for music and adapted them for this media. Thanks to him, music sounds suprisingly good, even with this modest hardware.

    Back to projects 
1. Home
2. Hardware
3. Video signal
4. Sound
5. Sync
6. Jumping Jack
7. Download