|
ZX Forum #04
19 ноября 1997 |
|
world of sound Spectrum - chapter 4.6: Treatment of external signals - digitization.

4.6. Processing of external signals
ZX-Spectrum provides programmers
an interesting opportunity - to read and memorize the sound
signals fed to its input tape. These fragments can be played at
different speeds, which is undoubtedly very interesting. True,
the quality of the received so the sound leaves much to be
desired, and its maximum duration limited to a few tens of
seconds (simply running out of 48K of RAM!)
But the move from words to deeds. That routine, record
sounds in memory: 1415.
10 DI; ban interrupt
20 LD HL, 25000; HL = address of save sound
30 LD DE, 35000; DE = duration of sound
40 LOOP1 LD B, 8; B = bit counter
50 LOOP2 SLA (HL); scrolling the values in memory
60 IN A, (254), enter the value from port 254
70 BIT 6, A; check bit recorder
80 JR Z, NOSIGN; if 0, then go to NOSIGN
90 SET 0, (HL); set bit D0 in the memory
100 NOSIGN LD C, 3; C = delay
110 PAUSE DEC C; C = C-1
120 JR NZ, PAUSE; if C <> 0 then loop
130 DJNZ LOOP2; continue the loop
Byte
140 INC HL; HL = HL +1
150 DEC DE; DE = DE-1
160 LD A, D; DE =
170 OR E; 0?
180 JR NZ, LOOP1; if not, then the cycle
190 EI; permission to interrupt
200 RET; Returns
2
This routine play:
1415.
10 DI; ban interrupt
20 LD HL, 25000; HL = address of the stored audio
30 LD DE, 35000; DE = duration of sound
40 NOP; reserve
50 XOR A; A = border color (0)
60 LOOP3 LD B, 8; B = bit counter
70 LOOP4 AND 239; reset bits D4 register A
80 RLC (HL); scrolling through the data flag
CY
90 JR NC, NOSGN; if the flag CY = 0, then go
on NOSGN
100 OR 16; setting bit D4 register A
110 NOSGN OUT (254), A; output to port A 254
120 LD C, 3; C = delay
130 PAUS2 DEC C; C = C-1
140 JR NZ, PAUS2; if C <> 0 then loop
150 DJNZ LOOP4; continue the loop
Byte
160 INC HL; HL = HL +1
170 LD C, A; preservation A
180 DEC DE; DE = DE-1
190 LD A, D; DE =
200 OR E; 0?
210 LD A, C; A recovery
220 JR NZ, LOOP3; if DE <> 0 then loop
230 EI; permission to interrupt
240 RET; Returns
2
Data address and length must be the same in these two
routines. Please Also note that they use
35 KB of memory from address 25000. Therefore,
this area of RAM there should be no
data. Own routines, too, should be placed somewhere else. The
best option would be: renumber the line second subprogramme
from 210 and increments of 10 (if you're in GENS4 - enter the
command for this purpose N210, 10); connect what happened to
The first subroutine and enter the following
lines:
1415.
7 ORG 24900
20 LD HL, BUFFER
30 LD DE, LENGTH
220 LD HL, BUFFER
230 LD DE, LENGTH
450 LENGTH EQU 35000; LENGTH = 35000
460 BUFFER NOP; there is a buffer
2
Make sure also that the assembly was located approximately
at the address 40000. In Either way, it will be erased from
memory subroutine is called a sound input. Therefore,
you should not call it from the doomed assembly.
One important note: When using these routines, make sure that
BUFFER + LENGTH expression was no longer
65535, another portion of the audio data just
is not recorded, but instead you will hear
noise.
In line 100 the first sub in
120 second row in the register C is stored
delay between the sample data. If these
two values are equal, then the sound will be played with real
pace. If the second number is smaller than the first, the sound
will be accelerated, and if more - to slow down. Moreover, the
smaller the delay in the input routine, the higher the quality
of the input signal, but less than its duration.
Bight reserve in routine play is designed for turning
sound that is playing it at the end
beginning. To enable this effect should be
replace operation NOP in this byte to ADD
HL, DE, and INC HL on line 160 at DEC HL.
There is another way of sound recording. It is based on the
calculation of sound pulses. Before the first way he has no
special advantages, except for possible slight decrease in
noise level. Here are routine, recording the sound of the
second method: 1415.
10 DI; ban interrupt
20 LD HL, 25000; HL = address of save sound
30 LD DE, 35000; DE = duration of sound
40 LD BC, 511; C - buffer, B - Counter
50 LOOP1 IN A, (254); input values of port 254
60 EXX; shift register set
70 LD B, 1; B = delay
80 PAUSE DJNZ PAUSE; delay
90 EXX; shift register set
100 BIT 6, A; check bit recorder
110 LD A, 0; A = 0
120 JR NZ, SIGN; if bit D6 = 1, then go
at SIGN
130 DEC A; A = 255
140 SIGN CP C; A = C (previous value)?
150 JR NZ, WRITE; if not, go to
WRITE
160 INC B; B = B +1 (pulse counter)
170 JR NZ, LOOP1; if B <> 0 then loop
180 WRITE DEC B; B = B-1
190 JR NZ, POKE; if B <> 0 then go to
POKE
200 LD B, 2; B = 2
210 CPL; inverting A
220 LD C, A; C = A
230 JR LOOP1; go to LOOP1
240 POKE INC B; B = B +1
250 LD (HL), B; record values in the memory
260 LD B, 1; B = 1
270 LD C, A; C = A
280 INC HL; HL = HL +1
290 DEC DE; DE = DE-1
300 LD A, D; DE =
310 OR E; 0?
320 JR NZ, LOOP1; if not, then the cycle
330 EI; permission to interrupt
340 RET; Returns
2
Line 20 is given the address conservation
sound, in line 30 - the duration of the input sound, the line
70 - the delay between samples the signal.
Lines 180 - 240 provide noise reduction.
The register C value stored previous samples, and register B
is the count of identical samples.
But the routine play:
1415.
10 DI; ban interrupt
20 LD HL, 25000; HL = address of the stored audio
30 LD DE, 35000; DE = duration of sound
40 NOP; reserve
50 XOR A; A = border color (0)
60 LOOP2 LD B, (HL); B = regular length
70 LOOP3 OUT (254), A; output to port A 254
80 EXX; shift register set
90 LD B, 1; B = delay
100 PAUS2 DJNZ PAUS2; delay
110 EXX; shift register set
120 CALL 124; compensation
130 BIT 0, (HL); delay
140 DJNZ LOOP3; cycle
150 LD B, (HL); B = current duration
160 DEC B; B =
170 INC B; 0?
180 JR Z, CONT; if yes, go to the CONT
190 XOR 16; inverting bits D4
200 CONT INC HL; HL = HL +1
210 DEC DE; DE = DE-1
220 LD B, A; preservation A
230 LD A, D; DE =
240 OR E; 0?
250 LD A, B; A recovery
260 JR NZ, LOOP2; if DE <> 0 then loop
270 EI; permission to interrupt
280 RET; Returns
2
Line 20 is given the address stored audio, line 30 - its
duration, On line 90 - a delay between samples
(It - playback speed).
Bight reserve, as before, is intended to reverse play. For
inclusion of this effect must be replaced
NOP operation in this byte to ADD HL, DE, and
INC HL on line 200 at DEC HL.
Lines 120 and 130 are only needed for time synchronization
with the routine recording (at 124 is the team RET).
Everything has been said about the delay between samples and
memory allocation for routines that use the first method
record, also holds for sub-programs, using the second method.
Feature of the second type sub-
is that the duration of the recorded sound depends not only on
the amount of dedicated memory, but from the sound. Than
smaller differences in the levels of the recorded sound (in
other words - less than its average frequency), the longer
sound can be recorded. For example, if you write a "silence",
the memory is enough for a few minutes!
You can arbitrarily change the address and
the length of the memorized sound, but
need to be very careful not to
spoil the vital areas of memory, such as the stack or the
system variables BASIC.
Sound recorded by these routines
can be stored on tape or disk using the normal write commands,
and then load as needed.
Since not even a very long beep
fragment is in memory of a lot of space,
there is a natural desire to somehow
his cut. I hasten to please you - this is
possible! Audio data is very good
is compressed by any algorithm. For
This can even be used on-screen
compressors. It would be their little
modified for such use,
but if you can not do it, ladies
some advice. First, without changing the compressor can
compress only those files whose size is less than or equal to
6912 bytes (if any compressor
refuses to accept files with a length different from the 6912
b. then supplement them with up to a given size zero).
Secondly, the usual compressors to extract images put it right
in the area of the screen. Therefore, have the data to move
from there to their Native address. This can be done using the
following routines: 1415.
10 LD HL, 16384;
20 LD DE, 16385, cleaning
30 LD BC, 6911;
40 LD (HL), L; screen
50 LDIR;
60 CALL DECOMP; call decompressor
70 LD HL, 16384; HL = move from
80 LD DE, ADDR; DE = to move
90 LD BC, LENGTH; BC = how to move
100 LDIR; data movement
110 CALL 3435; subroutine call CLS
120 RET; Returns
2
These will be screened so short
time that you most likely this and not
notice (at a sufficiently rapid procedure
decompression).
Finally, the text of the program
in Basic, which loads and reproducing
sounds with optimal parameters:
10 CLEAR VAL "24899": PRINT "Wait please ..."
20 FOR A = VAL "24900" TO VAL "24972": READ D: POKE A, D:
NEXT A
30 CLS: PRINT "Press any key, then speak ...": PAUSE NOT PI
40 CLS: RANDOMIZE USR VAL "24900"
50 CLS: PRINT "Press any key to replay ...": PAUSE NOT PI
60 CLS: RANDOMIZE USR VAL "24934": GOTO VAL "30"
1970 DATA
243,33,141,97,17,114,158,6,8,203,38,219,254,203,119,
40,2,203,198,14,1,13,32,253,16,239,35,27,122,179,32,
231,251,201
1980 DATA
243,33,141,97,17,114,158,0,62,7,6,8,230,239,203,6,48,
2,246,16,211,254,14,1,13,32,253,16,239,35,27,79,122,
179,121,32,229,251,201
If you want to start playing "the opposite," insert into
this program the following line:
1945 POKE VAL "24941", VAL "25": POKE VAL "24963", VAL "43"
To disable this effect, remove
this line and restart the program.
Unusual record numbers in this program leads to save memory.
Thus, the expression "24900" takes 11 bytes, and "VAL
"24900" - only 8 ("NOT PI" equals
zero).
Other articles:
Similar articles:
В этот день... 5 December