From 4ede5b1b4cc302494ed78211a3b11c0fa3606ffd Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 16 Feb 2020 10:28:29 +0900 Subject: [PATCH] Android: Play MIDI via temporary file MediaPlayer in old versions of Android does not accept data: URL. --- .../github/kichikuou/system3/GameActivity.kt | 8 +++---- src/android/mako.cpp | 24 ++++++++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/android/app/src/main/java/io/github/kichikuou/system3/GameActivity.kt b/android/app/src/main/java/io/github/kichikuou/system3/GameActivity.kt index 27cdd1d..ba0d742 100644 --- a/android/app/src/main/java/io/github/kichikuou/system3/GameActivity.kt +++ b/android/app/src/main/java/io/github/kichikuou/system3/GameActivity.kt @@ -19,7 +19,6 @@ package io.github.kichikuou.system3 import android.media.MediaPlayer import android.os.Bundle -import android.util.Base64 import android.util.Log import org.libsdl.app.SDLActivity import java.io.File @@ -79,7 +78,7 @@ class GameActivity : SDLActivity() { @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(buf: ByteArray, loop: Boolean) = midi.start(buf, loop) + @Suppress("unused") fun midiStart(path: String, loop: Boolean) = midi.start(path, loop) @Suppress("unused") fun midiStop() = midi.stop() @Suppress("unused") fun midiCurrentPosition() = midi.currentPosition() } @@ -152,12 +151,11 @@ private class MidiPlayer { private var playing = false private var playerPaused = false - fun start(buf: ByteArray, loop: Boolean) { - val url = "data:audio/midi;base64," + Base64.encodeToString(buf, Base64.DEFAULT) + fun start(path: String, loop: Boolean) { try { player.apply { reset() - setDataSource(url) + setDataSource(path) isLooping = loop prepare() start() diff --git a/src/android/mako.cpp b/src/android/mako.cpp index a995e58..ab90e9c 100644 --- a/src/android/mako.cpp +++ b/src/android/mako.cpp @@ -62,16 +62,24 @@ void MAKO::play_music(int page) } midi->load_mda(page); std::vector smf = midi->generate_smf(next_loop); - jbyteArray array = jni.env()->NewByteArray(smf.size()); - if (!array) { - WARNING("Failed to allocate an array"); + + char path[PATH_MAX]; + snprintf(path, PATH_MAX, "%s/tmp.mid", SDL_AndroidGetInternalStoragePath()); + FILE* fp = fopen(path, "w"); + if (!fp) { + WARNING("Failed to create temporary file"); return; } - jbyte *buf = jni.env()->GetByteArrayElements(array, NULL); - memcpy(buf, smf.data(), smf.size()); - jni.env()->ReleaseByteArrayElements(array, buf, 0); - jmethodID mid = jni.GetMethodID("midiStart", "([BZ)V"); - jni.env()->CallVoidMethod(jni.context(), mid, array, next_loop ? 0 : 1); + fwrite(smf.data(), smf.size(), 1, fp); + fclose(fp); + + jstring path_str = jni.env()->NewStringUTF(path); + if (!path_str) { + WARNING("Failed to allocate a string"); + return; + } + jmethodID mid = jni.GetMethodID("midiStart", "(Ljava/lang/String;Z)V"); + jni.env()->CallVoidMethod(jni.context(), mid, path_str, next_loop ? 0 : 1); } current_music = page;