getting sound effects out of the beeper

The place for codemasters or beginners to talk about programming any language for the Spectrum.
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

getting sound effects out of the beeper

Post by rothers »

Hi,

I'm sorry if this has been answered before, it's not the easiest thing to google.

I'm adding sound to my 48k game and I can hit the beeper and get sound from it, but I can't find anywhere explaining or giving sound 'samples'.

Eg I've got an array of '0,1,1,0,0,0,0,1,1,1,0,1' etc. and I get random sound from it by messing with these numbers but is there anywhere that I can find someone's array to get me, for example, a jump sound, a collect style sound etc?

I can't sit and try random sets of numbers searching for the right sound, I've been messing with it for days, and I've not managed to get anything as good as even Chucky egg.

This is for a very fast (~25-50fps) scrolling platform game, I'm actually trying to make the fastest scrolling game ever made on the 48k with parallax etc. hitting the sound chip does not slow the game down as much as I expected, so I can throw in quite a lot of beeper sound, maybe even simple music.

Thanks!

Here is a pic to show the game is real, I have a demo too if anyone wants to see it (the name at the top isn't final, it just started as a Mario clone).

Image
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: getting sound effects out of the beeper

Post by Dr beep »

easiest sound effect is swapping between 8 and 0 in OUT

xor a
ld b,20
loop
out (254),a
xor 8
djnz loop

will give a sound
User avatar
R-Tape
Site Admin
Posts: 6409
Joined: Thu Nov 09, 2017 11:46 am

Re: getting sound effects out of the beeper

Post by R-Tape »

Welcome @rothers!

It looks like you're pretty used to coding asm. You might find this thread useful. There are some short assembly routines there, and it may help you to design new ones too.

If you want to keep a rock solid frame rate, you could try timing the sound effects to interrupts. Something like this (for a 50fps game):

Code: Select all

mainloop:
ld a,(23672) ;ROM frames counter (if using IM1)
ld (framestore),a ;store frame count here
call drawsprites
call collisions
call scroll
...etc etc
call sounduntilinterrupt ;make a beeper sound until an interrupt occurs (this works instead of using HALT)
jr mainloop
;
sounduntilinterrupt:
;...choose which sound...e.g.
blastnoise:
	ld hl,blastflag
	dec (hl)
	ld hl,23672 ;ROM frames counter (using IM1 in this example)
	ld a,(framecount) ;
	ld e,a
	ld bc,0
bnlp:	ld a,(bc)
	inc bc
	and 16
	out (254),a
	ld a,e
	cp (hl)
	jr z,bnlp
	ret	
;
framecount: db 0
Looking forward to seeing the game :–)
worcestersource
Manic Miner
Posts: 530
Joined: Thu Feb 03, 2022 11:05 pm

Re: getting sound effects out of the beeper

Post by worcestersource »

Quite like Super Minimal Bros. Clever!
User avatar
R-Tape
Site Admin
Posts: 6409
Joined: Thu Nov 09, 2017 11:46 am

Re: getting sound effects out of the beeper

Post by R-Tape »

Dr beep wrote: Sat Dec 30, 2023 3:20 pm easiest sound effect is swapping between 8 and 0 in OUT

xor a
ld b,20
loop
out (254),a
xor 8
djnz loop

will give a sound
Shouldn't that be XOR 16? But it does indeed make a sound - I'm confused!
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: getting sound effects out of the beeper

Post by rothers »

So because I'm hitting the sound chip each frame, I'm not sure if I can call a routine to execute unless it's on some sort of interrupt?

I'm trying to keep this all super simple for speed and I assume the fastest route was a 1 bit array for each sound, just fire the array at the chip each frame, maybe 10 bits per frame or whatever it takes.

So that's why I was trying to find an already made 1 bit 'sample' I can just copy in to the code and fire it off.

I'm guessing this is not how it's usually done?
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: getting sound effects out of the beeper

Post by ParadigmShifter »

I use BeepFX from here:

https://shiru.untergrund.net/software.shtml

I removed the function which plays samples though so the code was smaller.

I have a "pending sfx" ID (only 1 byte at the moment) which I use to trigger a sound effect just before I do a halt. When I want to play a sound I just set the ID and it's played at the end of the frame, rather than playing SFX during the rest of the processing (and it's also easy to turn SFX off by skipping over the play in a single place too).

BeepFX blocks though (and does a DI at the start and an EI at the end, so you may miss an interrupt) but you could try moving it into the interrupt I suppose (although some SFX take more than a frame).
User avatar
PROSM
Manic Miner
Posts: 476
Joined: Fri Nov 17, 2017 7:18 pm
Location: Sunderland, England
Contact:

Re: getting sound effects out of the beeper

Post by PROSM »

