Wanting to add AY music to games

On the creation of AY or Beeper music, including the packages used to do so.
Post Reply
presh
Manic Miner
Posts: 237
Joined: Tue Feb 25, 2020 8:52 pm
Location: York, UK

Wanting to add AY music to games

Post by presh »

As the title suggests, but I've no idea where to start!

Obviously some kind of tracker software, and some Z80 code to play the file (if the tracker doesn't provide that itself)

Ideally looking for a lightweight player - I'm tempted to say speed is more important than size here, however I have no idea how much space a song is likely to take up, so there's that consider too!

It seems some players seem to have features others don't, or are suitable only for certain output formats, etc. so I don't want to waste time building a tune only to not be able to play it, or find out that it's enormous because of the format required by the player, etc

I will want multiple songs in the game, so ideally the code would allow this - preferably without having to copy the song to a buffer, even if a little code modification is required when switching tracks.

I did some digging, but just ended up more confused... so am hoping someone here can help put me on the right path :)
User avatar
R-Tape
Site Admin
Posts: 6481
Joined: Thu Nov 09, 2017 11:46 am

Re: Wanting to add AY music to games

Post by R-Tape »

I've only ever used Vortex Tracker. I last downloaded it from here. I wouldn't call the memory or speed footprint insignificant, but it's never caused me problems with timed sprite routines etc.

Once you have your music, export the file with ZX Spectrum Player option, you can choose to compile it anywhere, but it's most common at 49152 and paged in/out. I haven't tried it, but there's an export without player option, which you would use for multiple tracks (only exporting the player once). I export as a .TAP and put everything together using ZX-Blockeditor.

Vortex Tracker tells you which address to CALL for initiate, play and mute track depending where you compile to. Using 49152 as an example, here's how it fits together:

-on starting, disable interrupts
-set up vector table and interrupt routine that pages in the AY music and CALLS 49157 every frame.
-CALL 49152 to initiate the player
-set IM 2
-EI (remember what was paged in before), you should now be playing your AY music.

Is this what you were after? I suspect you knew most of this anyway, but I could post some code later if you need it.
User avatar
R-Tape
Site Admin
Posts: 6481
Joined: Thu Nov 09, 2017 11:46 am

Re: Wanting to add AY music to games

Post by R-Tape »

Or if you wanted to try something different, in Jonathan's "How to write Spectrum Games", there is a section in chapter 16 that has some simple code for using the AY chip. Takes up hardly any memory, and a decent coder like yourself could have some fun with it.
User avatar
Alessandro
Dynamite Dan
Posts: 1910
Joined: Wed Nov 15, 2017 11:10 am
Location: Messina, Italy
Contact:

Re: Wanting to add AY music to games

Post by Alessandro »

Hi [mention]presh[/mention] ,

it is true, there are several AY manager/player code examples out there. This is how I did it in all of my games where AY music has been implemented. It is not meant to be the Holy Truth but I hope it will help nonetheless :)

First, I compose my tracks with Vortex Player II. The program is currently developed by Ivan Pirog and you can find the latest releases here:

https://github.com/ivanpirog/vortextracker/releases

Then I export music as TAP files with player at a given address. Which one? It depends on the free space available.

In order to actually play the music on the background, you need a management code, like the following. It is not my creation; I took it from a source I cannot remember right now. But it has served me well throughout the years.

Code: Select all

  ; Routine for music management (83 byte)
im2_enable              ; initialize interrupts

    di
    call PLAYER         ; recall "player" code exported with VT2

    ld hl,64512         ; create a table at this address
    ld a,h
    ld i,a
    im 2
    dec a
    ld (hl),a
    inc l
    jr nz,$-2
    inc h
    ld (hl),a

    ld l,a              ; set music playback
    ld h,a
    ld de,im2_proc      ; call playback part (im2_proc)

    ld (hl),195
    inc l
    ld (hl),e
    inc l
    ld (hl),d
    ei
    ret

im2_disable             ; disables music (start address + 32)

    di
    call PLAYER+8       ; "turns off" the AY chip
    ld a,63
    ld i,a
    im 1
    ei
    ret                 ; exit

im2_proc                ; start of interrupt routine

    di

    push          af    ; storing registers
    push          hl
    push          bc
    push          de
    push          ix
    push          iy
    exx
    ex af,af'
    push          af
    push          hl
    push          bc
    push          de

    call PLAYER+5        ; music playback
    ld hl,23672
    inc (hl)             ; read keyboard input

    pop           de
    pop           bc
    pop           hl
    pop           af
    ex af,af'
    exx
    pop           iy
    pop           ix
    pop           de
    pop           bc
    pop           hl
    pop           af

    ei
    reti

  ; ORG [start+83]

