Jump to content
xxl

SFX Engine

Recommended Posts

23 hours ago, Heaven/TQA said:

legendary, too… Dropzone player Explosion when you got hit.

you have the Dropzone explosion in the first post under the name: sound_engine_dc

 

a few changes: separation of the new SETFUNC command and its removal from REPF / REPC - now it works faster and additionally FUNC can be used by any other command.

 

REPTF / REPC command format change - it can initiate AUDF or AUDC itself - now it can be the first command,

 

procedural SFX, for example instead of $20 bytes on SFX you can write like this:

      .HE A0 81
      .HE C0 01 1C 00
      .HE 00 02 0A 00   ; lightning strike from Cavelord

 

some procedural examples of SFX from Cavelord (lightning strike and volcanic eruption)

sound_engine_cl.obx

  • Like 3

Share this post


Link to post
Share on other sites

you can use RMT instruments as SFX - here a fragment of the Raster.

 

sfxEngine is good at playing music or SFX also when loading data from disk. xB

sound_engine-rmt.obx

  • Like 5

Share this post


Link to post
Share on other sites
6 hours ago, xxl said:

you can use RMT instruments as SFX - here a fragment of the Raster.

hmm... this one is a lot slower though... and it's playing a single channel ?

Share this post


Link to post
Share on other sites
6 hours ago, rensoup said:

hmm... this one is a lot slower though

two channels - this is just a demonstration of plugins and functions - the same end result can be achieved without them but takes less space with them 🙂 In this case I used the plugin to change the AUDCTL instead of using the POKE function ;-) This is just a demonstration.

 

Description:
SFX_Engine will have 3 levels in conditional build:
- LEVEL 1, only the simplest commands 1,2,3 - super fast (1 scanning line per channel)
- LEVEL 2, additionally the commands 4,5,6,7,8 (2 scanning lines max)
- LEVEL 3, additional commands 9,10 - takes as long as needed ;-)
In addition, if it is the main music engine (standalone) and you do not need integration with another music player, it will be additionally accelerated - you do not need to write registers every frame, even with unchanged values 🙂

 

thanks to such organization, everyone will be able to choose what they need, maybe just to play SFX? or additionally as a jingle player, music player maybe?

Exactly, LEVEL 3 allows you to create a plug-in for playing samples or a full-fledged music player. synthesizer or Pulse-Width Modulation playback.

Level 2 allows SFX to write to registers - for example, if you want to trigger some action at a certain moment of playback, you can order SFX to write to a specific register - View AlleyCat while playing music while an instrument simulating the glaze of a cat is playing, the cat on the screen performs an animation. If you insist, SFX can use this method to change hardware registers or draw on the screen ;-)

level 1 - the fastest and shortest player but the data takes up a lot of space

 

very important information: if you have compiled level 3 and you run a plugin that adds ADSR capability on a channel for example, the command (1) from level 1 can also use it.
How is a plugin different from a function? The plugin works with each channel service, so you can do, for example, ADSR and the function at the time of downloading data from SFX, i.e. you can change the format of data get by any command, e.g. normally (1) TIME, AUDF, AUDC can change into TIME, NOTE, INSTRUMENT

 

in the above demos I have not presented yet:
- POKE capabilities (but there is no philosophy here) - it allows to change the AUDCTL register for the entire SFX for example
- the possibility of using sampled instruments in SFX by dynamically setting the IRQ via SFX

 

(1) TIME,AUDF,AUDC
(2) LOOP
(3) END

(4) REPF,RTIME,COUNT,AUDC
(5) REPC,RTIME,COUNT,AUDF
(6) JSR SFX
(7) JMP SFX
(8) POKE ADRES,BYTE

(9) SETPLUG,PLUG
(10) SETFUNCF,FUNC | SETFUNCC,FUNC

I'm working on it all the time so the format may still change

Edited by xxl
  • Like 6

Share this post


Link to post
Share on other sites

for sampled SFX we have 3 channels F1, F2, F4 (Atari has no hardware IRQ counter for F3)
each channel can play samples with a different frequency