R-Tape wrote: Sat Dec 30, 2023 3:39 pm Shouldn't that be XOR 16? But it does indeed make a sound - I'm confused!
Bit 3 controls the MIC output; some emulators will produce sound from both the speaker and MIC. Of course, it's barely audible on a real Spectrum - I need my ear right next to my Issue 2's loudspeaker to hear it.
All software to-date
Working on something, as always.
berarma
Microbot
Posts: 106
Joined: Thu Mar 09, 2023 10:55 am

Re: getting sound effects out of the beeper

Post by berarma »

I've never done sound for any game on the Spectrum, but I have some experience implementing audio generators.

Your approach is good if your effects are so short that they can be reproduced in a frame. You could use some simple compression scheme to group together zeroes and ones.

Another approach that would allow you to make longer and richer sounds without spending too much time every frame would be looking at effects like chunks of sounds with silence between them. If you can call your sound routine 50 times per second, and execute some sound for maybe 20ms, modulating the frequency and the duty cycle of the square wave can produce a good variety of effects.

I can't give details because I've never got to implement it but I guess there'll be examples in disassembled and opensource games/engines.
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: getting sound effects out of the beeper

Post by rothers »

I am trying to play the sample over many frames, I'm not even sure how many bits I should play per frame.

I've been trying some experiments, eg:

16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16

And playing 10bits, 20bits, 30bits a frame to see what kind of sound I get, but it's just buzzing, no discernable sound really.

It's important to me that the sound is played without the game stopping, so it's a little per frame.

Cobra on the 48k spectrum has an amazing sound routine, but I can find nothing online explaining even how to make these 1bit samples or what it might be doing to make the sound:



All those little sounds are being sent to the chip a little per frame, but I've no idea HOW to make sounds... I'm now considering just writing a random bit generator and sitting pressing a button each time to play it and wait until I hear something good then export the bits...
berarma
Microbot
Posts: 106
Joined: Thu Mar 09, 2023 10:55 am

Re: getting sound effects out of the beeper

Post by berarma »

rothers wrote: Sat Dec 30, 2023 6:01 pm I am trying to play the sample over many frames, I'm not even sure how many bits I should play per frame.

I've been trying some experiments, eg:

16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16

And playing 10bits, 20bits, 30bits a frame to see what kind of sound I get, but it's just buzzing, no discernable sound really.

It's important to me that the sound is played without the game stopping, so it's a little per frame.

Cobra on the 48k spectrum has an amazing sound routine, but I can find nothing online explaining even how to make these 1bit samples or what it might be doing to make the sound:



All those little sounds are being sent to the chip a little per frame, but I've no idea HOW to make sounds... I'm now considering just writing a random bit generator and sitting pressing a button each time to play it and wait until I hear something good then export the bits...
This is just a short or long pulse. No frequency.

You need to send several complete waveform cycles. The output has to alternate a number of times between high and low at a given frequency.

You should first decide the max frequency you want to achieve. That would be the speed of the loop sending data to the speaker. If you send 1,0,1,0,1,0,1,0,1,0, that would be a square wave at max frequency. Sending 1,1,0,0,1,1,0,0,1,1,0,0 would be half that frequency.

If you want to use that technique I'd rather have data for the period/frequency to play and how long to play before the next.

The duty cycle is how much the output is high compared to how much is low without changing the frequency of the total wave. It has an effect in the timbre and also in the volume. A modulation of the duty cycle is sometimes used to play digitized sounds.

Thus an effect could be a sequence of {period, length, duty} values.
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: getting sound effects out of the beeper

Post by rothers »

Ahhh that is making sense yes. I'll try that.

I should point out I know nothing about music, so this is some learning cure going into it like this with a spectrum beeper.

I'm really trying to push the Spectrum to the max on all its hardware possibilities.
User avatar
MustardTiger
Microbot
Posts: 122
Joined: Tue May 02, 2023 8:05 pm

Re: getting sound effects out of the beeper

Post by MustardTiger »

This is some simple code I made for a game I'm working on. The long fx takes maybe half a frame :lol: and the short one maybe 1/10th. I've disassembled a couple of games (Sabre Wulf and Starquake) and they do similar things for their sound fx, often taking quite a lot of frame time to play them but you don't really notice any frame rate drops.

I think Cobra is stringing lots of shorter sounds together, playing a segment each frame, but notice when the powerup is collected in the video you shared, the whole game stops.

Code: Select all

			;short fx
SoundFX2	ld c,8			;overall loops
			ld e,2			;delay between on/off pulse
			ld d,10			;add to delay per loop
			jp sfxtone

			;longer fx
SoundFX1	ld c,40			;overall loops
			ld e,64			;delay between on/off pulse
			ld d,-5			;add to delay per loop
			jp sfxtone

sfxtone		ld a,16+6		;spk on and yellow border
			out (254),a
			ld b,e		
