News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Adding Arkos Tracker 2 Music to CPCTelera 1.5 Projects - a HOWTO guide

Started by Typhon, 22:03, 06 April 24

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

Typhon

This is a HOWTO on how I added Arkos Tracker 2 Music to my CPCTelera game NibblerDX (see attached DSK), as there is a bit of confusion on how to do it. Warning, this is a WALL OF TEXT.

Adding Arkos Tracker 2 Music to a CPCTelera 1.5 project.

Links of Reference:

1. https://64nops.wordpress.com/2020/12/20/easy-integration-of-arkos-tracker-2-player-with-cpctelera/
2. http://www.julien-nevo.com/arkostracker/index.php/using-a-song-in-production-using-any-assembler/
3. http://www.memoryfull.net/articles/64nops/arkos2.zip

Note that even though I personally am using Linux, for simplicity's sake, I will keep the references in the links above to long Windows-style filenames intact. The missive below covers the procedure you need to follow to add Music/Sound Effects, as I have done for my game NibblerDX.

You will need:
1. Music Song File you wish to incorporate, in AKS format.
2. Sound Effects Song File, also in AKS format.
3. Access to your Arkos Tracker 2 directory.
4. Access to the arkos2.zip file mentioned above.

I am using Rabbit.aks by Mr Lou from indiegamemusic.com in this example (he has very kindly given me permission to use it in NibblerDX).

To begin with, we will follow the steps in Link (2).

1. In Arkos Tracker 2, export both Song Files above, as AKM Minimalist Format, and stick the resulting asm files in a working directory somewhere, remembering what you called them. Just use the standard export options that Arkos Tracker 2 selects for you. Note that for each song file, you will end up with *two* asm files. So for the Music and Song files, you will have <songname>.asm and <songname>_playerconfig.asm for each.
2. Now, this next step is *missing* from the tutorial above. Go into your Arkos Tracker 2 directory, and find the /players/playerAkm/sources/ directory. From this, copy the PlayerAkm.asm *and* PlayerAkm_SoundEffects.asm files into your working directory above.
3. Back in your working directory, as the tutorial states, create a CompileAT2Files.asm. You will need to include each asm file generated in step 1 *and* both the PlayerAkm* files from Step 2. Here's an example of a working CompileAT2Files.asm file for the CPC. Ignore all the stuff about disabling sound effects for now.


;Compiles the player, the music and sfxs, using RASM.
;No ORG needed.

;This is the music, and its config file.
include "rabbit.asm"
include "rabbit_playerconfig.asm" ;Optional.

;This is the sfxs, and its config file. 
include "soundeffects.asm"
include "soundeffects_playerconfig.asm"  ;Optional.

;What hardware? Uncomment the right one.
;PLY_AKG_HARDWARE_MSX = 1       
;PLY_AKG_HARDWARE_SPECTRUM = 1
;PLY_AKG_HARDWARE_PENTAGON = 1

;Comment/delete this line if not using sound effects.
PLY_AKG_MANAGE_SOUND_EFFECTS = 1

;This is the player.
include "PlayerAkm.asm"
include "PlayerAkm_SoundEffects.asm"


4. Compile this using rasm (v1.8 is fine), for example:

../../rasm/rasm_linux64 CompileAT2Files.asm -o UniversalAt2Files -s -sl -sq

A successful compilation will result in *two* UniversalAt2Files.* files, a bin file and a sym file.

5. Now go back into the Arkos Tracker 2 directory, and under the /tools/ subdirectory, grab the Disark executable and copy it into your working directory. Use this tool as follows:

./Disark UniversalAt2Files.bin At2Files.asm --symbolFile UniversalAt2Files.sym --sourceProfile sdcc

So now after all that palaver we now have an At2Files.asm we can use goingforward. And now we switch over to the steps mentioned in Link (1).

6. From the arkos2.zip file in Link (3), grab sound.h and sound.c and stick them into your source/header directories as appropriate.

7. Create an arkos2 subdirectory in your source directory, and inside it, you will want the ArkosPlayer2.h and ArkosPlayer2_cbinding.s files. You will *not* want the PlayerAkm.asm file from the zip for reasons that will become clear very shortly.

8. Remember the generated At2Files.asm file from Step 5? Which is your compiled player/songs file? You need to copy *that* into the arkos2 subdirectory above, and *rename* it PlayerAkm.asm (I know!). This is the actual file mentioned in the "GENERATION AND CREATION OF FILES COMPATIBLE WITH CPCTELERA" section of the Tutorial in Link (2)

9. Now follow the instructions to modify sound.c. You want to grab the labels from the now-called PlayerAkm.asm file and update them appropriately - to find out the labels, look at the PlayerAkm.asm file. You will see something like this:

