This article is by Arnaud. Thanks to him!
The objective of this tutorial is to use music and sounds created by Arkos Tracker 3 with the CPCTelera development environment.
Many games use this environment, for example the winner of CPCRetroDev 2020 The abduction of Oscar Z (Dreamin`Bits), Sorcerers (SalvaKantero) second place of CPCRetroDev 2020 or Space Movies (RetroBytes). Most of the CPCRetrodev participants use this Framework.
Arkos Tracker 3 is natively integrated into CPCTeleraNext. Music and sound effects are generated by editing the associated configuration file.
This is essentially the same process as integrating ArkosTracker 1 with CPCtelera, but with CPCTeleraNext, only AT3 is supported, and the implementation is slightly different.
Here is the repository:
https://github.com/Arnaud6128/cpctelera/tree/cpctelera_next
All functions are documented in the help section, under Audio.
Example
The example is in the following directory « cpctelera/examples/medium/arkosAudio ».
In the “cfg/” directory of your project, the “music_conversion.mk” file generates the sounds.
Here are the different parameters:
- SET_FOLDER: specifies where to generate the music; by default, this is in the src/ directory.
- SET_PLAYER: specifies the Player (akg, akm, and fx). Special effects are linked to the selected Player.
- SET_OUTPUTS: specifies the output format “s” for assembly language output (SDCC compatible) and binary output “bin” as an array in a C file. For binary output, you will need to specify the memory address of the sound; for assembly language, the compiler will handle this automatically.
- CONVERT: launches the sound generation process. You must specify the path of the « aks » file, the name of the sound variable in the code, and its address for binary generation.
In the example provided, here is the content of the “music_conversion.mk” file:
$(eval $(call AKS2DATA, SET_OUTPUTS , bin ))
$(eval $(call AKS2DATA, SET_PLAYER , akg ))
$(eval $(call AKS2DATA, CONVERT , music/molusk.aks , music , 0x300))
$(eval $(call AKS2DATA, SET_OUTPUTS , s ))
$(eval $(call AKS2DATA, SET_PLAYER , fx ))
$(eval $(call AKS2DATA, CONVERT , music/sfx.aks , effects , ))
As you can see, the AKG Player is used, the music is generated in binary at address 0x300 in the variable « music », and the sound is generated in assembly language in the variable « effects ». The generated files are named as the input AKS file.
To start the generation process, simply enter the command make, which will execute the script and then compile the project.
The “src/” directory (specified by default) will contain all generated files:
- molusk.c
- molusk.h
- sfx.s
- sfx.h
Music generation
The « molusk.c » file contains the music named « g_music » and the variable is accessible via the « molusk.h » file. The binary generation will automatically prefix the variable with « g_ ».
A macro is used to position the music at 0x300.
// Generated by CPCTelera for ArkosPlayer3
#include <cpctelera.h>
CPCT_ABSOLUTE_LOCATION_AREA(0x2FF); // Array at 0x300
// File src/molusk.bin converted using cpct_bin2c
const unsigned char g_music[7841] = {
…
Sound effectusic generation
The « sfx.s » file contains all the sound effects and they are used in the code in « sfx.h ». The sound effects are automatically suffixed with « SoundEffects ».
// Generated by CPCTelera for ArkosPlayer3
extern u8 effectsSoundEffects[];
Implementing the AKG Player
In the « main.c » file, the generated code is included and the ArkosTracker 3 functions are used.
The generated files shall be included in this way :
#include "molusk.h"
#include "sfx.h"
In our case, we used the AKG Player, but the logic is the same with the AKM Player, the only difference is the function prefix, you will need to use cpct_PLY_AKG<function>.
As always, the sounds must be initialized before using them:
// Initialize the song to be played
cpct_PLY_AKG_Init(g_music, 0); // Initialize the music
cpct_PLY_AKG_InitSoundEffects(effectsSoundEffects); // Initialize the sound effects
// Music is played on interrupt.
cpct_setInterruptHandler(MusicInterruptHandler);
In the example, an interrupt is used to play the sound, which guarantees a frequency of 50Hz.
The cpct_PLY_AKG_Play method will allow the selected music and sound effect to be played.
void MusicInterruptHandler(void)
{
static u8 sInterrupt = 0;
// Play next music 1/50 step.
if (sInterrupt == 1)
{
if (gPlaying)
cpct_PLY_AKG_Play();
}
else if (sInterrupt == 6)
{
cpct_scanKeyboard_if();
sInterrupt = 0;
}
sInterrupt++;
}
In the main loop:
- Pressing 1 or 2 plays the associated sound using the cpct_PLY_AKG_PlaySoundEffect function.
- Pressing the spacebar stops all sounds using the cpct_PLY_AKG_Stop function or plays another sound.
while (1)
{
// When Space is released, stop / continue music
if ( checkKeyEvent(Key_Space, &k_space) == K_RELEASED )
{
// Change it from playing to not playing and viceversa (0 to 1, 1 to 0)
gPlaying ^= 1;
// Stop sound
if (!gPlaying){
cpct_PLY_AKG_Stop(); // Cut down sound output
}
else{
cpct_PLY_AKG_PlaySoundEffect(1, AT3_CHANNEL_A, 0); // Play sound
}
}
// Play sound effect when press key 1, or 2
// !! Warning sound effect start at index 1 !!
if ( checkKeyEvent(Key_1, &k_1) == K_RELEASED )
{
cpct_PLY_AKG_PlaySoundEffect(2, AT3_CHANNEL_A, 0);
}
if ( checkKeyEvent(Key_2, &k_2) == K_RELEASED )
{
cpct_PLY_AKG_PlaySoundEffect(3, AT3_CHANNEL_A, 0);
}
}
Using ArkosTracker Player is quite simple, for more information on Player functions consult the documentation.