mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-10-08 22:59:54 +03:00
Android: Add support for PCM sound
Now android/mako.cpp depends on SDL_mixer, and CD-DA is also played with SDL_mixer.
This commit is contained in:
@@ -14,6 +14,11 @@ FetchContent_Declare(
|
||||
URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.20.1/SDL2_ttf-2.20.1.tar.gz
|
||||
URL_HASH SHA1=f774ff407915ae4afa3d03e5a9395283d9090f28
|
||||
)
|
||||
FetchContent_Declare(
|
||||
SDL_mixer
|
||||
URL https://github.com/libsdl-org/SDL_mixer/releases/download/release-2.6.2/SDL2_mixer-2.6.2.tar.gz
|
||||
URL_HASH SHA1=036fc7839a6b8dc1af3dbfed4e2531224bbacdd7
|
||||
)
|
||||
|
||||
# Compilation of SDL and companion libraries
|
||||
FetchContent_GetProperties(SDL)
|
||||
@@ -29,6 +34,17 @@ if(NOT sdl_ttf_POPULATED)
|
||||
set(SDL2TTF_VENDORED ON CACHE BOOL "Use vendored third-party libraries" FORCE)
|
||||
add_subdirectory(${sdl_ttf_SOURCE_DIR} ${sdl_ttf_BINARY_DIR})
|
||||
endif()
|
||||
FetchContent_GetProperties(SDL_mixer)
|
||||
if(NOT sdl_mixer_POPULATED)
|
||||
FetchContent_Populate(SDL_mixer)
|
||||
set(SDL2MIXER_OPUS OFF CACHE BOOL "Enable Opus music" FORCE)
|
||||
set(SDL2MIXER_FLAC OFF CACHE BOOL "Enable FLAC music" FORCE)
|
||||
set(SDL2MIXER_MOD OFF CACHE BOOL "Support loading MOD music" FORCE)
|
||||
set(SDL2MIXER_MIDI OFF CACHE BOOL "Enable MIDI music" FORCE)
|
||||
set(SDL2MIXER_SAMPLES OFF CACHE BOOL "Build the SDL2_mixer sample program(s)" FORCE)
|
||||
set(SDL2MIXER_INSTALL OFF CACHE BOOL "Enable SDL2_mixer install target" FORCE)
|
||||
add_subdirectory(${sdl_mixer_SOURCE_DIR} ${sdl_mixer_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
# The main CMakeLists.txt of system3
|
||||
add_subdirectory(${PROJECT_ROOT_DIR}/src src)
|
||||
@@ -43,3 +59,4 @@ file(COPY_FILE ${sdl_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL)
|
||||
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL_ttf)
|
||||
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/external/freetype/docs/GPLv2.TXT ${ASSETS_DIR}/licenses/freetype)
|
||||
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/external/harfbuzz/COPYING ${ASSETS_DIR}/licenses/harfbuzz)
|
||||
file(COPY_FILE ${sdl_mixer_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL_mixer)
|
||||
|
||||
@@ -44,7 +44,6 @@ class GameActivity : SDLActivity() {
|
||||
}
|
||||
|
||||
private lateinit var gameRoot: File
|
||||
private lateinit var cdda: CddaPlayer
|
||||
private lateinit var prefs: SharedPreferences
|
||||
private val midi = MidiPlayer()
|
||||
private var useFM = true
|
||||
@@ -52,7 +51,6 @@ class GameActivity : SDLActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
gameRoot = File(intent.getStringExtra(EXTRA_GAME_ROOT)!!)
|
||||
cdda = CddaPlayer(File(gameRoot, Launcher.PLAYLIST_FILE))
|
||||
prefs = getSharedPreferences("system3", Context.MODE_PRIVATE)
|
||||
useFM = prefs.getBoolean(PREF_USE_FM, useFM)
|
||||
registerForContextMenu(mLayout)
|
||||
@@ -60,13 +58,11 @@ class GameActivity : SDLActivity() {
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
cdda.onActivityStop()
|
||||
midi.onActivityStop()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
cdda.onActivityResume()
|
||||
midi.onActivityResume()
|
||||
}
|
||||
|
||||
@@ -77,7 +73,8 @@ class GameActivity : SDLActivity() {
|
||||
override fun getArguments(): Array<String> {
|
||||
val args = arrayListOf(
|
||||
"-gamedir", intent.getStringExtra(EXTRA_GAME_ROOT)!!,
|
||||
"-savedir", intent.getStringExtra(EXTRA_SAVE_DIR)!! + "/@")
|
||||
"-savedir", intent.getStringExtra(EXTRA_SAVE_DIR)!! + "/@",
|
||||
"-playlist", Launcher.PLAYLIST_FILE)
|
||||
if (useFM)
|
||||
args.add("-fm")
|
||||
return args.toTypedArray()
|
||||
@@ -157,9 +154,6 @@ class GameActivity : SDLActivity() {
|
||||
private external fun selectSynthesizer(use_fm: Boolean)
|
||||
|
||||
// The functions below are called in the SDL thread by JNI.
|
||||
@Suppress("unused") fun cddaStart(track: Int, loop: Boolean) = cdda.start(track, loop)
|
||||
@Suppress("unused") fun cddaStop() = cdda.stop()
|
||||
@Suppress("unused") fun cddaCurrentPosition() = cdda.currentPosition()
|
||||
@Suppress("unused") fun midiStart(path: String, loop: Boolean) = midi.start(path, loop)
|
||||
@Suppress("unused") fun midiStop() = midi.stop()
|
||||
@Suppress("unused") fun midiCurrentPosition() = midi.currentPosition()
|
||||
@@ -183,73 +177,6 @@ class GameActivity : SDLActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private class CddaPlayer(private val playlistPath: File) {
|
||||
private val playlist =
|
||||
try {
|
||||
playlistPath.readLines()
|
||||
} catch (e: IOException) {
|
||||
Log.e("loadPlaylist", "Cannot load $playlistPath", e)
|
||||
emptyList()
|
||||
}
|
||||
private var currentTrack = 0
|
||||
private val player = MediaPlayer()
|
||||
private var playerPaused = false
|
||||
|
||||
init {
|
||||
player.setOnCompletionListener { currentTrack = 0 }
|
||||
}
|
||||
|
||||
fun start(track: Int, loop: Boolean) {
|
||||
val f = playlist.elementAtOrNull(track - 1)
|
||||
if (f.isNullOrEmpty()) {
|
||||
Log.w("cddaStart", "No playlist entry for track $track")
|
||||
return
|
||||
}
|
||||
Log.v("cddaStart", "$f Loop:$loop")
|
||||
try {
|
||||
player.apply {
|
||||
reset()
|
||||
setDataSource(File(playlistPath.parent, f).path)
|
||||
isLooping = loop
|
||||
prepare()
|
||||
start()
|
||||
}
|
||||
currentTrack = track
|
||||
} catch (e: IOException) {
|
||||
Log.e("cddaStart", "Cannot play $f", e)
|
||||
player.reset()
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
if (currentTrack > 0 && player.isPlaying) {
|
||||
player.stop()
|
||||
currentTrack = 0
|
||||
}
|
||||
}
|
||||
|
||||
fun currentPosition(): Int {
|
||||
if (currentTrack == 0)
|
||||
return 0
|
||||
val frames = player.currentPosition * 75 / 1000
|
||||
return currentTrack or (frames shl 8)
|
||||
}
|
||||
|
||||
fun onActivityStop() {
|
||||
if (currentTrack > 0 && player.isPlaying) {
|
||||
player.pause()
|
||||
playerPaused = true
|
||||
}
|
||||
}
|
||||
|
||||
fun onActivityResume() {
|
||||
if (playerPaused) {
|
||||
player.start()
|
||||
playerPaused = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MidiPlayer {
|
||||
private val player = MediaPlayer()
|
||||
private var playing = false
|
||||
|
||||
@@ -12,6 +12,7 @@ class LicensesMenuActivity : Activity() {
|
||||
Entry("system3-sdl2", "system3", "https://github.com/kichikuou/system3-sdl2"),
|
||||
Entry("SDL", "SDL", "https://www.libsdl.org/"),
|
||||
Entry("SDL_ttf", "SDL_ttf", "https://github.com/libsdl-org/SDL_ttf"),
|
||||
Entry("SDL_mixer", "SDL_mixer", "https://github.com/libsdl-org/SDL_mixer"),
|
||||
Entry("FreeType", "freetype", "https://freetype.org/"),
|
||||
Entry("HarfBuzz", "harfbuzz", "https://harfbuzz.github.io/"),
|
||||
Entry("ymfm", "ymfm", "https://github.com/aaronsgiles/ymfm"),
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ if (ANDROID)
|
||||
android/mako.cpp
|
||||
sys/mako_midi.cpp
|
||||
)
|
||||
target_link_libraries(system3 PRIVATE SDL2 SDL2_ttf ymfm)
|
||||
target_link_libraries(system3 PRIVATE SDL2 SDL2_ttf SDL2_mixer ymfm)
|
||||
|
||||
elseif (EMSCRIPTEN)
|
||||
add_executable(system3)
|
||||
|
||||
+129
-48
@@ -1,6 +1,8 @@
|
||||
#include <memory>
|
||||
#include <SDL.h>
|
||||
#include <SDL_mixer.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "jnihelper.h"
|
||||
#include "dri.h"
|
||||
@@ -13,12 +15,14 @@ namespace {
|
||||
const int SAMPLE_RATE = 44100;
|
||||
|
||||
MAKO *g_mako;
|
||||
Mix_Music *mix_music;
|
||||
Mix_Chunk *mix_chunk;
|
||||
SDL_mutex* fm_mutex;
|
||||
std::unique_ptr<MakoYmfm> fm;
|
||||
|
||||
void audio_callback(void*, Uint8* stream, int len) {
|
||||
void FMHook(void*, Uint8* stream, int len) {
|
||||
SDL_LockMutex(fm_mutex);
|
||||
fm->Process(reinterpret_cast<int16_t*>(stream), len/ 4);
|
||||
fm->Process(reinterpret_cast<int16_t*>(stream), len / 4);
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
}
|
||||
|
||||
@@ -31,32 +35,47 @@ MAKO::MAKO(NACT* parent, const Config& config) :
|
||||
nact(parent)
|
||||
{
|
||||
g_mako = this;
|
||||
|
||||
load_playlist(config.playlist.c_str());
|
||||
|
||||
strcpy(amus, "AMUS.DAT");
|
||||
strcpy(amse, "AMSE.DAT"); // unused
|
||||
for (int i = 1; i <= 99; i++)
|
||||
cd_track[i] = 0;
|
||||
|
||||
SDL_InitSubSystem(SDL_INIT_AUDIO);
|
||||
SDL_AudioSpec fmt;
|
||||
SDL_zero(fmt);
|
||||
fmt.freq = SAMPLE_RATE;
|
||||
fmt.format = AUDIO_S16;
|
||||
fmt.channels = 2;
|
||||
fmt.samples = 4096;
|
||||
fmt.callback = &audio_callback;
|
||||
if (SDL_OpenAudio(&fmt, NULL) < 0) {
|
||||
WARNING("SDL_OpenAudio: %s", SDL_GetError());
|
||||
use_fm = false;
|
||||
}
|
||||
fm_mutex = SDL_CreateMutex();
|
||||
const int mix_init_flags = MIX_INIT_MP3 | MIX_INIT_OGG;
|
||||
if (Mix_Init(mix_init_flags) != mix_init_flags)
|
||||
WARNING("Mix_Init(0x%x) failed", mix_init_flags);
|
||||
if (Mix_OpenAudio(SAMPLE_RATE, AUDIO_S16LSB, 2, 4096) < 0)
|
||||
WARNING("Mix_OpenAudio failed: %s", Mix_GetError());
|
||||
}
|
||||
|
||||
MAKO::~MAKO() {
|
||||
SDL_LockMutex(fm_mutex);
|
||||
SDL_CloseAudio();
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
SDL_DestroyMutex(fm_mutex);
|
||||
fm_mutex = nullptr;
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
MAKO::~MAKO()
|
||||
{
|
||||
stop_pcm();
|
||||
Mix_CloseAudio();
|
||||
Mix_Quit();
|
||||
}
|
||||
|
||||
bool MAKO::load_playlist(const char* path)
|
||||
{
|
||||
FILE* fp = fopen(path, "r");
|
||||
if (!fp) {
|
||||
WARNING("Cannot open %s", path);
|
||||
return false;
|
||||
}
|
||||
char buf[256];
|
||||
while (fgets(buf, sizeof(buf) - 1, fp)) {
|
||||
for (char *p = buf; *p; p++) {
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
else if (*p == '\r' || *p == '\n')
|
||||
*p = '\0';
|
||||
}
|
||||
playlist.push_back(buf[0] ? strdup(buf) : NULL);
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MAKO::play_music(int page)
|
||||
@@ -66,26 +85,42 @@ void MAKO::play_music(int page)
|
||||
|
||||
stop_music();
|
||||
|
||||
JNILocalFrame jni(16);
|
||||
if (!jni.env())
|
||||
return;
|
||||
|
||||
int track = page < 100 ? cd_track[page] : 0;
|
||||
if (track) {
|
||||
jmethodID mid = jni.GetMethodID("cddaStart", "(IZ)V");
|
||||
jni.env()->CallVoidMethod(jni.context(), mid, track + 1, next_loop ? 0 : 1);
|
||||
if (track < playlist.size() && playlist[track]) {
|
||||
// Mix_LoadMUS uses SDL_RWFromFile which requires absolute path on Android
|
||||
char path[PATH_MAX];
|
||||
if (!realpath(playlist[track], path))
|
||||
return;
|
||||
mix_music = Mix_LoadMUS(path);
|
||||
if (!mix_music) {
|
||||
WARNING("Mix_LoadMUS failed: %s: %s", playlist[track], Mix_GetError());
|
||||
return;
|
||||
}
|
||||
if (Mix_PlayMusic(mix_music, next_loop ? next_loop : -1) != 0) {
|
||||
WARNING("Mix_PlayMusic failed: %s", Mix_GetError());
|
||||
Mix_FreeMusic(mix_music);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (use_fm) {
|
||||
DRI dri;
|
||||
int size;
|
||||
uint8* data = dri.load(amus, page, &size);
|
||||
if (!data)
|
||||
return;
|
||||
if (!fm_mutex)
|
||||
fm_mutex = SDL_CreateMutex();
|
||||
|
||||
SDL_LockMutex(fm_mutex);
|
||||
fm = std::make_unique<MakoYmfm>(SAMPLE_RATE, data, true);
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
SDL_PauseAudio(0);
|
||||
Mix_HookMusic(&FMHook, this);
|
||||
} else {
|
||||
JNILocalFrame jni(16);
|
||||
if (!jni.env())
|
||||
return;
|
||||
|
||||
auto midi = std::make_unique<MAKOMidi>(nact, amus);
|
||||
if (!midi->load_mml(page)) {
|
||||
WARNING("load_mml(%d) failed", page);
|
||||
@@ -122,19 +157,19 @@ void MAKO::stop_music()
|
||||
if (!current_music)
|
||||
return;
|
||||
|
||||
if (mix_music) {
|
||||
Mix_FreeMusic(mix_music);
|
||||
mix_music = NULL;
|
||||
}
|
||||
|
||||
JNILocalFrame jni(16);
|
||||
if (jni.env()) {
|
||||
if (current_music < 100 && cd_track[current_music]) {
|
||||
jmethodID cdda = jni.GetMethodID("cddaStop", "()V");
|
||||
jni.env()->CallVoidMethod(jni.context(), cdda);
|
||||
} else {
|
||||
jmethodID mid = jni.GetMethodID("midiStop", "()V");
|
||||
jni.env()->CallVoidMethod(jni.context(), mid);
|
||||
}
|
||||
jmethodID mid = jni.GetMethodID("midiStop", "()V");
|
||||
jni.env()->CallVoidMethod(jni.context(), mid);
|
||||
}
|
||||
|
||||
if (fm) {
|
||||
SDL_PauseAudio(1);
|
||||
Mix_HookMusic(NULL, NULL);
|
||||
SDL_LockMutex(fm_mutex);
|
||||
fm = nullptr;
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
@@ -146,6 +181,8 @@ bool MAKO::check_music()
|
||||
{
|
||||
if (!current_music)
|
||||
return false;
|
||||
if (mix_music)
|
||||
return Mix_PlayingMusic();
|
||||
if (fm) {
|
||||
int mark, loop;
|
||||
SDL_LockMutex(fm_mutex);
|
||||
@@ -155,39 +192,83 @@ bool MAKO::check_music()
|
||||
}
|
||||
|
||||
JNILocalFrame jni(16);
|
||||
if (!jni.env())
|
||||
return false;
|
||||
if (current_music < 100 && cd_track[current_music]) {
|
||||
jmethodID cdda = jni.GetMethodID("cddaCurrentPosition", "()I");
|
||||
return jni.env()->CallIntMethod(jni.context(), cdda) != 0;
|
||||
} else {
|
||||
if (jni.env()) {
|
||||
jmethodID mid = jni.GetMethodID("midiCurrentPosition", "()I");
|
||||
return jni.env()->CallIntMethod(jni.context(), mid) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MAKO::get_mark(int* mark, int* loop)
|
||||
{
|
||||
SDL_LockMutex(fm_mutex);
|
||||
if (fm) {
|
||||
SDL_LockMutex(fm_mutex);
|
||||
fm->get_mark(mark, loop);
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
} else {
|
||||
*mark = 0;
|
||||
*loop = 0;
|
||||
}
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
}
|
||||
|
||||
void MAKO::play_pcm(int page, bool loop)
|
||||
{
|
||||
WARNING("not implemented");
|
||||
static char header[44] = {
|
||||
'R' , 'I' , 'F' , 'F' , 0x00, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' ,
|
||||
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00,
|
||||
0x01, 0x00, 0x08, 0x00, 'd' , 'a' , 't' , 'a' , 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
stop_pcm();
|
||||
|
||||
uint8* buffer = NULL;
|
||||
int size;
|
||||
DRI* dri = new DRI();
|
||||
|
||||
if((buffer = dri->load("AWAV.DAT", page, &size)) != NULL) {
|
||||
// WAV形式 (Only You)
|
||||
mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(buffer, size), 1 /* freesrc */);
|
||||
free(buffer);
|
||||
Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0);
|
||||
} else if((buffer = dri->load("AMSE.DAT", page, &size)) != NULL) {
|
||||
// AMSE形式 (乙女戦記)
|
||||
int total = (size - 12) * 2 + 0x24;
|
||||
int samples = (size - 12) * 2;
|
||||
|
||||
uint8* wav = (uint8*)malloc(total + 8);
|
||||
memcpy(wav, header, 44);
|
||||
wav[ 4] = (total >> 0) & 0xff;
|
||||
wav[ 5] = (total >> 8) & 0xff;
|
||||
wav[ 6] = (total >> 16) & 0xff;
|
||||
wav[ 7] = (total >> 24) & 0xff;
|
||||
wav[40] = (samples >> 0) & 0xff;
|
||||
wav[41] = (samples >> 8) & 0xff;
|
||||
wav[42] = (samples >> 16) & 0xff;
|
||||
wav[43] = (samples >> 24) & 0xff;
|
||||
for(int i = 12, p = 44; i < size; i++) {
|
||||
wav[p++] = buffer[i] & 0xf0;
|
||||
wav[p++] = (buffer[i] & 0x0f) << 4;
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(wav, total + 8), 1 /* freesrc */);
|
||||
free(wav);
|
||||
Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MAKO::stop_pcm() {}
|
||||
void MAKO::stop_pcm()
|
||||
{
|
||||
Mix_HaltChannel(-1);
|
||||
if (mix_chunk) {
|
||||
Mix_FreeChunk(mix_chunk);
|
||||
mix_chunk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool MAKO::check_pcm()
|
||||
{
|
||||
return false;
|
||||
return Mix_Playing(-1) != 0;
|
||||
}
|
||||
|
||||
void MAKO::select_synthesizer(bool use_fm_) {
|
||||
|
||||
+15
-13
@@ -29,7 +29,7 @@ Mix_Chunk *mix_chunk;
|
||||
SDL_mutex* fm_mutex;
|
||||
std::unique_ptr<MakoYmfm> fm;
|
||||
|
||||
void FMHook(void *udata, Uint8 *stream, int len) {
|
||||
void FMHook(void*, Uint8* stream, int len) {
|
||||
SDL_LockMutex(fm_mutex);
|
||||
fm->Process(reinterpret_cast<int16_t*>(stream), len / 4);
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
@@ -48,12 +48,11 @@ MAKO::MAKO(NACT* parent, const Config& config) :
|
||||
if (!config.playlist.empty() && load_playlist(config.playlist.c_str()))
|
||||
mix_init_flags |= MIX_INIT_MP3 | MIX_INIT_OGG;
|
||||
|
||||
strcpy_s(amus, 16, "AMUS.DAT");
|
||||
strcpy_s(amse, 16, "AMSE.DAT"); // 実際には使わない
|
||||
|
||||
for(int i = 1; i <= 99; i++) {
|
||||
strcpy(amus, "AMUS.DAT");
|
||||
strcpy(amse, "AMSE.DAT"); // unused
|
||||
for (int i = 1; i <= 99; i++)
|
||||
cd_track[i] = 0;
|
||||
}
|
||||
|
||||
if (Mix_Init(mix_init_flags) != mix_init_flags)
|
||||
WARNING("Mix_Init(0x%x) failed", mix_init_flags);
|
||||
if (Mix_OpenAudio(SAMPLE_RATE, AUDIO_S16LSB, 2, 4096) < 0)
|
||||
@@ -90,13 +89,13 @@ bool MAKO::load_playlist(const char* path)
|
||||
|
||||
void MAKO::play_music(int page)
|
||||
{
|
||||
if(current_music == page)
|
||||
if (current_music == page)
|
||||
return;
|
||||
|
||||
stop_music();
|
||||
|
||||
int track = page < 100 ? cd_track[page] : 0;
|
||||
if(track) {
|
||||
if (track) {
|
||||
if (track < playlist.size() && playlist[track]) {
|
||||
mix_music = Mix_LoadMUS(playlist[track]);
|
||||
if (!mix_music) {
|
||||
@@ -120,8 +119,8 @@ void MAKO::play_music(int page)
|
||||
|
||||
SDL_LockMutex(fm_mutex);
|
||||
fm = std::make_unique<MakoYmfm>(SAMPLE_RATE, data, true);
|
||||
Mix_HookMusic(&FMHook, this);
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
Mix_HookMusic(&FMHook, this);
|
||||
} else {
|
||||
auto midi = std::make_unique<MAKOMidi>(nact, amus);
|
||||
if (midi->load_mml(page)) {
|
||||
@@ -140,7 +139,9 @@ void MAKO::play_music(int page)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_music = page;
|
||||
next_loop = 0;
|
||||
}
|
||||
|
||||
void MAKO::stop_music()
|
||||
@@ -161,6 +162,8 @@ void MAKO::stop_music()
|
||||
|
||||
bool MAKO::check_music()
|
||||
{
|
||||
if (mix_music)
|
||||
return Mix_PlayingMusic();
|
||||
if (fm) {
|
||||
int mark, loop;
|
||||
SDL_LockMutex(fm_mutex);
|
||||
@@ -168,19 +171,19 @@ bool MAKO::check_music()
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
return !loop;
|
||||
}
|
||||
return Mix_PlayingMusic();
|
||||
return false;
|
||||
}
|
||||
|
||||
void MAKO::get_mark(int* mark, int* loop)
|
||||
{
|
||||
SDL_LockMutex(fm_mutex);
|
||||
if (fm) {
|
||||
SDL_LockMutex(fm_mutex);
|
||||
fm->get_mark(mark, loop);
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
} else {
|
||||
*mark = 0;
|
||||
*loop = 0;
|
||||
}
|
||||
SDL_UnlockMutex(fm_mutex);
|
||||
}
|
||||
|
||||
void MAKO::play_pcm(int page, bool loop)
|
||||
@@ -240,7 +243,6 @@ void MAKO::stop_pcm()
|
||||
|
||||
bool MAKO::check_pcm()
|
||||
{
|
||||
// 再生中でtrue
|
||||
return Mix_Playing(-1) != 0;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ private:
|
||||
NACT* nact;
|
||||
int cd_track[100]; // Z
|
||||
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
|
||||
#if !defined(__EMSCRIPTEN__)
|
||||
bool load_playlist(const char* path);
|
||||
|
||||
std::vector<const char*> playlist;
|
||||
|
||||
Reference in New Issue
Block a user