/* $Id: main.c,v 1.9 2006/09/16 10:36:23 toad32767 Exp $ */ /** ** 2005, 2006 by Marco Trillo ** This file is part of UModPlayer, and is released by ** its autors to the Public Domain. ** In case it's not legally possible, its autors grant ** anyone the right to use, redistribute and modify ** this software for any purpose, without any conditions, ** unless such conditions are required by law. ** ** THIS FILE COMES WITHOUT ANY WARRANTY. THE AUTHORS ** SHALL NOT BE LIABLE FOR ANY DAMAGE RESULTING BY THE ** USE OR MISUSE OF THIS SOFTWARE. **/ #include #include #include #include #include #include #include #include #include /* global variables */ EXPORT struct file file = {FALSE, NULL, NULL}; /* the module file loaded */ EXPORT struct oFlags sets; /* settings (configuration) */ EXPORT char **rr = NULL; /* text to be printed out by the table callback */ EXPORT int startpos = 0; /* start position for exportings */ EXPORT int endpos = -1; /* end position for exportings */ EXPORT int CoreSound_BitsPerSample = 0; /* bits per sample */ EXPORT char *AudioDriver = NULL; /* audio driver */ EXPORT Bool AudioActive = FALSE; /* audio active */ EXPORT ao_device *AO_Device = NULL; /* device for LibAo */ /* * Catch the SIGINT & SIGTERM signals */ void CatchSignal(int sig) { if (AudioActive == TRUE) CoreSound_Quit(); if (file.name != NULL) UFreeFile(); notice("\n[exiting by signal %d]\n", sig); exit(UM_OK); } /* * Print the version banner */ EXPORT void PrintBanner() { puts(UMODPLAYER_VERSION); puts(COMPILATION_DATE); } /* * Display the program usage */ LOCAL void DisplayUsage(char *progname) { fprintf(stderr, "Usage: %s [] []\n\n" "Options\n" "-V : print the UModPlayer version and exit.\n" "-i : Interactive mode (this is the default mode\n" " when no module file is given on command line.\n" "-q : Quiet; Do not print the status bar.\n" "-a : Start playback/export at order position .\n" "-z : End playback/export at order position .\n" "-o : Export loaded module to .\n" "-f : Select a format to export loaded module.\n" " Available formats:\n" " it, wav, aiff, s16se, s16le, s16be\n", progname); fprintf(stderr, "-d : Use the default config scheme.\n" "-w : Save the current config scheme.\n" "-m : Export module text message to .\n" "-s : Export module samplenames to .\n" "-I : Export module instrumentnames to .\n"); fprintf(stderr, "Audio options:\n" "-v : Volume level (1-512)\n" "-c : N. of channels. Possible values\n" " 1 = mono ; 2 = stereo\n" "-O : audio driver\n" " alsa09, alsa, oss, sun, macosx, arts, irix, esd, null\n" "-r : Sampling rate in Hz. Available values:\n" " 11025, 16000, 22050, 24000, 32000, 44100\n" "-M : Resampling mode. Available modes:\n" " NO_INTERPOLATE, LINEAR, SPLINE, FIR_FILTER\n" "+N,+R,+B,+S : Enable Noise Reduction, reverb, megabass\n" " & surround.\n" "-N,-R,-B,-S : Disable Noise Reduction, reverb, megabass\n" " & surround.\n"); return; } /* * A bogus monitor function for `no-status' mode. */ void QuietPlay() { /* only interrupted when finished or killed by a signal */ for (;;) { CoreSound_InjectPCM(); if (AudioActive == FALSE) { CoreSound_Quit(); return; } } } /* * umodplayer -- module player */ EXPORT int main(int argc, char **argv) { int i; int interactive = 0, status = 1, saveSettings = 0; char *ofile = NULL; int ofmt = 0, obps = 16; char *txt_ofile = NULL; char *spl_ofile = NULL; char *ins_ofile = NULL; if (argc == 2 && (strcmp("--help", argv[1]) == 0 || strcmp("-h", argv[1]) == 0)) { DisplayUsage(argv[0]); exit(UM_OK); } InitOptions(&sets); /* * Parse the command line options */ for (i = 1; i < argc; ++i) { char *p = argv[i], *h; /* * (-) */ if (*p == '-') { switch (*(++p)) { case 'i': interactive = 1; break; case 'a': i++; if (argc <= i) break; startpos = atoi(argv[i]); if (startpos < 0) startpos = 0; break; case 'z': i++; if (argc <= i) break; endpos = atoi(argv[i]); if (endpos <= startpos) endpos = -1; break; case 'o': i++; if (argc <= i) break; ofile = argv[i]; h = strrchr(ofile, '.'); if (!h) break; if (strcasecmp(h, ".it") == 0) ofmt = EXPORT_TYPE_IT; else if (strcasecmp(h, ".wav") == 0) ofmt = EXPORT_TYPE_WAV; else if (strcasecmp(h, ".aiff") == 0 || strcasecmp(h, ".aif") == 0) { obps = 16; ofmt = EXPORT_TYPE_AIFF; } else if (strcasecmp(h, ".pcm") == 0) ofmt = EXPORT_TYPE_PCM | EXPORT_SYS_ENDIAN; else if (strcasecmp(h, ".raw") == 0) ofmt = EXPORT_TYPE_PCM | EXPORT_LTE_ENDIAN; else ofmt = 0; break; case 'f': i++; if (argc <= i) break; h = argv[i]; if (strcmp(h, "it") == 0) ofmt = EXPORT_TYPE_IT; else if (strcmp(h, "wav") == 0) ofmt = EXPORT_TYPE_WAV; else if (strcmp(h, "aiff16") == 0) { ofmt = EXPORT_TYPE_AIFF; obps = 16; } else if (strcmp(h, "aiff24") == 0) { ofmt = EXPORT_TYPE_AIFF; obps = 24; } else if (strcmp(h, "s16se") == 0) ofmt = EXPORT_TYPE_PCM | EXPORT_SYS_ENDIAN; else if (strcmp(h, "s16le") == 0) ofmt = EXPORT_TYPE_PCM | EXPORT_LTE_ENDIAN; else if (strcmp(h, "s16be") == 0) ofmt = EXPORT_TYPE_PCM | EXPORT_BIG_ENDIAN; else fprintf(stderr, "Invalid format -- %s\n", h); break; case 'd': DefaultOptions(&sets); break; case 'w': saveSettings = 1; break; case 'm': ++i; if (argc <= i) break; txt_ofile = argv[i]; break; case 's': ++i; if (argc <= i) break; spl_ofile = argv[i]; break; case 'I': ++i; if (argc <= i) break; ins_ofile = argv[i]; break; case 'v': ++i; if (argc <= i) break; sets.vol = (unsigned int) atol(argv[i]); if (sets.vol > 768) /* XXX - not really sure about the Modplug limit */ sets.vol = 768; if (sets.vol < 1) sets.vol = 1; break; case 'c': ++i; if (argc <= i) break; sets.channels = atoi(argv[i]); if (sets.channels < 1) sets.channels = 1; if (sets.channels > 2) sets.channels = 2; break; case 'r': ++i; if (argc <= i) break; sets.samplerate = atoi(argv[i]); switch (sets.samplerate) { case 11025: case 16000: case 22050: case 24000: case 32000: case 44100: break; default: sets.samplerate = 44100; } break; case 'M': ++i; if (argc <= i) break; h = argv[i]; if (strcmp(h, "NO_INTERPOLATE") == 0 || strcmp(h, "RESAMPLE") == 0) /* deprecated, compat. only */ sets.resampling = 0; else if (strcmp(h, "LINEAR") == 0) sets.resampling = 1; else if (strcmp(h, "SPLINE") == 0) sets.resampling = 2; else if (strcmp(h, "FIR_FILTER") == 0) sets.resampling = 3; break; case 'O': ++i; if (argc <= i) break; AudioDriver = argv[i]; break; case 'q': status = 0; --(sets.verbosity); break; case 'V': PrintBanner(); if (file.name != NULL) UFreeFile(); exit(UM_OK); break; /* NOTREACHED */ /* Disable options */ case 'N': sets.flags &= (~MODPLUG_ENABLE_NOISE_REDUCTION); break; case 'R': sets.flags &= (~MODPLUG_ENABLE_REVERB); break; case 'B': sets.flags &= (~MODPLUG_ENABLE_MEGABASS); break; case 'S': sets.flags &= (~MODPLUG_ENABLE_SURROUND); break; } /* * (+) */ } else if (*p == '+') { switch (*(++p)) { /* Enable options */ case 'N': sets.flags |= MODPLUG_ENABLE_NOISE_REDUCTION; break; case 'R': sets.flags |= MODPLUG_ENABLE_REVERB; break; case 'B': sets.flags |= MODPLUG_ENABLE_MEGABASS; break; case 'S': sets.flags |= MODPLUG_ENABLE_SURROUND; break; } } else { file.name = argv[i]; file.malloc = FALSE; } } if (file.name == NULL) interactive = 1; /* print version banner? */ if (status > 0 && sets.verbosity > 0) { PrintBanner(); } /* save settings? */ if (saveSettings == 1) { SaveOptions(&sets); } /* load a file? */ if (file.name != NULL) { ULoadFile(); } /* export the loaded file? */ if (!interactive && file.name != NULL && ofile != NULL) { int ret; if (ofmt == 0) { error("CAN'T guess format of <%s>\n", ofile); exit(UM_ERR_INVAL); } switch (ofmt) { case EXPORT_TYPE_IT: #ifdef MODPLUG_CAN_SAVE ret = ModPlug_ExportIT(file.mod, ofile); #else error("ModPlug compiled without 'save' support\n", stderr); ret = 0; #endif break; case EXPORT_TYPE_WAV: ret = ((long) WriteWAV(ofile) > 0L); break; case EXPORT_TYPE_AIFF: ret = (int) WriteAIFF(ofile, obps); break; case EXPORT_TYPE_PCM: ret = ((long) WritePCM(ofile, ofmt) > 0L); break; default: ret = 0; } UFreeFile(); if (!ret) { error("export failed!\n"); exit(UM_ERR_INVAL); } else { exit(UM_OK); } } /* save misc. stuff */ if (!interactive && file.name && txt_ofile) SaveSongComments(txt_ofile); if (!interactive && file.name && spl_ofile) { int fd; fd = open(spl_ofile, O_WRONLY | O_TRUNC | O_CREAT, 0644); if (fd < 0) { error("file creation error.\n"); } else { DisplaySamples(fd); close(fd); } } if (!interactive && file.name && ins_ofile) { int fd; fd = open(ins_ofile, O_WRONLY | O_TRUNC | O_CREAT, 0644); if (fd < 0) { error("file creation error.\n"); } else { DisplayInstruments(fd); close(fd); } } if (!interactive && file.name && (ofile || txt_ofile || spl_ofile || ins_ofile)) { UFreeFile(); exit(UM_OK); } /* catch the SIGINT and SIGTERM signals */ signal(SIGINT, CatchSignal); signal(SIGTERM, CatchSignal); if (!interactive) { if (file.name == NULL) { error("file load: %s\n", strerror(errno)); exit(UM_ERR_IO); } if (status > 0) { DrawInfoTable(); CoreSound_StartMonitor(); } else { CoreSound_Start(QuietPlay); } UFreeFile(); exit(UM_OK); } else { /* * Launch the command interpreter */ notice("Launching the command interpreter...\n"); notice("Type 'help' and to get a list of available commands.\n"); notice("Configure the advanced features with the 'setadvanced' command.\n"); CommandInterpreter(); UFreeFile(); exit(UM_OK); } /* NOTREACHED */ return UM_OK; }