world of sound Spectrum - Chapter 4.2: Programming Sound Effects - Volume Control.

ZX Forum #04
       4.2. Volume Control


   In fact, ZX-Spectrum absolutely
adjusted for volume control, but
it still can be changed within a small range due to the 
relatively high clock rate microprocessor Z80 (About 3.5 MHz).


   As mentioned in Chapter 2, when you
sends a signal to the speaker, his diaphragm
changes its position. If, during its
motion to send a return signal, it
returns to its original position without going through the 
desired path. Thus, the amplitude (And consequently the volume) 
is less than normal. For example, compare the sound of two 
nearly identical programs: 1415.

 10 PROG1 DI; ban interrupt
 20 LD B, 255; B = frequency
 30 LD C, 255; C = duration
 40 XOR A; A = border color (0)
 50 LOOP1 XOR 16; inverting bits D4
 60 OUT (254), A; output to port A 254
 1970 PUSH BC; preservation BC
 80 LOOP2 DJNZ LOOP2; delay
 1990 POP BC; restore BC
100 DEC C; C = C-1
110 JR NZ, LOOP1; if C <> 0 then loop
120 EI; permission to interrupt
130 RET; return to BASIC

 10 PROG2 DI;
 20 LD B, 255;
 30 LD C, 255;
 40 XOR A;
 50 LOOP1 XOR 16, all
 60 OUT (254), A;
 70 XOR 16; (except these two lines,
 80 OUT (254), A; repeating previous)
 1990 PUSH BC;
100 LOOP2 DJNZ LOOP2; similarly
110 POP BC;
120 DEC C; previous
130 JR NZ, LOOP1;
140 EI; example!
150 RET;
2

   When you have collected in assembly and
run, you were surprised. However,
against the facts do not trample - the second subprogram will 
be heard several times quieter first!


   Bring the text more universal routines:
1415.
 10 DI; ban interrupt
 20 LD B, 50; B = volume
 30 LD C, 50; C = frequency
 40 LD D, 15; D = duration
 50 LD E, 50; E = number of notes
 60 XOR A; A = border color (0)
 70 LOOP1 PUSH DE; conservation DE
 80 LOOP2 PUSH BC; preservation BC
 90 XOR 16; inverting bits D4
100 OUT (254), A; output to port A 254
110 LOOP3 DJNZ LOOP3; delay (volume)
120 XOR 16; inverting bits D4
130 OUT (254), A; output to port A 254
140 LD B, C; B = C
150 LOOP4 DJNZ LOOP4; delay (frequency)
160 POP BC; restore BC
170 DEC D; D = D-1
180 JR NZ, LOOP2; if D <> 0 then loop
190 POP DE; restoration DE
200 NOP; reserve
210 NOP; reserve
220 NOP; reserve
230 DEC E; E = E-1
240 JR NZ, LOOP1; if E <> 0 then loop
250 EI; permission to interrupt
260 RET; return to BASIC
2

   In this effect, you can choose the desired volume. But do 
not get carried away: at values ​​greater than 40-50, the 
volume has not increased. It must be noted that a change in 
volume during playing time and frequency changes.

Therefore, it is necessary to provide compensation.

   Now the three-byte transfer (command
NOP). They are designed to change
volume (case B), frequency (case C)
and duration (case D). If you replace these three NORa to 
commands DEC B (volume down), INC C (compensation rate), and 
INC D (prolongation) then you get an interesting effect with 
decaying volume.