 |
QUDS
Quds is a development of Uds. Like its predecessor it uses 8-bit values as wavelengths to create sound. The Q in Quds is for seQuential. Unlike its predecessor, the sound it plays will, within a margin of drift, be the same length in time no matter the data being read, so it can be used as the basis of a sound sequencer.
Where Uds finds a zero, it will halt. If Quds finds a zero it will return to the beginning of the data and keep going. So when does it stop? Two variables, initially one a copy of the other, are used to determine duration; Total and Current Total. A typical value for these would be 24*256. This is the sum total of the wavelengths put through the Quds sound engine before it terminates.
There are two benefits from using Quds instead of Uds. Firstly is the independently-determined duration and secondly, it does not have to rely on large samples of data to sculpt sound. In fact it does not need any devoted Udata information. Quds can be pointed at any part of memory and interesting sound will emerge. However, WARNING! Remember that where Quds finds a zero it will loop. So if the FIRST piece of data is zero, then it will loop indefinitely as it subtracts nothing from the duration limit.
So firstly, here is the Z80 assembly code and its opcodes in decimal. Preceding the routine are the two variables Total and Current total. They are referred to in the routine by their low and high-order byte addresses as totL, totH, curtL and curtH. The address for qudata (the address of the sound data) is inserted at quds+1 (low-order byte) and quds+2 (high-order byte). At quds+10 is something called stretch with a default of 1, its shortest value. Increasing this number (POKE quds+10, 4 for instance) will stretch the sound, but will also increase the inaccuracies in the timing. Another variable hidden in the routine is at quds+72. It has a default of 5 for tuning balance but it could be adjusted for serious detuning of the sound. If you are not interested in assembly, don't worry about this listing, further below is the BASIC code for compiling the routine, creating a sound and a way of triggering it.
Total : 0 24 Current total: 0 24
Quds: LD HL, udata 33 qudataL qudataH XOR A 175 LD A, (HL) 126 OR 0 246 0 JRZ -9 40 247
LD BC, stretch 1 1 0 PUSH BC 197 LD B, 0 6 0 LD C, (HL) 78
PUSH HL 229 LD HL, (current total) 237 107 curtL curtH SBC HL, BC 237 66 JPP quds+57 242 targL targH
LD A, L 125 NEG 237 68 LD B, 0 6 0 LD C, A 79 PUSH BC 197
LD BC, 9 1 9 0 DEC BC 11 LD A, C 121 OR B 176 JRNZ -5 32 251
POP BC 193 DEC BC 11 LD A, C 121 OR B 176 JRNZ -15 32 241
LD HL, (total) 237 107 totL totH LD (current total), HL 34 curtL curtH POP HL 225 POP BC 193 RET 201
LD (current total), HL 34 curtL curtH POP HL 225
PUSH BC 197 LD A, 16 62 16 OUT (254), A 211 254 DEC BC 11 LD A, C 121 OR B 176 JRNZ -5 32 251
LD BC, 5 1 5 0 DEC BC 11 LD A, C 121 OR B 176 JRNZ -5 32 251
LD A, 7 62 7 OUT (254), A 211 254 POP BC 193 DEC BC 11 LD A, C 121 OR B 176 JRNZ -5 32 251
POP BC 193 DEC BC 11 LD A, C 121 OR B 176 JRNZ -83 32 173
INC HL 35
JR -95 24 161
BASIC Compiler of Quds
10 LET quds = 32772 20 LET qudata = quds + 256 30 LET qudataH = INT (qudata / 256) 40 LET qudataL = qudata - (qudataH * 256) 50 LET target = quds + 57 60 LET targH = INT (target / 256) 70 LET targL = target - (targH * 256) 80 LET tot = quds - 4 90 LET totH = INT (totH / 256) 100 LET totL = tot - (totH * 256) 110 LET curt = quds - 2 120 LET curtH = INT (curt / 256) 130 LET curtL = curt - (curt * 256) 140 LET a = quds - 4 150 RESTORE 220 160 READ x 170 IF x = -1 THEN GOTO 500 180 POKE a, x 190 LET a = a + 1 200 GOTO 150 210 REM ____Variables 220 DATA 0, 24, 0, 24 230 REM ____Quds 240 DATA 33, qudataL, qudataH 250 DATA 175, 126, 246, 0, 40, 247 260 DATA 1, 1, 0, 197 270 DATA 6, 0, 78 280 DATA 229 290 DATA 237, 107, curtL, curtH 300 DATA 237, 66 310 DATA 242, targL, targH 320 DATA 125, 237, 68, 6, 0, 79, 197 330 DATA 1, 9, 0, 11, 121, 176, 32, 251 340 DATA 193, 11, 121, 176, 32, 241 350 DATA 237, 107, totL, totH 360 DATA 34, curtL, curtH 370 DATA 225, 193, 201 380 DATA 34, curtL, curtH 390 DATA 225 400 DATA 197 410 DATA 62, 16, 211, 254 420 DATA 11, 121, 176, 32, 251 430 DATA 1, 5, 0, 11, 121, 176, 32, 251 440 DATA 62, 7, 211, 254 450 DATA 193, 11, 121, 176, 32, 251 460 DATA 193, 11, 121, 176, 32, 173 470 DATA 35 480 DATA 24, 161 490 DATA -1 500 REM _______Sound Generator 510 RESTORE 580 520 LET a = qudata 530 READ x 540 IF x = -1 THEN POKE a, 0: GOTO 640 550 POKE a, x 560 LET a = a + 1 570 GOTO 530 580 DATA 1, 2, 3, 4, 5, 6, 7, 8, 9 590 DATA 32, 34, 32, 30, 64 600 DATA 32, 34, 32, 30, 60 610 DATA 32, 34, 32, 30, 64 620 DATA 32, 34, 32, 30, 68 630 DATA -1 640 REM _______Sound Trigger 650 FOR m = 5 TO 45 STEP 10 660 POKE quds + 72, m 670 FOR n = 1 TO 4 680 POKE quds + 10, n 690 RANDOMIZE USR quds 700 NEXT n 710 NEXT m 720 GOTO 650
Sound Generation (lines 500 to 630) This is where a demonstration sound is created by reading the data values held in lines 580 to 620 and poking them into memory at the address previously defined as qudata at line 20. This method of shaping the sound, wavelength by wavelength, is the most detailed and it is usual to instead use an equation for drum sounds, but the method shown hear is the most transparent. Experimenting by changing the values held after DATA will give a better understanding of how the whole routine works. It doesn't matter how many or how few values you choose to put here as long as there is at least one and the data has -1 at the end. Notice also that when the sound is triggered, you can actually see the wavelengths in the border region of the screen. This is because port 254 on the ZX Spectrum is connected to both to the sound output and the border.
Sound Triggering (lines 640 to 720) Here the code is demonstrating the use of the two variables of detune (quds+72) and stretch (quds+10), but the sound needs only to be triggered by RANDOMIZE USR quds.
7:53 PM
Powered by  | | English | | Albanian | | Arabic | | Bulgarian | | Catalan | | Chinese | | Croatian | | Czech | | Danish | | Dutch | | Estonian | | Filipino | | Finnish | | French | | Galician | | German | | Greek | | Hebrew | | Hindi | | Hungarian | | Indonesian | | Italian | | Japanese | | Korean | | Latvian | | Lithuanian | | Maltese | | Norwegian | | Polish | | Portuguese | | Romanian | | Russian | | Serbian | | Slovak | | Slovenian | | Spanish | | Swedish | | Thai | | Turkish | | Ukrainian | | Vietnamese |
|