example of playing SFX from International Karate on one channel and synth from Preliminary Monty on the other

sound_engine-sample.obx

Edited by xxl
  • Like 5

Share this post


Link to post
Share on other sites

I think the idea has worked:

 

so I add it to SFX_ENGINE (LEVEL 3). The IRQ plugin can be turned on in a given channel only for the duration of the sample playing (of course it can be shortened if SFX needs it) - for example it plays an octave on a guitar on one channel and a Preliminary Monty jingle on the other - this is only for demonstration.

 

Of course, the method has limitations - sampled instruments can only be played in 3 octaves (not anymore - you can have resampling ... any)

 

of course the speed and quality could be better but this is a test - I deliberately do some things ineffectively just to demonstrate a certain possibility.

 

 

sound_engine-st.obx

Edited by xxl
  • Like 3

Share this post


Link to post
Share on other sites

I add the ability to synthesize speech to SFXEngine, although it's not as cool as the one from S.A.M. but it doesn't take up a lot of RAM - 1 KB of tables and Atari can talk ;-) Of course this is only an option, we don't need to compile 1KB of data if we don't want to use speech.
The method has limitations :( but it works best when generating whole words, not single tones - one tone takes 8 bytes. One word can take up 2 pages of memory. It's an experiment, maybe completely redundant.

sound_engine_speak.obx

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

after maximum simplification, the generation of speech takes 768 bytes (3 memory pages), two of which are tables, i.e. the generation of speech itself fit into 256 bytes.

 

 

in the attachment a comparative test on the same settings for S.A.M. and SFXEngine (spoken text includes intonation - Polish pronunciation)

 

 

sam.mp3 sfxengine.mp3

Edited by xxl
  • Like 4

Share this post


Link to post
Share on other sites
36 minutes ago, RetroCoder said:

Would love to see the code for this

LEVEL1 and LEVEL2 done: https://xxl.atari.pl/sfx-engine/

 

LEVEL3 - in preparation - as soon as the code is worthy I will publish it

  • Like 3

Share this post


Link to post
Share on other sites

What if we would like to compose on RasterMusicTracker but play instruments sampled with SFXEngine on one channel instead of synthetic instruments? Let's check.
Of course I only have one sample so I put bass on each instrument on channel 2 ;-) a bit of rubbish in the code but it's about showing the idea.

sound_engine-rmt.obx

  • Like 4

Share this post


Link to post
Share on other sites

The last thing I want to introduce is a notification sound plugin - I know it's not used yet, but I think it's worth trying.

Currently we know the sound of "Key Click" and "Bell" - but only "Bell" can be evoked, I want to introduce sounds generated on GTIA which can be called from SFXEngine:

 

1. Key Click 
2. Bell / Warning
3. Notice
4. Fault / Error
5. Beep (duration and pitch)

 

i think programs should start using notification sounds ...

 

if anyone has an idea how individual sounds should sound 3, 4 (these will be sounds generated in the same way as 1,2 currently in the system KeyClick and Bell) then I listen.

  • Like 2

Share this post


Link to post
Share on other sites

this is nice, will be good to have such library

 

on the side note, how do you generate all these sound data for engine? what is Your process for that? 

Share this post


Link to post
Share on other sites

in the attachment, the proposed sounds are in sequence:
Bell, Key, Error, Notice, Load / Save, Beep (255 notes)

The set of sound procedures on Gtia takes 70 60 bytes (70 with the ability to generate noise but this is unnecessary) and gives you the ability to create your own sounds - low cost, and if someone insists, he can even compose music on GTIA thanks to the Beep command ;-)

 

14 hours ago, myriadcs said:

how do you generate all these sound data for engine?

I decompiled a lot of games ... a lot

sound_engine-notification.obx

Edited by xxl
  • Like 3

Share this post


Link to post
Share on other sites

Remarks:

Your code is missing the SKCTL initalization, it would be nice if it would be usable out-of-the box.

Your documentation is confusing: Above you mentioned commands from (1) to (10) while in reality it seems to be individual bits interpreted as commands.

