Difference between revisions of "Modules/arkos/aky player"

From MSX Game Library

< Modules

(Created page with "{{MODULE |name=arkos/aky_player |category=AudioFormat |image=raw.githubusercontent.com/aoineko-fr/MSXgl/main/engine/doc/img/sample_arkos.png |dependency1= |dependency2= |depen...")
 
 
Line 1: Line 1:
 
{{MODULE
 
{{MODULE
 
|name=arkos/aky_player
 
|name=arkos/aky_player
|category=AudioFormat
+
|category=Audio
 
|image=raw.githubusercontent.com/aoineko-fr/MSXgl/main/engine/doc/img/sample_arkos.png
 
|image=raw.githubusercontent.com/aoineko-fr/MSXgl/main/engine/doc/img/sample_arkos.png
 
|dependency1=
 
|dependency1=

Latest revision as of 00:09, 16 January 2024

arkos/aky_player

Code: arkos/aky_player.h

Category: Audio

Dependencies: None

Samples:

The arkos/aky_player module lets you play music in Arkos Tracker II's Streamed player (AKY) format.

Usage

To use this module, include "arkos/aky_player.h" in your source code, and add "arkos/aky_player" to the modules list (LibModules) in your project's configuration file (project_config.js).

Music address

Arkos music is designed to work only if played at a specific address. When you export a music file from Arkos Tracker, you select this address (e.g., 0xD000).

Arkos Tracker II's AKG exporter
Encode to address (bottom-left)
Arkos Tracker 3's AKG exporter
Encode to address (middle)

In your program, you must ensure that the music is placed at this address to initialize the playback properly.

There are several possible approaches:

  • Store your music in a compressed format (Pletter, ZX0, etc.) anywhere in your program and then decompress it to the correct address in RAM when needed. In this case, you must reserve enough space in RAM to put the current music and the SFX (if needed). A possible layout maybe:
    • Music at 0xD000 (4 KB up to 0xDFFF)
    • SFX at 0xE000 (1 KB up to 0xE3FF)
  • Put the music directly in the "right" place in your program. This can be quite complicated in C, unless you manually place the data at a given address (with the __at() directive). This is possible in page 0 of 48 KB ROMs, for example, or more simply with mapper segments. For example, with an 8 KB mapper, you could use the last bank (0xA000-0xBFFF) to put your music at the beginning of the segment, so that it's readable in 0xA000.

Interruption

The AKY_Decode() function temporarily changes the call stack address (SP register value) to optimize its execution and restores the correct value at the end. If the update function is called from the main loop, an interrupt may occur while the call stack address is incorrect, potentially overwriting music data and causing the game to crash.

In such cases, a simple solution is to disable interrupts while updating the music:

DisableInterrupt();
AKG_Decode();
EnableInterrupt();

A better solution is to execute the music update directly from the interrupt handler. Not only does this remove the risk of an interrupt occurring in the middle of the update, but it also allows your music to play at a constant speed even if the main loop takes several frames (for example, when you load a level or unpack data).

However, in this case, this means that all functions that change music data — notably the AKY_Play() function — must also be called from the handler or executed with interrupts disabled.

Samples

See module use cases in the sample programs:

Settings


Dependencies

Dependency on other modules: None

Documentation