I've been playing with routines to add sound to my games but I'm hitting a weird problem and I just can't figure out if that's just the way it is or if I'm missing something. I've taken Shiru's BeepFX routines and adapted them to play in the "background". If you're familiar with BeepFX, it plays sounds in frames. I've created my sounds with relatively small frames so I can play each one as part of each raster cycle. I store all the registers after playing a frame and resume playing the next frame on the next cycle. I've extracted the code from my game to work standalone and pasted it below.
The PlaySound routine is pretty simple. It looks if there's a new sound effect to play or if there's already one that's playing. If neither are true, it loads the siren sound, plays the first frame and repeats the cycle. In the next cycle, there's already a sound that's playing and continues to the next frame.
The thing is I get this weird "thumping" sound when the siren is looping in the background and I have no idea what's causing it. All emulators I've tried recreate it pretty consistently so I'm assuming a real Spectrum would do it as well (don't have any real hardware to test).
Do any of you have more experience than I do to help clarify this mystery? Or, alternatively, suggest a different routine I could try?
Thanks!
Code: Select all
.org 60000
Start:
ld b, 16
PlayLoop:
halt
push bc
call PlaySound
pop bc
djnz PlayLoop
jp Start
ReadData:
ld c, (ix+1) ;read duration 1
ld b, (ix+2)
ld e, (ix+3) ;read duration 2
ld d, (ix+4)
push de
pop iy
ld e, (ix+5) ;freq
ld d, (ix+6)
ld a, (ix+9) ;duty
ld (sfx_routine_tone_duty+1), a
ret
PlaySound:
ld ix, (play_sound)
ld a, ixh
or ixl
jp z, PlaySound_NoNewSound
ld hl, 0
ld (play_sound), hl
call ReadData
jp PlaySound_Frame
PlaySound_NoNewSound:
ld bc, (sound_frame)
ld a, b
or c
jp z, PlaySound_NoNewFrame
ld de, (sound_pitch)
ld ix, (sound_tone)
ld iy, (sound_frame_length)
jp PlaySound_Frame
PlaySound_NoNewFrame:
ld ix, sound_siren
call ReadData
PlaySound_Frame:
push bc
push iy
pop bc
PlaySound_Loop:
add hl, de ;11
ld a, h ;4
sfx_routine_tone_duty: cp 0 ;7
sbc a, a ;4
and %00010000 ;7
or 0 ;7 dummy
out (254), a ;11
ld a, (0) ;13 dummy
dec bc ;6
ld a, b ;4
or c ;4
jr nz, PlaySound_Loop ;10=88t
ld a, (sfx_routine_tone_duty+1) ;duty change
add a, (ix+10)
ld (sfx_routine_tone_duty+1), a
ld c, (ix+7) ;slide
ld b, (ix+8)
ex de, hl
add hl, bc
ex de, hl
pop bc
dec bc
ld a, b
or c
jp nz, PlaySound_MoreFrames
ld a, (ix+11)
or a
jp z, PlaySound_MoreFrames
ld c, 11
add ix, bc
call ReadData
PlaySound_MoreFrames:
ld (sound_frame), bc
ld (sound_pitch), de
ld (sound_tone), ix
ld (sound_frame_length), iy
ret
sound_siren:
.db 1
.dw 8, 160, 1000, 100, 128
.db 1
.dw 8, 160, 1700, -100, 128
.db 0
play_sound:
.dw 0
sound_frame:
.dw 0
sound_pitch:
.dw 0
sound_tone:
.dw 0
sound_frame_length:
.dw 0