Jump to content

Photo

Sound Effect driver


19 replies to this topic

#1 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • 11,316 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sat Jun 8, 2013 3:54 PM

Here's a preliminary sound effect driver for use with bB. I've not added anything to bB before, so I'm open to suggestions on how to make this better.
Attached File  sfx.zip   4.77KB   168 downloads

Here's the test BIN. Joystick up/down to select a sound effect, hit FIRE to trigger it. Sound Effect 0 is a special case, it silences all output.
Attached File  sfx_demo.bas.bin   4KB   173 downloads

To use in your program you need to do the following.
1. Allocate 2 of the bB variables for use by the driver:
dim SFX_LEFT = y
 dim SFX_RIGHT = z

2. Include the driver in your bB program:
inline sfx.asm

3. Trigger a sound effect whenever appropriate. (is there a way to eliminate the temp1=?)
temp1=sfxtrigger(#sfxJUMP)

4. Add a call to update the sound effects. For best results, put it after every drawscreen (this is to make the updates happen at the exact time every screen):
drawscreen 
 temp1=sfxupdate() : rem for best results, update sound effect after drawscreen

The sound effects are defined in 2 tables at the top of sfx.asm. The first table defines the Frequencies:
sfxF:
 .byte 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 ; Jump
 .byte 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 ; jump 2
 .byte 0, 24, 25, 26, 27, 28, 29, 30, 31 ; throw
 .byte 0,  0,  0,  0,  1,  1,  1,  2,  2,  2,  3,  3,  3 ; collect
 .byte 0,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8 ; ping
 .byte 0,  3,  3,  3,  2,  2,  2,  1,  1,  1,  0,  0,  0 ; stole   
 .byte 0,  1,  2,  3,  4,  5,  6,  1,  2,  3,  4,  5,  6 ; extra
 .byte 0,$10,$10,$10,$10,$10,$10 ; Bonus 50
 .byte 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10 ; Health

The second table defines the Control (tone) and Volume:
sfxCV:
 .byte 0,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf ; Jump
sfxJUMP = *-sfxCV-1
 .byte 0,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ; Jump 2
sfxJUMP2 = *-sfxCV-1
 .byte 0,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f; throw
sfxTHROW = *-sfxCV-1
 .byte 0,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f ; collect
sfxCOLLECT = *-sfxCV-1
 .byte 0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ; ping
sfxPING = *-sfxCV-1
 .byte 0,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f,$6f ; stole
sfxSTOLE = *-sfxCV-1
 .byte 0,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f ; extra
sfxEXTRA = *-sfxCV-1
 .byte 0,$40,$40,$4f,$4f,$4f,$4f ; bonus
sfxBONUS50 = *-sfxCV-1
 .byte $0,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f ; Full Health
sfxHEALTH = *-sfxCV-1

Each .byte line contains the data for a single sound effect. The two tables are used together, so data in the first .byte line in sfxF goes along with the data in the first .byte line in sfxCV. The number of values must be the same in each table and each .byte line. The first value in each .byte line should be 0, it denotes end-of-sfx.

Table sfxCV looks a little complicated because of the extra lines such as sfxJUMP = *-sfxCV-1. All those are doing is calculating the value to be used when you trigger a sound effect. You can name your sound effects whatever you want, just make sure it's followed by = *-sfxCV-1 (also make sure you have a space before and after the equal sign).

Lets look at a single sound effect to explain how the data is used:
sfxF:
 .byte 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 ; Jump


sfxCV:
 .byte 0,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf ; Jump
sfxJUMP = *-sfxCV-1

When you trigger a JUMP sound effect by the function temp1=sfxtrigger(#sfxJUMP), a sound effect pointer will be initialized so that it points to the 26 in the sfxF table and the $cf in the sfxCV table. When you update the TIA sound registers by calling temp1=sfxupdate(), the 26 goes into AUDFx while $cf is split into two parts with the c going into AUDCx and the f going into AUDVx. Lastly the pointer gets updated so it now points to 25 and $ce for the next call to sfxupdate.

#2 Rabbit 2600 OFFLINE  

Rabbit 2600

    Dragonstomper

  • 745 posts
  • Location:Sweden

Posted Sat Jun 8, 2013 4:56 PM

Sweet!

#3 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 11,316 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sun Jun 9, 2013 10:15 AM

So far this morning I've added some validation checks for the sound effect tables. These check that the tables are not too large (max size is 256 bytes), plus they check that the tables are the same size.

~/Projects/Atari/bB11d/sfx> 2600basic.sh sfx_demo.bas
Starting build of sfx_demo.bas
batari Basic v1.01 (C)2005-2007
(40) Warning: function call with no arguments
(54) Warning: function call with no arguments
2600 Basic compilation complete.
 SFX Warning: table sfxF is too large
 SFX Warning: table sfxCV is too large
 SFX Warning: table sfxF is not the same size as table sfxCV
      bytes of ROM space left
 SFX Warning: table sfxF is too large
 SFX Warning: table sfxCV is too large
 SFX Warning: table sfxF is not the same size as table sfxCV
      1880 bytes of ROM space left
Build complete.

The two "no arguments" warnings are for these lines:
if sound_effect = 0 then temp1=sfxoff()
...
 temp1=sfxupdate()

Is there way to eliminate that warning, or a different way to set up sfxoff and sfxupdate so the bB compiler knows that "no arguments" is OK for those two functions?

It'd be nice to eliminate the assignment requirement too (the temp1= part of the command) as that'll save 2 bytes of ROM for each function call.

Edited by SpiceWare, Sun Jun 9, 2013 10:39 AM.


#4 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 11,316 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Sun Jun 9, 2013 10:37 AM

Looks like I neglected to include a comment about sound effect priority. Since there's only 2 sound channels, the Atari can only play 2 concurrent sound effects. My routine is set up with a priority system so that if 2 sound effects are currently playing then a new call to sfxtrigger will override one of the currently playing sound effects only if the new sound effect has a higher priority.

The priority is controlled by the order the sound effects are defined. In the sfxCV table, listed in the first post, you can see that the sound effects are defined in this order:
  • sfxJUMP
  • sfxJUMP2
  • sfxTHROW
  • sfxCOLLECT
  • sfxPING
  • sfxSTOLE
  • sfxEXTRA
  • sfxBONUS50
  • sfxHEALTH
The first sound effect has the lowest priority, the last sound effect has the highest. If 2 sound effects are currently playing then the command temp1=sfxtrigger(#sfxJUMP) will be ignored while temp1=sfxtrigger(#sfxHEALTH) will always occur.

For a real game example, in Space Rocks my sound effects are defined in this order:
  • sfxHeartbeat1
  • sfxHeartbeat2
  • sfxThrust
  • sfxFlip180
  • sfxPlayerShoot
  • sfxSaucerShoot
  • sfxSmallAsteroidHit
  • sfxMediumAsteroidHit
  • sfxLargeAsteroidHit
  • sfxShields
  • sfxSmallUFO
  • sfxLargeUFO
  • sfxSmallSaucerHit
  • sfxLargeSaucerHit
  • sfxPlayerHit
  • sfxWarpIn
  • sfxMagnaMine
  • sfxMenuBlip
  • sfxExtraShip

The order of sound effects was carefully selected. The Heartbeat and Thrust sound effects are background noise. It's no big deal if you don't hear them, so they're first in the list to denote that they have the lowest priority.

The asteroid explosion sound effects are ordered Small, Medium, then Large as a large explosion would "drown out" a medium or small explosion.

The MagnaMine and ExtraShip are highest priority as when those occur you always want the player to know. The MenuBlip will never occur during game play, so it's priority position doesn't really matter.

Edited by SpiceWare, Sun Jun 9, 2013 10:42 AM.


#5 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 8,829 posts

Posted Mon Jun 10, 2013 7:54 AM

Is there a way to import from, say, sfxr?
http://www.drpetter....oject_sfxr.html

Or a utility to generate samples for your sound engine?

#6 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 11,316 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Jun 10, 2013 9:27 AM

Looks like sfxr creates WAV files, which won't work with this driver.

PacManPlus has a tool which he used to create the sound effects for Space Rocks. I'm not familiar with his tool, nor do I know if he's made it (or plans to make it) available for others. I do know his tool is used with a Korg X5D though, so if you don't have one the tool wouldn't be useful.

Space Rocks also uses a more advanced driver, which packs a duration count in with the frequency data. The currently bB driver uses the data at a rate of 1 entry per screen, the advanced one lets you hold a value for up to 8 frames. However, to keep track of duration, the advanced driver needs you to give up 2 more bB variables. RAM is tight in bB, which is why I ported the simpler driver first. I should be able to rewrite the driver to only need 1 extra bB variable instead of 2, it'll just take more ROM to do so.

I plan to port the advanced driver once this one is finalized. This will give people a choice on which driver to use based on how many bB variables they're willing to give up.


What I envision is people sharing sound effects for the driver. Something along the lines of a topic with posts like this:

Space Rocks Shot sound effect
sfxF:
    .byte 0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14 ; Player Shoots

sfxCV:
    .byte 0,$40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c ; Player Shoots
sfxSHOOT = *-sfxCV-1

Then others would just copy the data into their tables.

Edited by SpiceWare, Mon Jun 10, 2013 9:31 AM.


#7 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 8,829 posts

Posted Mon Jun 10, 2013 9:43 AM

Thanks for your work on this. I'm sure a standard sound effect engine would be as useful as the music engine has been for VisualbB users.

Hopefully someone will come up with a side project to create waveforms for this.

#8 bogax OFFLINE  

bogax

    Dragonstomper

  • 706 posts

Posted Mon Jun 10, 2013 9:58 AM

I really have no experience with this (Atari sounds)
and what someone might want.

After looking at mostly theloon's sound effects
I was thinking something like this

Choose voice from a subset of the possible values
so that it could be packed in a byte with frequency.

I wonder if volume could be compressed in a similar way
3 bits of roughly log scale for volume 5 bits for duration
a 0 byte delimits sounds
bytes are in pairs the byte paired with zero selects
which voice subset to use.

a variable for each channel for voice subset table pointer
and duration counter.

edit ack 3 bits of roughly log scale for VOLUME 5 bits for duration
edit2 double ack

Edited by bogax, Mon Jun 10, 2013 10:09 AM.


#9 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 11,316 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Jun 10, 2013 10:26 AM

There's many ways to write a sound driver, I'm only planning to port the two I currently use. I won't feel slighted in the least if you write another driver if mine doesn't do what you need.


As far as compression, the data for my advanced driver would shrink this 20 bytes of sound effect data:
sfxF:
 .byte 0,$13,$13,$13,$13 ; heartbeat1
 .byte 0,$16,$16,$16,$16 ; heartbeat2

sfxCV:
 .byte 0, $6f,$6f,$6f,$6f
sfxHEART1 = *-sfxCV-1
 .byte 0, $6f,$6f,$6f,$6f
sfxHEART2 = *-sfxCV-1

down to 8 bytes of data:
sfxF:
 .byte 0, D4 + $13 ; heartbeat1
 .byte 0, D4 + $16 ; heartbeat2

sfxCV:
 .byte 0, $6f
sfxHEART1 = *-sfxCV-1
 .byte 0, $6f
sfxHEART2 = *-sfxCV-1

The D4 is one of the eight duration constants:
D1 = 0
D2 = 1*32
D3 = 2*32
D4 = 3*32
D5 = 4*32
D6 = 5*32
D7 = 6*32
D8 = 7*32

The compression can potentially lot of ROM, at the expense of using more RAM. There isn't always a ROM savings though - if you look at the data in the first post you see this:
  • sfxJUMP - cannot be compressed, sfxF value changes on every frame
  • sfxJUMP2 - cannot be compressed, sfxF value changes on every frame
  • sfxTHROW - cannot be compressed, sfxF value changes on every frame
  • sfxCOLLECT - can be compressed
    sfxF:
    .byte 0, D3+1, D3+2, D3+3
    sfCV:
    .byte 0, $6f, $6f, $6f
  • sfxPING - cannot be compressed, sfxCV value changes on every frame
  • sfxSTOLE - can be compressed
    sfxF:
    .byte 0, D3+3, D3+2, D3+1, D3+0
    sfxCV:
    .byte 0, $6f, $6f, $6f, $6f
  • sfxEXTRA - cannot be compressed, sfxF value changes on every frame
  • sfxBONUS50 - can be compressed
    sfxF:
    .byte 0, D2+$10, D4+$10
    sfxCV:
    .byte 0, $40, $4f
  • sfxHEALTH - cannot be compressed, sfxF value changes on every frame


One benefit of my driver, provided you're not writing a game that utilizes stereo sound, is you no longer have to worry about assigning channels to sound effects as the driver automatically selects a channel for you. The driver first looks for an idle channel, if it can't find an idle one it then uses priority to determine if the requested sound effect should be played or ignored.

Edited by SpiceWare, Mon Jun 10, 2013 10:29 AM.


#10 bogax OFFLINE  

bogax

    Dragonstomper

  • 706 posts

Posted Mon Jun 10, 2013 10:57 AM

LIke I said I realy know nothing about it
I was only thinking about it because theloon
mentioned it once.

Mostly I wonder if using a subset of voices is
practical.

I suspect a log scale for volume would work out
just fine.

5 bits for duration seems like more than enough,
maybe too much. but I hadn't thought of anything
to use an extra bit for
of course it would be simpler to just make it
4 bits volume and 4 bits duration

Now you've got me thinking about prioritizing sound
effects
edit
and automatically assigning channels

As to compression
another possibility I was thinking of exploring is doing
something more stream like and using difference compression
(which looks like it would do just fine for your jumps)
I expect that's overkill though, and you'd probably have
to have a custom editor to make it usable


I was planning on doing it all in bB
I was thinking about rewriting yours in bB
just for the hell of it.

Edited by bogax, Mon Jun 10, 2013 11:02 AM.


#11 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 11,316 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Jun 10, 2013 12:23 PM

Mostly I wonder if using a subset of voices is
practical.

There's only 2 voices (the channels), so using a subset would mean only 1 sound effect at a time.

I was planning on doing it all in bB
I was thinking about rewriting yours in bB
just for the hell of it.


Go for it.

#12 bogax OFFLINE  

bogax

    Dragonstomper

  • 706 posts

Posted Mon Jun 10, 2013 1:24 PM

There's only 2 voices (the channels), so using a subset would mean only 1 sound effect at a time.
.


I meant the control
each channel has frequency, volume and control (voice)
and restricting it to a subset of 8 of the possible 15
(of which 5 are redundant anyway according to RT's page)

#13 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • Topic Starter
  • 11,316 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Mon Jun 10, 2013 1:38 PM

Ah - that's a good idea.

You can disregard Control = 0 as well; that's only useful for playing back digital samples, which requires advanced coding that's not possible with bB. For digital samples you must update AUDVx on every-single-scanline, even during vertical blank and overscan.

#14 iesposta OFFLINE  

iesposta

    River Patroller

  • 3,345 posts
  • Retro-gaming w/my VCS
  • Location:Pennsylvania

Posted Thu Jun 20, 2013 6:06 PM

This will help me in making sound effects.
I had simple music figured out, but sound effects was stopping me.
Not only did Rev Eng help me with his priority sound effect routine, but now there is Spiceware's also!
I should stop taking such long vacations, so much happens...

#15 RevEng OFFLINE  

RevEng

    River Patroller

  • 4,675 posts
  • Bitnik
  • Location:Canada

Posted Thu Jun 20, 2013 6:47 PM

You can disregard Control = 0 as well; that's only useful for playing back digital samples[...]


Actually there's one more use. If you change the volume level once (instead of toggling it at audible frequencies) you get a short snap of higher frequencies that makes a nice understated percussive sound. I used this as a lead-in beat to the 21 blue ditty.

#16 Mountain King OFFLINE  

Mountain King

    Dragonstomper

  • 615 posts
  • Location:Philadelphia, PA

Posted Wed Feb 10, 2016 11:31 AM

I didn't know this existed. I can't wait to try it. It could have saved me from making splat noises over and over.



#17 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,082 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Wed Feb 10, 2016 11:54 AM

I didn't know this existed. I can't wait to try it. It could have saved me from making splat noises over and over.

 

Have you tried making sounds with the Music and Sound Editor?



#18 Mountain King OFFLINE  

Mountain King

    Dragonstomper

  • 615 posts
  • Location:Philadelphia, PA

Posted Wed Feb 10, 2016 5:41 PM

 

Have you tried making sounds with the Music and Sound Editor?

I used that to write the Gizzle Wap song, but not sound effects. 



#19 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,082 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Wed Feb 10, 2016 6:38 PM

I used that to write the Gizzle Wap song, but not sound effects. 

 

It's great for making sound effects. You can have fun trying to weave Atari 2600 sounds that you haven't heard a million times before. Every sound effect in Seaweed Assault and ChipOff were made using the Music and Sound Editor.



#20 kdgarris ONLINE  

kdgarris

    Chopper Commander

  • 166 posts

Posted Mon Jun 5, 2017 8:36 AM

This driver is quite awesome!  It makes sound so much easier to deal with.  Thank you so much for providing this.  The current version is perfect for my game, but for one that had music of any non-trivial length, I would think that the 4-byte version would be worth the ROM savings.

 

Here are two sound effects I have made.  I'm happy with my ship shooting noise:

 
sfxF:
.byte 0, 8, 7, 7, 6, 5, 4, 3, 2, 2, 3 ; Player fires

sfxCV:
.byte $0,$16,$18,$18,$1A,$1B,$1C,$1D,$1F,$1D ; Player fires
sfxFIRE = *-sfxCV-1

I think my explosion sound could be improved, although I'm not sure how to do so:

sfxF:
 .byte 0, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 ; Explosion

sfxCV:
    .byte 0,$82,$84,$86,$88,$86,$88,$86,$88,$86,$88 ; Explosion
sfxEXPLODE = *-sfxCV-1

I could really use an alien-sounding shooting noise, but I haven't yet had luck making one that sounds at all good.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users