SFXplay v0.1 for SN76489

SFXplayer is a sound effects re-player for the Sega Master System (SMS) using the PSG (SN76489).

The origin of this re-player comes form the ZX-spectrum sound effects player ‘ayfxplayer’ and the accompanying windows utility ‘ayfxedit’. More information can be found here.

Origin:


While programming my first SMS game I needed a sound effect re-player. But found out that there were no out-of-the-box solutions. As having worked with ayfxplay on the MSX. I decided to build something similar for the SMS.  The MSX sound chip (AY3-8910) and the SMS sound chip (SN76489) are fairly similar. So I decided to try and build something similar for the SMS. The new re-player is based on the AY re-player but slightly different.

Old format:

Each sound effect is build up out if multiple lines that are processed each ISR iteration. Only changing (tone and noise) values are stored.

cmd+vol byte:  [NntTvvvv]            T(one)/N(oise) -> 1=off;  v=0 silence
tone (word):   [dddddddd][xxxxdddd]  (only if t=1)  d=tone value
noise (byte):  [EEEnnnnn]            (only if n=1) E=EndOfSfx n=noise value
;
end marker:
cmd_vol byte   [11010000] 0xD0        ; T and N are off, volume is 0
noise (byte)   [00100000] 0x20        ; noise is 0

New format:

To implement the replayer on the SMS the data structure of the sound effects has been changed:

cmd+vol byte: [NntTvvvv]        T(one)/N(oise) -> 1=off; v=15 silence
tone (word):    [1xx0dddd][0-dddddd] (only if t=1) d=tone value
noise (byte)    [1110Ewdd]            (only if n=1) E=EndOfSfx n=noise value
;                                      w=1 white noise
end marker:
cmd_vol byte    [1101FFFF] 0xDF        ; T and N are off, volume is silenced
noise (byte)    [11101000] 0xE8        ; noise is 0

For easier processing the layout of the data is changed and includes the extra bits set for writing the SMS PSG (only need to add the channel bits: xx). The volume value has been inverted.

The re-player workings:


The re-player can handle up to 3 simultaneous sound effects divided over the three tone channels. The noise (4th)  channel is used by the last sound effect that writes a noise value. If the sound effect in the 3rd channel has no noise it will not set the noise volume to 15 (silence) but it will leave the noise channel value untouched.

To implement multiple sound effects simultaneously the re-player prioritizes the channels in use. The priority runs from high (0) to low (255). When a new sound effect it started it will have a custom priority (“call SFX_play”) or a default priority (“call SFX_play_fixed”).  The custom priority can be used to implement background noises with low priority that will only be noticeable if there are few sound effects played or for important sound effects that have to be heard at all times. When a new sound effect is requested the re-player will choose the channel with the lowest priority (but has a lower priority then the new sound effect) to play.

Each ISR the priority of the channel will be lowered by 1.

 

Using the re-player in a project.


To use the re-player in a project only 2 files are to be included in your code: SFXplay.asm and SFXplay_RAM.asm.

SFXplay contains re-player code:
; SFX_init
;     Initialize the variables
;    SFX bank contains start addresses of the SFX'es.
;    !!! SFX cannot be placed lower than 0x0020 in ROM/RAM !!!
;    !!! SFX cannot be larger than 255 lines (on 50Hz 7 seconds)!!!
;
;
; SFX_play
;    [A] contains the SFX number to play.
;    [C] contains the priority of the sfx
;
; SFX_play_fixed
;    [A] contains the SFX number to play.
;    Priority is always set to 10
;
; SFX_route
;    ISR routine to process SFX sound for PSG channels.
;     !!! try to skip every 6th isr call when on 60Hz !!!

SFXplay_RAM contains the needed variable for the replayer (only 9 bytes) and needs to be located in RAM (0xC000)
CHAN_DATA:        #3*3        ; data for playback

The sound effects need to be included under the label “sfxBank”. As shown in the example below:
sfxBank:
dw    sfx0
dw    sfx1
dw    sfx2
;
sfx0:
incbin    ".\data\sfx00.tfx"
sfx1:
incbin    ".\data\sfx01.tfx"
sfx2:
incbin    ".\data\sfx02.tfx"

Converting ayfxedit files


In the download sction below there is a little utility that converts the ‘.afx’ files from ayfxedit to ‘.tfx’ files that can be played by re-player. The converter is very brute force atm. But it works quite well. There is noise range loss and some of the tone ranges are not noticeable on the SMS PSG.

The convert utility will ask for an “.afx” file and converts it to “.tfx” which is placed into the same folder. The converter will ask for antoher file until the ‘Cancel’ button is chosen.

Things still to do


The replayer code is still not optimal. The handling of multiple noise register values is not handled in the best way yet. Probably the results will be better using a better algorithm that decides which noise register value to play.

 

Download SFXplay