#include #include #include #include "sndfile.h" #include "fmt.h" /* * gcc -O2 -o playit-sdl2 playit-sdl2.c -I.. -I../src/include -DHAVE_CONFIG_H -lm `pkg-config sdl2 --cflags --libs` -s ../src/libplayit.a */ static song_t * song_load_it(const char *file) { slurp_t *s; song_t *song; s = slurp(file, NULL, 0); if (!s) { printf("failed to open \"%s\"\n", file); goto _fail; } song = csf_allocate(); if (!song) { printf("failed to allocate song\n"); goto _fail_slurp; } if (fmt_it_load_song(song, s, 0) != LOAD_SUCCESS) goto _fail_song; unslurp(s); return song; _fail_song: csf_free(song); _fail_slurp: unslurp(s); _fail: return NULL; } static SDL_AudioDeviceID sdl2_open(const char *device) { SDL_AudioDeviceID dev; SDL_AudioSpec aspec = { .freq = 44100, .format = AUDIO_S16, .channels = 2, .samples = 4096, }; if (SDL_Init(SDL_INIT_AUDIO) != 0) { printf("Failed to initialize SDL w/audio!\n"); return -1; } dev = SDL_OpenAudioDevice(device, 0, &aspec, NULL, 0); if (dev < 0) { printf("Failed to open SDL audio device!\n"); return -1; } SDL_PauseAudioDevice(dev, 0); return dev; } static void sdl2_close(SDL_AudioDeviceID dev) { SDL_CloseAudioDevice(dev); } int main(int argc, char *argv[]) { song_t *song; uint8_t buf[8192]; int len; SDL_AudioDeviceID dev; if (argc != 2) { printf("usage: %s song.it\n", argv[0]); goto _fail; } song = song_load_it(argv[1]); if (!song) { printf("failed to load song!\n"); goto _fail; } if (!(dev = sdl2_open(NULL))) { printf("Failed to open audio!\n"); goto _fail_song; } csf_set_current_order(song, 0); song->repeat_count = 0; song->buffer_count = 0; song->stop_at_order = -1; song->stop_at_row = -1; song->flags &= ~(SONG_PAUSED | SONG_PATTERNLOOP | SONG_ENDREACHED); csf_reset_playmarks(song); csf_set_resampling_mode(song, SRCMODE_LINEAR); csf_set_wave_config(song, 44100, 16, 2); while ((len = csf_read(song, buf, sizeof(buf)))) { int err; while (SDL_GetQueuedAudioSize(dev) > 8192) SDL_Delay(10); if ((err = SDL_QueueAudio(dev, buf, len * 4)) < 0) { fprintf(stderr, "write failed (%s)\n", SDL_GetError()); break; } } sdl2_close(dev); return EXIT_SUCCESS; _fail_song: /* TODO cleanup song */ _fail: return EXIT_FAILURE; }