.lp1		djnz .lp1

			ld a,4			;spk off and green border
			out (254),a
			ld b,e
.lp3		djnz .lp3

			ld a,e
			add d
			ld e,a

			dec c
			jr nz,sfxtone

			xor a 
			out (254),a
			ret
dfzx
Manic Miner
Posts: 683
Joined: Mon Nov 13, 2017 6:55 pm
Location: New Forest, UK
Contact:

Re: getting sound effects out of the beeper

Post by dfzx »

rothers wrote: Sat Dec 30, 2023 6:01 pm All those little sounds are being sent to the chip a little per frame, but I've no idea HOW to make sounds...
Several times you've referred to "the chip" which makes me wonder if you understand how the 48K machine makes sounds? It doesn't have a chip. It has a speaker. When you send a logic 1 to the speaker (via a Z80 OUT instruction) the speaker is energised. When you then send a logic 0 to the speaker, the speaker is de-energised. Energising and then de-energising the speaker uses a magnet to move its diaphragm and you get a single click. That's it, there's nothing more sophisticated in there.

In order to make a tone you have to time a stream of OUT instructions correctly in order to make a stream of clicks at the correct frequency. Timing a precise stream of Z80 instructions on the Spectrum isn't easy. There's no "chip" or any other hardware to assist with the timing. The only way to do it is to do an OUT (with a logic 1), busy-wait the Z80 for the correct number of machine cycles (i.e. just count down in a tight loop), then do another OUT (with a logic 0), then busy-wait again, etc. The problem, fairly obviously, is that the Z80 can't really do anything else while it's busy-waiting. To get the tone right the timing needs to be accurate almost to the machine cycle. The 50Hz interrupt, which is the only hardware timer the Spectrum has, isn't much use.

To get sound effects you need to send a stream of 1s and 0s which toggle the speaker such that you get the effect you want. Send a stream with decreasing gaps between the toggles, for example, and you'll get a squeak with a rising pitch. If you don't vary the gaps you'll get steady buzzing, as you've found. But do it right and you can get remarkable effects. Then you need to weave your stream of clicks into your screen updates, etc. It's another Spectrum based art form. :)

Maybe you knew all this. But if you didn't, one option would be to look in the archive for 1980s sound utilities. The are many which help you fine tune squeaks and zaps and croaks and then allow you to export the effects you create for use in your own programs. They just produce a bit of machine code (the "player") with a data table which controls the flow of toggles to the speaker. I remember playing with them BITD.
Derek Fountain, author of the ZX Spectrum C Programmer's Getting Started Guide and various open source games, hardware and other projects, including an IF1 and ZX Microdrive emulator.
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: getting sound effects out of the beeper

Post by Dr beep »

Here is my sound routine I coded in my MC10 emulator

Enter with B and C as duration and tone

Code: Select all


playt	equ	8000		; the playtime of the note

	di
	ld	a,b		; save duration
	ld	b,0		; subtract with C
	and	a		; clear carry
	ld	hl,800		; freq
	sbc	hl,bc		; freq of current note
	sbc	hl,bc		; freq of current note
	sbc	hl,bc		; freq of current note
	ld	c,b		; C now 0
	ld	b,a		; get duration
snd	ld	de,playt	; fixed playtime	
snd0	push	hl		; save freq
	ld	a,c
	xor	8
	ld	c,a		; toggle sound bit
	out	(254),a
snd1	inc	d
	dec	de
	dec	d
	jp	z,snd2		; end of duration?
	ld	a,r		;  9 same time
	jr	snd3		; 21
snd2	dec	b		;  4 test end
	jr	z,snd4		; 11
	ld	de,playt	; 21 get next duration 
snd3	dec	hl		; remaining freq
	ld	a,h
	or	l
	jr	nz,snd1
	pop	hl		; get next loop freq
	jr	snd0
snd4	pop	hl		; drop freq
	ei
	ret
Problem is that frequency and duration must keep going when frequency is higher lower.
The routine is exactly equal in timing for each sound
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: getting sound effects out of the beeper

Post by rothers »

dfzx wrote: Sat Dec 30, 2023 10:16 pm Several times you've referred to "the chip" which makes me wonder if you understand how the 48K machine makes sounds? It doesn't have a chip. It has a speaker. When you send a logic 1 to the speaker (via a Z80 OUT instruction) the speaker is energised. When you then send a logic 0 to the speaker, the speaker is de-energised. Energising and then de-energising the speaker uses a magnet to move its diaphragm and you get a single click. That's it, there's nothing more sophisticated in there.
Yes, I understand how it works (hence me sending a 16 byte). Berarma's explanation has put me on the right track with using waves. I simply have no music knowledge, but this is probably a good low level way to learn. Sending samples will probably take up too much memory (although I have quite a lot free) so time to write some tone code and a little tracker I guess.
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: getting sound effects out of the beeper