PLAYER: INCBIN "vtplayer.bin"

  ORG [music address]

MUSIC: INCBIN "music.bin"
Now some explanations:
  • you should export your player+music TAP file from VT2 at least 83 bytes higher than the address where you stored this routine;
  • extract the "vtplayer" code and the music code from the file as binary files - an utility like ZX-Blockeditor will do;
  • remember to put the music code at the address you see in the TAP file exported from VT2;
  • calling the start address of the management routine starts music playback;
  • playback stops when you call the im_disable part located at start address + 32.
This is another example: a routine that plays an AY music exported from VT2 at address 49152 continuously until a key is pressed.

Code: Select all

  PLAYER EQU 49152

  ORG 49120
 
  LD A,1
  LD (PLAYER+10),A
  CALL PLAYER
  EI
LOOP:
  HALT
  CALL PLAYER+5
  XOR A
  IN A,(254)
  CPL 
  AND 31
  JR NZ,FINE
  LD A,(PLAYER+10)
  RLA
  JR NC,LOOP
FINE:
  CALL PLAYER+8
  RET
andydansby
Microbot
Posts: 148
Joined: Fri Nov 24, 2017 5:09 pm
Location: Syracuse, NY, USA
Contact:

Re: Wanting to add AY music to games

Post by andydansby »

I've got a couple of GitHub repositories on Vortex.

Pasmo version
https://github.com/andydansby/Vortex2_P ... ress_index

Z80Asm (z88dk assembler)
https://github.com/andydansby/Vortex2_P ... ress_index

Both use ZX0 and an index to choose the song and have all that's needed including the compilers, ZX0 compression tool, music and code. Just drop to a command prompt and run the batch file.
User avatar
RMartins
Manic Miner
Posts: 776
Joined: Thu Nov 16, 2017 3:26 pm

Re: Wanting to add AY music to games

Post by RMartins »

R-Tape wrote: Tue Jan 11, 2022 11:28 am I've only ever used Vortex Tracker. I last downloaded it from here. I wouldn't call the memory or speed footprint insignificant, but it's never caused me problems with timed sprite routines etc.

Once you have your music, export the file with ZX Spectrum Player option, you can choose to compile it anywhere, but it's most common at 49152 and paged in/out. I haven't tried it, but there's an export without player option, which you would use for multiple tracks (only exporting the player once). I export as a .TAP and put everything together using ZX-Blockeditor.

Vortex Tracker tells you which address to CALL for initiate, play and mute track depending where you compile to. Using 49152 as an example, here's how it fits together:

- on starting, disable interrupts
- set up vector table and interrupt routine that pages in the AY music and CALLS 49157 every frame.
- CALL 49152 to initiate the player
- set IM 2
- EI (remember what was paged in before), you should now be playing your AY music.

Is this what you were after? I suspect you knew most of this anyway, but I could post some code later if you need it.
I have been doing something similar, except that I'm considering 48K with AY, and hence no paging the player memory in and out.
But it's basically what R-Tape mentioned.

You can have several modules/music, the player supports that directly.


The only short coming I see is that by using modules (a self contained unit), we are in fact duplicating all the instruments defined in each music/module, even if they are the same.

But usually, for the sake of saving memory it would be interesting to be able to share the instrument definitions.

Another, is the fact that patterns could be repeated in a specific channel, but a Vortex Tracker pattern involves all 3 channels.

So some improvements to minimize memory in some specific cases, are still possible.
Something I might work on in a near future.

The good thing about Vortex Tracker, is that it has a editor that runs on a PC, which generates almost identical music for what you will hear on the physical machine, which is great.

