Last active
December 9, 2018 16:27
-
-
Save jaygarcia/049ca44adee4664464c865c1938d7f57 to your computer and use it in GitHub Desktop.
libxmp replay bug
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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