ZX Forum #04
19 ноября 1997 |
|
world of sound Spectrum - Chapter 4.1: Programming sound effects - Tone, Noise, Complexes effects.
4.1. Programming Sound Effects In fact, programming effects code differs little from similar classes in Basic, but you get a significant advantage at the expense of speed. Therefore, other than pure tones in assembler, you can create and noise. 4.1.1. Tone We begin with the effects based on the generation of tones. What are they? Roughly the same as the effects in Basic: the sound of smoothly varying frequency. For complete similarity can even use the same routine from ROM: 1415. 10 LD B, 30; B = number of notes 20 LD HL, 100; HL = start frequency 30 LOOP LD DE, 2; DE = duration 1940 PUSH HL; conservation HL 1950 PUSH BC; preservation BC 60 CALL 949, call ROM routines 1970 POP BC; restore BC 1980 POP HL; recovery HL 90 LD DE, 25; DE = step frequency changes 100 ADD HL, DE; increase in HL 110 DJNZ LOOP; cycle 120 RET; return to BASIC 2 Most likely, you've noticed that in this effect does not prohibit termination, and signal quality no worse (see chapter "How is sound"). The fact is that routine is called to do everything myself. If you have already managed to recruit and run this fragment, it probably felt the difference in the sound, not in favor of BASIC. Modify somewhat the effect possible by changing the frequency is not the whole but only its Low byte: 1415. 10 LD B, 60; B = number of notes 20 LD C, 50; C = step frequency changes 30 LD HL, 300; HL = start frequency 40 LOOP LD DE, 10; DE = duration 1950 PUSH HL; conservation HL 1960 PUSH BC; preservation BC 70 CALL 949, call ROM routines 1980 POP BC; restore BC 1990 POP HL; recovery HL 100 LD A, L; uveli110 ADD C; chenie 120 LD L, A; L 130 DJNZ LOOP; cycle 140 RET; return to BASIC 2 The use of sub-ROMs proceed to creating your own. The sound of the previous examples can be made smoother and more prolonged: 1415. 10 DI; ban interrupt 20 XOR A; A = border color (0) 30 LD B, 255; B = initial frequency 40 LD C, 255; C = duration 50 BEEP XOR 16; inverting bits D4 60 OUT (254), A; output to port A 254 1970 PUSH BC; preservation BC 1980 LOOP DJNZ LOOP; delay 1990 POP BC; restore BC 100 DEC B; decrease in B 110 DEC C; C = C-1 120 JR NZ, BEEP; if C <> 0 then loop 130 EI; permission to interrupt 140 RET; return to BASIC 2 The possibilities of this effect can be easily increased to: 1415. 10 DI; ban interrupt 20 XOR A; A = border color (0) 30 LD B, 255; B = number of notes 40 LD C, 1; C = initial frequency 50 LOOP1 PUSH BC; preservation BC 60 LD B, 5; B = length 70 LOOP2 XOR 16; inverting bits D4 80 OUT (254), A; output to port A 254 1990 PUSH BC; preservation BC 100 LD B, C; B = C 110 LOOP3 DJNZ LOOP3; delay 120 POP BC; restore BC 130 DJNZ LOOP2; cycle 140 POP BC; restore BC 150 INC C; increase in C 160 DJNZ LOOP1; second cycle 170 EI; permission to interrupt 180 RET; return to BASIC 2 Most likely, you've noticed that in the first variant delay is reduced, and the second increases. Nothing prevents you to change direction of change. It only should choose DEC (decrease) or INC (increase). You can also configure and duration, start frequency, etc. You can change the pitch of the frequency shift: 1415. 10 DI; ban interrupt 20 XOR A; A = border color (0) 30 LD B, 255; B = initial frequency 40 LD C, 255; C = duration 50 BEEP XOR 16; inverting bits D4 60 OUT (254), A; output to port A 254 1970 PUSH BC; preservation BC 1980 LOOP DJNZ LOOP; delay 1990 POP BC; restore BC 100 EX AF, AF '; shift registers A and F on Alternative 110 LD A, B; A = B 120 SUB 3; A = A-3 130 LD B, A; B = A 140 EX AF, AF '; feedback shift registers 150 DEC C; C = C-1 160 JR NZ, BEEP; if C <> 0 then loop 170 EI; permission to interrupt 180 RET; return to BASIC 2 Now we use the freedom of action, which we provide programming in the codes. We write the non-standard procedure Runtime: 1415. 10 DI; ban interrupt 20 LD D, 10; D = delay 1 30 LD E, 100; E = Delay 2 40 LD C, 255; C = duration 50 XOR A; A = border color (0) 60 LOOP1 XOR 16; inverting bits D4 70 OUT (254), A; output to port A 254 80 LD B, D; B = D 90 LOOP2 DJNZ LOOP2; delay 100 XOR 16; inverting bits D4 110 OUT (254), A; output to port A 254 120 LD B, E; B = E 130 LOOP3 DJNZ LOOP3; delay 140 INC D; increase in D 150 INC E; increase in E 160 DEC C; C = C-1 170 JR NZ, LOOP1; if C <> 0 then loop 180 EI; permission to interrupt 190 RET; return to BASIC 2 Here, too, can be long and carefully vary the parameters (see Appendix 1 - Flowing 2). Quite an interesting effect is obtained by using the register R, value under seven bits of which increases after the next machine cycle. This effect can be described as "polushumom. Here is an example of such an effect: 1415. 10 DI; ban interrupt 20 LD C, 53; C = delay 1 30 LD B, 207; B = Delay 2 40 LD E, 203; E = duration 50 LD D, 0; D = Border color 60 LD A, 128; A = temp (0 / 128) 70 LD R, A; R = A 80 BEGIN LD A, R; A = R 90 PAUS1 DEC A; A = A-1 100 JR NZ, PAUS1; if A <> 0 then loop 110 LD A, D; A = D 120 OR 16; setting bit D4 130 OUT (254), A; output to port A 254 140 LD A, C; A = C 150 PAUS2 DEC A; A = A-1 160 JR NZ, PAUS2; if A <> 0 then loop 170 LD A, D; A = D 180 OUT (254), A; output to port A 254 190 LD A, B; A = B 200 PAUS3 DEC A; A = A-1 210 JR NZ, PAUS3; if A <> 0 then loop 220 INC C; C = C +1 230 INC B; B = B +1 240 DEC E; E = E-1 250 JR NZ, BEGIN; if E <> 0 then loop 260 EI; permission to interrupt 270 RET; Returns 2 Values in lines 20 and 30 define delay between the differences of level, in line 40 - duration of effect, in line 50 - Border color, and line 60 - the tempo. In line 60 makes sense to use only values 0 and 128, since all other will be similar to this. In lines 220 and 230 You can set the law of variation of both delay (command INC, DEC and NOP with the registers B and C in any combination). If you do not get caught in all these examples, then move on to the generation of noise. If are you still did not understand, I advise you to test these effects and their poizmenyat parameters. 4.1.2. Noise What is the fuss? This sequence of pulses of random duration. Therefore, in order to create us need random data. Where their get it? The only suitable source - ROM, which contains the BASIC interpreter. ROM located at address 0 to 16383 (# 3FFF). It is true that these values will not completely random, or rather not random, but they gave us. Create noise in two different ways. They differ slightly in sound. The first consists in the withdrawal of the port values read from the ROM. The second - to use these values as delay. In the generation of noise in any of these methods do not necessarily prohibit the interruption, as a crackling noise heard will not. When you use the first method of each byte can retrieve data on eight passes cycle of reproduction, but it is not beneficial to the software point of view. Therefore, most of the effects of bytes takes one value. For example: 1415. 10 LD HL, 0; HL = address of ROM 20 LD BC, 1000; BC = length 30 BEGIN PUSH BC; preservation BC 40 LD A, (HL); A = cell contents ROM 50 AND 240; reset bits curb 60 OUT (254), A; output to port A 254 70 LD B, 50; B = frequency 1980 LOOP DJNZ LOOP; delay 90 INC HL; HL = HL +1 100 POP BC; restore BC 110 DEC BC; BC = BC-1 120 LD A, B; BC = 130 OR C; 0? 140 JR NZ, BEGIN; cycle 150 RET; return to BASIC 2 An example of the second method: 1415. 10 LD HL, 0; HL = address of ROM 20 LD BC, 1000; BC = length 30 XOR A; A = border color (0) 40 BEGIN PUSH BC; preservation BC 50 XOR 16; inverting bits D4 60 OUT (254), A; output to port A 254 70 LD B, (HL); B = cell contents ROM 80 LOOP1 DJNZ LOOP1; delay 90 LD B, 40; B = frequency 100 LOOP2 DJNZ LOOP2; delay 110 INC HL; HL = HL +1 120 POP BC; restore BC 130 DEC BC; BC = BC-1 140 LD D, A; preservation A 150 LD A, B; BC = 160 OR C; 0? 170 LD A, D; A recovery 180 JR NZ, BEGIN; cycle 190 RET; return to BASIC 2 If these effects team replaced INC HL INC L, then they will sound like to galloping. This is due to the fact that the data are taken not from the entire set of ROM, as part of its 256 bytes. And, when this part ends reading continues from the beginning. Try poizmenyat other options. The next step - the noise with varying frequency. It will look like this: 1415. 10 LD HL, 0; HL = address of ROM 20 LD B, 100; B = length of effect 30 LD C, 10; C = initial frequency 40 LOOP1 PUSH BC; preservation BC 50 LD B, 20; B = length 60 LOOP2 LD A, (HL); A = cell contents ROM 70 AND 240; reset bits curb 80 OUT (254), A; output to port A 254 1990 PUSH BC; preservation BC 100 LD B, C; B = C 110 LOOP3 DJNZ LOOP3; delay 120 INC HL; HL = HL +1 130 POP BC; restore BC 1415.140 DJNZ LOOP2; cycle 150 POP BC; restore BC 160 INC C; increase delay 170 DJNZ LOOP1; cycle 180 RET; return to BASIC 2 This effect can be changed beyond recognition: Change the length, frequency, duration, pitch shift in the frequency, direction, frequency offset (command INC C or DEC C), type of noise (or command INC HL INC L). Another version of Sound Effect: 1415. 10 LD HL, 0; HL = address of ROM 20 LD D, 100; D = delay 1 30 LD E, 10; E = Delay 2 40 LD C, 255; C = duration 50 XOR A; A = border color (0) 60 BEGIN XOR 16; inverting bits D4 70 OUT (254), A; output to port A 254 80 LD B, (HL); B = cell contents ROM 90 LOOP1 DJNZ LOOP1; delay 1 100 LD B, D; B = D 110 LOOP2 DJNZ LOOP2; Delay 2 120 XOR 16; inverting bits D4 130 OUT (254), A; output to port A 254 140 LD B, (HL); B = cell contents ROM 150 LOOP3 DJNZ LOOP3; delay 3 160 LD B, E; B = E 170 LOOP4 DJNZ LOOP4; delay 4 180 INC HL; HL = HL +1 190 INC D; increase in D 200 INC E; increase in E 210 DEC C; C = C-1 220 JR NZ, BEGIN; if C <> 0 then loop 230 RET; return to BASIC 2 On this example can be fun because as long as over all the previous ones. All the effects presented in this chapter can be regarded as a blank. To get the final version, you may have to work hard. As already it was said, they all have a huge number of options. In addition, you can combine multiple effects together, or cause them to run in a loop, etc. All the basic principles of combination effects are listed in chapter 2.1. All effects were written so that you can could change the maximum number of parameters. In cases of a particular application they can be greatly simplified. Here's an example combined and simplified the effect: 1415. 10 DI; ban interrupt 20 LD E, 100; E = cycle time 30 LD C, 0; C = color of the border 40 LD B, 4; B = number of cycles 50 LD L, 1; L = frequency offset 60 LD H, 30; H = initial frequency 70 LOOP1 LD D, E; D = E 80 LOOP2 LD A, C; A = C 90 XOR 16; inverting bits D4 100 OUT (254), A; output to port A 254 110 LD C, A; C = A 120 LD A, H; A = H 130 ADD A, L; add L to the A 140 LD H, A; H = A 150 LOOP3 DEC A; A = A-1 160 JR NZ, LOOP3; if A <> 0 then loop 170 DEC D; D = D-1 180 JR NZ, LOOP2; if D <> 0 then loop 190 LD A, L; A = L 200 NEG; the sign of the register A 210 LD L, A; L = A 220 DJNZ LOOP1; cycle 230 EI; permission to interrupt 240 RET; Returns 2 All of the above effects can customize your own needs. For example, change the color of the border or make it so except that the signal dynamics when the SIM tape recorder (for this team all XOR 16 must be replaced by XOR 24 and AND 240 AND 248). 4.1.3. Complexes effects Usually in games (and in any other programs) is not used one or two sound effects, and much more. Therefore, the effects conveniently grouped (Complexes) and call them on the a subroutine, passing it as parameter number effect. If the effects are varied and play various sub-programs, the table of effects is best stored addresses these routines. In this case, to reproduce the effects you can use this subroutine: 1415. 10 ADD A, A; A = A * 2 20 LD E, A; DE 30 LD D, 0; = A 40 LD HL, TABLE; HL = address of table 50 ADD HL, DE; HL = HL + DE 60 LD E, (HL); DE = 70 INC HL; address 80 LD D, (HL); routines 90 EX DE, HL; exchange values HL and DE 100 JP (HL); subroutine call effect 110 TABLE DEFW ... , Address table 2 Before calling this subroutine in the register A has to enter number effect. Do not forget to fill in the table addresses effects. Naturally, the effects themselves must be located at the address. No in no case should indicate the number of effect greater than the number listed in the table routines, otherwise the computer will freeze or "reset". Note also that this subprogram can work a maximum of 127 effects. If the effects are similar and reproduce the same routine, then Table of effects parameters can be stored This subroutine. Here's an example that uses this method: 1415. 10 LD E, A; A 20 ADD A, A; = 30 ADD A, E; A * 3 40 LD E, A; DE 50 LD D, 0; = A 60 LD HL, TABLE; HL = address of table 70 ADD HL, DE; HL = HL + DE 80 LD C, (HL); C = duration 90 INC HL; HL = HL +1 100 LD E, (HL); E = rate 110 INC HL; HL = HL +1 120 LD A, (HL); A = change in frequency 130 LD (CHNG), A; setting frequency 140 DI; ban interrupt 150 XOR A; A = color of the border (0) 160 BEGIN XOR 16; inverting bits D4 170 OUT (254), A; output to port A 254 180 LD B, E; B = E 190 PAUSE DJNZ PAUSE; delay 200 CHNG NOP; reserve for frequency 210 DEC C; C = C-1 220 JR NZ, BEGIN; if C <> 0 then loop 230 EI; permission to interrupt 240 RET; Returns 250 TABLE DEFB 0,0,28; table 260 DEFB 0,0,29; 270 DEFB 0,128,28; effects 280 DEFB 0,128,29; 2 Before calling this subroutine in the register A has to enter number effect. In the above program has already created four effects, but you can change them or increase their number. When you call the effect, the number which is greater than the number described routines can also happen that some awful. In this example, the description of the effect given to three bytes. The first byte - the duration of effect, the second - the initial frequency, and the third - a way to change the frequency. Third byte can be 0, 28 and 29. What does it mean, respectively, maintaining, increasing and decreasing frequency. Enter any other value in this byte is not worth it, because it may cause to unpredictable consequences. The above program is only example. You can configure it to work with absolutely any effect. This routine can handle a maximum of 85 effects. In both of the above routines effects numbering starts with zero.
Other articles:
Similar articles:
В этот день... 21 November