NOTE: There is something that I don't like in the latest versions of the tracker, it doesn't allows to export the player in ASM format, only in pre-assembled/compiled form. So you are adding a bunch of bytes into memory without being able to change simple things (that won't affect play out), unless you disassemble the code.
presh
Manic Miner
Posts: 237
Joined: Tue Feb 25, 2020 8:52 pm
Location: York, UK

Re: Wanting to add AY music to games

Post by presh »

Thank you folks, this is exactly what I was after - much appreciated!

Sounds like Vortex is the way forward.

I've already got IM2 set up (does nothing at present, just lets me use IY) so first thing would be to get a simple song playing, then I can look at using [mention]andydansby[/mention]'s code to switch tracks :D
Ralf
Rick Dangerous
Posts: 2303
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: Wanting to add AY music to games

Post by Ralf »

Ideally looking for a lightweight player
I also recommend Vortex Tracker but unfortunately wouldn't call it light.

If you check existing tunes (for example here https://zxart.ee/eng/music/ ) , an average size of a tune would be about 4-5 kB.
That's a considerable size. I wrote several games for Spectrum 48 using AY music and often wished that music took less space.

As for the speed, asyou probably know Zx Spectrum displays 50 picture frames per second and has 50 interrupts per second. In most cases the music code also needs to be called 50 times per second, during each interrupt. From my exaperience, the music made in Vortex Tracker
takes about 20% of interrupt time. Again, it's a considerable amount. This time also varies quite a lot. Some drums play and suddenly
music player takes much longer time to execute than a moment before. You can test it by changing the colour of the border before and
after the music code. So sometimes you need a very precise timing for your code and music with its random execution time can be a pain here.
andydansby
Microbot
Posts: 148
Joined: Fri Nov 24, 2017 5:09 pm
Location: Syracuse, NY, USA
Contact:

Re: Wanting to add AY music to games

Post by andydansby »

[mention]Ralf[/mention] what I do is create a 5-6k “buffer” and use ZX0 to decompress a song there. A song will decompress to about 1-2k depending on the length. You can fit quite a few songs in there. Of course the buffer has to be a large as your longest song.

WYZ’s songs are pretty compact. Arkos 1 & 2 songs are about the same as Vortex.
presh
Manic Miner
Posts: 237
Joined: Tue Feb 25, 2020 8:52 pm
Location: York, UK

Re: Wanting to add AY music to games

Post by presh »

Ralf wrote: Tue Jan 11, 2022 5:36 pm From my exaperience, the music made in Vortex Tracker
takes about 20% of interrupt time.
What do you mean by "interrupt time"? (I suspect you mean the top border before the screen starts being drawn)

Speed is a concern, as the game currently takes 3-4 frames to render one frame, so the music function would be called 3-4 times before the next frame is output. That's gonna add up! Hoping it won't be too noticeable... :?
User avatar
R-Tape
Site Admin
Posts: 6481
Joined: Thu Nov 09, 2017 11:46 am

Re: Wanting to add AY music to games

Post by R-Tape »

presh wrote: Tue Jan 18, 2022 1:25 am What do you mean by "interrupt time"? (I suspect you mean the top border before the screen starts being drawn)

Speed is a concern, as the game currently takes 3-4 frames to render one frame, so the music function would be called 3-4 times before the next frame is output. That's gonna add up! Hoping it won't be too noticeable... :?
Yep it's about that, and not constant unfortunately - there are spikes that occupy most of the top border. See below, this is Vortex Tracker playing my periodic table demo ([mention]djnzx48[/mention]'s music) with yellow border marking the AY time.

Image
User avatar
DenisGrachev
Dizzy
Posts: 88
Joined: Fri Feb 09, 2018 2:32 am
Location: Novosibirsk, RU
Contact:

Re: Wanting to add AY music to games

Post by DenisGrachev »

I always wonder why everyone export with player from Vortex Tracker. All players sources are in a same site as tracker :)

Anyway, here is a zip with a two pt3 players to be compiled with sjasmplus and also a bin folder with precompiled to 49152
https://www.retrosouls.net/zx/pt3players.zip

There is a faster version of standart pt3player included with vortex player from [mention]introspec[/mention] it's about 15% faster than regular
Also there is a fast pt3 player from [mention]Alone Coder[/mention] that fits in 5000 tstates, as i remember

Feel free to test and have fun!
Alone Coder
Manic Miner
Posts: 401
Joined: Fri Jan 03, 2020 10:00 am

Re: Wanting to add AY music to games

Post by Alone Coder »

Info Guide #11 http://alonecoder.nedopc.com/zx/books/IG11.ZIP also contains the shortest player by Dr.Lion (down to 571 bytes) and a fast player by Monster/Sage (used in Born Dead and Insanity).
presh
Manic Miner
Posts: 237
Joined: Tue Feb 25, 2020 8:52 pm
Location: York, UK

Re: Wanting to add AY music to games

Post by presh »

Thanks guys, all good info :)

Managed to knock a quick tune in Vortex together with a bit of help from this thread

My first attempt at implement it within the game however was... not good :lol:

