home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d159
/
miditools
/
sysex-source
/
sex.c
< prev
Wrap
C/C++ Source or Header
|
1988-10-02
|
20KB
|
758 lines
/* (C) Copyright 1988 Jack Deckard Helicon Software */
/* */
/* SYS-EX Filer Program Load and Save SYS-EX dumps */
#include <exec/types.h>
#include <exec/exec.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <stdio.h>
#include <midi/midi.h>
#include <functions.h>
#include <fcntl.h>
#include <libraries/arpbase.h> /* Standard ARP header file */
#include <arpfunc.h> /* Predeclared functions */
extern struct NewWindow NewWindowStructure1;
extern struct Menu Menu1;
extern struct Gadget Gadget1;
extern struct IntuiText IText1;
extern struct MenuItem MenuItem1;
extern struct MenuItem MenuItem2;
extern struct MenuItem MenuItem3;
extern struct MenuItem MenuItem4;
extern struct MenuItem MenuItem5;
extern struct Border Border3;
#define VERSION 33L /* 1.2 Library Version */
#define OTHER 0
#define DX 1
#define FB 2
#define TX81Z 3
#define MATRX6 10
/* Define all global variables, pointers, structures, etc */
struct Window *window;
struct IntuiMessage *message;
void *MidiBase;
UBYTE datasaved[] = " Data Saved ";
UBYTE ioerror[] = "I/O ERROR File not saved ";
UBYTE ioerror2[] = "I/O ERROR Can't Read File";
UBYTE ioerror3[] = "I/O ERROR Can't Open File";
UBYTE ioerror4[] = "I/O ERROR File Not Found ";
UBYTE dataerror[] = "Data Error in SYS-EX File ";
UBYTE loadaborted[] = " Load Aborted ";
UBYTE saveaborted[] = " Save Aborted ";
UBYTE yamtext[] = " File ID is Yamaha ";
UBYTE seqtext[] = "File ID is Seq Circuits ";
UBYTE mootext[] = " File ID is Moog ";
UBYTE obetext[] = " File ID is Oberheim ";
UBYTE emutext[] = " File ID is E-mu ";
UBYTE roltext[] = " File ID is Roland ";
UBYTE kortext[] = " File ID is Korg ";
UBYTE castext[] = " File ID is Casio ";
UBYTE unktext[] = " File ID is Unknown ";
struct IntuiText Mess1 = {
1,0,JAM2, /* front and back text pens, drawmode and fill byte */
36,35, /* XY origin relative to container TopLeft */
NULL, /* font pointer or NULL for default */
datasaved, /* pointer to text */
NULL /* next IntuiText structure */
};
struct IntuiText Mess2 = {
1,0,JAM2, /* front and back text pens, drawmode and fill byte */
60,47, /* XY origin relative to container TopLeft */
NULL, /* font pointer or NULL for default */
(UBYTE *)"Transmit Complete", /* pointer to text */
NULL /* next IntuiText structure */
};
struct Image cleartext = {
0,0,
260,28,0,
NULL,
0,0,
NULL
};
struct MDest *dest=0;
struct MRoute *routei=0;
struct MRouteInfo routeiinfo = { MMF_SYSEX }; /* receive only sys/ex msg's */
struct MSource *source=0;
struct MRoute *routeo=0;
struct MRouteInfo routeoinfo = { -1, -1 }; /* support all msg's */
char def_dir[96] = "MIDI_Tools:sysexfiles";
char def_name[32];
char pathname[128];
BYTE LFR[] = "Load SysEx File";
BYTE SFR[] = "Save SysEx File";
struct FileRequester FR = {
LFR,
def_name,
def_dir,
NULL,
NULL,
NULL,
NULL,
};
/************/
UBYTE fbreq[] = {0xf0,0x43,0x75,0x00,0x20,0x00,0x00,0xf7};
UBYTE dxreq[] = {0xf0,0x43,0x20,0x04,0xf7};
UBYTE m6req[] = {0xf0,0x10,0x06,0x04,0x01,0x00,0xf7};
UBYTE ttxv1[] = "Which Voice Bank (1 - 2)?";
UBYTE ttxv2[] = "Which Voice Bank (1 - 7)?";
UBYTE ttxv3[] = " Which Voice (0 - 99)?";
UBYTE ttxc1[] = "Which Config Bank (1-16)?";
UBYTE ttxs1[] = " Splits Number (0 - 49)?";
struct IntuiText Title = {
1,0,JAM2, /* front and back text pens, drawmode and fill byte */
4,5, /* XY origin relative to container TopLeft */
NULL, /* font pointer or NULL for default */
ttxv1, /* pointer to text */
NULL /* next IntuiText structure */
};
UBYTE undo[4];
UBYTE SNum[4];
struct StringInfo RSfo = {
SNum,
undo,
0,3,0,0,0,0,0,
NULL,
0,
NULL
};
struct Gadget RGadget = {
NULL, /* next gadget */
218,4, /* origin XY of hit box relative to window TopLeft */
24,11, /* hit box width and height */
NULL, /* gadget flags */
RELVERIFY+LONGINT+ENDGADGET, /* activation flags */
STRGADGET+REQGADGET, /* gadget type flags */
(APTR)&Border3, /* gadget border or image to be rendered */
NULL, /* alternate imagery for selection */
NULL, /* first IntuiText structure */
NULL, /* gadget mutual-exclude long word */
(APTR)&RSfo, /* SpecialInfo structure */
1, /* user-definable data */
NULL /* pointer to user-definable data */
};
SHORT BRV1[] = {
0,0,
258,0,
258,60,
0,60,
0,0
};
struct Border BRs1 = {
-2,-1, /* XY origin relative to container TopLeft */
1,0,JAM1, /* front pen, back pen and drawmode */
5, /* number of XY vectors */
BRV1, /* pointer to XY vectors */
NULL /* next border in list */
};
struct Requester Rqstr1 = {
NULL,
4,11,256,58, /* Left, Top, Width, Height */
0,0,
&RGadget, /* first gadget in gadget list */
&BRs1, /* Requester Border */
&Title, /* window title */
NULL, /* Flags */
0,
NULL,
{NULL},
{NULL},
NULL,
{NULL}
};
/************************************************************************/
main()
{
SHORT GetReqNum();
SHORT savefile();
struct FileLock *lock;
struct FileHandle *filehandle; /* Load voice file */
struct FileInfoBlock *fib;
struct Gadget *igad;
UBYTE *midimsg,
*buffer;
LONG len,
gadgid;
ULONG class;
USHORT i,
j,
code,
menunum,
itemnum,
subnum,
checksum;
SHORT keepgoing = 1,
errorcheck = OTHER;
char lastchar;
register LONG error;
register UBYTE id,
sysexch;
error = 1;
sysexch = 15;
/* Open libraries. If error, exit immediatly */
if(!(MidiBase = OpenLibrary (MIDINAME,MIDIVERSION)))
goto clean;
if(!(dest = CreateMDest (NULL,NULL)))
goto clean;
/* create our source node (private) */
if(!(source = CreateMSource (NULL,NULL)))
goto clean;
/* create our routes to MidiIn and MidiOut */
if(!(routei = MRouteDest ("MidiIn", dest, &routeiinfo)))
goto clean;
if(!(routeo = MRouteSource (source,"MidiOut",&routeoinfo)))
goto clean;
/* Initialize window struct, then call OpenWindow. Exit if error */
if((window = (struct Window *)OpenWindow(&NewWindowStructure1)) == NULL)
goto clean;
/* Initialize Menu items, then submit them to Intuition */
SetMenuStrip(window,&Menu1);
/* Wait for message at IDCMP port */
while(keepgoing)
{
/* wait for window message or midi message */
Wait((1L<<dest->DestPort->mp_SigBit)|(1L<<window->UserPort->mp_SigBit));
while((midimsg = GetMidiMsg(dest))!=NULL)
{
len = MidiMsgLength(midimsg);
error = 0;
if(len>5)
{
DrawImage(window->RPort,&cleartext,2L,28L);
if(errorcheck) /* check file for errors if possible */
{
checksum = 0;
switch(errorcheck)
{
case DX:
if(*(midimsg+3)==9)
{
error = 1;
for (i = 6; i < 4102; ++i)
checksum += *(midimsg+i);
checksum = 127 & ((~checksum)+1);
if (checksum == *(midimsg+4102))
error = 0;
}
else if(*(midimsg+3)==1)
{
error = 1;
for (i = 6; i < 161; ++i)
checksum += *(midimsg+i);
checksum = 127 & ((~checksum)+1);
if (checksum == *(midimsg+161))
error = 0;
}
break;
case FB:
if(*(midimsg+5)==0) /* check sum voice data to validate */
{
for(i=0;i<48;i++)
{
buffer = i * 131 + 74;
checksum = 0;
for (j=2;j<128;++j)
checksum += *(midimsg+buffer+j);
if(*(midimsg+buffer+130) != (UBYTE)(127 & ((~checksum)+1)))
{
error = 1;
i = 48;
}
}
}
else if((*(midimsg+5)==1)||(*(midimsg+5)==2)) /* check sum config data to validate */
{
for(i=9;i<169;i++)
checksum += *(midimsg+i);
if(*(midimsg+169) != (UBYTE)(127&((~checksum)+1)))
error = 1;
}
else if(*(midimsg+5)==3) /* check sum all configs */
{
for(i=0;i<16;i++)
{
buffer = i*169+7;
for(j=2;j<169;j++)
checksum += *(midimsg+buffer+j);
if(*(midimsg+buffer+169)!=(UBYTE)(127&((~checksum)+1)))
error = 1;
}
}
break;
case TX81Z:
if(*(midimsg+3)==4)
{
error = 1;
for (i = 6; i < 4102; ++i)
checksum += *(midimsg+i);
checksum = 127 & ((~checksum)+1);
if (checksum == *(midimsg+4102))
error = 0;
}
break;
case MATRX6:
error = 1;
if(*(midimsg+3) == 1)
{
if(*(midimsg+274)==0xf7)
error = 0;
}
else if(*(midimsg+3)==2)
{
for(i=5;i<39;i++);
checksum +=*(midimsg+i);
checksum = 127 & checksum;
if(checksum == *(midimsg+39))
error = 0;
}
else if(*(midimsg+3)==3)
{
for(i=5;i<475;i++);
checksum +=*(midimsg+i);
checksum = 127 & checksum;
if(checksum == *(midimsg+475))
error = 0;
}
break;
}
}
if(error==0)
{
/* save voicedata to disk */
error = savefile(midimsg,len);
FreeMidiMsg(midimsg);
if(error == 1)
{
Mess1.IText = datasaved;
PrintIText(window->RPort,&Mess1,0L,0L);
}
else if(error == 0)
{
Mess1.IText = ioerror;
PrintIText(window->RPort,&Mess1,0L,0L);
}
else if(error == -1)
{
Mess1.IText = saveaborted;
PrintIText(window->RPort,&Mess1,0L,0L);
}
}
else
{
FreeMidiMsg(midimsg);
Mess1.IText = dataerror;
PrintIText(window->RPort,&Mess1,0L,0L);
}
}
else FreeMidiMsg(midimsg);
}
while((message=(struct IntuiMessage *)GetMsg(window->UserPort))!=NULL)
{
class = message->Class;
code = message->Code;
igad = (struct Gadget *) message->IAddress; /* Ptr to a gadget */
ReplyMsg(message);
DrawImage(window->RPort,&cleartext,2L,28L);
switch(class)
{
case CLOSEWINDOW: /* User is ready to quit, so
indicate that execution should terminate with
next iteration of the loop. */
keepgoing = 0;
break;
case GADGETUP:
gadgid = igad->GadgetID; /* Get GadgetID */
switch(gadgid)
{
case 0:
sysexch = (++sysexch) & 15;
sprintf(IText1.IText,"%2d",(SHORT)sysexch + 1);
RefreshGList(&Gadget1,window,NULL,1L);
break;
}
break;
case MENUPICK:
if(code!=MENUNULL)
{
menunum = MENUNUM(code);
itemnum = ITEMNUM(code);
subnum = SUBNUM(code);
switch(menunum)
{
case 0: /* Amiga send SYSEX */
/* Load the file on disk into array voicefile */
FR.fr_Hail = LFR;
if(FileRequest(&FR))
{
/* copy path and file name to pathname */
strcpy(pathname,def_dir);
if(strlen(pathname))
{
lastchar = pathname[strlen(pathname)-1];
if((lastchar!='/')||(lastchar!=':'))
strcpy(pathname+strlen(pathname),"/");
}
strcpy(pathname+strlen(pathname),def_name);
if(lock = (struct FileLock *)Lock(pathname,ACCESS_READ))
{
fib=(struct FileInfoBlock *)AllocMem((LONG)sizeof(struct FileInfoBlock),MEMF_CLEAR);
if(Examine(lock,fib))
{
len = (LONG)fib->fib_Size;
FreeMem(fib,(LONG)sizeof(struct FileInfoBlock));
buffer = (UBYTE *)AllocMem((LONG)len,0L);
filehandle = (struct FileHandle *)Open(pathname,MODE_OLDFILE);
if(filehandle)
{
if(Read(filehandle,buffer,(LONG)len) != -1)
{
Close(filehandle);
UnLock(lock);
if(*(buffer+1)==0x43) /* if yamaha file */
{
if(*(buffer+2)==0x75) /* if FB-01 file, get bank number to load to */
{
if(*(buffer+5)==0x00) /* Voice bank */
{
Title.IText = ttxv1;
*(buffer+6) = GetReqNum();
*(buffer+3) = sysexch;
}
else if((*(buffer+5)==0x01)||(*(buffer+5)==0x02)) /* Config Bank */
{
*(buffer+5) = 0x02;
Title.IText = ttxc1;
*(buffer+6) = GetReqNum();
*(buffer+3) = sysexch;
}
}
else *(buffer+2) = (*(buffer+2) & 0xf0)|sysexch;
}
else if(*(buffer+1)==0x10) /* Oberheim ID? */
{
if(*(buffer+2)==0x06) /* Matrix 6? */
{
if(*(buffer+3)==0x01) /* Single Voice? */
{
*(buffer+4)=(UBYTE)GetReqNum();
}
}
}
id = *(buffer+1);
/* Print file ID */
switch(id)
{
case 0x01:
Mess1.IText = seqtext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
case 0x04:
Mess1.IText = mootext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
case 0x10:
Mess1.IText = obetext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
case 0x18:
Mess1.IText = emutext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
case 0x41:
Mess1.IText = roltext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
case 0x42:
Mess1.IText = kortext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
case 0x43:
Mess1.IText = yamtext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
case 0x44:
Mess1.IText = castext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
Default:
Mess1.IText = unktext;
PrintIText(window->RPort,&Mess1,0L,0L);
break;
}
/* transmit file */
PutMidiMsg(source,buffer);
FreeMem(buffer,len);
PrintIText(window->RPort,&Mess1,0L,0L);
PrintIText(window->RPort,&Mess2,0L,0L);
}
else /* Can't READ file */
{
FreeMem(buffer,len);
Close(filehandle); /* error */
UnLock(lock);
Mess1.IText = ioerror2;
PrintIText(window->RPort,&Mess1,0L,0L);
}
}
else /* Can't Open file */
{
FreeMem(buffer,len);
UnLock(lock);
Mess1.IText = ioerror3;
PrintIText(window->RPort,&Mess1,0L,0L);
}
}
else /* Can't Examine file */
{
FreeMem(fib,(LONG)sizeof(struct FileInfoBlock));
UnLock(lock);
}
}
else /* Can't Lock file */
{
Mess1.IText = ioerror4;
PrintIText(window->RPort,&Mess1,0L,0L);
}
}
else
{
Mess1.IText = loadaborted;
PrintIText(window->RPort,&Mess1,0L,0L);
}
break;
case 1: /* Dump Request */
switch(itemnum)
{
case 0: /* TX */
errorcheck = DX;
MenuItem1.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP+CHECKED; /* DX, TX */
MenuItem2.Flags = MenuItem3.Flags = MenuItem4.Flags = MenuItem5.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP; /* Other */
dxreq[2] = 0x20 | sysexch;
dxreq[3] = 9;
PutMidiMsg(source,dxreq);
break;
break;
case 1: /* FB-01 */
errorcheck = FB;
MenuItem2.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP+CHECKED; /* FB-01 */
MenuItem1.Flags = MenuItem3.Flags = MenuItem4.Flags = MenuItem5.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP; /* Other */
fbreq[3] = sysexch;
switch(subnum)
{
case 0: /* Voice Bank X */
Title.IText = ttxv2;
i = GetReqNum();
fbreq[5] = 0;
fbreq[6] = i;
PutMidiMsg(source,fbreq);
break;
case 1: /* Config Bank X */
Title.IText = ttxc1;
i = GetReqNum();
fbreq[5] = 2;
fbreq[6] = i;
PutMidiMsg(source,fbreq);
break;
}
break;
case 2: /* DX27 DX100 */
errorcheck = DX;
MenuItem1.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP+CHECKED; /* DX, TX */
MenuItem2.Flags = MenuItem3.Flags = MenuItem4.Flags = MenuItem5.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP; /* Other */
dxreq[2] = 0x20 | sysexch;
dxreq[3] = 4;
PutMidiMsg(source,dxreq);
break;
case 3: /* Matrix 6 */
errorcheck = MATRX6;
MenuItem1.Flags = MenuItem2.Flags = MenuItem3.Flags = MenuItem5.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP; /* TX81Z */
MenuItem4.Flags = CHECKIT+ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP+CHECKED; /* Matrix 6 */
switch(subnum)
{
case 0: /* Voice file */
Title.IText = ttxv3;
m6req[4] = 0x01;
m6req[5] = (UBYTE)GetReqNum();
PutMidiMsg(source,m6req);
break;
case 1: /* Splits */
Title.IText = ttxs1;
m6req[4] = 2;
m6req[5] = (UBYTE)GetReqNum();
PutMidiMsg(source,m6req);
break;
case 2:
m6req[4] = 3;
PutMidiMsg(source,m6req);
break;
}
break;
}
break;
case 2: /* Error Checking and identification */
switch(itemnum)
{
case 0: /* DX type */
errorcheck = DX;
break;
case 1: /* FB type */
errorcheck = FB;
break;
case 2: /* TX81Z */
errorcheck = TX81Z;
break;
case 3: /* Oberheim Matrix 6 */
errorcheck = MATRX6;
break;
case 4: /* None */
errorcheck = OTHER;
break;
}
break;
} /* end of switch(menunum) */
} /* end of if(menunum not null) */
break;
} /* end of switch (class) */
} /* end of while(intuimessage)*/
} /* end while (keepgoing) */
/* Time to quit, so clean up and exit. */
clean:
if(window)
{
ClearMenuStrip(window);
CloseWindow(window);
}
if(routei)
DeleteMRoute(routei);
if(routeo)
DeleteMRoute(routeo);
if(dest)
DeleteMDest(dest);
if(source)
DeleteMSource(source);
if(MidiBase)
CloseLibrary(MidiBase);
exit();
} /* end of main */
/************************************************************************/
/* Create a file on disk using buffered I/O. Open the disk file, */
/* write the array to it, and close the file. */
SHORT savefile(buffer,len)
UBYTE *buffer; /* pointer to voice file */
long len;
{
struct FileHandle *filehandle; /* Save voice file */
char lastchar;
FR.fr_Hail = SFR;
if(FileRequest(&FR))
{
strcpy(pathname,def_dir);
if(strlen(pathname))
{
lastchar = pathname[strlen(pathname)-1];
if((lastchar!='/')||(lastchar!=':'))
strcpy(pathname+strlen(pathname),"/");
}
strcpy(pathname+strlen(pathname),def_name);
if(!(filehandle = Open(&pathname,MODE_NEWFILE)))
return(0);
if(Write(filehandle,buffer,len) == -1L)
{
Close(filehandle); /* error */
return(0);
}
Close(filehandle);
return(1);
}
else
return(-1); /* aborted save */
}
SHORT GetReqNum()
{
SHORT returncode;
LONG class;
RGadget.LongInt = 0;
RSfo.BufferPos = 0;
RSfo.DispPos = 0;
for(returncode=0;returncode<4;returncode++)
SNum[returncode] = 0;
Request(&Rqstr1,window);
for(class = 0;class != REQSET;)
{
Wait(1L<<window->UserPort->mp_SigBit);
message=(struct IntuiMessage *)GetMsg(window->UserPort);
class = message->Class;
ReplyMsg(message);
}
ActivateGadget(&RGadget,window,&Rqstr1);
for(;class!=GADGETUP;)
{
Wait(1L<<window->UserPort->mp_SigBit);
message=(struct IntuiMessage *)GetMsg(window->UserPort);
class = message->Class;
ReplyMsg(message);
}
returncode = RSfo.LongInt;
return(returncode);
}