It doesn't help that your comments are in not in English in the source examples and I really would like meaningful defines where applicable, so that I could use

 symbolic names for the commands, like SFX_REPTF, SFX_LOOP etc.

A clear, verbose list could help.

(E.g. What is the LOOP value? Effect line, offset, sfx number, number of loops?)

 

I know, you would loose free channel assignment, but there no possibility to change AUDCTL values?

Could it make sense to split commands for AUDC and AUDF as AUDC is often static?

Share this post


Link to post
Share on other sites

You are very right in what you write. actually the documentation is poor. I tried to give a lot of examples but I understand that this is not a substitute for a good description.

I published the code for Level1 and Level2 because I had the opportunity to use it in a real project and it was just easier for me, Level3 only as a demonstration of the effects. If you would like to use it, of course I will make a description and answer questions, as if it would help to create a good description of the function in English would be great.

 

42 minutes ago, Irgendwer said:

Your code is missing the SKCTL initalization, it would be nice if it would be usable out-of-the box.

It depends on the implementation, if the xSFX Engine is used to create effects and is integrated with a music engine such as CMC or RMT then they themselves have register initialization.

 

44 minutes ago, Irgendwer said:

(E.g. What is the LOOP value? Effect line, offset, sfx number, number of loops?)

jump to a byte in the effect definition. example:

sfx5               ; Pacman BG2
 .HE A3            ; A0 = JSR; E0 = JMP  starsze 3 bity %1110 0000
                   ; 03 = SFX nr. 03     mlodszy 5 bitow %0001 1111
 .HE C0 01 0A A5
 .HE 80 70 60 50 40 50 60 70 80 90
HERE .HE C0 01 0A A4                      ; loop
 .HE 80 70 60 50 40 50 60 70 80 90
 .HE C0 01 0A A3
 .HE 80 70 60 50 40 50 60 70 80 90
 .HE 00 0F         ; 00 0F = LOOP do pozycji 0F "HERE"

 

48 minutes ago, Irgendwer said:

I know, you would loose free channel assignment, but there no possibility to change AUDCTL values?

There are at least 3 ways to do this. you have an example in post 27. https://atariage.com/forums/applications/core/interface/file/attachment.php?id=846881

This is xSFX, not RMT!

 

51 minutes ago, Irgendwer said:

Could it make sense to split commands for AUDC and AUDF as AUDC is often static?

this is not true, I have analyzed a lot of sound effects in different games and many of them create sfx just by changing the AUDC register. I even posted examples in this thread.

 

if you want to use the engine and have the patience to ask questions that I would be happy to answer, that would be great - it would motivate me to create documentation :D

 

Share this post


Link to post
Share on other sites

First of all, thank you for your quick reply! Please don't see my comments as general critique, but as experience report when try to use your code.

 

For example: I'm missing the information which duration/time is safe (maximum frame number) before it may gets reinterpreted as different command $3F?

I understand, that the commands try to be memory conservative as possible, but see also potential interpretation conflicts.

And what is the philosophy of starting effect numbers with 1, and not 0?

When I let SFX care about the channel distribution (which is a neat feature), how get I the channel back, in case I like to stop that effect?

 

1 hour ago, xxl said:

this is not true, I have analyzed a lot of sound effects in different games and many of them create sfx just by changing the AUDC register. I even posted examples in this thread.

From your example code:

sfx3                   ; Donkey Kong
 .HE 02 44 A7        ; zagraj 2 ramki wartosci AUDF i AUDC
 .HE 01 43 A7
 .HE 01 44 A7
 .HE 01 3C A7
 .HE 01 3D A7
 .HE 01 3C A7
 .HE 01 35 A7
 .HE 02 34 A7
 .HE 01 35 A7
 .HE 01 34 A7
 .HE 01 28 A7
 .HE 01 27 A7
 .HE 01 29 A7
 .HE 01 28 A6
 .HE 01 27 A6
 .HE 02 28 A5
 .HE 01 27 A5
 .HE 01 28 A5
 .HE 01 29 A4
 .HE 01 28 A3
 .HE 04 28 A0
 .HE 04 32 A7
 .HE 01 33 A7
 .HE 03 32 A7
 .HE 01 33 A7
 .HE 03 32 A7
 .HE 01 33 A7
 .HE 04 32 A7
 .HE 01 32 A7
 .HE 01 32 00
 .HE 00 FF

