/* Name: MIKMODUX.C Description: Modplaying example of mikmod - bare unix? version. Original by MikMak <mikmak@via.nl>, then Chris Conn <cconn@tohs.abacom.com>, then Steve McIntyre <stevem@chiark.greenend.org.uk> HISTORY ======= v1.00 (06/12/96) - first "versioned" version */ package audio.jmikmod.MikMod; import java.io.*; import java.lang.*; import java.net.URL; import audio.jmikmod.MikMod.*; import audio.jmikmod.MikMod.Display.*; import audio.jmikmod.MikMod.Drivers.*; import audio.jmikmod.MikMod.Loaders.*; import audio.jmikmod.MikMod.MDriver.*; import audio.jmikmod.MikMod.MLoader.*; import audio.jmikmod.MikMod.MMIO.*; import audio.jmikmod.MikMod.MPlayer.*; import audio.jmikmod.MikMod.MUniTrk.*; import audio.jmikmod.MikMod.UI.*; import audio.jmikmod.MikMod.Virtch.*; public class clMain extends clMainBase { public final int DMODE_STEREO = 1; public final int DMODE_16BITS = 2; public final int DMODE_INTERP = 4; public String d_text[]; public String helptext; public boolean quiet; public short md_type; public final String mikversion = mikversion_; public int optind, opterr, in_opt_charpos; public String optarg; //char optarg[80]; public clMPlayer MPlayer; public clVirtch Virtch; public myUI UI; public clMDriver MDriver; public clDisplay Display; public clMain() { { int i; d_text = new String[4]; for(i=0;i<4;i++) d_text[i] = new String(); cur_mod = new curmod(); } d_text[0] = " "; /*standard, not deleted*/ d_text[1] = " <del> "; /*marked for deletion*/ d_text[2] = " <deleted> "; /*deleted, gone!*/ d_text[3] = " <del error>"; /*can't delete...*/ helptext= new String( "Available switches (CaSe SeNsItIvE!):\n" + "\n" + " -d x use device-driver #x for output (0 is autodetect). Default=0\n" + " -ld List all available device-drivers\n"+ " -ll List all available loaders\n"+ " -x disables protracker extended speed\n"+ " -p disables panning effects (9fingers.mod)\n"+ " -v xx Sets volume from 0 (silence) to 100. Default=100\n"+ " -f xxxx Sets mixing frequency. Default=44100\n"+ " -m Force mono output (so sb-pro can mix at 44100)\n"+ " -8 Force 8 bit output\n"+ " -i Use interpolated mixing\n"+ " -r Restart a module when it's done playing\n"+ " -q Quiet mode (interactive commands disabled, displays only errors)\n" + /*#ifdef CPUTIME_SNAGGER " -s Renice to -20 (more scheduling priority)\n"+ " -S Get realtime priority (snag all the cpu needed, beware :))\n"+ #endif /* CPUTIME_SNAGGER */ " -t Tolerant mode - do not stop on non-fatal file access errors." ); quiet=false; /* set if quiet mode is enabled */ md_type=0; /* default is a non-wavetable sound device */ optind = 0; in_opt_charpos = 0; } /* public int clMain.usleep() Well, I just implemented it using Java's Thread.Sleep(). It doesn't have range checking yet, but since it's called only once 1000 as its parameter it should do fine. */ /* * NAME: * usleep -- This is the precision timer for Test Set * Automation. It uses the select(2) system * call to delay for the desired number of * micro-seconds. This call returns ZERO * (which is usually ignored) on successful * completion, -1 otherwise. * * ALGORITHM: * 1) We range check the passed in microseconds and log a * warning message if appropriate. We then return without * delay, flagging an error. * 2) Load the Seconds and micro-seconds portion of the * interval timer structure. * 3) Call select(2) with no file descriptors set, just the * timer, this results in either delaying the proper * ammount of time or being interupted early by a signal. * * HISTORY: * Added when the need for a subsecond timer was evident. * Modified for Solaris-specific bits by SAM 24/10/96 * AUTHOR: * Michael J. Dyer Telephone: AT&T 414.647.4044 * General Electric Medical Systems GE DialComm 8 *767.4044 * P.O. Box 414 Mail Stop 12-27 Sect'y AT&T 414.647.4584 * Milwaukee, Wisconsin USA 53201 8 *767.4584 * internet: mike@sherlock.med.ge.com GEMS WIZARD e-mail: DYER */ public int usleep( int microSeconds ) { try { Thread.sleep(microSeconds/1000,(microSeconds%1000)*1000); } catch (InterruptedException intex1) { } return 0; } int java_getopt(int argc, String argv[], String optstring) { int ret=mmIO.EOF,i; if (optind < 1) optind = 1; if (optind == argc) return mmIO.EOF; if ((in_opt_charpos == 0) && (argv[optind].charAt(0) == '-')) { in_opt_charpos = 1; } if (in_opt_charpos > 0) { ret = '?'; for(i=0;i != optstring.length() ; i++) { if (optstring.charAt(i) == ':') continue; if (argv[optind].charAt(in_opt_charpos) == optstring.charAt(i)) { ret = argv[optind].charAt(in_opt_charpos); if (optstring.charAt(i+1) == ':') { //if (argv[optind].charAt(in_opt_charpos+1) == '\0') if (argv[optind].length() == in_opt_charpos+1) { optarg = new String(argv[++optind]); } else { optarg = new String(argv[optind].substring(in_opt_charpos+1)); //strcpy(optarg, argv[optind]+in_opt_charpos+1); } in_opt_charpos = 0; } else { in_opt_charpos++; //if (argv[optind].charAt(in_opt_charpos) == '\0') if (argv[optind].length() == in_opt_charpos) { optind++; in_opt_charpos = 0; } return ret; } break; } } optind++; } return ret; /*int ret = getopt(argc, argv, optstring); if (::optarg != NULL) strcpy(optarg, ::optarg); else optarg[0] = '\0'; return ret;*/ } /* public int clMain.main() This function corresponds with the C program main() function. It also accepts an array of string a-la-style of C's "char * argv[]" parameter: argv[0] is an arbitary program name, as in C. */ public int main(String nargv[], URL url) { int nargc = nargv.length; UNIMOD mf=null; int cmderr=0; /* error in commandline flag */ int morehelp=0; /* set if user wants more help */ int t; //extern float speed_constant; /* tempo multiplier, initialised to 1*/ /* Initialize soundcard parameters.. you _have_ to do this before calling MD_Init(), and it's illegal to change them after you've called MD_Init() */ boolean tolerant =false; MUniTrk = new clMUniTrk(this); MPlayer = new clMPlayer(this); Virtch = new clVirtch(this); mmIO = new MMIO(this); mmIO._mm_setiobase(0); UI = new myUI(this); Display = new clDisplay(this); super.Display = Display; MDriver = new clMDriver(this); super.MDriver = MDriver; MLoader = new clMLoader(this); MPlayer.play_current =true; /* we are playing _this_ mod; jump to next when this goes to 0 */ MDriver.md_mixfreq =44100; /* standard mixing freq */ MDriver.md_dmabufsize =32768; /* standard dma buf size */ MDriver.md_mode =(short)(DMODE_16BITS|DMODE_STEREO); /* standard mixing mode */ MDriver.md_device =0; /* standard device: autodetect */ /* Register the loaders we want to use.. */ M15_Loader cl_load_m15 = new audio.jmikmod.MikMod.Loaders.M15_Loader(this); MLoader.ML_RegisterLoader(cl_load_m15); MOD_Loader cl_load_mod = new MOD_Loader(this); MLoader.ML_RegisterLoader(cl_load_mod); MTM_Loader cl_load_mtm = new audio.jmikmod.MikMod.Loaders.MTM_Loader(this); MLoader.ML_RegisterLoader(cl_load_mtm); S3M_Loader cl_load_s3m = new audio.jmikmod.MikMod.Loaders.S3M_Loader(this); MLoader.ML_RegisterLoader(cl_load_s3m); STM_Loader cl_load_stm = new audio.jmikmod.MikMod.Loaders.STM_Loader(this); MLoader.ML_RegisterLoader(cl_load_stm); ULT_Loader cl_load_ult = new audio.jmikmod.MikMod.Loaders.ULT_Loader(this); MLoader.ML_RegisterLoader(cl_load_ult); UNI_Loader cl_load_uni = new audio.jmikmod.MikMod.Loaders.UNI_Loader(this); MLoader.ML_RegisterLoader(cl_load_uni); S69_Loader cl_load_669 = new audio.jmikmod.MikMod.Loaders.S69_Loader(this); MLoader.ML_RegisterLoader(cl_load_669); XM_Loader cl_load_xm = new audio.jmikmod.MikMod.Loaders.XM_Loader(this); MLoader.ML_RegisterLoader(cl_load_xm); /* Register the drivers we want to use: */ NS_Driver cl_drv_nos = new NS_Driver(this); MDriver.MD_RegisterDriver(cl_drv_nos); Raw_Driver cl_drv_raw = new Raw_Driver(this); MDriver.MD_RegisterDriver(cl_drv_raw); /* * Commenting out so we won't depend on the native extension. Native_Driver cl_drv_native = new Native_Driver(this); MDriver.MD_RegisterDriver(cl_drv_native); */ Wav_Driver cl_drv_wav = new Wav_Driver(this); MDriver.MD_RegisterDriver(cl_drv_wav); JavaX_Driver cl_drv_javax = new JavaX_Driver(this); MDriver.MD_RegisterDriver(cl_drv_javax); // [Rafael, the Esper] MPlayer.mp_loop=true; quiet = true; /*#ifdef SUN MD_RegisterDriver(&drv_sun); #elif defined(SOLARIS) MD_RegisterDriver(&drv_sun); #elif defined(__alpha) MD_RegisterDriver(&drv_AF); #elif defined(OSS) Vox_Driver cl_drv_vox(this); MDriver.MD_RegisterDriver(&cl_drv_vox); #ifdef ULTRA MD_RegisterDriver(&drv_ultra); #endif // ULTRA #elif defined(__hpux) MD_RegisterDriver(&drv_hp); #elif defined(AIX) MD_RegisterDriver(&drv_aix); #elif defined(SGI) MD_RegisterDriver(&drv_sgi); #elif defined(WIN32) //MDriver.MD_RegisterDriver(&drv_win32); Win32_Driver cl_drv_win32(&main_class); MDriver.MD_RegisterDriver(&cl_drv_win32); #endif */ //MDriver.MD_RegisterPlayer(clMDriver::tickhandler); /* Parse option switches using standard getopt function: */ opterr=0; while( (cmderr==0) && //#ifdef CPUTIME_SNAGGER // (t=java_getopt(nargc,nargv,"ohxpm8irv:f:l:d:tsS")) != mmIO.EOF ){ //#else (t=java_getopt(nargc,nargv,"ohxpm8irv:f:l:d:t")) != mmIO.EOF ){ switch(t){ case 'd': MDriver.md_device=Integer.valueOf(optarg).intValue(); break; case 'l': if(optarg.charAt(0)=='d') MDriver.MD_InfoDriver(); else if(optarg.charAt(0)=='l') MLoader.ML_InfoLoader(); else{ cmderr=1; break; } return 0; //exit(0); case 'r': MPlayer.mp_loop=true; break; case 'm': MDriver.md_mode &= ~DMODE_STEREO; break; case '8': MDriver.md_mode &= ~DMODE_16BITS; break; case 'i': MDriver.md_mode |= DMODE_INTERP; break; case 'x': MPlayer.mp_extspd=false; break; case 'p': MPlayer.mp_panning=false; break; case 'v': if((MPlayer.mp_volume=(short)(Integer.valueOf(optarg).intValue()))>100) MPlayer.mp_volume=100; break; case 'f': MDriver.md_mixfreq = Integer.valueOf(optarg).intValue(); break; case 'h': morehelp=1; cmderr=1; break; case 't': tolerant=true; break; case 'q': quiet=true; break; /*#ifdef CPUTIME_SNAGGER case 's': if (nice(-20) == -1) perror("renice to -20"); break; case 'S': { struct sched_param sp; memset(&sp, 0, sizeof(struct sched_param)); sp.sched_priority = 1; if (sched_setscheduler(0, SCHED_RR, &sp) == -1) perror("realtime priority"); } break; #endif /* CPUTIME_SNAGGER */ case '?': System.out.println("\07Invalid switch or option needs an argument\n"); cmderr=1; break; } } if((cmderr!=0) || optind>=nargc){ /* there was an error in the commandline, or there were no true arguments, so display a usage message */ System.out.print("Usage: "+nargv[0]+" [switches] <fletch.mod> ... \n"); if(morehelp != 0) System.out.println(helptext); else System.out.print("Type "+nargv[0]+" -h for more help.\n"); return -1; //exit(-1); } if (!quiet) System.out.print(mikbanner); /* initialize soundcard */ if(!MDriver.MD_Init()){ System.out.print("Driver error: "+mmIO.myerr+".\n"); return 0; } /* initialize volume and tempo multipliers */ MPlayer.speed_constant=(float)1.0; MPlayer.mp_volume=100; cur_mod.version = new String(); cur_mod.driver = new String(); cur_mod.filename = null; //new String(); cur_mod.file_output = new String(); cur_mod.name_type = new String(); cur_mod.status = new String(); /* initialize curses interface */ Display.init_display(); for(MPlayer.quit=false; !MPlayer.quit && optind<nargc; optind++){ /* kill audio output, as some mods sound awful left hanging... */ MDriver.MD_PatternChange(); cur_mod.deleted=false; cur_mod.filename = url; //new String(nargv[optind]); /* load the module */ { //String strFilename = new String(nargv[optind]); mf=MLoader.ML_LoadFN(cur_mod.filename); } /* didn't work . exit with errormsg. */ if(mf==null){ if(tolerant) { Display.display_version(); Display.display_error(mmIO.myerr,mmIO.myerr_file); continue; } else { //printf("MikMod Error: %s\n",mmIO.myerr); System.out.print(("MikMod Error: " + mmIO.myerr + "\n")); break; } } /* initialize modplayer to play this module */ MPlayer.MP_Init(mf); Display.update_driver_display(); Display.update_file_display(); Display.display_version(); Display.display_driver(); Display.display_file(); cur_mod.numpat=mf.numpos; cur_mod.songname=mf.songname; cur_mod.modtype=mf.modtype; cur_mod.flags=mf.flags; Display.update_name_display(); Display.display_name(); /* set the number of voices to use.. you could add extra channels here (e.g. md_numchn=mf.numchn+4; ) to use for your own soundeffects: */ MDriver.md_numchn=mf.numchn; /* start playing the module: */ MDriver.MD_PlayStart(); while((! MPlayer.MP_Ready() ) && (! MPlayer.quit)){ /* if we have a quit signal, exit loop */ MDriver.MD_Update(); /* no need to wait with the unix drivers */ if (md_type == 0) /* handled elsewhere for GUS cards */ { /* update the status display... */ cur_mod.sngpos=(short)(MPlayer.mp_sngpos+1); cur_mod.patpos=(short)MPlayer.mp_patpos; Display.update_status_display(); Display.display_status(); } if(!MPlayer.play_current){ /*play_current=0 when the next or previous*/ MPlayer.play_current=true; /*mod is selected*/ break; } } MDriver.MD_PlayStop(); /* stop playing */ MLoader.ML_Free(mf); /* and free the module */ } MDriver.MD_Exit(); Display.exit_display(); if (MPlayer.quit) { return 0; } if(!quiet) if(mf==null){ //printf("MikMod Error: %s\n",mmIO.myerr); System.out.println(("MikMod Error: " + mmIO.myerr + "\n")); if((mmIO.myerr_file == null) || (mmIO.myerr_file == "")) //printf("%s\n",mmIO.myerr_file); System.out.println(mmIO.myerr_file); } else System.out.print("Finished playlist...\n"); return 1; } }