Post by Dr beep »

rothers wrote: Sun Dec 31, 2023 6:23 pm Yes, I understand how it works (hence me sending a 16 byte). Berarma's explanation has put me on the right track with using waves. I simply have no music knowledge, but this is probably a good low level way to learn. Sending samples will probably take up too much memory (although I have quite a lot free) so time to write some tone code and a little tracker I guess.
I gave you a well working routine..
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: getting sound effects out of the beeper

Post by rothers »

Haha! Success with fake waves!

I have beeps and boops!

I'll play around with getting some jump and collect sounds. It does not slow the game at all which I'm really happy about, although this is for the 48k I could have 128k music and 48k sound effects I guess.

I do want to try to have in game music like Cobra if I can... even if it's pretty basic. I just like pushing the hardware. Not many 48k games did in game music.
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: getting sound effects out of the beeper

Post by rothers »

Dr beep wrote: Sun Dec 31, 2023 6:27 pm I gave you a well working routine..
Thank you, I do appreciate all the feedback I'm just trying to write it all myself, so I understand it from the lowest level.

Once I have the full game working I'll probably come back with my code asking if it's the best approach, I can probably write the graphics faster, but I want to go through the whole learning curve for my own understanding of the system.

I'm amazed it's as fast as it is so far!
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: getting sound effects out of the beeper

Post by Dr beep »

rothers wrote: Sun Dec 31, 2023 6:55 pm Thank you, I do appreciate all the feedback I'm just trying to write it all myself, so I understand it from the lowest level.

Once I have the full game working I'll probably come back with my code asking if it's the best approach, I can probably write the graphics faster, but I want to go through the whole learning curve for my own understanding of the system.

I'm amazed it's as fast as it is so far!
I started the same as you now want to do.
Problem is that the frequency and time both must be constant.
If you increase the frequency or lower than ending the frequency can be out of time or before time ends. Then you need to set the frequency again. This must be constant for all tones. See the timing at itis all constant.
User avatar
Joefish
Rick Dangerous
Posts: 2059
Joined: Tue Nov 14, 2017 10:26 am

Re: getting sound effects out of the beeper

Post by Joefish »

I vaguely remember an explanation from Joffa about how the sound works in Green Beret, Cobra etc.
The game is carefully written so that it always updates within 2 frames of the TV picture (i.e. take less than 1/25 second to execute one cycle of the main game program loop). If it finishes that cycle early (which it usually does), it then switches to a sound routine that can play a single note and just never stop. An interrupt is configured so that the instant the next TV frame refresh starts, it breaks out of the sound routine and starts the next game cycle. So by setting different notes, the game code can play little tunes, or ramping up/down scales as sound effects.
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: getting sound effects out of the beeper

Post by rothers »

I need to look in to doing a wait VBL of some kind, as I can see I'm all over the place with drawing the screen, it looks fine now but if you slow the emulator down I can see some parts tearing as I start to draw the next frame too early. I guess you can't just watch the final pixel or attribute to tell when it's done drawing?

I've noticed a lot of games just don't seem to care and draw like this anyway, I guess in some cases it's faster if you don't have anything to do while waiting...
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: getting sound effects out of the beeper

Post by ParadigmShifter »

I always do

HALT ; wait vblank

draw everything, racing the raster. So you need to draw everything before the raster reaches the top of the drawable area for no flicker or else you need to do more logic afterwards to make sure you draw stuff at the top of the screen before things lower down.

update game logic for next frame

If you double buffer you can always beat the raster of course at the expense of a lot of memory for the back buffer.

then it's the time to worry about sfx and such, I do that before waiting for the next VBlank.

I'm using beepFX which turs off interrupts but I guess you could still keep them going and cancel if a VBlank goes off... makes the code more complicated and with sound it's important to have a constant runtime per loop.

EDIT: So the main thing I do is draw everything immediately after the VBlank and do the processing for the next frame at the end rather than the (simpler) way of doing things which is update the game logic, read the keyboard etc. and then draw. It's better to start drawing straight away after the vblank.
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: getting sound effects out of the beeper

Post by rothers »

How are you detecting the raster? I read that reading port 255 is a bad idea?

Are you just running an exact timing routine for each Spectrum model?
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: getting sound effects out of the beeper

Post by ParadigmShifter »

I'm not detecting the raster. I just start drawing as soon as the HALT finishes. You need to read a port (floating bus) if you want to start drawing at a specific place (usually, the bottom of the drawable area) but I'm not doing that.

It sounds like you have no HALT at all and are just doing the game loop as fast as possible? I think Jetpac may have done that, not sure though.

Another thing that is possible to do is draw in the interrupt routine and set a flag in the main loop to say you are ready to draw. Then you can play SFX while waiting for that I suppose
Post Reply