4.5. Polyphonic ringtones
While in the previous chapter, I carefully
You proved the futility of attempts to music programming in
assembler, you still should know the basic principles of this
activity.
Now I will describe the creation of polyphonic
music, ie music which can
sound two or more notes simultaneously.
The first example is a subroutine,
Two-simulating sound:
1415.
10 DI; ban interrupt
20 LD D, 200; D = Frequency 1
30 LD E, 50; E = Frequency 2
40 LD H, 150; H = duration
50 XOR A; A = border for voice 1 (0)
60 EX AF, AF '; shift registers A and F on
Alternative
70 XOR A; A = border for voice 2 (0)
80 LD C, E; C = Counter 1
90 LD B, D; B = Counter 2
100 BEEP EX AF, AF '; shift registers A and F
(Changing voice)
110 DEC C; C = C-1
120 JR NZ, CONT; if C <> 0 then go to
CONT
130 LD C, E; restore counter 1
140 XOR 16; invert the bits D4 to vote
1
150 CONT OUT (254), A; bring A to port 254
160 EX AF, AF '; shift registers A and F
(Changing voice)
170 DEC B; B = B-1
180 JR NZ, CONT2; if B <> 0 then go to
CONT2
190 LD B, D; restore Counter 2
200 XOR 16; invert the bits D4 to vote
2
210 CONT2 OUT (254), A; bring A to port 254
220 INC L; L = L +1
230 JR NZ, BEEP; if L <> 0 then go to
BEEP
240 NOP; reserve
250 NOP; reserve
260 DEC H; H = H-1
270 JR NZ, BEEP; if H <> 0 then go to
BEEP
280 EI; permission to interrupt
290 RET; Returns
2
Now I will explain some details.
Two alternative register A is used first and second votes
for the storage Border color and condition of the speaker.
Countries of operations to register before L
completion of the cycle is designed to "stretch" length. If you
remove it, then the sound of this subprogramme will be so short
that you can get it do not even hear.
Two-byte transfer (operation NOP) you can use to change the
frequency Both votes during playback.
To do this, instead of "NOP" to insert INC
DEC D or D for the first vote and INC E or
DEC E for the second.
This routine can be used to
assembly (see previous chapter), or
BASIC (in this case, the parameters should be entered by the
operator in the following POKE
cell: ADDR +2 - Frequency 1, ADDR +4 - frequency 2, ADDR +6 -
duration, where ADDR - the address of the subroutine in memory).
The next two polyphonic routines very similar to each other,
but the first sounds much quieter and cleaner than a few
second.
Here they are:
1415.
10 DI; ban interrupt
20 LD HL, 2000; HL = length
30 LOOP1 LD IX, FRQS; IX = address of frequency tables
40 LD B, 5; B = number of votes
50 LOOP2 DEC (IX +0); byte at IX +0
decrease 1
60 JR NZ, NOSIGN; if not 0, then go to
NOSIGN
70 LD A, 24; A = Border color + 24
80 OUT (254), A; output to port A 254
90 LD A, (IX +5); update counter
100 LD (IX +0), A; current channel
110 XOR A; A = color of the border (0)
120 OUT (254), A; output to port A 254
130 NOSIGN INC IX; IX = IX +1
140 DJNZ LOOP2; cycle
150 DEC HL; HL = HL-1
160 LD A, H; HL =
170 OR L; 0?
180 JR NZ, LOOP1; if not, then the cycle
190 EI; permission to interrupt
200 RET; Returns
210 FRQS DEFB 1,1,1,1,1; counters for 5 channels
220 DEFB 10,20,30; frequency
230 DEFB 40,50; 5 channels
10 DI; ban interrupt
20 LD HL, 2000; HL = length
30 LOOP1 LD IX, FRQS; IX = address of frequency tables
40 LD B, 5; B = number of votes
50 LOOP2 DEC (IX +0); byte at IX +0
decrease 1
60 JR NZ, NOSIGN; if not 0, then go to
NOSIGN
70 LD A, (IX +5); A = IX +5 contents
80 XOR 1; invert bit D0
90 LD (IX +5), A; contents IX +5 = A
100 LD A, 0; A = Border color
110 JR Z, NOSIGN; if D0 contains. IX +5 = 0, then
go to NOSIGN
120 OR 24; set to 1 bits D3 and
D4 register A
130 OUT (254), A; output to port A 254
140 LD A, (IX +10); update counter
150 LD (IX +0), A; current channel
160 NOSIGN INC IX; IX = IX +1
170 DJNZ LOOP2; cycle
180 DEC HL; HL = HL-1
190 LD A, H; HL =
200 OR L; 0?
210 JR NZ, LOOP1; if not, then the cycle
220 EI; permission to interrupt
230 RET; Returns
240 FRQS DEFB 1,1,1,1,1; counters for 5 channels
250 DEFB 0,0,0,0,0; buffers for 5 channels
260 DEFB 10,20,30; frequency
270 DEFB 40,50; 5 channels
2
These routines give birth counters
each channel and subsequently their
reduced. If any of the counters
becomes 0, the speaker output
signal, and at the counter recorded the frequency of the table.
In these examples, routines reproduce by five votes, but you
can easily change their number, modifying values in lines 40
and 90 for the first subprogram, or 40,70,90 and 140 (line 140
need to insert the number of votes multiplied by 2) - for the
second. It should also adjust the frequency table.
While the vote may be quite a lot (85), to get involved in
their number is not worth it, because more of them, the worse
the quality. However, there is hardly a genius able to write a
song by 85 votes.
If you want to use polyphony, but at any given time you
want to play a lesser number of votes
What is given, then the unused voices need to assign
frequencies, which coincide with the frequencies used by the
votes.