libmsx
C library for MSX
Loading...
Searching...
No Matches
LA0 - PSG, SCC/SCC+, OPLL sound driver.

#include <la0.h> More...

+ Collaboration diagram for LA0 - PSG, SCC/SCC+, OPLL sound driver.:

Modules

 Open LA0 file image.
 
 Set a song in LA0 file to the decoder.
 
 Other LA0 specific APIs.
 

Files

file  la0.h
 The libmsx audio format 0 (LA0) decoder.
 

Variables

const AudioDecoder LA0_BGM_DECODER
 LA0 BGM decoder.
 
const AudioDecoder LA0_SFX_DECODER
 LA0 SFX decoder.
 

Detailed Description

#include <la0.h>

LA0 decoder is a decoder for the libmsx audio replayer.

la0.h provides LA0 decoder specific APIs. It is supposed to use with audio.h the libmsx audio replayer APIs.

LA0 decoder supports all functionality of the libmsx audio replayer.

Example
The following sample application la0_demo shows usecase of LA0 and the libmsx audio replayer.

// -*- coding: utf-8-unix -*-
/*
* Copyright (c) 2021-2024 Daishi Mori (mori0091)
*
* This software is released under the MIT License.\n
* See https://github.com/mori0091/libmsx/blob/main/LICENSE
*
* GitHub libmsx project\n
* https://github.com/mori0091/libmsx
*/
#include <msx.h>
#include <screen.h>
#include <text.h>
#include <audio.h>
#include <audio_buf.h>
#include <audio_efx_amp.h>
#include <la0.h>
#include <stdio.h>
// current song number
uint8_t song_number = 255;
uint8_t number_of_songs;
uint8_t number_of_sfx;
static MemFile bgm;
static MemFile sfx;
// joypad state
uint8_t pressed;
uint8_t clicked;
void show_vsync_freq(void) {
locate(0, 0);
printf("VSYNC:%dHz ", (int)msx_get_vsync_frequency());
}
void show_player_freq(void) {
locate(0, 1);
printf(" PLAY:%dHz ", (int)audio_get_bgm_frequency());
}
void show_bgm_info(void) {
locate(0, 2);
printf(" BGM:%dHz (#%d/%d) ",
(int)song_number+1,
(int)number_of_songs);
show_player_freq();
locate(26, 1); printf("%5zu", (size_t)la0_get_bgm_total_samples());
locate(26, 2); printf("%5zu", (size_t)la0_get_bgm_loop_samples());
}
void increase_player_freq(void) {
uint8_t Hz = audio_get_bgm_frequency();
if (Hz < 240) {
show_player_freq();
}
}
void decrease_player_freq(void) {
uint8_t Hz = audio_get_bgm_frequency();
if (10 < Hz) {
show_player_freq();
}
}
// void toggle_pause(void) {
// locate(13, 10);
// if (audio_is_paused()) {
// // resume
// audio_start();
// print(" ");
// }
// else {
// // pause
// audio_pause();
// print("PAUSE");
// }
// }
void next_song(void) {
if (song_number < number_of_songs - 1) {
song_number++;
}
else {
song_number = 0;
}
la0_set_bgm(song_number, &bgm);
JIFFY = 0;
show_bgm_info();
}
void prev_song(void) {
if (0 < song_number) {
song_number--;
} else {
song_number = number_of_songs - 1;
}
la0_set_bgm(song_number, &bgm);
JIFFY = 0;
show_bgm_info();
}
void show_psg_register_values(void) {
for (uint8_t i = 0; i < 14; ++i) {
locate(5, 4+i);
uint8_t val = audio_buf_cache[0xb0+i];
printx((uint16_t)(val >> 4));
printx((uint16_t)(val & 15));
}
}
void show_psg_registers(void) {
locate(0, 4);
for (uint8_t i = 0; i < 14; ++i) {
printf("R#%02d\n", (int)i);
}
show_psg_register_values();
}
void update_joypad_state(void) {
uint8_t joy = joypad_get_state(0);
clicked = pressed & ~joy;
pressed = joy;
}
static void play(void) {
audio_play(); // The libmsx audio replayer
audio_efx_amp(); // Effector (amp)
}
void main(void) {
color(15, 4, 7);
cls();
number_of_songs = la0_open_resource(&bgm, "bgm.la0");
number_of_sfx = la0_open_resource(&sfx, "sfx.la0");
srand(JIFFY);
locate(0, 21);
print(" LEFT/RIGHT Select BGM\n");
print(" UP/DOWN Player Freq.\n");
print(" SPACE Sound effects\n");
show_vsync_freq();
show_player_freq();
show_psg_registers();
for (;;) {
locate(26, 0); printf("%5zu", (size_t)JIFFY);
show_psg_register_values();
next_song();
}
// If the current song has a looped section, it repeats up to twice.
// Start fade-out, wait for it to complete, then stop the replayer.
}
// Reset the main volume, select the next song, and restart the replayer.
next_song();
}
update_joypad_state();
if (clicked & VK_FIRE_0) {
if (number_of_sfx) {
la0_set_sfx(rand() % number_of_sfx, &sfx);
}
// else {
// toggle_pause(); // pause / resume
// }
}
if (clicked & VK_RIGHT) {
next_song();
}
if (clicked & VK_LEFT) {
prev_song();
}
if (pressed & VK_UP) {
increase_player_freq();
}
if (pressed & VK_DOWN) {
decrease_player_freq();
}
}
}
The libmsx audio replayer.
Unified sound-chip buffer of the libmsx audio replayer.
The AMP effector.
uint8_t audio_buf_cache[256]
The latest value of each command.
int8_t audio_efx_amp_get_fade(void)
MSX Return the status of fade-in/out.
void audio_efx_amp_fadeout(uint8_t ticks)
MSX Decrease the main volume level by one for each specified period of time.
void audio_efx_amp_set_volume(uint8_t volume)
MSX Sets the main volume level to the AMP effector.
void audio_efx_amp(void)
MSX The AMP effector for the libmsx audio replayer.
void audio_set_repeat(bool repeat)
MSX Turn on/off the auto-repeat of the BGM.
void audio_start(void)
MSX Start / Resume music.
uint8_t audio_get_bgm_frequency(void)
MSX Return replayer frequency of the background music.
bool audio_is_playing_bgm(void)
MSX Return whether BGM is playing or not.
void audio_set_bgm_frequency(uint8_t freq)
MSX Force replayer frequency of the background music.
void audio_stop(void)
MSX Stop music.
void audio_init(void)
MSX Initialize the libmsx audio replayer.
void audio_play(void)
MSX Main routine of the libmsx audio replayer.
uint8_t msx_get_vsync_frequency(void)
MSX Returns VSYNC frequency in Hz.
Definition bios.h:78
#define color(fg, bg, border)
MSX Set foreground, background, and border color.
Definition text.h:156
#define locate(x, y)
MSX Set cursor position.
Definition text.h:54
#define cls()
MSX Clear the screen and move the cursor to the top left corner.
Definition text.h:66
void print(const char *str)
MSX Print string on the screen.
void printx(uint16_t x)
MSX Print unsigned integer in hexadecimal on the screen.
uint8_t joypad_get_state(uint8_t controller)
MSX Get the status of the joystick buttons and levers.
#define VK_UP
Bitmask for UP direction of joystick or UP arrow key.
Definition input.h:40
#define VK_FIRE_0
Bitmask for trigger button #1 or SPACE key.
Definition input.h:68
#define VK_LEFT
Bitmask for LEFT direction of joystick or LEFT arrow key.
Definition input.h:54
#define VK_RIGHT
Bitmask for RIGHT direction of joystick or RIGHT arrow key.
Definition input.h:61
#define VK_DOWN
Bitmask for DOWN direction of joystick or DOWN arrow key.
Definition input.h:47
void await_vsync(void)
MSX Waits for next VSYNC interrupt.
void set_vsync_handler(void(*handler)(void))
MSX Register user defined VSYNC interrupt handler.
uint16_t la0_get_bgm_total_samples(void)
MSX Return the total number of BGM samples.
uint8_t la0_get_bgm_frequency(void)
MSX Return default frequency of the current background music.
uint16_t la0_get_bgm_loop_samples(void)
MSX Return the number of samples in the loop portion of BGM.
uint8_t la0_get_bgm_loop_counter(void)
MSX Return the loop counter value.
int la0_open_resource(MemFile *mf, const char *path)
MSX Open LA0 file stored as named resources in banked memory (MegaROM).
void la0_set_sfx(uint8_t idx, MemFile *mf)
MSX Set a song in the LA0 file to the LA0 audio decoder, as sound effects (SFX).
void la0_set_bgm(uint8_t idx, MemFile *mf)
MSX Set a song in the LA0 file to the LA0 audio decoder, as background music (BGM).
void screen1(void)
MSX SCREEN 1: WIDTH 32 (GRAPHIC 1 mode).
The libmsx audio format 0 (LA0) decoder.
Internal structure of MemFile type.
Using #include <msx.h> includes almost all C header files in libmsx, for ease to use.
SCREEN mode initialization function like MSX-BASIC.
Utility functions for text ouput.
static volatile uint16_t JIFFY
MSX Free-running counter that counts up every VSYNC interrupts.
Definition workarea.h:258
See also
The API of the libmsx audio replayer.
Effectors for the libmsx audio replayer.
la0_demo sample application.
vgm2la VGM files to LA0 file conversion tool.

Variable Documentation

◆ LA0_BGM_DECODER

const AudioDecoder LA0_BGM_DECODER
extern

LA0 BGM decoder.

◆ LA0_SFX_DECODER

const AudioDecoder LA0_SFX_DECODER
extern

LA0 SFX decoder.