home *** CD-ROM | disk | FTP | other *** search
-
- /***************************************************************\
- * GPlayer V 0.0 Sonix/DMCS Score ummmm...player *
- * *
- * By Greg Cunningham, *
- * Nomad Development *
- * *
- * SMUS/DMCS/8SVX IFF form reader *
- * And other stuff too. *
- * *
- * Notes: I have no idea what all this does!!! *
- * But it may contain usefull info for a music player. *
- * Questions: *
- * What's the Sonix SNX1: chunk? *
- * How do you figure out Sonix instrument forms? *
- * And how about TRAK/UBR1 notes? *
- \***************************************************************/
-
- #include <Exec/Types.h>
- #include <Exec/Memory.h>
- #include <Proto/Dos.h>
- #include <Proto/Exec.h>
-
- #define MAKE_ID(a,b,c,d)\
- (((long)(a)<<24)+((long)(b)<<16)+((long)(c)<<8)+(long)(d))
-
- #define FORM MAKE_ID('F','O','R','M')
- #define SMUS MAKE_ID('S','M','U','S')
- #define SHDR MAKE_ID('S','H','D','R')
- #define NAME MAKE_ID('N','A','M','E')
- #define AUTH MAKE_ID('A','U','T','H')
- #define Copy MAKE_ID('S','N','X','1')
- #define SNX1 MAKE_ID('S','N','X','1')
- #define ANNO MAKE_ID('A','N','N','O')
- #define INS1 MAKE_ID('I','N','S','1')
- #define TRAK MAKE_ID('T','R','A','K')
- #define Copyrt MAKE_ID('(','c',')',' ')
- /*_Sonix SampledSound_________________*/
- #define Samp MAKE_ID('S','a','m','p')
- /*__________8SVX______________________*/
- #define BODY MAKE_ID('B','O','D','Y')
- #define ESVX MAKE_ID('8','S','V','X')
- #define VHDR MAKE_ID('V','H','D','R')
- #define ATAK MAKE_ID('A','T','A','K')
- #define RLSE MAKE_ID('R','L','S','E')
- /*__________DMCS______________________*/
- #define DMCS MAKE_ID('D','M','C','S')
- #define USC1 MAKE_ID('U','S','C','1')
- #define UBR1 MAKE_ID('U','B','R','1')
- #define UVLT MAKE_ID('U','V','L','T')
- #define UIID MAKE_ID('U','I','I','D')
-
- /*_____Score_______*/
- #define INS1_Name 0
- #define INS1_MIDI 1
-
- #define SID_FirstNote 0
- #define SID_LastNote 127
- #define SID_Rest 128
- #define SID_Instrument 129
- #define SID_TimeSig 130
- #define SID_KeySig 131
- #define SID_Dynamic 132
- #define SID_MIDI_Chnl 133
- #define SID_MIDI_Preset 134
- #define SID_Clef 135
- #define SID_Tempo 136
- #define SID_Mark 255
-
- #define noteChord (1<<7)
- #define noteTieOut (1<<6)
- #define noteNShift 4
- #define noteN3 (1<<noteNShift)
- #define noteN5 (2<<noteNShift)
- #define noteN7 (3<<noteNShift)
- #define noteNMask noteN7
- #define noteDot (1<<3)
- #define noteDShift 0
- #define noteD1 (0<<noteDShift)
- #define noteD2 (1<<noteDShift)
- #define noteD4 (2<<noteDShift)
- #define noteD8 (3<<noteDShift)
- #define noteD16 (4<<noteDShift)
- #define noteD32 (5<<noteDShift)
- #define noteD64 (6<<noteDShift)
- #define noteD128 (7<<noteDShift)
- #define noteDMask noteD128
- #define noteDurMask 0x3F
- #define IsChord(snote) (((UWORD)snote)¬eChord)
- #define IsTied(snote) (((UWORD)snote)¬eTieOut)
- #define NTuplet(snote) ((((UWORD)snote)¬eNMask)>>noteNShift)
- #define IsDot(snote) (((UWORD)snote)¬eDot)
- #define Division(snote) ((((UWORD)snote)¬eDMask)>>noteDShift)
-
- #define timeNMask 0xF8
- #define timeNShift 3
- #define timeDMask 7
-
- #define TimeNSig(sTime) ((((UWORD)sTime)&timeNMask)>>timeNShift)
- #define TimeDSig(sTime) (((UWORD)sTime)&timeDMask)
-
- typedef struct{UWORD tempo; UBYTE volume,ctTrack; }SScoreHeader;
- typedef struct{UBYTE iRegister,type,data1,data2,name[60]; }RefInstrument;
- typedef struct{UBYTE sID,data; }SEvent;
- typedef struct{
- unsigned tone :8,
- chord :1,
- tieOut :1,
- nTuplet :2,
- dot :1,
- division :3;
- }SNote;
-
- typedef struct{
- unsigned type :8,
- timeNSig :5,
- timeDSig :3;
- }STimeSig;
-
-
- /*_____8SVX________*/
- #define Unity 0x10000L
- #define sCmpNone 0
- #define sCmpFibDelta 1
-
- typedef struct{
- ULONG oneShotHiSamples,repeatHiSamples,samplesPerHiCycle;
- UWORD samplesPerSec;
- UBYTE ctOctave,sCompression;
- LONG volume;
- }Voice8Header;
-
- typedef struct{
- UWORD duration;
- LONG dest;
- }EGPoint;
-
- /*_____IFF Chunk___*/
- union typekludge{char type_str[4]; long type_long;};
- struct ChunkHeader{union typekludge chunktype; long chunksize;};
-
- struct FileHandle *File=0;
- SScoreHeader shdr;
- RefInstrument Inst[20];
- Voice8Header vhdr;
- struct ChunkHeader ch;
- UBYTE insnum=0,traknum=0,Buf[80],InstDir[30],voicenum=0,dmcs=0;
- BYTE *Trak[4];
- LONG TrakSize[4];
-
- void skipchunk(size)long size; {Seek(File,size,0);}
-
-
- readform(formsize)
- long formsize;
- {
- long subtype;
- UBYTE is_8SVX=0;
-
- if(!getsubtype(&subtype)) return(0);
- formsize -=sizeof(subtype);
- if(subtype==DMCS){ printf("FORM: DMCS\n"); dmcs=1;}
- else if(subtype==SMUS) printf("FORM: SMUS\n");
- else if(subtype==ESVX){printf("FORM: 8SVX\n"); is_8SVX=1;}
- else return(0);
- while(formsize>0){
- if(!getchunkheader(&ch)) return(0);
- formsize -=sizeof(ch);
- switch(ch.chunktype.type_long){
- case SHDR:
- Read(File,&shdr,ch.chunksize);
- printf("SHDR: Tempo=%d Volume=%d Tracks=%d\n",
- shdr.tempo,shdr.volume,shdr.ctTrack);
- break;
- case VHDR:
- Read(File,&vhdr,ch.chunksize);
- printf("VHDR: OneShotHiSamples=%ld RepeatHiSamples=%ld\n",
- vhdr.oneShotHiSamples,vhdr.repeatHiSamples);
- printf("SamplesPerHiCycle=%ld SamplesPerSec=%ld Octave=%d\n",
- vhdr.samplesPerHiCycle,vhdr.samplesPerSec,vhdr.ctOctave);
- voicenum++; break;
- case NAME:
- Read(File,Buf,ch.chunksize);
- Buf[ch.chunksize]=0;
- printf("NAME: %s\n",Buf);
- break;
- case INS1:
- Read(File,&Inst[insnum],ch.chunksize);
- Inst[insnum].name[ch.chunksize-4]=0;
- printf("INS1: Instrument[%d]=%s\n",insnum+1,Inst[insnum].name);
- insnum++; break;
- case TRAK:/* Sonix notes */
- TrakSize[traknum]=ch.chunksize;
- Trak[traknum]=(BYTE *)AllocMem(TrakSize[traknum],MEMF_CHIP);
- Read(File,Trak[traknum],ch.chunksize);
- printf("TRAK: Track[%d] Bytes=%ld\n",traknum+1,ch.chunksize);
- traknum++; break;
- case SNX1:
- skipchunk(ch.chunksize); /* Important for Sonix */
- printf("SNX1: Bytes=%ld\n",ch.chunksize);
- break;
- case AUTH:
- Read(File,Buf,ch.chunksize);
- Buf[ch.chunksize]=0;
- printf("AUTH: %s\n",Buf);
- break;
- case ANNO:
- skipchunk(ch.chunksize);
- printf("ANNO: Beats me!\n");
- break;
- case ATAK:
- skipchunk(ch.chunksize);
- printf("ATAK: Bytes=%ld\n",ch.chunksize);
- break;
- case RLSE:
- skipchunk(ch.chunksize);
- printf("RLSE: Bytes=%ld\n",ch.chunksize);
- break;
- case BODY:
- skipchunk(ch.chunksize);
- printf("BODY: Bytes=%ld\n",ch.chunksize);
- /**
- if(vhdr[vh_num]->sCompression){
- temp=(BYTE *)AllocMem(ch.chunksize<<1,MEMF_CHIP);
- DUnpack(buf,ch.chunksize,temp);
- FreeMem(buf,ch.chunksize);
- buf=temp;
- }
- **/
- break;
-
- case Copyrt:
- Read(File,Buf,ch.chunksize);
- Buf[ch.chunksize]=0;
- printf("%s\n",Buf);
- break;
- case USC1:
- skipchunk(ch.chunksize);
- printf("USC1: Bytes=%ld\n",ch.chunksize);
- break;
- case UBR1:/* DMCS notes & text */
- skipchunk(ch.chunksize);
- printf("UBR1: Bytes=%ld\n",ch.chunksize);
- break;
- case UVLT:
- skipchunk(ch.chunksize);
- printf("ULVT: Bytes=%ld\n",ch.chunksize);
- break;
- case UIID:
- Read(File,&Inst[insnum].name,ch.chunksize);
- Inst[insnum].name[ch.chunksize]=0;
- printf("UIID: Instrument[%d]=%s\n",insnum+1,Inst[insnum].name);
- insnum++; break;
-
- default: skipchunk(ch.chunksize); break;
- }
- formsize -=ch.chunksize;
- if(ch.chunksize&1){formsize--; Seek(File,1,0);}
- }
- return(1);
- }
-
- getchunkheader(header) struct ChunkHeader *header;
- {return(Read(File,header,sizeof(*header)));}
-
- getsubtype(type) long *type;
- {return(Read(File,type,sizeof(*type)));}
-
- void FreeTraks()
- {
- int i;
-
- for(i=0;i<4;i++)
- if(Trak[i]) FreeMem(Trak[i],TrakSize[i]);
- }
-
- void LoadInst()
- {
- int i;
-
- for(i=0;i<insnum;i++){
- if(!strcmp(Inst[i].name,"First Voice")) goto SKIP;
- if(dmcs) sprintf(Buf,"%s%s",InstDir,Inst[i].name);
- else sprintf(Buf,"%s%s.instr",InstDir,Inst[i].name);
- printf("%-36s",Buf);
- if(!(File=Open(Buf,1005))){printf("\n\nFile not found: %s\n"); return;}
- getchunkheader(&ch);
- if(ch.chunktype.type_long==FORM) readform(ch.chunksize);
- else if(ch.chunktype.type_long==Samp){
- printf("SampledSound\n"); Close(File);
- printf("%s%s.ss",InstDir,Inst[i].name);
- if(!(File=Open(Buf,1005))){printf("\n\nFile not found: %s\n",Buf); return;}
- printf("\n");
- }else printf("Sonix Editor Instrument\n");
- if(File) Close(File);
- SKIP:
- }
- }
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- printf("\nGPlayer V 0.0 by Greg Cunningham.\n");
- printf("SMUS Score Player.\n\n");
- if(argc<3){printf("Usage: GPlayer Score Instruments/\n"); goto Q;}
-
- if(!(File=Open(argv[1],1005))){
- sprintf(Buf,"%s.smus",argv[1]);
- if(!(File=Open(Buf,1005)))
- {printf("File not found: %s\n",Buf); goto Q;}
- }
- if(!getchunkheader(&ch)) goto Q;
- if(ch.chunktype.type_long!=FORM) goto Q;
- if(!readform(ch.chunksize)) goto Q;
- if(File) Close(File);
-
- strcpy(InstDir,argv[2]); LoadInst(); File=0;
-
- FreeTraks();
- printf("\n\n Sorry, can't get audio channels!\n"); /* Fake'em out */
- Q:
- if(File) Close(File);
- exit(0); return(0);
- }
-
-
-
- /* Unpack Fibonacci-delta encoded data from n byte source
- * buffer into 2*n byte dest buffer, given initial data
- * value x. It returns the lats data value x so you can
- * call it several times to incrementally decompress the data.
- */
-
- BYTE codeToDelta[16]={-34,-21,-13,-8,-5,-3,-2,-1,0,1,2,3,5,8,13,21};
-
- BYTE D1Unpack(source,n,dest,x) BYTE source[],dest[]; LONG n; BYTE x;
- {
- BYTE d;
- LONG i,lim;
-
- lim=n<<1;
- for(i=0;i<lim;++i){
- /* Decode a data nibble, high nibble then low nibble */
- d=source[i>>1]; /* get a pair of nibbles */
- if(i&1) /* select low or high nibble */
- d&=0xf; /* mask to get the low nibble */
- else d>>=4; /* shift to get the high nibble */
- x +=codeToDelta[d]; /* add in the decoded delta */
- dest[i]=x; /* store a 1 byte sample */
- }
- return(x);
- }
-
- /* Unpack Fibonacci-delta encoded data from n byte
- * source buffer into 2*(n-2) byte dest buffer.
- * Source buffer has a pad byte, an 8-bit initial
- * value, followed by n-2 bytes comprising 2*(n-2)
- * 4-bit encoded samples.
- */
-
- void DUnpack(source,n,dest) BYTE source[],dest[]; LONG n;
- {D1Unpack(source+2,n-2,dest,source[1]);}
-
-
-