home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 42 / af042b.adf / Extras.lha / Sonix.AMOS / Sonix.amosSourceCode
AMOS Source Code  |  1992-02-21  |  10KB  |  395 lines

  1. '               Sonix (IFF .SMUS) Music file converter   
  2. '
  3. '                        By Francois Lionet  
  4. '                    (c) Mandarin / Jawx 1990  
  5. '
  6. ' This program converts IFF SMUS files to AMOS music bank format.  
  7. '
  8. ' Because the AMOS music system is closer to the SoundTracker format, this 
  9. ' converter can only use IFF samples with just ONE sample for all octaves. 
  10. '
  11. ' If your music contains multiple octave samples or the converter fails to 
  12. ' locate the required sample from the disc, a file selector will open and  
  13. ' you will be requested to allocate a sample. It is thus important to create 
  14. ' some IFF samples before you use this program.
  15. '
  16. ' You can also load a fake instrument (something small like a TOM for example) 
  17. ' into each instrument used by the song. This will create a fake bank with the 
  18. ' melody converted. You will then be able to edit it with the AMOS Music 
  19. ' editor (to be released soon!)... 
  20. '                  *** NTSC users see below!!! *** 
  21. '
  22. Set Buffer 16
  23. '
  24. Dim CHK$(8),INS$(32),V$(4),APAT(4),NTE(128+12),SAM_RATE(128),DELAY(16),DELTA#(4),FLAG(4)
  25. Global CHK$(),PCHUNK,LCHUNK
  26. Global INS$(),V$(),MS_TEMPO,MS_VOL,NTRACK,ADPOKE,VCE,MXINS,NAME$,SAM_RATE()
  27. '
  28. ' I use the ram disk as temporary storage... 
  29. F_INST$="RAM:SMus_Conv.Temp"
  30. '
  31. ' Change the next line if you have a NTSC system 
  32. ' PAL clock
  33. CLOCK#=1.0/3546895
  34. '
  35. ' NTSC clock 
  36. ' clock#=1.0/3579545 
  37. '
  38. Restore TNOTE
  39. For N=12 To 108
  40.    Read NTE(N)
  41. Next 
  42. Restore TDELAY
  43. For N=0 To 15
  44.    Read DELAY(N)
  45. Next 
  46. Restore TDELTA
  47. For N=0 To 3
  48.    Read DELTA#(N)
  49. Next 
  50. '
  51. I_END=$8000 : I_SLUP=$8100 : I_SLDOWN=$8200 : I_SVOL=$8300 : I_REP=$8500
  52. I_LEDM=$8600 : I_LEDA=$8700 : I_TEMPO=$8800 : I_INST=$8900 : SONGDATA=4
  53. '
  54. AGAIN:
  55. On Error Goto D_ERROR
  56. Screen Open 0,640,32,2,Hires : Curs Off 
  57. Palette 0,$FFF
  58. '---> Load and store SMUS file   
  59. F$=Fsel$("*.SMUS","","Please choose SONG to convert")
  60. If F$="" : ABORT : End If 
  61. VCE=0 : MXINS=0
  62. CHK$(0)="SMUS" : CHK$(1)="SHDR" : CHK$(2)="INS1" : CHK$(3)="TRAK"
  63. RD_IFF[F$,0]
  64. 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 
  65. If Param : Error 32 : End If 
  66. '---> Compute instrument list
  67. Open Out 2,F_INST$
  68. Print #2,Chr$(0)+Chr$(0)+Chr$(0)+Chr$(0);
  69. '
  70. Reserve As Work 10,32*MXINS+34
  71. Doke Start(10),MXINS
  72. '
  73. For NI=0 To MXINS
  74.    If INS$(NI)<>""
  75.       CHK$(0)="8SVX" : CHK$(1)="VHDR" : CHK$(2)="BODY"
  76.       Print 
  77.       Print "* Processing "+INS$(NI)
  78.       NAME$=INS$(NI)
  79.       I$=PATH_INS$+INS$(NI)
  80.       FLAG=-1
  81.       If Exist(I$)
  82.          RD_IFF[I$,NI]
  83.          FLAG=Param
  84.       Else 
  85.          If Exist(I$+".Instr")
  86.             RD_IFF[I$+".Instr",NI]
  87.             FLAG=Param
  88.          Else 
  89.             If Exist(I$+"(IFF).Instr")
  90.                RD_IFF[I$+"(IFF).Instr",NI]
  91.                FLAG=Param
  92.             End If 
  93.          End If 
  94.       End If 
  95.       Repeat 
  96.          If FLAG<0 : Print "  I can't find "+I$+" !" : End If 
  97.          If FLAG=1 : Print "  This instrument is not an IFF SINGLE sample sound!" : End If 
  98.          If FLAG>1 : Bell : Print : Print "  Disk error!" : End If 
  99.          If FLAG
  100.             Print "  Please click and use the file selector to choose another instrument..."
  101.             WT_CLIC
  102.             I$=Fsel$("**","","Choose a new instrument for",INS$(NI))
  103.             If I$="" : ABORT : End If 
  104.             EXTRACT_NAME[I$]
  105.             RD_IFF[I$,NI] : FLAG=Param
  106.          End If 
  107.       Until FLAG=0
  108.    End If 
  109. Next 
  110. Close 2
  111. '  
  112. '---> Open output
  113. F$=Fsel$("*.Abk","","Please enter output bank name")
  114. If F$="" : ABORT : End If 
  115. On Error Goto D_ERROR
  116. Open Out 2,F$
  117. Print #2,"AmBk........Music   ";
  118. Print #2,"................";
  119. '
  120. ' Copy instruments 
  121. Print "* Saving instruments";
  122. DTA_COPY[Start(10),Length(10)]
  123. Open In 1,F_INST$
  124. FILE_COPY[Lof(1)]
  125. Print 
  126. LINST=Lof(1)+Length(10)
  127. Close 1
  128. Erase 10 : Kill F_INST$
  129. '
  130. ' Compute pattern  
  131. L=0
  132. For V=0 To 3
  133.    L=L+Len(V$(V))*3
  134. Next 
  135. Reserve As Work 10,L
  136. NPAT=4 : AOFF=Start(10) : APAT=AOFF+2+NPAT*2
  137. Doke AOFF,NPAT
  138. For V=0 To 3
  139.    Print "* Processing track";V
  140.    Doke AOFF+2+V*2,APAT-AOFF
  141.    FLAG(V)=0 : CU_I=0 : KY=0
  142.    If V$(V)<>""
  143.       Doke APAT,I_INST : Add APAT,2
  144.       For P=0 To Len(V$(V))-2 Step 2
  145.          P1=Peek(Varptr(V$(V))+P) : P2=Peek(Varptr(V$(V))+P+1)
  146.          If P1<=128
  147.             Inc FLAG(V)
  148.             F=NTE(P1+KY) : PER=0
  149.             If F
  150.                PER#=1.0/(SAM_RATE(CU_I)*F*CLOCK#)
  151.                PER=PER#+0.5
  152.                If PER<124 : PER=0 : End If 
  153.             End If 
  154.             D=(P2 and %110000)/%10000
  155.             D#=DELAY(P2 and %1111)*DELTA#(D)
  156.             DEL=D# : Add DELTA#,DEL-D#
  157.             If DELTA#<>0.0
  158.                If Int(DELTA#)=DELTA#
  159.                   Add DEL,DELTA#
  160.                   DELTA#=0.0
  161.                End If 
  162.             End If 
  163.             Poke APAT,P1-1 : Poke APAT+1,DEL : Doke APAT+2,PER
  164.             Add APAT,4
  165.          Else 
  166.             If P1=$83
  167.                KY=P2
  168.             End If 
  169.             If P1=$81
  170.                CU_I=P2 : Doke APAT,I_INST+P2 : Add APAT,2
  171.             End If 
  172.             If P1=$84
  173.                Doke APAT,I_SVOL+(P2*64)/256 : Add APAT,2
  174.             End If 
  175.             If P1=$88
  176.                Doke APAT,I_STEMPO+(P2*100)/188 : Add APAT,2
  177.             End If 
  178.          End If 
  179.       Next 
  180.    End If 
  181.    Doke APAT,I_END : Add APAT,2
  182.    V$(V)=""
  183. Next 
  184. LPATTERNS=APAT-AOFF
  185. '
  186. ' Copy songs 
  187. Reserve As Work 11,256
  188. AMU=Start(11)
  189. Doke AMU,1 : Add AMU,2
  190. Loke AMU,6 : Add AMU,4
  191. LLIST=1 : LPAT=(LLIST+1)*2 : APAT=8+SONGDATA+16
  192. For N=0 To 3
  193.    APAT(N)=APAT+AMU
  194.    Doke AMU+N*2,APAT
  195.    Add APAT,LPAT
  196. Next 
  197. Add AMU,8 : Doke AMU,MS_TEMPO : Add AMU,SONGDATA
  198. For A=0 To 15 : Poke AMU+A,Peek(Varptr(F$)+A) : Next : Add AMU,16
  199. P=0
  200. For V=0 To 3
  201.    If FLAG(V)
  202.       Doke APAT(V),0 : Doke APAT(V)+2,-2
  203.    Else 
  204.       Doke APAT(V),-1
  205.    End If 
  206.    AMU=APAT(V)+4
  207. Next 
  208. LSONG=AMU-Start(11)
  209. '
  210. ' Output SONG and PATTERNS 
  211. Print : Print "* Saving song";
  212. DTA_COPY[Start(11),LSONG]
  213. Print : Print "* Saving patterns";
  214. DTA_COPY[Start(10),LPATTERNS]
  215. '
  216. ' Music bank header
  217. Pof(2)=4
  218. OUT_NB[2,3]
  219. OUT_NB[2,0]
  220. TL=8+16+LINST+LSONG+LPATTERNS : OUT_NB[4,$80000000+TL]
  221. Pof(2)=20
  222. OUT_NB[4,16] : OUT_NB[4,16+LINST] : OUT_NB[4,16+LINST+LSONG] : OUT_NB[4,0]
  223. Close 
  224. ' Finished 
  225. Clw 
  226. Print "* Conversion finished!"
  227. Print "  Press any key to restart..."
  228. Erase 10 : Erase 11
  229. Load F$ : Music 1 : Tempo 40
  230. Wait Key 
  231. Erase 3
  232. Goto AGAIN
  233. ' Disk error 
  234. D_ERROR:
  235. Close 
  236. Clw : Boom : Print "Disk error!"
  237. Print : Print "Press a key to restart..."
  238. Wait Key 
  239. Resume AGAIN
  240. Procedure ABORT
  241.    Close 
  242.    Screen Close 0
  243.    Edit 
  244. End Proc
  245. Procedure RD_IFF[N$,PAR]
  246.    On Error Goto RD_ERR2
  247.    Open In 1,N$
  248.    On Error Goto RD_ERR1
  249.    LFILE=Lof(1)
  250.    I$=Input$(1,4) : If I$<>"FORM" : Error 21 : End If 
  251.    Pof(1)=Pof(1)+4
  252.    I$=Input$(1,4) : If I$<>CHK$(0) : Error 21 : End If 
  253.    LCHUNK=0
  254.    PCHUNK=Pof(1)
  255.    Do 
  256.       On Error Goto RD_ERR1
  257.       Exit If PCHUNK>=LFILE
  258.       Pof(1)=PCHUNK
  259.       H$=Input$(1,4)
  260.       A$=Input$(1,4) : LCHUNK=(Leek(Varptr(A$))+1) and $FFFFFFFE
  261.       For NCHK=1 To 8
  262.          Exit If CHK$(NCHK)=""
  263.          If H$=CHK$(NCHK)
  264.             On Error Goto RD_ERR0
  265.             Gosub "LD_"+CHK$(NCHK)
  266.          End If 
  267.       Next 
  268.       Add PCHUNK,LCHUNK+8
  269.    Loop 
  270.    For N=0 To 8
  271.       CHK$(N)=""
  272.    Next 
  273.    Error 20
  274.    ' IFF - SMUS 
  275.    LD_SHDR:
  276.    I$=Input$(1,4)
  277.    MS_TEMPO=40
  278.    Return 
  279.    '
  280.    LD_INS1:
  281.    I$=Input$(1,LCHUNK)
  282.    N=Peek(Varptr(I$))
  283.    X=0
  284.    Do 
  285.       P=Peek(Varptr(I$)+X+4)
  286.       Exit If P=0
  287.       INS$(N)=INS$(N)+Chr$(P)
  288.       Inc X
  289.    Loop 
  290.    MXINS=Max(N,MXINS)
  291.    Return 
  292.    '
  293.    LD_TRAK:
  294.    V$(VCE)=Input$(1,LCHUNK)
  295.    Inc VCE
  296.    Return 
  297.    ' IFF-8VSX 
  298.    LD_VHDR:
  299.    Print "  Loading IFF instrument";
  300.    I$=Input$(1,LCHUNK)
  301.    If Peek(Varptr(I$)+14)<>1 : Error 21 : End If 
  302.    If Peek(Varptr(I$)+15) : Error 21 : End If 
  303.    AD=Start(10)+PAR*32+2
  304.    Loke AD,Length(10)+Pof(2)
  305.    Doke AD+8,Leek(Varptr(I$))/2
  306.    Loke AD+4,Length(10) : Doke AD+10,2
  307.    L2=Leek(Varptr(I$)+4)
  308.    If L2 : Loke AD+4,Length(10)+Pof(2)+L1 : Doke AD+10,L2/2 : End If 
  309.    Doke AD+12,Leek(Varptr(I$)+16)/$400
  310.    SAM_RATE(PAR)=Leek(Varptr(I$)+8) : Doke AD+14,SAM_RATE(PAR)
  311.    Doke AD+16+14,Deek(Varptr(I$)+12)
  312.    Add AD,16
  313.    For N=1 To 14
  314.       If N<=Len(NAME$) : Poke AD+N-1,Asc(Mid$(NAME$,N,1)) : End If 
  315.    Next 
  316.    Return 
  317.    '  
  318.    LD_BODY:
  319.    FILE_COPY[LCHUNK] : FILE_EVEN
  320.    Print 
  321.    Return 
  322.    '
  323.    RD_ERR0: Pop 
  324.    RD_ERR1: Close 1
  325.    RD_ERR2: E=Errn : Resume RD_END
  326.    RD_END:
  327. End Proc[E-22]
  328. Procedure WT_CLIC
  329.    Repeat : Until Mouse Key
  330.    While Mouse Key : Wend 
  331. End Proc
  332. Procedure EXTRACT_NAME[N$]
  333.    For N=Len(N$) To 1 Step -1
  334.       A$=Mid$(N$,N,1)
  335.       Exit If(A$=":") or(A$="/")
  336.    Next 
  337.    NAME$=Mid$(N$,N+1)
  338. End Proc
  339. Procedure FILE_COPY[LONG]
  340.    LS=512
  341.    Repeat 
  342.       NL=LONG/LS
  343.       If NL
  344.          For N=1 To NL
  345.             A$=Input$(1,LS)
  346.             Print #2,A$;
  347.             Print ".";
  348.          Next 
  349.          Add LONG,-LS*NL
  350.       End If 
  351.       LS=LS/2
  352.    Until LONG=0
  353. End Proc
  354. Procedure FILE_EVEN
  355.    L=Lof(2)
  356.    If Btst(0,L)
  357.       Print #2,Chr$(0);
  358.    End If 
  359. End Proc
  360. Procedure DTA_COPY[AD,LONG]
  361.    LS=512
  362.    Repeat 
  363.       NL=LONG/LS
  364.       If NL
  365.          A$=Space$(LS)
  366.          For N=1 To NL
  367.             Copy AD,AD+LS To Varptr(A$)
  368.             Add AD,LS
  369.             Print #2,A$;
  370.             Print ".";
  371.          Next 
  372.          Add LONG,-LS*NL
  373.       End If 
  374.       LS=LS/2
  375.    Until LONG=0
  376. End Proc
  377. Procedure OUT_NB[BITS,NB]
  378.    For N=4-BITS To 3
  379.       A$=Chr$(Peek(Varptr(NB)+N)) : Print #2,A$;
  380.    Next 
  381. End Proc
  382. TNOTE:
  383. Data 33,35,37,39,41,44,46,49,52
  384. Data 55,58,62,65,69,73,78,82,87,92,98,104
  385. Data 110,117,123,131,139,147,156,165,175,185,196,208
  386. Data 220,233,247,262,277,294,311,330,349,370,392,415
  387. Data 440,466,494,523,554,587,622,659,698,740,784,830
  388. Data 880,932,988,1046,1109,1175,1245,1319,1397,1480,1568,1661
  389. Data 1760,1865,1986,2093,2217,2349,2489,2637,2794,2960,3136,3322
  390. Data 3520,3729,3952,4186,4435,4699,4978,5274,5588,5920,6272,6645
  391. Data 7040,7459,7902,8372
  392. TDELAY:
  393. Data 32,16,8,4,2,1,1,1,48,24,12,6,3,1,1,1
  394. TDELTA:
  395. Data 1.0,2.0/3.0,4.0/5.0,6.0/7.0