...last column seems to be somewhat static. It's not an big issue, but I would prefer clear commands without reinterpretations/conflicts in specific situations written in human readable form.

Something like

 

.byte SFX_AUDF, x

.byte SFX_WAIT,  y

.byte SFX_AUDC, z

.byte SFX_LOOP ...

 

Edit:

Using your subroutine mechanism, this would allow f.e. just to write a routine for raising a frequency or dimming the volume for the given voice, which sounds ;) good to me...

 

Edited by Irgendwer

Share this post


Link to post
Share on other sites
44 minutes ago, Irgendwer said:

I'm missing the information which duration/time is safe (maximum frame number) before it may gets reinterpreted as different command $3F?

it depends what command you use, the range can be truncated to $1F for the first command or it can be $FF for the second command - you get the same effect, but you have different ranges (different number of bytes).

 

46 minutes ago, Irgendwer said:

but see also potential interpretation conflicts.

where do you see the conflict? 

 

 

47 minutes ago, Irgendwer said:

And what is the philosophy of starting effect numbers with 1, and not 0?

When I let SFX care about the channel distribution (which is a neat feature), how get I the channel back, in case I like to stop that effect?

after a channel is initialized, in the X register you get which channel was used and otherwise: 

SFX_NO .HE 00 00 00

the individual bytes are channels -- as you can see, you can change the ranges or even block channels if you like (you can also extend this to stereo :). 00 is the unused channel and any other value is your sfx number, hence the fact that there can't be any sfx number 0 🙂

xSFX_START      jmp SFX_INSERT           ; xSFX_ENGINE+3

reg.x = which channel you have allocated

 

 

reg.X - channel to free

xSFX_STOP       jmp SFX_CHANNEL_OFF      ; xSFX_ENGINE+6

 

54 minutes ago, Irgendwer said:

From your example code:

this is just an example to demonstrate command number 1. it doesn't matter if it's not used optimally - it's just an example. Every following command is more "concise" to make the sfx take as little space as possible and what's important, all the commands that create sound are executed in one step while the control commands are not counted so for example jumping to another SFX doesn't take a "step" of execution.

 

59 minutes ago, Irgendwer said:

Using you subroutine mechanism, this would allow f.e. just to write a routine for raising a frequency or dimming the volume for the given voice, which sounds ;) good to me...

of course you can: post 24.
https://atariage.com/forums/applications/core/interface/file/attachment.php?id=846160

  • Thanks 1

Share this post


Link to post
Share on other sites
40 minutes ago, xxl said:

where do you see the conflict? 

Just as you wrote, the truncation of the range depending on the "circumstances". A clear statement like "a sound can last for about 5 seconds on PAL" in any situation, while the duration is 8 bit, would be much easier to learn/apply...

Share this post


Link to post
Share on other sites

for now, pay attention to the 3 oldest bits in command ... you will see that soon you will read SFX definitions faster than atari ;-) you will never make a mistake 🙂

Share this post


Link to post
Share on other sites

Having problems with the automatic channel distribution.

 

Shouldn't

SFX_FORCE       pha
                jsr SFX_CHANNEL_OFF
                pla
                asl @
SFX_SETNO       sta SFX_NO,x
                clc                         
                rts

be

SFX_FORCE       pha
                jsr SFX_CHANNEL_OFF
                pla
SFX_SETNO       asl @
                sta SFX_NO,x
                clc                         
                rts

???

  • Like 2

Share this post


Link to post
Share on other sites

yes

  • Like 1

Share this post


Link to post
Share on other sites

it is quite simple.
First you need to answer the question what effect you want to achieve, what kind of sfx do you have e.g. 1/2/3/4 channels, is playing sfx on any channel supposed to mute or turn down the music on the other channels? (for this RMT must support RMTGLOBALVOLUMEFADE)

 