RABBIT_START:
_RABBIT_START:


Thus change the symbols in sound.c to this sort of thing:

extern void* RABBIT_START;
extern void* SOUNDEFFECTS_START;

...

void InitSound()
{
   _fxChanged = 0;
   _songChanged = 0;
   
    InitSFX(&SOUNDEFFECTS_START);
    InitMusic(&RABBIT_START);
}


10. The next step mentioned in the Tutorial in (1), about using an alternative music player, we don't need to worry about, as we're just using the AKM file already. So at this point, you will have a sound.c and sound.h file in your project source/header directories (as appropriate) and you will have a further arkos2 subdirectory in your source directory, which contains 3 files: rkosPlayer2.h, ArkosPlayer2_cbinding.s, and PlayerAkm.asm.

11. *Now* you this should actually compile when you next run make or whatever your compiler of choice is. If you end up with error messages about unknown symbols in ArkosPlayer2_cbinding.s, it will be because you will have forgotten to include the "PlayerAkm_SoundEffects.asm" file in Step 3.

12. Once it compiles, congratulations, you have got Arkos Tracker 2 files incorporated into your game. No, really, you have. Now to test this out, you need to do the following:

   a) Early in your code, before you do much call InitSound(); (this is from sound.h/c).
   b) In your interrupt handler (or your main loop, but I prefer to use the interupt handler), call PlaySound(); - again from sound.h/c - but remember if you are using an interrupt handler only do so every 1/50 of a second; that is, every 6 interrupts (as interrupts fire every 1/300 of a second). The standard way of handling this is to use a static counter that counts from 0 to 5 repeatedly, and if this counter is 5 (or whatever) then call PlaySound();
   c) *Before* the interrupt is setup call PlayMusic(0); then and only *then* set up the interrupt handler.

13. Music will now play. But you are using interrupt handlers, you *will* end up with a crash when you disable the interrupt handler. That's because even though a C-binding to a Stop Music function is provided, none is given in sound.c/h. So add one:

void StopMusic() {
   PLAYER_ARKOS_STOP();
}


Make sure to call this *after* you disable the interrupt. Of course, in your code you are only going to play music/sound effects when toggled on.

And that's how I added Arkos Tracker 2 music to NibblerDX. All the intermediate steps you can find in the /collateral/sound directory of the source code. Feel free to pilfer it as needed. NibblerDX (and indeed the relevant arkos2.zip code) is open source under the GPL2/3.

*Phew*.

Comments and criticism welcome, and if other people find it useful, feel free to add it to the wiki etc.



mr_lou

Nice write-up!

Anything to help devs use Arkos Tracker 2 files is a most welcome help.

I remember trying to follow those tutorials as well when I wanted to add my Arkos Tracker 2 music to "Light Grid". I spent a tremendously amount of time trying to figure it out - but still ended up failing miserably. No matter what I did, the music just didn't play properly.
So in the end I gave up! And instead, I ended up manually editing the Arkos Tracker 2 XML file and changed it into an Arkos Tracker 1 file. Extremely tedius work - but easier than getting my Arkos Tracker 2 file playing properly.

After experiencing all the trouble with Arkos Tracker 2 music for cpcTelera, I decided I'd personally stop making Arkos Tracker 2 music. I want my CPC tracks to be easily usable by as many CPC devs as possible. So it was/is quite clear to me that I need to be creating Arkos Tracker 1 files instead of Arkos Tracker 2 files from now on.

Unfortunately Arkos Tracker 1 doesn't run on Linux. Arkos Tracker 2 doesn't export to Arkos Tracker 1 format. There exists no converter tools either, and there's no hope that anyone will ever add Arkos Tracker 2 support to cpcTelera native tools.
Nothing is ever easy.

So, as it often goes, I'm currently trying to find my own workaround, by making myself a little tool that converts my MOD files into Arkos Tracker 1 format. In other words: I'm creating a tool that'll let me create Amstrad CPC music with Milkytracker. Kinda like how Timidity is a tool that lets me create MIDI music with Milkytracker, and SNESMOD is a tool that lets me create Super Nintendo music with Milkytracker.
If all goes well it should finally result in more Amstrad music at IndieGameMusic in the near future - some that is a lot easier to include in a cpcTelera project. Fingers crossed.

Typhon

Alright, so upon further investigation, I need to figure out a way of pausing music, as simply not calling PLAYER_ARKOS_PLAY in the interrupt when music/sfx are switched off doesn't work cleanly - it sometimes leaves a constant dead sound until such time as the sound player is enabled again. Additionally, I note from the AT website that there's no way to have music decoupled from the sfx unless you have a second "silent" song.

Maybe its something to do with a sound queue/buffer? Is there anywhere in the minimalist AKM player that has the ability to clear this? I note that PLAYER_ARKOS_STOP only seems to be able to be called once. Is that correct?

