home *** CD-ROM | disk | FTP | other *** search
AMOS Source Code | 1978-10-10 | 10.0 KB | 412 lines |
- '---------------------------------------------------------------------------
- ' Sonix (IFF .SMUS) Music file converter
- '
- ' By Francois Lionet
- ' (c) Mandarin / Jawx 1990
- '---------------------------------------------------------------------------
- ' This program converts IFF SMUS files to AMOS music bank format.
- '
- ' Because the AMOS music system is closer to the SoundTracker format, this
- ' converter can only use IFF samples with just ONE sample for all octaves.
- '
- ' If your music contains multiple octave samples or the converter fails to
- ' locate the required sample from the disc, a file selector will open and
- ' you will be requested to allocate a sample. It is thus important to create
- ' some IFF samples before you use this program.
- '
- ' You can also load a fake instrument (something small like a TOM for example)
- ' into each instrument used by the song. This will create a fake bank with the
- ' melody converted. You will then be able to edit it with the AMOS Music
- ' editor (to be released soon!)...
- ' *** NTSC users see below!!! ***
- '---------------------------------------------------------------------------
- '
- Set Buffer 16
- '
- Dim CHK$(8),INS$(32),V$(4),APAT(4),NTE(128+12),SAM_RATE(128),DELAY(16),DELTA#(4),FLAG(4)
- Global CHK$(),PCHUNK,LCHUNK
- Global INS$(),V$(),MS_TEMPO,MS_VOL,NTRACK,ADPOKE,VCE,MXINS,NAME$,SAM_RATE()
- '
- ' I use the ram disk as temporary storage...
- F_INST$="RAM:SMus_Conv.Temp"
- '
- ' Change the next line if you have a NTSC system
- ' PAL clock
- CLOCK#=1.0/3546895
- '
- ' NTSC clock
- ' clock#=1.0/3579545
- '
- Restore TNOTE
- For N=12 To 108
- Read NTE(N)
- Next
- Restore TDELAY
- For N=0 To 15
- Read DELAY(N)
- Next
- Restore TDELTA
- For N=0 To 3
- Read DELTA#(N)
- Next
- '
- I_END=$8000
- I_SLUP=$8100
- I_SLDOWN=$8200
- I_SVOL=$8300
- I_REP=$8500
- I_LEDM=$8600
- I_LEDA=$8700
- I_TEMPO=$8800
- I_INST=$8900
- SONGDATA=4
- '
- AGAIN:
- On Error Goto D_ERROR
- Screen Open 0,640,32,2,Hires : Curs Off
- Palette 0,$FFF
- '
- '---> Load and store SMUS file
- F$=Fsel$("*.SMUS","","Please choose SONG to convert")
- If F$="" : ABORT : End If
- VCE=0 : MXINS=0
- CHK$(0)="SMUS" : CHK$(1)="SHDR" : CHK$(2)="INS1" : CHK$(3)="TRAK"
- RD_IFF[F$,0]
- If Param=1 : Bell : Print "This file is not an IFF music file!" : Print "Press a key to restart..." : Wait Key : Goto AGAIN : End If
- If Param : Error 32 : End If
- '
- '---> Compute instrument list
- Open Out 2,F_INST$
- Print #2,Chr$(0)+Chr$(0)+Chr$(0)+Chr$(0);
- '
- Reserve As Work 10,32*MXINS+34
- Doke Start(10),MXINS
- '
- For NI=0 To MXINS
- If INS$(NI)<>""
- CHK$(0)="8SVX" : CHK$(1)="VHDR" : CHK$(2)="BODY"
- Print
- Print "* Processing "+INS$(NI)
- NAME$=INS$(NI)
- I$=PATH_INS$+INS$(NI)
- FLAG=-1
- If Exist(I$)
- RD_IFF[I$,NI]
- FLAG=Param
- Else
- If Exist(I$+".Instr")
- RD_IFF[I$+".Instr",NI]
- FLAG=Param
- Else
- If Exist(I$+"(IFF).Instr")
- RD_IFF[I$+"(IFF).Instr",NI]
- FLAG=Param
- End If
- End If
- End If
- Repeat
- If FLAG<0 : Print " I can't find "+I$+" !" : End If
- If FLAG=1 : Print " This instrument is not an IFF SINGLE sample sound!" : End If
- If FLAG>1 : Bell : Print : Print " Disk error!" : End If
- If FLAG
- Print " Please click and use the file selector to choose another instrument..."
- WT_CLIC
- I$=Fsel$("**","","Choose a new instrument for",INS$(NI))
- If I$="" : ABORT : End If
- EXTRACT_NAME[I$]
- RD_IFF[I$,NI] : FLAG=Param
- End If
- Until FLAG=0
- End If
- Next
- Close 2
- '
- '---> Open output
- F$=Fsel$("*.Abk","","Please enter output bank name")
- If F$="" : ABORT : End If
- On Error Goto D_ERROR
- Open Out 2,F$
- Print #2,"AmBk........Music ";
- Print #2,"................";
- '
- ' Copy instruments
- Print "* Saving instruments";
- DTA_COPY[Start(10),Length(10)]
- Open In 1,F_INST$
- FILE_COPY[Lof(1)]
- Print
- LINST=Lof(1)+Length(10)
- Close 1
- Erase 10 : Kill F_INST$
- '
- ' Compute pattern
- L=0
- For V=0 To 3
- L=L+Len(V$(V))*3
- Next
- Reserve As Work 10,L
- NPAT=4 : AOFF=Start(10) : APAT=AOFF+2+NPAT*2
- Doke AOFF,NPAT
- For V=0 To 3
- Print "* Processing track";V
- Doke AOFF+2+V*2,APAT-AOFF
- FLAG(V)=0 : CU_I=0 : KY=0
- If V$(V)<>""
- Doke APAT,I_INST : Add APAT,2
- For P=0 To Len(V$(V))-2 Step 2
- P1=Peek(Varptr(V$(V))+P) : P2=Peek(Varptr(V$(V))+P+1)
- If P1<=128
- Inc FLAG(V)
- F=NTE(P1+KY) : PER=0
- If F
- PER#=1.0/(SAM_RATE(CU_I)*F*CLOCK#)
- PER=PER#+0.5
- If PER<124 : PER=0 : End If
- End If
- D=(P2 and %110000)/%10000
- D#=DELAY(P2 and %1111)*DELTA#(D)
- DEL=D# : Add DELTA#,DEL-D#
- If DELTA#<>0.0
- If Int(DELTA#)=DELTA#
- Add DEL,DELTA#
- DELTA#=0.0
- End If
- End If
- Poke APAT,P1-1 : Poke APAT+1,DEL : Doke APAT+2,PER
- Add APAT,4
- Else
- If P1=$83
- KY=P2
- End If
- If P1=$81
- CU_I=P2 : Doke APAT,I_INST+P2 : Add APAT,2
- End If
- If P1=$84
- Doke APAT,I_SVOL+(P2*64)/256 : Add APAT,2
- End If
- If P1=$88
- Doke APAT,I_STEMPO+(P2*100)/188 : Add APAT,2
- End If
- End If
- Next
- End If
- Doke APAT,I_END : Add APAT,2
- V$(V)=""
- Next
- LPATTERNS=APAT-AOFF
- '
- ' Copy songs
- Reserve As Work 11,256
- AMU=Start(11)
- Doke AMU,1 : Add AMU,2
- Loke AMU,6 : Add AMU,4
- LLIST=1 : LPAT=(LLIST+1)*2 : APAT=8+SONGDATA+16
- For N=0 To 3
- APAT(N)=APAT+AMU
- Doke AMU+N*2,APAT
- Add APAT,LPAT
- Next
- Add AMU,8 : Doke AMU,MS_TEMPO : Add AMU,SONGDATA
- For A=0 To 15 : Poke AMU+A,Peek(Varptr(F$)+A) : Next : Add AMU,16
- P=0
- For V=0 To 3
- If FLAG(V)
- Doke APAT(V),0 : Doke APAT(V)+2,-2
- Else
- Doke APAT(V),-1
- End If
- AMU=APAT(V)+4
- Next
- LSONG=AMU-Start(11)
- '
- ' Output SONG and PATTERNS
- Print : Print "* Saving song";
- DTA_COPY[Start(11),LSONG]
- Print : Print "* Saving patterns";
- DTA_COPY[Start(10),LPATTERNS]
- '
- ' Music bank header
- Pof(2)=4
- OUT_NB[2,3]
- OUT_NB[2,0]
- TL=8+16+LINST+LSONG+LPATTERNS : OUT_NB[4,$80000000+TL]
- Pof(2)=20
- OUT_NB[4,16]
- OUT_NB[4,16+LINST]
- OUT_NB[4,16+LINST+LSONG]
- OUT_NB[4,0]
- Close
- '
- ' Finished
- Clw
- Print "* Conversion finished!"
- Print " Press any key to restart..."
- Erase 10 : Erase 11
- Load F$ : Music 1 : Tempo 40
- Wait Key
- Erase 3
- Goto AGAIN
- '
- ' Disk error
- D_ERROR:
- Close
- Clw : Boom : Print "Disk error!"
- Print : Print "Press a key to restart..."
- Wait Key
- Resume AGAIN
- Procedure ABORT
- Close
- Screen Close 0
- Edit
- End Proc
- Procedure RD_IFF[N$,PAR]
- On Error Goto RD_ERR2
- Open In 1,N$
- On Error Goto RD_ERR1
- LFILE=Lof(1)
- I$=Input$(1,4) : If I$<>"FORM" : Error 21 : End If
- Pof(1)=Pof(1)+4
- I$=Input$(1,4) : If I$<>CHK$(0) : Error 21 : End If
- LCHUNK=0
- PCHUNK=Pof(1)
- Do
- On Error Goto RD_ERR1
- Exit If PCHUNK>=LFILE
- Pof(1)=PCHUNK
- H$=Input$(1,4)
- A$=Input$(1,4) : LCHUNK=(Leek(Varptr(A$))+1) and $FFFFFFFE
- For NCHK=1 To 8
- Exit If CHK$(NCHK)=""
- If H$=CHK$(NCHK)
- On Error Goto RD_ERR0
- Gosub "LD_"+CHK$(NCHK)
- End If
- Next
- Add PCHUNK,LCHUNK+8
- Loop
- For N=0 To 8
- CHK$(N)=""
- Next
- Error 20
- ' IFF - SMUS
- LD_SHDR:
- I$=Input$(1,4)
- MS_TEMPO=40
- Return
- '
- LD_INS1:
- I$=Input$(1,LCHUNK)
- N=Peek(Varptr(I$))
- X=0
- Do
- P=Peek(Varptr(I$)+X+4)
- Exit If P=0
- INS$(N)=INS$(N)+Chr$(P)
- Inc X
- Loop
- MXINS=Max(N,MXINS)
- Return
- '
- LD_TRAK:
- V$(VCE)=Input$(1,LCHUNK)
- Inc VCE
- Return
- ' IFF-8VSX
- LD_VHDR:
- Print " Loading IFF instrument";
- I$=Input$(1,LCHUNK)
- If Peek(Varptr(I$)+14)<>1 : Error 21 : End If
- If Peek(Varptr(I$)+15) : Error 21 : End If
- AD=Start(10)+PAR*32+2
- Loke AD,Length(10)+Pof(2)
- Doke AD+8,Leek(Varptr(I$))/2
- Loke AD+4,Length(10) : Doke AD+10,2
- L2=Leek(Varptr(I$)+4)
- If L2 : Loke AD+4,Length(10)+Pof(2)+L1 : Doke AD+10,L2/2 : End If
- Doke AD+12,Leek(Varptr(I$)+16)/$400
- SAM_RATE(PAR)=Leek(Varptr(I$)+8) : Doke AD+14,SAM_RATE(PAR)
- Doke AD+16+14,Deek(Varptr(I$)+12)
- Add AD,16
- For N=1 To 14
- If N<=Len(NAME$) : Poke AD+N-1,Asc(Mid$(NAME$,N,1)) : End If
- Next
- Return
- '
- LD_BODY:
- FILE_COPY[LCHUNK] : FILE_EVEN
- Print
- Return
- '
- RD_ERR0: Pop
- RD_ERR1: Close 1
- RD_ERR2: E=Errn : Resume RD_END
- RD_END:
- End Proc[E-22]
- Procedure WT_CLIC
- Repeat : Until Mouse Key
- While Mouse Key : Wend
- End Proc
- Procedure EXTRACT_NAME[N$]
- For N=Len(N$) To 1 Step -1
- A$=Mid$(N$,N,1)
- Exit If(A$=":") or(A$="/")
- Next
- NAME$=Mid$(N$,N+1)
- End Proc
- Procedure FILE_COPY[LONG]
- LS=512
- Repeat
- NL=LONG/LS
- If NL
- For N=1 To NL
- A$=Input$(1,LS)
- Print #2,A$;
- Print ".";
- Next
- Add LONG,-LS*NL
- End If
- LS=LS/2
- Until LONG=0
- End Proc
- Procedure FILE_EVEN
- L=Lof(2)
- If Btst(0,L)
- Print #2,Chr$(0);
- End If
- End Proc
- Procedure DTA_COPY[AD,LONG]
- LS=512
- Repeat
- NL=LONG/LS
- If NL
- A$=Space$(LS)
- For N=1 To NL
- Copy AD,AD+LS To Varptr(A$)
- Add AD,LS
- Print #2,A$;
- Print ".";
- Next
- Add LONG,-LS*NL
- End If
- LS=LS/2
- Until LONG=0
- End Proc
- Procedure OUT_NB[BITS,NB]
- For N=4-BITS To 3
- A$=Chr$(Peek(Varptr(NB)+N)) : Print #2,A$;
- Next
- End Proc
- TNOTE:
- Data 33,35,37,39,41,44,46,49,52
- Data 55,58,62,65,69,73,78,82,87,92,98,104
- Data 110,117,123,131,139,147,156,165,175,185,196,208
- Data 220,233,247,262,277,294,311,330,349,370,392,415
- Data 440,466,494,523,554,587,622,659,698,740,784,830
- Data 880,932,988,1046,1109,1175,1245,1319,1397,1480,1568,1661
- Data 1760,1865,1986,2093,2217,2349,2489,2637,2794,2960,3136,3322
- Data 3520,3729,3952,4186,4435,4699,4978,5274,5588,5920,6272,6645
- Data 7040,7459,7902,8372
- TDELAY:
- Data 32,16,8,4,2,1,1,1,48,24,12,6,3,1,1,1
- TDELTA:
- Data 1.0,2.0/3.0,4.0/5.0,6.0/7.0