let me give you the simplest example. put the call on the vbi in this order:

 

  jsr xSFX_PROCEED
  jsr RASTERMUSICTRACKER+3

 

then find in the file rmtplayer.a65 (oryginal RMT player)


    ELI STEREOMODE==0 ;* L1 L2 L3 L4
    ldy #$ff
v_audctl equ *-1
    lda trackn_audf+0
    ldx trackn_audc+0
    sta $d200
    stx $d201
    lda trackn_audf+1
    ldx trackn_audc+1
    sta $d200+2
    stx $d201+2
    lda trackn_audf+2
    ldx trackn_audc+2
    sta $d200+4
    stx $d201+4
    lda trackn_audf+3
    ldx trackn_audc+3
    sta $d200+6
    stx $d201+6
    sty $d208

 

and replace:

 

    ELI STEREOMODE==0 ;* L1 L2 L3 L4
    ldy #$ff
v_audctl equ *-1
        lda SFX_NO
        bne @+
    lda trackn_audf+0
    ldx trackn_audc+0
    sta SFX_AUDF
    stx SFX_AUDC
    lda trackn_audf+1
    ldx trackn_audc+1
    sta SFX_AUDF+1
    stx SFX_AUDC+1
    lda trackn_audf+2
    ldx trackn_audc+2
    sta SFX_AUDF+2
    stx SFX_AUDC+2
    lda trackn_audf+3
    ldx trackn_audc+3
    sta SFX_AUDF+3
    stx SFX_AUDC+3
@ sty $d208

 

and that's it.


(if this example doesn't help you, write me on priv exactly what you expect and I will make a specific code).
 

 

  • Like 2

Share this post


Link to post
Share on other sites
On 9/3/2021 at 5:54 PM, xxl said:

it is quite simple.
First you need to answer the question what effect you want to achieve, what kind of sfx do you have e.g. 1/2/3/4 channels, is playing sfx on any channel supposed to mute or turn down the music on the other channels? (for this RMT must support RMTGLOBALVOLUMEFADE)

 

let me give you the simplest example. put the call on the vbi in this order:

 

  jsr xSFX_PROCEED
  jsr RASTERMUSICTRACKER+3

 

then find in the file rmtplayer.a65 (oryginal RMT player)


    ELI STEREOMODE==0 ;* L1 L2 L3 L4
    ldy #$ff
v_audctl equ *-1
    lda trackn_audf+0
    ldx trackn_audc+0
    sta $d200
    stx $d201
    lda trackn_audf+1
    ldx trackn_audc+1
    sta $d200+2
    stx $d201+2
    lda trackn_audf+2
    ldx trackn_audc+2
    sta $d200+4
    stx $d201+4
    lda trackn_audf+3
    ldx trackn_audc+3
    sta $d200+6
    stx $d201+6
    sty $d208

 

and replace:

 

    ELI STEREOMODE==0 ;* L1 L2 L3 L4
    ldy #$ff
v_audctl equ *-1
        lda SFX_NO
        bne @+
    lda trackn_audf+0
    ldx trackn_audc+0
    sta SFX_AUDF
    stx SFX_AUDC
    lda trackn_audf+1
    ldx trackn_audc+1
    sta SFX_AUDF+1
    stx SFX_AUDC+1
    lda trackn_audf+2
    ldx trackn_audc+2
    sta SFX_AUDF+2
    stx SFX_AUDC+2
    lda trackn_audf+3
    ldx trackn_audc+3
    sta SFX_AUDF+3
    stx SFX_AUDC+3
@ sty $d208

 

and that's it.


(if this example doesn't help you, write me on priv exactly what you expect and I will make a specific code).
 

 

Hi, thanks for reply. I have probably misunderstood previous reference to RMT - my (naive) idea was that i could use RMT instruments in your library but now i can see it was all about plugging your system inside RMT. This is clearly completely different story so if I want use your library and stop using RMT, i will simply have to recreate all sounds in format your library uses.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...