Refactor mididevice_t interface

This commit is contained in:
kichikuou
2025-02-02 12:49:39 +09:00
parent d14b42c146
commit 2857c13e15
9 changed files with 176 additions and 267 deletions
+41 -69
View File
@@ -23,58 +23,25 @@
#include "portab.h"
#include "midi.h"
static int midi_initialize(int subdev);
static int midi_exit(void);
static int midi_reset(void);
static int midi_start(int no, int loop, char *data, int datalen);
static int midi_stop();
static int midi_pause(void);
static int midi_unpause(void);
static int midi_get_playing_info(midiplaystate *st);
static int midi_getflag(int mode, int index);
static int midi_setflag(int mode, int index, int val);
static int midi_setvol(int vol);
static int midi_getvol();
static int midi_fadestart(int time, int volume, int stop);
static bool midi_fading();
static void midi_stop(void);
#define midi midi_android
mididevice_t midi = {
midi_initialize,
midi_exit,
midi_reset,
midi_start,
midi_stop,
midi_pause,
midi_unpause,
midi_get_playing_info,
midi_getflag,
midi_setflag,
midi_setvol,
midi_getvol,
midi_fadestart,
midi_fading
};
static int midi_initialize(int subdev) {
return OK;
static bool midi_initialize(int subdev) {
return true;
}
static int midi_exit(void) {
static void midi_exit(void) {
midi_stop();
return OK;
}
static int midi_reset(void) {
static void midi_reset(void) {
midi_stop();
return OK;
}
static int midi_start(int no, int loop, char *data, int datalen) {
static bool midi_start(int no, int loop, const uint8_t *data, int datalen) {
JNIEnv *env = SDL_AndroidGetJNIEnv();
if ((*env)->PushLocalFrame(env, 16) < 0) {
WARNING("Failed to allocate JVM local references");
return NG;
return false;
}
char path[PATH_MAX];
@@ -83,7 +50,7 @@ static int midi_start(int no, int loop, char *data, int datalen) {
if (!fp) {
WARNING("Failed to create temporary file");
(*env)->PopLocalFrame(env, NULL);
return NG;
return false;
}
fwrite(data, datalen, 1, fp);
fclose(fp);
@@ -92,7 +59,7 @@ static int midi_start(int no, int loop, char *data, int datalen) {
if (!path_str) {
WARNING("Failed to allocate a string");
(*env)->PopLocalFrame(env, NULL);
return NG;
return false;
}
jobject context = SDL_AndroidGetActivity();
@@ -101,40 +68,38 @@ static int midi_start(int no, int loop, char *data, int datalen) {
(*env)->CallVoidMethod(env, context, mid, path_str, loop == 0);
(*env)->PopLocalFrame(env, NULL);
return OK;
return true;
}
static int midi_stop() {
static void midi_stop(void) {
JNIEnv *env = SDL_AndroidGetJNIEnv();
if ((*env)->PushLocalFrame(env, 16) < 0) {
WARNING("Failed to allocate JVM local references");
return NG;
return;
}
jobject context = SDL_AndroidGetActivity();
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
"midiStop", "()V");
(*env)->CallVoidMethod(env, context, mid);
(*env)->PopLocalFrame(env, NULL);
return OK;
}
static int midi_pause(void) {
return NG; // FIXME
static void midi_pause(void) {
// FIXME
}
static int midi_unpause(void) {
return NG; // FIXME
static void midi_unpause(void) {
// FIXME
}
static int midi_get_playing_info(midiplaystate *st) {
static bool midi_get_playing_info(midiplaystate *st) {
st->in_play = false;
st->loc_ms = 0;
JNIEnv *env = SDL_AndroidGetJNIEnv();
if ((*env)->PushLocalFrame(env, 16) < 0) {
WARNING("Failed to allocate JVM local references");
return NG;
return false;
}
jobject context = SDL_AndroidGetActivity();
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
@@ -146,29 +111,36 @@ static int midi_get_playing_info(midiplaystate *st) {
st->in_play = true;
st->loc_ms = pos;
}
return OK;
return true;
}
static int midi_getflag(int mode, int index) {
return 0;
}
static int midi_setflag(int mode, int index, int val) {
return NG;
static bool midi_setflag(int mode, int index, int val) {
return false;
}
static int midi_setvol(int vol) {
return NG; // FIXME
}
static int midi_getvol() {
return 100; // FIXME
}
static int midi_fadestart(int time, int volume, int stop) {
return NG; // FIXME
}
static bool midi_fading() {
static bool midi_fadestart(int time, int volume, int stop) {
return false; // FIXME
}
static bool midi_fading(void) {
return false; // FIXME
}
mididevice_t midi_android = {
.init = midi_initialize,
.exit = midi_exit,
.reset = midi_reset,
.start = midi_start,
.stop = midi_stop,
.pause = midi_pause,
.unpause = midi_unpause,
.getpos = midi_get_playing_info,
.getflag = midi_getflag,
.setflag = midi_setflag,
.fadestart = midi_fadestart,
.fading = midi_fading,
};
+2 -2
View File
@@ -47,8 +47,8 @@ extern mididevice_t midi_sdlmixer;
extern mididevice_t midi_portmidi;
#endif
int midi_init(mididevice_t *midi) {
int ret = NG;
bool midi_init(mididevice_t *midi) {
bool ret = false;
switch(default_mode) {
case 'e':
+30 -45
View File
@@ -24,90 +24,75 @@
#include "portab.h"
#include "midi.h"
static int midi_initialize(int subdev) {
return OK;
static bool midi_initialize(int subdev) {
return true;
}
EM_JS(int, midi_stop, (void), {
EM_JS(void, midi_stop, (void), {
xsystem35.midiPlayer.stop();
return xsystem35.Status.OK;
});
static int midi_exit(void) {
static void midi_exit(void) {
midi_stop();
return OK;
}
static int midi_reset(void) {
static void midi_reset(void) {
midi_stop();
return OK;
}
static int midi_start(int no, int loop, char *data, int datalen) {
static bool midi_start(int no, int loop, const uint8_t *data, int datalen) {
EM_ASM_ARGS({ xsystem35.midiPlayer.play($0, $1, $2); }, loop, data, datalen);
return OK;
return true;
}
EM_JS(int, midi_pause, (void), {
EM_JS(void, midi_pause, (void), {
xsystem35.midiPlayer.pause();
return xsystem35.Status.OK;
});
EM_JS(int, midi_unpause, (void), {
EM_JS(void, midi_unpause, (void), {
xsystem35.midiPlayer.resume();
return xsystem35.Status.OK;
});
static int midi_get_playing_info(midiplaystate *st) {
static bool midi_get_playing_info(midiplaystate *st) {
int pos = EM_ASM_INT_V( return xsystem35.midiPlayer.getPosition(); );
if (pos >= 0) {
st->in_play = true;
st->loc_ms = pos;
return OK;
return true;
}
st->in_play = false;
st->loc_ms = 0;
return OK;
return true;
}
static int midi_getflag(int mode, int index) {
return 0;
}
static int midi_setflag(int mode, int index, int val) {
return NG;
static bool midi_setflag(int mode, int index, int val) {
return false;
}
EM_JS(int, midi_setvol, (int vol), {
xsystem35.midiPlayer.setVolume(vol);
return xsystem35.Status.OK;
EM_JS(bool, midi_fadestart, (int time, int volume, int stop), {
xsystem35.midiPlayer.fadeStart(time, volume, stop);
return 1;
});
EM_JS(int, midi_getvol,(), {
return xsystem35.midiPlayer.getVolume();
});
EM_JS(int, midi_fadestart, (int time, int volume, int stop), {
return xsystem35.midiPlayer.fadeStart(time, volume, stop);
});
EM_JS(bool, midi_fading, (), {
EM_JS(bool, midi_fading, (void), {
return xsystem35.midiPlayer.isFading();
});
mididevice_t midi_emscripten = {
midi_initialize,
midi_exit,
midi_reset,
midi_start,
midi_stop,
midi_pause,
midi_unpause,
midi_get_playing_info,
midi_getflag,
midi_setflag,
midi_setvol,
midi_getvol,
midi_fadestart,
midi_fading
.init = midi_initialize,
.exit = midi_exit,
.reset = midi_reset,
.start = midi_start,
.stop = midi_stop,
.pause = midi_pause,
.unpause = midi_unpause,
.getpos = midi_get_playing_info,
.getflag = midi_getflag,
.setflag = midi_setflag,
.fadestart = midi_fadestart,
.fading = midi_fading,
};
+18 -20
View File
@@ -24,7 +24,8 @@
#ifndef __MIDI_H__
#define __MIDI_H__
#include "portab.h"
#include <stdbool.h>
#include <stdint.h>
typedef struct {
bool in_play; /* now playing ? */
@@ -32,26 +33,23 @@ typedef struct {
int play_no; /* current playing no */
} midiplaystate;
typedef struct mididevice mididevice_t;
struct mididevice {
int (* init)(int);
int (* exit)(void);
int (* reset)(void);
typedef struct {
bool (*init)(int);
void (*exit)(void);
void (*reset)(void);
// Play through the music loop times. If loop == 0, loops forever.
int (* start)(int no, int loop, char *data, int datalen);
int (* stop)(void);
int (* pause)(void);
int (* unpause)(void);
int (* getpos)(midiplaystate *);
int (* getflag)(int mode, int index);
int (* setflag)(int mode, int index, int val);
int (* setvol)(int);
int (* getvol)(int);
int (* fadestart)(int time, int volume, int stop);
bool (* fading)();
};
bool (*start)(int no, int loop, const uint8_t *data, int datalen);
void (*stop)(void);
void (*pause)(void);
void (*unpause)(void);
bool (*getpos)(midiplaystate *);
int (*getflag)(int mode, int index);
bool (*setflag)(int mode, int index, int val);
bool (*fadestart)(int time, int volume, int stop);
bool (*fading)(void);
} mididevice_t;
extern int midi_init(mididevice_t *);
extern void midi_set_output_device(int mode);
bool midi_init(mididevice_t *);
void midi_set_output_device(int mode);
#endif /* __MIDI_H__ */
+34 -50
View File
@@ -42,33 +42,7 @@ static struct {
char midi_flag[128];
} flags;
static int midi_initialize(int subdev);
static int midi_exit(void);
static int midi_reset(void);
static int midi_start(int no, int loop, char *data, int datalen);
static int midi_stop(void);
static int midi_pause(void);
static int midi_unpause(void);
static int midi_getpos(midiplaystate *st);
static int midi_getflag(int mode, int index);
static int midi_setflag(int mode, int index, int val);
mididevice_t midi_portmidi = {
midi_initialize,
midi_exit,
midi_reset,
midi_start,
midi_stop,
midi_pause,
midi_unpause,
midi_getpos,
midi_getflag,
midi_setflag,
NULL,
NULL,
NULL,
NULL
};
static void midi_stop(void);
enum midi_command {
CMD_PLAY,
@@ -233,7 +207,7 @@ static void midi_playloop(PortMidiStream *stream, struct midiinfo *midi) {
}
}
static int midi_thread(void*) {
static int midi_thread(void* unused) {
PortMidiStream *stream;
PmError err = Pm_OpenOutput(&stream, device_id, NULL, 0, midi_time_proc, NULL, MIDI_LATENCY);
if (err != pmNoError) {
@@ -272,11 +246,11 @@ static int midi_thread(void*) {
}
}
static int midi_initialize(int subdev) {
static bool midi_initialize(int subdev) {
PmError err = Pm_Initialize();
if (err != pmNoError) {
WARNING("%s", Pm_GetErrorText(err));
return NG;
return false;
}
int ndevices = Pm_CountDevices();
@@ -287,14 +261,14 @@ static int midi_initialize(int subdev) {
}
if (subdev < 0 || subdev >= ndevices) {
WARNING("invalid midi device number");
return NG;
return false;
}
device_id = subdev;
return OK;
return true;
}
static int midi_exit(void) {
static void midi_exit(void) {
if (queue) {
ENQUEUE(CMD_STOP);
ENQUEUE(CMD_QUIT);
@@ -304,16 +278,14 @@ static int midi_exit(void) {
queue = NULL;
}
Pm_Terminate();
return OK;
}
static int midi_reset(void) {
static void midi_reset(void) {
midi_stop();
return OK;
}
/* no = 0~ */
static int midi_start(int no, int loop, char *data, int datalen) {
static bool midi_start(int no, int loop, const uint8_t *data, int datalen) {
static int seq = 0;
if (queue) {
@@ -326,47 +298,44 @@ static int midi_start(int no, int loop, char *data, int datalen) {
struct midiinfo *midi = mf_read_midifile(data, datalen);
if (!midi) {
WARNING("error reading midi file");
return NG;
return false;
}
SDL_AtomicSet(&atomic_seq, ++seq);
ENQUEUE(CMD_PLAY, seq, midi);
start_time = SDL_GetTicks();
return OK;
return true;
}
static int midi_stop(void) {
static void midi_stop(void) {
if (queue) {
SDL_AtomicSet(&atomic_seq, 0);
ENQUEUE(CMD_STOP);
}
return OK;
}
static int midi_pause(void) {
static void midi_pause(void) {
if (queue)
ENQUEUE(CMD_PAUSE);
return OK;
}
static int midi_unpause(void) {
static void midi_unpause(void) {
if (queue)
ENQUEUE(CMD_UNPAUSE);
return OK;
}
static int midi_getpos(midiplaystate *st) {
static bool midi_get_playing_info(midiplaystate *st) {
if (SDL_AtomicGet(&atomic_seq) == 0) {
st->in_play = false;
st->loc_ms = 0;
return OK;
return true;
}
st->in_play = true;
st->loc_ms = SDL_GetTicks() - start_time;
return OK;
return true;
}
static int midi_getflag(int mode, int index) {
@@ -379,7 +348,7 @@ static int midi_getflag(int mode, int index) {
}
}
static int midi_setflag(int mode, int index, int val) {
static bool midi_setflag(int mode, int index, int val) {
if (mode == 0) {
/* flag */
flags.midi_flag[index] = val;
@@ -387,5 +356,20 @@ static int midi_setflag(int mode, int index, int val) {
/* variable */
flags.midi_variable[index] = val;
}
return OK;
return true;
}
mididevice_t midi_portmidi = {
.init = midi_initialize,
.exit = midi_exit,
.reset = midi_reset,
.start = midi_start,
.stop = midi_stop,
.pause = midi_pause,
.unpause = midi_unpause,
.getpos = midi_get_playing_info,
.getflag = midi_getflag,
.setflag = midi_setflag,
.fadestart = NULL,
.fading = NULL,
};
+40 -70
View File
@@ -31,146 +31,116 @@
#define MIX_INIT_MID MIX_INIT_FLUIDSYNTH
#endif
static int midi_initialize(int subdev);
static int midi_exit(void);
static int midi_reset(void);
static int midi_start(int no, int loop, char *data, int datalen);
static int midi_stop();
static int midi_pause(void);
static int midi_unpause(void);
static int midi_get_playing_info(midiplaystate *st);
static int midi_getflag(int mode, int index);
static int midi_setflag(int mode, int index, int val);
static int midi_setvol(int vol);
static int midi_getvol();
static int midi_fadestart(int time, int volume, int stop);
static bool midi_fading();
#define midi midi_sdlmixer
mididevice_t midi = {
midi_initialize,
midi_exit,
midi_reset,
midi_start,
midi_stop,
midi_pause,
midi_unpause,
midi_get_playing_info,
midi_getflag,
midi_setflag,
midi_setvol,
midi_getvol,
midi_fadestart,
midi_fading
};
static void midi_stop(void);
static Mix_Music *mix_music;
static int start_time;
static uint32_t fade_tick;
static int midi_initialize(int subdev) {
static bool midi_initialize(int subdev) {
if (Mix_Init(MIX_INIT_MID) != MIX_INIT_MID)
return NG;
return OK;
return false;
return true;
}
static int midi_exit(void) {
static void midi_exit(void) {
Mix_Quit();
return OK;
}
static int midi_reset(void) {
static void midi_reset(void) {
midi_stop();
return OK;
}
static int midi_start(int no, int loop, char *data, int datalen) {
static bool midi_start(int no, int loop, const uint8_t *data, int datalen) {
midi_stop();
SDL_RWops *rwops = SDL_RWFromConstMem(data, datalen);
mix_music = Mix_LoadMUSType_RW(rwops, MUS_MID, SDL_TRUE /* freesrc */);
if (!mix_music) {
WARNING("Cannot load MIDI: %s", SDL_GetError());
return NG;
return false;
}
if (Mix_PlayMusic(mix_music, loop ? loop : -1) != 0) {
WARNING("Cannot play MIDI: %s", SDL_GetError());
Mix_FreeMusic(mix_music);
mix_music = NULL;
return NG;
return false;
}
start_time = SDL_GetTicks();
return OK;
return true;
}
static int midi_stop() {
static void midi_stop() {
if (!mix_music)
return OK;
return;
Mix_FreeMusic(mix_music);
mix_music = NULL;
return OK;
}
static int midi_pause(void) {
static void midi_pause(void) {
// FIXME: adjust start_time
Mix_PauseMusic();
return OK;
}
static int midi_unpause(void) {
static void midi_unpause(void) {
// FIXME: adjust start_time
Mix_ResumeMusic();
return OK;
}
static int midi_get_playing_info(midiplaystate *st) {
static bool midi_get_playing_info(midiplaystate *st) {
if (!mix_music || !Mix_PlayingMusic()) {
st->in_play = false;
st->loc_ms = 0;
return OK;
return true;
}
st->in_play = true;
st->loc_ms = SDL_GetTicks() - start_time;
return OK;
return true;
}
static int midi_getflag(int mode, int index) {
return 0;
}
static int midi_setflag(int mode, int index, int val) {
return NG;
static bool midi_setflag(int mode, int index, int val) {
return false;
}
static int midi_setvol(int vol) {
Mix_VolumeMusic(vol * MIX_MAX_VOLUME / 100);
return OK;
}
static int midi_getvol() {
return Mix_VolumeMusic(-1) * 100 / MIX_MAX_VOLUME;
}
static int midi_fadestart(int time, int volume, int stop) {
static bool midi_fadestart(int time, int volume, int stop) {
if (time == 0) {
midi_setvol(volume);
Mix_VolumeMusic(volume * MIX_MAX_VOLUME / 100);
if (stop)
midi_stop();
return OK;
return true;
}
if (volume == 0) {
Mix_FadeOutMusic(time); // FIXME: this always stops the music
fade_tick = SDL_GetTicks() + time;
return OK;
return true;
}
WARNING("(time=%d, volume=%d, stop=%d) unsupported", time, volume, stop);
return NG;
return false;
}
static bool midi_fading() {
static bool midi_fading(void) {
return SDL_GetTicks() < fade_tick;
}
mididevice_t midi_sdlmixer = {
.init = midi_initialize,
.exit = midi_exit,
.reset = midi_reset,
.start = midi_start,
.stop = midi_stop,
.pause = midi_pause,
.unpause = midi_unpause,
.getpos = midi_get_playing_info,
.getflag = midi_getflag,
.setflag = midi_setflag,
.fadestart = midi_fadestart,
.fading = midi_fading,
};
+3 -3
View File
@@ -47,8 +47,8 @@
#define META_SET_TEMPO 0x51
struct stream {
uint8_t *p;
uint8_t *end;
const uint8_t *p;
const uint8_t *end;
};
static inline uint8_t read8(struct stream *input) {
@@ -269,7 +269,7 @@ static bool read_header(struct midiinfo *midi, struct stream *input) {
return true;
}
struct midiinfo *mf_read_midifile(uint8_t *data, size_t len) {
struct midiinfo *mf_read_midifile(const uint8_t *data, size_t len) {
struct stream input = { .p = data, .end = data + len };
struct midiinfo *midi = calloc(1, sizeof(struct midiinfo));
+1 -1
View File
@@ -60,7 +60,7 @@ struct midiinfo {
int sys35_label[128]; /* system35 jump info */
};
extern struct midiinfo *mf_read_midifile(uint8_t *stream, size_t len);
extern struct midiinfo *mf_read_midifile(const uint8_t *stream, size_t len);
extern void mf_remove_midifile(struct midiinfo *m);
#endif /* __MIDIFILE_H__ */
+7 -7
View File
@@ -30,9 +30,7 @@
#include "ald_manager.h"
int musmidi_init(void) {
int st = midi_init(&prv.mididev);
if (st == -1) {
if (!midi_init(&prv.mididev)) {
prv.midi_valid = false;
return NG;
} else {
@@ -65,7 +63,10 @@ int musmidi_start(int no, int loop) {
if (dfile == NULL)
return NG;
prv.mididev.start(no, loop, dfile->data, dfile->size);
if (!prv.mididev.start(no, loop, dfile->data, dfile->size)) {
ald_freedata(dfile);
return NG;
}
if (prv.midi_dfile)
ald_freedata(prv.midi_dfile);
@@ -117,8 +118,7 @@ midiplaystate musmidi_getpos(void) {
int musmidi_setflag(int mode, int index, int val) {
if (!prv.midi_valid) return NG;
prv.mididev.setflag(mode, index, val);
return OK;
return prv.mididev.setflag(mode, index, val) ? OK : NG;
}
int musmidi_getflag(int mode, int index) {
@@ -132,7 +132,7 @@ int musmidi_fadestart(int time, int volume, int stop) {
if (!prv.mididev.fadestart)
return NG;
return prv.mididev.fadestart(time, volume, stop);
return prv.mididev.fadestart(time, volume, stop) ? OK : NG;
}
bool musmidi_fading(void) {