But I'm using bank switching a lot, so used DI before working in other banks and only EI again once copying the data was finished... leading to lots of missed interrupts. Fixed this with a CALL to set the current page variable and do the paging - a bit slower, but not crippling.

Worse though, my screen blitter routine uses the stack to read a LUT ( POP DE / LDI x 24 / DEC A / JP NZ, loop ) making the music sound very slow, beyond drunk... so I quickly replaced this with another version, using the same lookup table, but it was sloooow... noticeably slow enough for me to hate it, in fact. Figured I could do it quicker by breaking the code up into 3 loops (block x3, vertical cell x8, vertical pixel x8) which seems less slugginsh and noticeably better.

On the plus side, I no longer need that 384 byte LUT, so got a bit of space... may be time to replace some JRs with JPs again and see if leads to a noticeable speed gain.

I've had to disable my sound effects in the meantime, as they aren't handled by the interrupt routine yet, and were messing things up when they fired. If I just run the sound effect code immediately after the music code finished, effectively overwriting what the music player did, will that be adequate? The sound FX all occupy channel C, and I'm writing the tunes with this in mind (so the "important" stuff is in channels A+B... I'm aware the noise generator is shared, too). In my head it seems fine, but am I about to walk into a typical newbie trap?

Also wondering about...
andydansby wrote: Tue Jan 11, 2022 11:53 am Z80
How long does it take to decompress a track? Ideally I'd like different music to play in each car (like in GTA) but can't have the game hanging for several seconds while waiting for this to happen. If it's almost instantaneous though (i.e. a handful of frames, tops) I can probably live with it.
presh
Manic Miner
Posts: 237
Joined: Tue Feb 25, 2020 8:52 pm
Location: York, UK

Re: Wanting to add AY music to games

Post by presh »

Alone Coder wrote: Tue Jan 18, 2022 5:12 pm Info Guide #11 http://alonecoder.nedopc.com/zx/books/IG11.ZIP also contains the shortest player by Dr.Lion (down to 571 bytes) and a fast player by Monster/Sage (used in Born Dead and Insanity).
I definitely need to check out the fast player, trying to save as many T-states as possible over here! :D
User avatar
DenisGrachev
Dizzy
Posts: 88
Joined: Fri Feb 09, 2018 2:32 am
Location: Novosibirsk, RU
Contact:

Re: Wanting to add AY music to games

Post by DenisGrachev »

presh wrote: Fri Jan 21, 2022 8:58 pm
Alone Coder wrote: Tue Jan 18, 2022 5:12 pm Info Guide #11 http://alonecoder.nedopc.com/zx/books/IG11.ZIP also contains the shortest player by Dr.Lion (down to 571 bytes) and a fast player by Monster/Sage (used in Born Dead and Insanity).
I definitely need to check out the fast player, trying to save as many T-states as possible over here! :D
Fast player it's not about pt3, you need export pt3 to psg and use some psg compressors with fast ~1000tstates players, like tbk player
Here is a latest upgrade of tbk from Roman Vasilenko
https://github.com/vasilenkoroman/psg_compressor
Alone Coder
Manic Miner
Posts: 401
Joined: Fri Jan 03, 2020 10:00 am

Re: Wanting to add AY music to games

Post by Alone Coder »

Monster's fast player is for slightly processed PT3.
introspec
Dizzy
Posts: 53
Joined: Wed Jan 02, 2019 2:26 pm
Location: London
Contact:

Re: Wanting to add AY music to games

Post by introspec »

DenisGrachev wrote: Tue Jan 18, 2022 4:04 pm I always wonder why everyone export with player from Vortex Tracker. All players sources are in a same site as tracker :)

Anyway, here is a zip with a two pt3 players to be compiled with sjasmplus and also a bin folder with precompiled to 49152
https://www.retrosouls.net/zx/pt3players.zip

There is a faster version of standart pt3player included with vortex player from @introspec it's about 15% faster than regular
Also there is a fast pt3 player from @Alone Coder that fits in 5000 tstates, as i remember

Feel free to test and have fun!
Just a quick note: although the version of vortex player that I modified is a bit faster, it was never intended to be used as a mainstream player; I hacked it together for a canned project and have no intention to do a more serious work with it. Hence, I cannot recommend using it, unless you know what you are doing and it fits your use profile. I only shared it with several people because they needed full VT2 compatibility and at least a bit of a speed-up. Personally, I use various types of PSG players for almost all of my projects since 2014.
Post Reply