From aa759ff708196e5ea0f39bedabfbecb8f164294e Mon Sep 17 00:00:00 2001 From: zlago Date: Mon, 2 Sep 2024 10:58:10 +0200 Subject: cleanup --- GNUmakefile | 8 +- src/SDL2.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++ src/include.h | 4 + src/modules/fluidsynth.c | 2 +- src/modules/openmpt.c | 2 +- src/sdl.c | 214 --------------------------------------------- 6 files changed, 231 insertions(+), 220 deletions(-) create mode 100644 src/SDL2.c delete mode 100644 src/sdl.c diff --git a/GNUmakefile b/GNUmakefile index 58990fd..a9e2537 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,7 +3,7 @@ GLAD ?= glad MKDIR ?= mkdir -p -libs ::= SDL2 openmpt fluidsynth +libs ::= openmpt fluidsynth cflags ::= -I . -g -Og ${CFLAGS} ldflags ::= -Wl,--rpath,'$$ORIGIN' $(addprefix -l,${libs}) ${LDFLAGS} @@ -13,9 +13,9 @@ deps ::= $(addprefix out/,$(notdir ${srcs:.c=.d})) .PHONY: all run clean -all: out/mu-sdl +all: out/mu-SDL2 -run: out/mu-sdl +run: out/mu-SDL2 ./$< clean: @@ -37,6 +37,6 @@ out/%.d: src/%.c | out/ ${CC} ${cflags} ${CPPFLAGS} -MM -MG -MF $@ -MT "${@:.d=.o} $@" $< out/mu-%: out/%.o ${objs} | out/ - ${CC} -o $@ $^ ${cflags} ${ldflags} + ${CC} -o $@ $^ ${cflags} ${ldflags} -l${<:out/%.o=%} include ${deps} diff --git a/src/SDL2.c b/src/SDL2.c new file mode 100644 index 0000000..4e51269 --- /dev/null +++ b/src/SDL2.c @@ -0,0 +1,221 @@ +#define SDL_MAIN_HANDLED +#include + +#include +#include +#include + +#include "include.h" + +int module_openmpt(struct blob *file, struct userdata *userdata); +int module_fluidsynth(struct blob *file, struct userdata *userdata); + +#define eprintf(...) fprintf(stderr, __VA_ARGS__) + +static const int WINDOW_WIDTH = 160, WINDOW_HEIGHT = 90; + +SDL_Window *window = NULL; + +int paused = 0; + +struct blob load_file(char const *const name); + +struct userdata userdata = { + .callback = NULL, + .user = NULL, +}; + +void audio_callback(void *userdata_void, unsigned char *stream_void, int const length) { + struct userdata *user = userdata_void; + float *stream = (float *) stream_void; + if (user->callback == NULL) { + for (int i = 0; i < length / sizeof (float); i++) { + stream[i] = 0.0; + } + } else { + user->callback(user->user, stream_void, length); + } +} + +int (*file_ext(char *file))(struct blob *, struct userdata *); + +int main(int argc, char **argv) { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + eprintf("failed to init SDL: %s\n"); + return EXIT_FAILURE; + } + + SDL_StopTextInput(); + + if ((window = SDL_CreateWindow("mu-sdl", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN)) == NULL) { + eprintf("failed to create a window: %s\n"); + SDL_Quit(); + return EXIT_FAILURE; + } + + SDL_Renderer *renderer; + if ((renderer = SDL_CreateRenderer(window, -1, 0)) == NULL) { + eprintf("failed to create a renderer: %s\n"); + SDL_DestroyWindow(window); + SDL_Quit(); + return EXIT_FAILURE; + } + + SDL_ShowWindow(window); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + SDL_AudioSpec desired = { + .freq = SAMPLE_RATE, + .format = AUDIO_F32SYS, + .channels = OUT_CHANNELS, + .samples = 8096, + .callback = audio_callback, + .userdata = &userdata, + }; + SDL_AudioDeviceID audio = SDL_OpenAudioDevice(NULL, 0, &desired, NULL, 0); + + if (argc == 2) { + int (*module_func)(struct blob *, struct userdata *) = file_ext(argv[1]); + if (module_func == NULL) { + eprintf("%s: unrecognized file extension\n", argv[1]); + goto arg_load_done; + } + struct blob file = load_file(argv[1]); + if (file.data == NULL) { + perror(argv[1]); + goto arg_load_done; + } + module_func(&file, &userdata); + } + arg_load_done: + + SDL_PauseAudioDevice(audio, 0); + while (true) { + SDL_Event evt; + while (SDL_PollEvent(&evt)) { + switch (evt.type) { + case SDL_QUIT: + goto done; + + case SDL_WINDOWEVENT: + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + break; + + case SDL_KEYDOWN: + // ^Q + if (evt.key.keysym.sym == SDLK_q && evt.key.keysym.mod & KMOD_CTRL) { + goto done; + } + // ESC + if (evt.key.keysym.sym == SDLK_ESCAPE) { + goto done; + } + + if (evt.key.keysym.sym == SDLK_SPACE) { + paused = !paused; + SDL_PauseAudioDevice(audio, paused); + } + break; + + case SDL_DROPFILE: + puts(evt.drop.file); + struct blob file = load_file(evt.drop.file); + if (file.data == NULL) { + perror(evt.drop.file); + SDL_free(evt.drop.file); + break; + } + struct userdata newuser = {.callback = NULL, .freefunc = NULL}; + int (*module_func)(struct blob *, struct userdata *) = file_ext(evt.drop.file); + if (module_func == NULL) { + eprintf("%s: unrecognized file extension\n", evt.drop.file); + free(file.data); + break; + } + SDL_free(evt.drop.file); + if (module_func(&file, &newuser)) { + // error + } else { + SDL_LockAudioDevice(audio); + if (userdata.freefunc != NULL) { + userdata.freefunc(userdata.user); + } + userdata = newuser; + SDL_UnlockAudioDevice(audio); + } + free(file.data); + break; + + default: + } + } + } + done: + if (userdata.freefunc != NULL) { + SDL_LockAudioDevice(audio); + userdata.freefunc(userdata.user); + SDL_PauseAudioDevice(audio, 1); + SDL_UnlockAudioDevice(audio); + } + + SDL_DestroyRenderer(renderer); + + SDL_DestroyWindow(window); + + SDL_CloseAudioDevice(audio); + + SDL_Quit(); + + return EXIT_SUCCESS; +} + +int (*file_ext(char *file))(struct blob *, struct userdata *) { + size_t len = strlen(file); + #define ext(extension) memcmp(file + len - sizeof (extension) + 1, extension, sizeof (extension)) + if ((ext(".mptm") && ext(".mod") && ext(".xm") && ext(".s3m") && ext(".it")) == 0) { + return module_openmpt; + } else if ((ext(".mid") && ext(".midi")) == 0) { + return module_fluidsynth; + } + #undef ext + return NULL; +} + +struct blob load_file(char const *const name) { + const size_t START_SIZE = 1; + FILE *file = fopen(name, "rb"); + if (file == NULL) { + return (struct blob) {.data = NULL}; + } + void *data = malloc(START_SIZE); + size_t allocated = START_SIZE; + size_t used = 0; + while (1) { + size_t read = fread(data + used, 1, allocated - used, file); + if (read != allocated - used) { + used += read; + break; + } + used += read; + allocated *= 2; + void *const newdata = realloc(data, allocated); + if (newdata == NULL) { + goto realloc_error; + } + data = newdata; + } + void *const newdata = realloc(data, used); + if (newdata == NULL && used != 0) { + goto realloc_error; + } + fclose(file); + return (struct blob) {.data = newdata, .size = used}; + + realloc_error: + free(data); + fclose(file); + return (struct blob) {.data = NULL}; +} diff --git a/src/include.h b/src/include.h index 389aaf2..6bd52ff 100644 --- a/src/include.h +++ b/src/include.h @@ -1,6 +1,10 @@ #pragma once #include +#define SAMPLE_RATE 48000 +#define IN_CHANNELS 0 +#define OUT_CHANNELS 2 + struct blob { void *data; size_t size; diff --git a/src/modules/fluidsynth.c b/src/modules/fluidsynth.c index fd3c874..9eedc2c 100644 --- a/src/modules/fluidsynth.c +++ b/src/modules/fluidsynth.c @@ -36,7 +36,7 @@ int module_fluidsynth(struct blob *file, struct userdata *userdata) { fs->settings = new_fluid_settings(); // wasteful, but when trying to 'fix' it it just caused more errors fluid_settings_setnum(fs->settings, "synth.gain", 0.5); fluid_settings_setint(fs->settings, "player.reset-synth", 0); - fluid_settings_setnum(fs->settings, "synth.sample-rate", 48000); + fluid_settings_setnum(fs->settings, "synth.sample-rate", SAMPLE_RATE); fs->synth = new_fluid_synth(fs->settings); char *soundfont_path = getenv("SOUNDFONT"); if (soundfont_path == NULL) { diff --git a/src/modules/openmpt.c b/src/modules/openmpt.c index 58c3994..027519f 100644 --- a/src/modules/openmpt.c +++ b/src/modules/openmpt.c @@ -4,7 +4,7 @@ #include static void openmpt_callback(void *mod, unsigned char *stream, int const length) { - openmpt_module_read_interleaved_float_stereo(mod, 48000, length / sizeof (float) / 2, (float *) stream); + openmpt_module_read_interleaved_float_stereo(mod, SAMPLE_RATE, length / sizeof (float) / 2, (float *) stream); } static void libopenmpt_example_logfunc( const char * message, void * userdata ); diff --git a/src/sdl.c b/src/sdl.c deleted file mode 100644 index 21ce1a8..0000000 --- a/src/sdl.c +++ /dev/null @@ -1,214 +0,0 @@ -#define SDL_MAIN_HANDLED -#include - -#include -#include -#include - -#include "include.h" - -int module_openmpt(struct blob *file, struct userdata *userdata); -int module_fluidsynth(struct blob *file, struct userdata *userdata); - -#define eprintf(...) fprintf(stderr, __VA_ARGS__) - -static const int WINDOW_WIDTH = 160, WINDOW_HEIGHT = 90; - -SDL_Window *window = NULL; - -struct blob load_file(char const *const name); - -struct userdata userdata = { - .callback = NULL, - .user = NULL, -}; - -void audio_callback(void *userdata_void, unsigned char *stream_void, int const length) { - struct userdata *user = userdata_void; - float *stream = (float *) stream_void; - if (user->callback == NULL) { - for (int i = 0; i < length / sizeof (float); i++) { - stream[i] = 0.0; - } - } else { - user->callback(user->user, stream_void, length); - } -} - -int (*file_ext(char *file))(struct blob *, struct userdata *); - -int main(int argc, char **argv) { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { - eprintf("failed to init SDL: %s\n"); - return EXIT_FAILURE; - } - - SDL_StopTextInput(); - - if ((window = SDL_CreateWindow("mu-sdl", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN)) == NULL) { - eprintf("failed to create a window: %s\n"); - SDL_Quit(); - return EXIT_FAILURE; - } - - SDL_Renderer *renderer; - if ((renderer = SDL_CreateRenderer(window, -1, 0)) == NULL) { - eprintf("failed to create a renderer: %s\n"); - SDL_DestroyWindow(window); - SDL_Quit(); - return EXIT_FAILURE; - } - - SDL_ShowWindow(window); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - - SDL_AudioSpec desired = { - .freq = 48000, - .format = AUDIO_F32SYS, - .channels = 2, - .samples = 8096, - .callback = audio_callback, - .userdata = &userdata, - }; - SDL_AudioDeviceID audio = SDL_OpenAudioDevice(NULL, 0, &desired, NULL, 0); - - if (argc == 2) { - int (*module_func)(struct blob *, struct userdata *) = file_ext(argv[1]); - if (module_func == NULL) { - eprintf("%s: unrecognized file extension\n", argv[1]); - goto arg_load_done; - } - struct blob file = load_file(argv[1]); - if (file.data == NULL) { - perror(argv[1]); - goto arg_load_done; - } - module_func(&file, &userdata); - } - arg_load_done: - - SDL_PauseAudioDevice(audio, 0); - while (true) { - SDL_Event evt; - while (SDL_PollEvent(&evt)) { - switch (evt.type) { - case SDL_QUIT: - goto done; - - case SDL_WINDOWEVENT: - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - break; - - case SDL_KEYDOWN: - // ^Q - if (evt.key.keysym.sym == SDLK_q && evt.key.keysym.mod & KMOD_CTRL) { - goto done; - } - // ESC - if (evt.key.keysym.sym == SDLK_ESCAPE) { - goto done; - } - break; - - case SDL_DROPFILE: - puts(evt.drop.file); - struct blob file = load_file(evt.drop.file); - if (file.data == NULL) { - perror(evt.drop.file); - SDL_free(evt.drop.file); - break; - } - struct userdata newuser = {.callback = NULL, .freefunc = NULL}; - int (*module_func)(struct blob *, struct userdata *) = file_ext(evt.drop.file); - if (module_func == NULL) { - eprintf("%s: unrecognized file extension\n", evt.drop.file); - free(file.data); - break; - } - SDL_free(evt.drop.file); - if (module_func(&file, &newuser)) { - // error - } else { - SDL_LockAudioDevice(audio); - if (userdata.freefunc != NULL) { - userdata.freefunc(userdata.user); - } - userdata = newuser; - SDL_UnlockAudioDevice(audio); - } - free(file.data); - break; - - default: - } - } - } - done: - if (userdata.freefunc != NULL) { - SDL_LockAudioDevice(audio); - userdata.freefunc(userdata.user); - SDL_PauseAudioDevice(audio, 1); - SDL_UnlockAudioDevice(audio); - } - - SDL_DestroyRenderer(renderer); - - SDL_DestroyWindow(window); - - SDL_CloseAudioDevice(audio); - - SDL_Quit(); - - return EXIT_SUCCESS; -} - -int (*file_ext(char *file))(struct blob *, struct userdata *) { - size_t len = strlen(file); - #define ext(extension) memcmp(file + len - sizeof (extension) + 1, extension, sizeof (extension)) - if ((ext(".mptm") && ext(".mod") && ext(".xm") && ext(".s3m") && ext(".it")) == 0) { - return module_openmpt; - } else if ((ext(".mid") && ext(".midi")) == 0) { - return module_fluidsynth; - } - #undef ext - return NULL; -} - -struct blob load_file(char const *const name) { - const size_t START_SIZE = 1; - FILE *file = fopen(name, "rb"); - if (file == NULL) { - return (struct blob) {.data = NULL}; - } - void *data = malloc(START_SIZE); - size_t allocated = START_SIZE; - size_t used = 0; - while (1) { - size_t read = fread(data + used, 1, allocated - used, file); - if (read != allocated - used) { - used += read; - break; - } - used += read; - allocated *= 2; - void *const newdata = realloc(data, allocated); - if (newdata == NULL) { - goto realloc_error; - } - data = newdata; - } - void *const newdata = realloc(data, used); - if (newdata == NULL && used != 0) { - goto realloc_error; - } - fclose(file); - return (struct blob) {.data = newdata, .size = used}; - - realloc_error: - free(data); - fclose(file); - return (struct blob) {.data = NULL}; -} -- cgit 1.4.1-2-gfad0