Mercurial > hg > dmlib
view tests/plrtest.c @ 2251:d736ff74663b
Oops, we had two '-n' short options. Change the line items one to '-l'.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 15 Jun 2019 21:39:41 +0300 |
parents | 186cf6a7d634 |
children | aacf3bd1cceb |
line wrap: on
line source
#include "jss.h" #include "jssmod.h" #include "jssmix.h" #include "jssplr.h" #include <string.h> #include <unistd.h> #include <SDL.h> static const char patNoteTable[12][3] = { "C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-" }; #define jmpNMODEffectTable (36) static const char jmpMODEffectTable[jmpNMODEffectTable] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; void printRow(FILE * fh, const JSSPattern * pat, const int row) { const JSSNote *note = &(pat->data[pat->nchannels * row]); int width = pat->nchannels < 5 ? pat->nchannels : 5; fprintf(fh, "%.2x: ", row); for (int channel = 0; channel < width; channel++) { switch (note->note) { case jsetNotSet: fprintf(fh, "... "); break; case jsetNoteOff: fprintf(fh, "=== "); break; default: fprintf(fh, "%s%d ", patNoteTable[note->note % 12], note->note / 12); break; } if (note->instrument != jsetNotSet) fprintf(fh, "%.2x ", note->instrument + 1); else fprintf(fh, ".. "); if (note->volume == jsetNotSet) fprintf(fh, ".. "); else if (note->volume >= 0x00 && note->volume <= 0x40) fprintf(fh, "%.2x ", note->volume); else { char ch; switch (note->volume & 0xf0) { case 0x50: ch = '-'; break; case 0x60: ch = '+'; break; case 0x70: ch = '/'; break; case 0x80: ch = '\\'; break; case 0x90: ch = 'S'; break; case 0xa0: ch = 'V'; break; case 0xb0: ch = 'P'; break; case 0xc0: ch = '<'; break; case 0xd0: ch = '>'; break; case 0xe0: ch = 'M'; break; default: ch = '?'; break; } fprintf(fh, "%c%x ", ch, note->volume & 0x0f); } if (note->effect >= 0 && note->effect < jmpNMODEffectTable) fprintf(fh, "%c", jmpMODEffectTable[note->effect]); else fprintf(fh, "%c", note->effect == jsetNotSet ? '.' : '?'); if (note->param != jsetNotSet) fprintf(fh, "%.2x|", note->param); else fprintf(fh, "..|"); note++; } } void audioCallback(void *userdata, Uint8 *stream, int len) { JSSMixer *d = (JSSMixer *) userdata; if (d != NULL) { jvmRenderAudio(d, stream, len / jvmGetSampleSize(d)); } } int main(int argc, char *argv[]) { SDL_AudioSpec afmt; DMResource *file = NULL; char *inFilename = NULL; int result = -1; JSSModule *mod = NULL; JSSMixer *dev = NULL; JSSPlayer *plr = NULL; if (argc > 1) inFilename = argv[1]; // Open the files if (inFilename == NULL) result = dmf_open_stdio_stream(stdin, &file); else result = dmf_open_stdio(inFilename, "rb", &file); if (result != DMERR_OK) { fprintf(stderr, "Error opening input file '%s', #%d: %s\n", inFilename, result, dmErrorStr(result)); return 1; } // Initialize miniJSS fprintf(stderr, "Initializing miniJSS\n"); jssInit(); // Read module file dmMsg(1, "Reading file: %s\n", inFilename); #ifdef JSS_SUP_XM result = jssLoadXM(file, &mod, TRUE); #endif #ifdef JSS_SUP_JSSMOD dmfreset(file); if (result != DMERR_OK) { dmMsg(1, "* Trying JSSMOD ...\n"); result = jssLoadJSSMOD(file, &mod, TRUE); dmfreset(file); if (result == DMERR_OK) result = jssLoadJSSMOD(file, &mod, FALSE); } else { dmMsg(2, "* Trying XM...\n"); result = jssLoadXM(file, &mod, FALSE); } #endif dmf_close(file); // Check for errors, we still might have some data tho if (result != DMERR_OK) { dmErrorMsg("Error loading module file, %d: %s\n", result, dmErrorStr(result)); } // Check if we have anything if (mod == NULL) return 3; // Try to convert it if ((result = jssConvertModuleForPlaying(mod)) != DMERR_OK) { fprintf(stderr, "Could not convert module for playing, %d: %s\n", result, dmErrorStr(result)); return 3; } // Initialize SDL audio afmt.freq = 48000; afmt.format = AUDIO_S16SYS; afmt.channels = 2; // Initialize mixing device fprintf(stderr, "Initializing miniJSS mixer with: %d, %d, %d\n", JSS_AUDIO_S16, afmt.channels, afmt.freq); dev = jvmInit(JSS_AUDIO_S16, afmt.channels, afmt.freq, JMIX_AUTO); if (dev == NULL) { fprintf(stderr, "jvmInit() returned NULL\n"); return 3; } afmt.samples = afmt.freq / 4; afmt.callback = audioCallback; afmt.userdata = (void *) dev; // Open the audio device fprintf(stderr, "Trying to init SDL with: %d, %d, %d\n", afmt.format, afmt.channels, afmt.freq); if (SDL_OpenAudio(&afmt, NULL) < 0) { fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); return 4; } // Initialize player if ((plr = jmpInit(dev)) == NULL) { fprintf(stderr, "jmpInit() returned NULL\n"); return 4; } // Initialize playing jvmSetCallback(dev, jmpExec, plr); jmpSetModule(plr, mod); jmpPlayOrder(plr, 0); jvmSetGlobalVol(dev, 100); // okay, main loop here ... "play" module and print out info printf("----------------------------------------------------\n"); SDL_LockAudio(); SDL_PauseAudio(0); SDL_UnlockAudio(); BOOL playing = TRUE; while (playing) { JSSPattern *pattern = NULL; int currRow, prevRow; JSS_LOCK(plr); currRow = prevRow = plr->row; JSS_UNLOCK(plr); while (currRow == prevRow && playing) { JSS_LOCK(plr); currRow = plr->row; playing = plr->isPlaying; pattern = plr->pattern; JSS_UNLOCK(plr); SDL_Delay(50); } if (playing && pattern != NULL) { printRow(stdout, pattern, currRow); printf("\n"); } } printf("----------------------------------------------------\n"); SDL_LockAudio(); SDL_PauseAudio(1); jmpClose(plr); jvmClose(dev); jssFreeModule(mod); SDL_UnlockAudio(); SDL_Quit(); jssClose(); return 0; }