Targhan

@Typhon This is excellent stuff! I contacted the person in charge of CPCtelera (via the email found on Github) but had no reply yet :(. I don't have time right now, but I'd like to help integrating AT2 (and soon AT3!) into CPCTelera in a seamless way.

QuoteAlright, so upon further investigation, I need to figure out a way of pausing music
As explained in the doc, calling the STOP method will cut the PSG sound, that's all you have to do (of course, don't call the PLAY method for as long as you don't want music).

QuoteAdditionally, I note from the AT website that there's no way to have music decoupled from the sfx unless you have a second "silent" song.
An alternative is to use the SFX stand-alone player. It is short and efficient, and it's the best solution if you never play music at any other point.
Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

Typhon

As an aside, I vaguely recall that the CPCTelera author/maintainer is also registered and active (or has been) here on this forum.

jesusdelmas

Quote from: Targhan on 11:03, 08 April 24@Typhon This is excellent stuff! I contacted the person in charge of CPCtelera (via the email found on Github) but had no reply yet :(. I don't have time right now, but I'd like to help integrating AT2 (and soon AT3!) into CPCTelera in a seamless way.

QuoteAlright, so upon further investigation, I need to figure out a way of pausing music
As explained in the doc, calling the STOP method will cut the PSG sound, that's all you have to do (of course, don't call the PLAY method for as long as you don't want music).

QuoteAdditionally, I note from the AT website that there's no way to have music decoupled from the sfx unless you have a second "silent" song.
An alternative is to use the SFX stand-alone player. It is short and efficient, and it's the best solution if you never play music at any other point.
@ronaldo i think this may be a matter of interest for you  8)

trocoloco

@Targhan, in Telegram there's a CPCTelera group,  you can find him there also

Typhon

As an side, there's a line of code missing from Step 3 above. Oops.

PLY_AKG_HARDWARE_CPC = 1


ivavilagu

Trying to add some songs to cpctelera. One song works but more than one not.

My compile.asm file:

include "TITLE.asm"
include "TITLE_playerconfig.asm"
include "FIRST_LEVEL.asm"
include "FIRST_LEVEL_playerconfig.asm"
include "EMPTY.asm"
include "EMPTY_playerconfig.asm"

;This is the sfxs, and its config file. 
include "soundeffects.asm"
include "soundeffects_playerconfig.asm"  ;Optional.

PLY_AKG_HARDWARE_CPC = 1       


;Comment/delete this line if not using sound effects.
PLY_AKG_MANAGE_SOUND_EFFECTS = 1

;This is the player.
include "PlayerAkm.asm"
include "PlayerAkm_SoundEffects.asm"


It doesn´t work when playing second or third song.

Need to modify sound.c to add extra songs?

Typhon

Yes, as far as I know, yes, you need to grab the <song>_START label from the generated asm file and add it in to sound.c etc indeed.

ivavilagu

Quote from: Typhon on 22:34, 28 May 24Yes, as far as I know, yes, you need to grab the <song>_START label from the generated asm file and add it in to sound.c etc indeed.
Yes, adding a label for every new song and  modified initMusic() function.

Thanks!!

Typhon

Odd, I can't get Sound to play in my new project.

Have done all of the above (lol), using

PlaySFX(1, CHANNEL_A, MAX_VOL);

referring to an exported and compiled etc AKM of Sound Effects.

music works fine.

ivavilagu

Quote from: Typhon on 19:40, 29 May 24Odd, I can't get Sound to play in my new project.

Have done all of the above (lol), using

PlaySFX(1, CHANNEL_A, MAX_VOL);

referring to an exported and compiled etc AKM of Sound Effects.

music works fine.
In Arkos2 .zip there is a code example using sound effects

Typhon

Ah, I'm going to try the automatic conversion then in that!

ivavilagu

New problem added. Songs play well but when I draw a full tilemap at the beginning of the level game crashes. The solution is to draw the tilemap in some steps but the game still crashes when PlaySound is called at the interruption

void drawMap(){

   u8 i;

   for (i=0;i<32;i++){
      cpct_etm_drawTileBox2x4 (0, i, 32, 1, 32, cpct_getScreenPtr((u8*)0xC000,0,0), currentMap);
      cpct_etm_drawTileBox2x4 (0, i, 32, 1, 32, cpct_getScreenPtr((u8*)0xC400,0,0), currentMap);
   }
}



Code below works but obviously an unpleasant sound effect appears (last note listen longer while map is drawed) 

cpct_removeInterruptHandler();
drawMap();
setInterruptAtVSYNCStart(gameInterrupt);

I don´t know why the game crashes when playSound is called while map is drawing

mr_lou

This sounds like the kind of trouble I was having when trying to use Arkos Tracker 2 tracks with cpcTelera.

Sadly I have no help to offer. I gave up in the end, and manually changed the Arkos Tracker 2 XML into an Arkos Tracker 1 XML instead, in order to be able to use native cpcTelera methods for music playback. Then everything worked fine.

ivavilagu

Quote from: mr_lou on 18:01, 30 May 24This sounds like the kind of trouble I was having when trying to use Arkos Tracker 2 tracks with cpcTelera.

Sadly I have no help to offer. I gave up in the end, and manually changed the Arkos Tracker 2 XML into an Arkos Tracker 1 XML instead, in order to be able to use native cpcTelera methods for music playback. Then everything worked fine.

At title screen, with it´s own interrupt manager song plays well. Starting the game, changing to another manager and it doesn,t work with drawing functions as cpct_etm_drawTilebox2_4 and cpct_etm_drawTileRow2x4. Maybe there is som kind of incompatibility.

Returning to Arkos 1  :'(
 cpct_etm_drawTileBox2x4cpct_etm_drawTileBox2x4 cpct_etm_drawTileBox2x4

Typhon

Do those cpctelera routines use the alternate registers?

Because that's a known issue with AK2 it seems.

From the demo zip you linked above:

// Uncomment if your code use alternate registers
//#include "optional/setInterruptHandler.h"


..

// If your code use alternate registers use this function instead of cpct_setInterruptHandler
// asm_setInterruptHandler(sInterruptHandler);



ivavilagu

Quote from: Typhon on 20:53, 30 May 24Do those cpctelera routines use the alternate registers?

Because that's a known issue with AK2 it seems.

From the demo zip you linked above:

// Uncomment if your code use alternate registers
//#include "optional/setInterruptHandler.h"


..

// If your code use alternate registers use this function instead of cpct_setInterruptHandler
// asm_setInterruptHandler(sInterruptHandler);



I tried these alternative files with no effects but..... you are right with alternate registers. Tilemap functions use these registers, so when playSound is called registers are overwritten and game crash. The easy solution is save these registers before sound is played and restore after. PlaySound look lke this

    if (_fxChanged)
    {
        PLAYER_ARKOS_PLAYSOUNDEFFECT(_fxNumber, _fxChannel, _fxVolume);
        _fxChanged = 0;
    }
   
    if (_songChanged)
    {
        PLAYER_ARKOS_INIT(_currentMusic, _songNumber);
        _songChanged = 0;
    }
    __asm
        // Save registers before calling PLY_AKM_PLAY   
        exx
        ex af',af
        push af
        push bc
        push de
        push hl

        call _PLAYER_ARKOS_PLAY

        //Revert back registers after calling
        pop hl
        pop de
        pop bc
        pop af
        ex af',af
        exx
    __endasm;


and it works!!!!    :P :P :P


See the solution at this thread

https://www.cpcwiki.eu/forum/programming/using-arkos-tracker-2-together-with-cpctelera/

ivavilagu

Hi again,

music game finished, let´s go with sound effects.

In the tutorial have to change line "PLY_AKG_MANAGE_SOUND_EFFECTS = 1" by "PLY_AKM_MANAGE_SOUND_EFFECTS = 1"

After export sound effects in AT2 I have a rasm error with duplicate labels.

Pre-processing [compile.asm]
Assembling
Error: [.\PlayerAkm_SoundEffects.asm:75] Duplicate label [PLY_AKM_INITSOUNDEFFECTSDISARKGENERATEEXTERNALLABEL] - previously defined in [.\PlayerAkm_SoundEffects.asm:75]
Error: [.\PlayerAkm_SoundEffects.asm:76] Duplicate label [PLY_AKM_INITSOUNDEFFECTS] - previously defined in [.\PlayerAkm_SoundEffects.asm:76]
                                                         .
                                                         .
                                                         .
...same error with many others labels


PlayerAkm_SoundEffects.asm is the original source code from AT2 without change anything. Those labels are not duplicate in the file, so I don´t know which is the reason of the error



ivavilagu

Answering myself,

trying crazy things, commented line PlayerAkm_SoundEffects.asm seems to work

Targhan

I really don't know why there is so much trouble using AT2 with CPCTelera, it's just normal CPC code. I promise I'll check that out in the following months.
Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

pelrun

Basically it has a lot of fiddly manual steps that require knowledge of the internals of both AT2 and CPCTelera in order to integrate them properly, but most users are just blindly following the guide and can easily make a minor mistake that causes everything to blow up.

CPCTelera already has this concept of automatic resource conversion in a project, but nobody's ever updated it to work with AT2 files. That would be a useful improvement, even if it's only able to handle the simplest cases.

Powered by SMFPacks Menu Editor Mod