home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
amiga
/
midi
/
obrst103.lha
/
OberSuite-1.03
/
SourceCode
/
obget.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-23
|
8KB
|
315 lines
/**************************************************************************
* obget.c: Main program for ObGet.
* Request patch data from the Oberheim synth and store it in
* a disk file.
* A part of OberSuite for the Commodore Amiga.
*
* Author: Daniel Barrett, barrett@cs.umass.edu.
* Version: 1.0.
* Copyright: None! This program is in the Public Domain.
* Please share it with others.
***************************************************************************/
#include "decl.h"
#include "obget.h"
char *version = "$VER: ObGet " VERSION " " VERDATE;
/***************************************************************************
* The main program.
***************************************************************************/
main(argc, argv)
int argc; char *argv[];
{
Enable_Abort = 0; /* Disable ^C aborts. */
strcpy(programName, BaseName(argv[0])); /* Global variable. */
thePrintStyle = VERBOSE; /* Global variable. */
overwriteAll = FALSE; /* Global variable. */
if (argc == 1)
{
ShortUsageMsg();
BegForUsage();
}
else if ((argc == 2) && (!strcmp(argv[1], "?")))
DetailedUsage();
else if (argc < 3)
ErrorMsg(ERROR_NUMARGS);
else if (!HandleOptions(argc, argv))
BegForUsage();
else if (optind != argc-2)
ErrorMsg(ERROR_NUMARGS);
else
ObGet(argv[optind], argv[optind+1]);
exit(0);
}
/*
* Request the given patch (specified by patchString) and store it in the
* given file.
*/
void ObGet(char *patchString, char *filename)
{
PATCHINFO pi;
InitPatchInfo(&pi);
pi.source = PI_SOURCE_MIDI;
if (!SerialSetup())
return;
if (BreakUp(patchString, &pi))
{
if (!overwriteAll && DontOverwriteExistingFile(filename))
;
else if (CtrlcCheck())
ErrorMsg(ERROR_CTRLC);
else if (!TransmitPatchInfo(&pi, filename))
ErrorMsg(ERROR_FAILED);
else
;
}
FreePatchInfo(&pi);
SerialShutdown();
}
/*
* Given a patch string like "s23" or "m95", break it into its components
* ('s' or 'm', and the optional integer patch number).
* Store these components in the PATCHINFO structure.
* Return TRUE on success (else FALSE).
*/
BOOL BreakUp(char *patchString, PATCHINFO *pi)
{
if ((!patchString) || (patchString[0] == '\0'))
{
ErrorMsg(ERROR_PATCHTYPE);
return(FALSE);
}
else if (!FigureOutMode(pi, patchString[0]))
return(FALSE);
else if (!FigureOutPatchNumber(pi, patchString+1))
return(FALSE);
else
return(TRUE);
}
/*
* The modeLetter must be either MODE_SINGLE or MODE_MULTI.
* From the letter, deduce the mode and mode name (string).
* Return TRUE on success (else FALSE).
*/
BOOL FigureOutMode(PATCHINFO *pi, char modeLetter)
{
if (toupper(modeLetter) == LETTER_SINGLE)
{
pi->mode = MODE_SINGLE;
strcpy(pi->modeName, NAME_SINGLE);
}
else if (toupper(modeLetter) == LETTER_MULTI)
{
pi->mode = MODE_MULTI;
strcpy(pi->modeName, NAME_MULTI);
}
else
{
ErrorMsg(ERROR_PATCHTYPE);
return(FALSE);
}
return(TRUE);
}
/*
* The string numString must be either empty (implying that all patches
* should be transferred) or an integer between FIRST_PATCH and LAST_PATCH.
* Anything else is illegal.
* Store the patch number in the patchNum field of the PATCHINFO struct, and
* put a "1" in the numPatches field.
* If the string is empty, store ALL_PATCHES_NUM in the patchNum field,
* and put ALL_PATCHES_NUM in the numPatches field.
*/
BOOL FigureOutPatchNumber(PATCHINFO *pi, char *numString)
{
if (!numString)
{
ErrorMsg(ERROR_PATCHNUM);
return(FALSE);
}
else if (!(*numString))
{
pi->patchNum = ALL_PATCHES_NUM;
pi->numPatches = ALL_PATCHES_NUM;
}
else if (!AllDigits(numString))
{
ErrorMsg(ERROR_PATCHNUM);
return(FALSE);
}
else
{
pi->patchNum = atoi(numString);
if (Between(pi->patchNum, FIRST_PATCH, LAST_PATCH))
pi->numPatches = 1L;
else if (pi->patchNum == ALL_PATCHES_NUM)
pi->numPatches = (long)ALL_PATCHES_NUM;
else
{
ErrorMsg(ERROR_PATCHNUM);
return(FALSE);
}
}
return(TRUE);
}
/***************************************************************************
* Handle the command-line options.
***************************************************************************/
BOOL HandleOptions(int argc, char *argv[])
{
int c;
short printed = 0; /* How many print options were chosen? */
while ((c = getopt(argc, argv, options)) != EOF)
{
switch (c)
{
case OPT_SILENT:
thePrintStyle = SILENT;
printed++;
break;
case OPT_VERBOSE:
thePrintStyle = VERBOSE;
printed++;
break;
case OPT_DEADQUIET:
thePrintStyle = DEADQUIET;
printed++;
break;
case OPT_OVERWRITE:
overwriteAll = TRUE;
break;
default:
return(FALSE);
}
}
if (printed > 1) /* Can't choose 2 print options. */
ErrorMsg(ERROR_TWOPRINTS);
return(printed <= 1);
}
/***************************************************************************
* Transmit the PATCHINFO structure data to MIDI.
***************************************************************************/
BOOL TransmitPatchInfo(PATCHINFO *pi, char *filename)
{
BOOL result = TRUE;
/* This is still a hack, but better than before (slightly).
* We set rightSize to be >= than what we'll need, based on
* the mode. This wastes RAM for Xpander multi-patches, because
* Matrix-12 multi-patch dumps are almost 2 times larger.
* Note that in FigureOutInstrument(), we finally set rightSize
* to its proper value. Take this into consideration when we
* finally fix this hack.
*/
pi->rightSize = (pi->mode == MODE_MULTI)
? MATRIX12_MULTI_SIZE
: LARGEST_OBERHEIM_PATCHSIZE;
if (! (result = AllocPatchInfo(pi)) )
ErrorMsg(ERROR_MALLOC);
else if (! (result = GetPatchFromMidi(pi)) )
ErrorMsg(ERROR_GETFAILED);
else if (! (result = PutPatchToFile(pi, filename)) )
ErrorMsg(ERROR_PUTFAILED_SAVE);
return(result);
}
/***************************************************************************
* Usage information.
***************************************************************************/
void ShortUsageMsg(void)
{
if (!ERR_OUTPUT_ALLOWED)
return;
fprintf(stderr, "Usage: %s [options] PATCH filename\n", programName);
}
void UsageMsg(void)
{
if (!ERR_OUTPUT_ALLOWED)
return;
fprintf(stderr, "%s grabs Xpander/Matrix-12 patch data"
" and saves it in a file.\n",
programName);
ShortUsageMsg();
fprintf(stderr, "\nLegal options are:\n");
fprintf(stderr,
"\t-%c:\tOverwrite existing files without asking permission.\n",
OPT_OVERWRITE);
fprintf(stderr, "\t-%c:\tQuiet output; error messages only.\n",
OPT_SILENT);
fprintf(stderr, "\t-%c:\tNo output; not even error messages.\n",
OPT_DEADQUIET);
fprintf(stderr, "\t-%c:\tLong output. (DEFAULT)\n",
OPT_VERBOSE);
fprintf(stderr, "\n\"PATCH\" may be any of the following forms:\n");
fprintf(stderr, " One single patch:\t");
fprintf(stderr, "The letter %c followed by a number between %d-%d.\n",
LETTER_SINGLE, FIRST_PATCH, LAST_PATCH);
fprintf(stderr, " One multi patch:\t");
fprintf(stderr, "The letter %c followed by a number between %d-%d.\n",
LETTER_MULTI, FIRST_PATCH, LAST_PATCH);
fprintf(stderr,
" All single patches:\tThe letter %c, or %c%d.\n",
LETTER_SINGLE, LETTER_SINGLE, ALL_PATCHES_NUM);
fprintf(stderr,
" All multi patches:\tThe letter %c, or %c%d.\n",
LETTER_MULTI, LETTER_MULTI, ALL_PATCHES_NUM);
fprintf(stderr,
"Upper and lower case are equivalent for '%c' and '%c'.\n",
LETTER_SINGLE, LETTER_MULTI);
fprintf(stderr, "Examples:\n");
fprintf(stderr, "\t%s %c34 MyFile\n", programName, LETTER_SINGLE);
fprintf(stderr, "\t%s %c MyFile\n", programName,
tolower(LETTER_MULTI));
}
char *Version(void)
{
static char v[] = VERSION;
return(v);
}