Skip to content

Instantly share code, notes, and snippets.

@jaygarcia
Last active December 9, 2018 16:27
Show Gist options
  • Save jaygarcia/049ca44adee4664464c865c1938d7f57 to your computer and use it in GitHub Desktop.
Save jaygarcia/049ca44adee4664464c865c1938d7f57 to your computer and use it in GitHub Desktop.
libxmp replay bug
#include <SDL2/SDL.h>
#include <SDL2/SDL_audio.h>
#include "xmp.h"
#include "sndfile.h"
#include "stdlib.h"
#include "string.h"
#define SAMPLE_RATE 44100
#define CHANNELS 2
xmp_context xmpContext;
int random_int(int min, int max) {
return min + rand() % (max+1 - min);
}
void SDL_Callback(void *uData, Uint8 *stream, int length) {
if (length == 0) {
return;
}
memset(stream, 0, length);
int result = xmp_play_buffer(xmpContext, stream, length, 0);
if (result != 0) {
printf("Result = %i | Length = %i\n", result, length); fflush(stdout);
}
}
long int getFileSize(char *myFile) {
FILE* fp = fopen(myFile, "r");
fseek(fp, 0L, SEEK_END);
long int effectFileSize = ftell(fp);
fclose(fp);
return effectFileSize;
}
int maxSfx = 8;
const char *sfxFiles[] = {
"/home/jgarcia/Desktop/game/genus/resources/sound_effects/SFX_bad_drop_block.wav",
"/home/jgarcia/Desktop/game/genus/resources/sound_effects/SFX_explode_block.wav",
"/home/jgarcia/Desktop/game/genus/resources/sound_effects/SFX_good_drop_block.wav",
"/home/jgarcia/Desktop/game/genus/resources/sound_effects/SFX_move_block.wav",
"/home/jgarcia/Desktop/game/genus/resources/sound_effects/SFX_option_select.wav",
"/home/jgarcia/Desktop/game/genus/resources/sound_effects/SFX_rotate_block_left.wav",
"/home/jgarcia/Desktop/game/genus/resources/sound_effects/SFX_rotate_block_right.wav",
"/home/jgarcia/Desktop/game/genus/resources/sound_effects/SFX_score_combo.wav",
};
int maxModFiles = 12;
const char *modFiles[] = {
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-afternoon_pr0n.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-agnetas_telephone.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-alf2_zalza_edit.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-annas_silver_stick.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-arkanoid_rmx.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-bisv_rm.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-cph_rides_high.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-cp-knarkmix3.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-crusin_sicilia.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-erika_online.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-fly_bird_funktro.xm",
"/home/jgarcia/Desktop/game/genus/resources/music_test/zalza-g_te_g_r_p_tivoli.xm"
};
void loadNewMod(const char *newModFile) {
SDL_PauseAudio(1);
SDL_Delay(50); // Let's be generous and let the other thread stop.
printf("Loading mod file: %s\n", newModFile);
xmp_end_smix(xmpContext);
xmp_end_player(xmpContext);
FILE *f = fopen(newModFile, "rb");
fseek(f, 0, SEEK_END);
long fileSize = ftell(f);
fseek(f, 0, SEEK_SET); //same as rewind(f);
auto *fileData = (uint8_t *)malloc(fileSize);
fread(fileData, fileSize, 1, f);
fclose(f);
int loadResult = xmp_load_module_from_memory(xmpContext, fileData, fileSize);
if (loadResult < 0) {
printf("ERROR:: Could not open %s! %i", newModFile, loadResult);
return;
}
// printf("loadResult = %i\n", loadResult);
struct xmp_module_info mi;
xmp_get_module_info(xmpContext, &mi);
printf("%s (%s)\n", mi.mod->name, mi.mod->type);
xmp_start_smix(xmpContext, 4, maxSfx);
for (int i = 0; i < maxSfx; i++) {
char *sfxFile = strdup(sfxFiles[i]);
// printf("xmp_smix_load_sample(%i, %s)\n", i, sfxFile);
int sfxLoadResult = xmp_smix_load_sample(xmpContext, i, sfxFile);
// printf("SFX Load result: %i\n", sfxLoadResult);
}
xmp_start_player(xmpContext, SAMPLE_RATE, 0);
SDL_PauseAudio(0);
}
int main(int argc, char *argv[]) {
SDL_AudioSpec fmt;
SDL_AudioSpec actual_fmt;
int finished;
int currentModFile = 0;
struct xmp_frame_info fi;
struct xmp_module_info mi;
xmpContext = xmp_create_context();
loadNewMod(modFiles[currentModFile]);
/* initialize SDL audio and start playing */
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
printf("could not initialize SDL: %s\n", SDL_GetError());
exit(1);
}
fmt.freq = SAMPLE_RATE;
fmt.format = AUDIO_S16;
fmt.channels = CHANNELS;
fmt.samples = 18; //BUFFER_SIZE >> 2;
fmt.callback = SDL_Callback;
fmt.userdata = xmpContext;
/* open audio */
if (SDL_OpenAudio(&fmt, &actual_fmt) < 0) {
printf("could not open SDL audio: %s\n", SDL_GetError());
exit(1);
}
// Play
SDL_PauseAudio(0);
finished = 0;
int64_t counter = 0;
int currentSfx = -1;
while (!finished) {
xmp_get_frame_info(xmpContext, &fi);
xmp_get_module_info(xmpContext, &mi);
if (counter % 1000 == 0) {
currentModFile++;
if (currentModFile > maxModFiles - 1) {
currentModFile = 0;
}
loadNewMod(modFiles[currentModFile]);
}
if (counter % 100 == 0) {
currentSfx++;
if (currentSfx > maxSfx - 1) {
currentSfx = 1;
}
xmp_smix_play_sample(xmpContext, currentSfx, 60, 64, 0);
}
counter++;
fflush(stdout);
SDL_Delay(4);
}
SDL_CloseAudio();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment