home *** CD-ROM | disk | FTP | other *** search
/ AMOS PD CD / amospdcd.iso / sourcecode / subroutines / music-merger.amos / music-merger.amosSourceCode
AMOS Source Code  |  1991-08-06  |  8KB  |  334 lines

  1. '--------------------------------------------------------------
  2. ' MELANGEUR DE MUSIQUES: plusieurs musiques dans une banque... 
  3. ' (c) 1991 F.Lionet / A.N.T. 
  4. '--------------------------------------------------------------
  5. Set Buffer 16
  6. '
  7. Dim I2(256),SUM1(256),SUM2(256)
  8. Global APOKE,SPOKE
  9. '
  10. Do 
  11.    '
  12.    Screen Open 0,640,200,2,Hires : Curs Off : Colour 1,$FF4
  13.    Centre At(,0)+">>> Merger of Music <<<"
  14.    '
  15.    Erase 3
  16.    '
  17.    F1$=Fsel$("*.Abk","","Select Music Bank -1.","QUIT to Exit")
  18.    If F1$="" : Edit : End If 
  19.    F2$=Fsel$("*.Abk","","Select Music Bank -2.","QUIT to Exit")
  20.    If F2$="" : Edit : End If 
  21.    Open In 1,F1$
  22.    Open In 2,F2$
  23.    '
  24.    ' Verification de la validite des banques
  25.    A$=Input$(1,20)
  26.    If Left$(A$,4)<>"AmBk" : Print At(0,10),"File -1 Not An AMOS Bank!" : End : End If 
  27.    If Right$(A$,8)<>"Music   " : Print At(0,10),"File -1 Not A MUSIC Bank!" : End : End If 
  28.    A$=Input$(2,20)
  29.    If Left$(A$,4)<>"AmBk" : Print At(0,10),"File -2 Not An AMOS Bank!" : End : End If 
  30.    If Right$(A$,8)<>"Music   " : Print At(0,10),"File -1 Not A MUSIC Bank!" : End : End If 
  31.    '
  32.    ' Reservation de la banque de travail
  33.    LM1=Lof(1)
  34.    LM2=Lof(2)
  35.    Reserve As Chip Data 3,LM1+LM2+256
  36.    ABANK=Start(3)+20
  37.    '
  38.    ' Charge les entetes 
  39.    APOKE=ABANK
  40.    HEAD1$=Input$(1,16)
  41.    HEAD2$=Input$(2,16)
  42.    '
  43.    ' Adresses des diff�rentes parties 
  44.    AINST1=Leek(Varptr(HEAD1$))+20
  45.    AINST2=Leek(Varptr(HEAD2$))+20
  46.    AMUS1=Leek(Varptr(HEAD1$)+4)+20
  47.    AMUS2=Leek(Varptr(HEAD2$)+4)+20
  48.    APAT1=Leek(Varptr(HEAD1$)+8)+20
  49.    APAT2=Leek(Varptr(HEAD2$)+8)+20
  50.    EPAT1=Leek(Varptr(HEAD1$)+12)+20 : If EPAT1=20 : EPAT1=Lof(1) : End If 
  51.    EPAT2=Leek(Varptr(HEAD2$)+12)+20 : If EPAT2=20 : EPAT2=Lof(2) : End If 
  52.    '
  53.    ' Va faire le travail
  54.    Print At(0,10);"Merging- ";F1$;" (";LM1;" Bytes.)"
  55.    Print At(0,11);"     and ";F2$;" (";LM2;" Bytes.)"
  56.    Print "Total Length =";LM1+LM2;" Bytes."
  57.    Print 
  58.    Print "Total Number Of Instruments:";
  59.    Gosub MERGE_SAMPLES
  60.    Print NTI;
  61.    If NTI<NI1+NI2
  62.       Print " - Discarding";NI1+NI2-NTI;" instrument(s)!";
  63.    End If 
  64.    Print 
  65.    '
  66.    Print "Total Number Of Songs      :";
  67.    MUMU=SPOKE : Gosub MERGE_MUSICS
  68.    Print NMU
  69.    '
  70.    Print "Total Number Of Patterns   :";
  71.    Gosub MERGE_PATTERNS : EBANK=APOKE
  72.    Print NPAT
  73.    '
  74.    APOKE=MUMU : Gosub MERGE_MUSICS
  75.    '
  76.    Close 
  77.    '
  78.    LBANK=EBANK-ABANK+8
  79.    E=LM1+LM2-LBANK
  80.    If E>0
  81.       Print : Print "Saved ";E;" Bytes! Making Final Bank";LBANK;" Bytes."
  82.    End If 
  83.    Print 
  84.    Print "Hit Mouse Key!"
  85.    Repeat : Until Mouse Click>0
  86.    '
  87.    ' Sauve la banque... 
  88.    APOKE=ABANK-20
  89.    STRPOKE["AmBk"]
  90.    BDOKE[3] : BDOKE[0] : BLOKE[$80000000+LBANK]
  91.    STRPOKE["Music   "]
  92.    BLOKE[AINST-ABANK]
  93.    BLOKE[AMUS-ABANK]
  94.    BLOKE[APAT-ABANK]
  95.    BLOKE[EBANK-ABANK]
  96.    '
  97.    F$=Fsel$("*.Abk","","Select A File Name To Save Bank As...")
  98.    If F$<>""
  99.       Bsave F$,ABANK-20 To EBANK
  100.    End If 
  101.    '
  102.    Erase 3
  103.    '
  104. Loop 
  105. '
  106. '----------------------------------------------------------------------------
  107. MERGE_SAMPLES:
  108. '
  109. ' Copie les instruments de la premiere banque, en stockant les noms
  110. Pof(1)=AINST1 : A$=Input$(1,2) : NI1=Deek(Varptr(A$))
  111. Pof(2)=AINST2 : A$=Input$(2,2) : NI2=Deek(Varptr(A$))
  112. INST1$=Input$(1,NI1*32)
  113. INST2$=Input$(2,NI2*32)
  114. '
  115. ' Pour chaque instrument, calcule une somme de controle des 512 1ers samples 
  116. For N=0 To NI1-1
  117.    A=Varptr(INST1$)+N*32
  118.    AI=Leek(A)+AINST1 : LI=Min(512,Deek(A+8)*2)
  119.    Pof(1)=AI : A$=Input$(1,LI)
  120.    S=0 : SA=Varptr(A$)
  121.    For L=0 To LI-1
  122.       Add S,Peek(SA+L)
  123.    Next 
  124.    SUM1(N)=S
  125. Next 
  126. For N=0 To NI2-1
  127.    A=Varptr(INST2$)+N*32
  128.    AI=Leek(A)+AINST2 : LI=Min(512,Deek(A+8)*2)
  129.    Pof(2)=AI : A$=Input$(2,LI)
  130.    S=0 : SA=Varptr(A$)
  131.    For L=0 To LI-1
  132.       Add S,Peek(SA+L)
  133.    Next 
  134.    SUM2(N)=S
  135. Next 
  136. '
  137. ' Compte les instruments semblables
  138. NTI=NI1
  139. For N2=0 To NI2-1
  140.    A2=Varptr(INST2$)+N2*32
  141.    L2=Leek(A2+8)
  142.    FLAG=-1
  143.    For N1=0 To NI1-1
  144.       A1=Varptr(INST1$)+N1*32
  145.       L1=Leek(A1+8)
  146.       If L1=L2 and SUM1(N1)=SUM2(N2)
  147.          I2(N2)=N1
  148.          FLAG=0 : Exit 
  149.       End If 
  150.    Next 
  151.    If FLAG
  152.       I2(N2)=NTI : Inc NTI
  153.    End If 
  154. Next 
  155. '
  156. ' Recopie les instruments
  157. AINST=ABANK+16
  158. APOKE=AINST : BDOKE[NTI]
  159. SVIDE=APOKE+NTI*32
  160. SPOKE=SVIDE+4
  161. '
  162. For N=0 To NI1-1
  163.    AI=Varptr(INST1$)+N*32
  164.    A1=SPOKE : S1=AINST1+Leek(AI) : L1=Deek(AI+8)*2
  165.    A2=SPOKE+L1 : S2=AINST1+Leek(AI+4) : L2=Deek(AI+10)*2
  166.    If L2<=4
  167.       A2=SVIDE : L2=4
  168.    End If 
  169.    BLOKE[A1-AINST] : BLOKE[A2-AINST]
  170.    BDOKE[L1/2] : BDOKE[L2/2]
  171.    For O=0 To 16 Step 4
  172.       BLOKE[Leek(AI+12+O)]
  173.    Next 
  174.    SCOPY[1,S1,L1]
  175.    If A2<>SVIDE
  176.       SCOPY[1,S2,L2]
  177.    End If 
  178. Next 
  179. '
  180. For N=0 To NI2-1
  181.    If I2(N)>=NI1
  182.       AI=Varptr(INST2$)+N*32
  183.       A1=SPOKE : S1=AINST2+Leek(AI) : L1=Deek(AI+8)*2
  184.       A2=SPOKE+L1 : S2=AINST2+Leek(AI+4) : L2=Deek(AI+10)*2
  185.       If L2<=4
  186.          A2=SVIDE : L2=4
  187.       End If 
  188.       BLOKE[A1-AINST] : BLOKE[A2-AINST]
  189.       BDOKE[L1/2] : BDOKE[L2/2]
  190.       For O=0 To 16 Step 4
  191.          BLOKE[Leek(AI+12+O)]
  192.       Next 
  193.       SCOPY[2,S1,L1]
  194.       If A2<>SVIDE
  195.          SCOPY[2,S2,L2]
  196.       End If 
  197.    End If 
  198. Next 
  199. '
  200. INST1$="" : INST2$=""
  201. APOKE=SPOKE
  202. Return 
  203. '
  204. '----------------------------------------------------------------------------
  205. MERGE_MUSICS:
  206. '
  207. LMU1=APAT1-AMUS1 : Pof(1)=AMUS1
  208. MU1$=Input$(1,LMU1) : NMU1=Deek(Varptr(MU1$))
  209. LMU2=APAT2-AMUS2 : Pof(2)=AMUS2
  210. MU2$=Input$(2,LMU2) : NMU2=Deek(Varptr(MU2$))
  211. NMU=NMU1+NMU2 : AMUS=APOKE : BDOKE[NMU]
  212. SPOKE=APOKE+NMU*4
  213. '
  214. ' Recopie les musiques de la banque 1
  215. For N=0 To NMU1-1
  216.    BLOKE[SPOKE-AMUS]
  217.    A=Varptr(MU1$) : AM=Leek(A+N*4+2)
  218.    If N<NMU1-1
  219.       FM=Leek(A+N*4+6)
  220.    Else 
  221.       FM=LMU1
  222.    End If 
  223.    Copy A+AM,A+FM To SPOKE
  224.    Add SPOKE,FM-AM
  225. Next 
  226. '
  227. ' Recopie les musiques de la banque 2, en pointant les nouveaux patterns 
  228. For N=0 To NMU2-1
  229.    BLOKE[SPOKE-AMUS]
  230.    A=Varptr(MU2$) : AM=Leek(A+N*4+2)
  231.    If N<NMU2-1
  232.       FM=Leek(A+N*4+6)
  233.    Else 
  234.       FM=LMU2
  235.    End If 
  236.    Copy A+AM,A+FM To SPOKE
  237.    ' Change les numeros de patterns 
  238.    For P=0 To 3
  239.       AP=SPOKE+Deek(SPOKE+P*2)
  240.       Do 
  241.          B=Deek(AP)
  242.          Exit If Btst(15,B)
  243.          Doke AP,B+NPAT1
  244.          Add AP,2
  245.       Loop 
  246.    Next 
  247.    Add SPOKE,FM-AM
  248. Next 
  249. '
  250. MU1$="" : MU2$=""
  251. APOKE=SPOKE
  252. Return 
  253. '
  254. '----------------------------------------------------------------------------
  255. MERGE_PATTERNS:
  256. '
  257. ' Recopie les patterns 
  258. Pof(1)=APAT1 : A$=Input$(1,2) : NPAT1=Deek(Varptr(A$))
  259. Pof(2)=APAT2 : A$=Input$(2,2) : NPAT2=Deek(Varptr(A$))
  260. NPAT=NPAT1+NPAT2 : APAT=APOKE : BDOKE[NPAT] : SPOKE=APAT+NPAT*8+2
  261. PAT1$=Input$(1,NPAT1*8) : SPAT1=Pof(1)
  262. PAT2$=Input$(2,NPAT2*8) : SPAT2=Pof(2)
  263. '
  264. ' Recopie betement les patterns de la premiere banque
  265. For N=0 To NPAT1-1
  266.    For P=0 To 3
  267.       BDOKE[Deek(Varptr(PAT1$)+N*8+P*2)+NPAT2*8]
  268.    Next 
  269. Next 
  270. LPAT1=EPAT1-SPAT1
  271. SCOPY[1,SPAT1,LPAT1]
  272. '
  273. ' Recopie les patterns de la deuxieme de la meme maniere...  
  274. For N=0 To NPAT2-1
  275.    For P=0 To 3
  276.       BDOKE[Deek(Varptr(PAT2$)+N*8+P*2)+NPAT1*8+LPAT1]
  277.    Next 
  278. Next 
  279. LPAT2=EPAT2-SPAT2
  280. SCOPY[2,SPAT2,LPAT2]
  281. '
  282. ' Analyse les patterns de la deuxieme banque pour changer les instruments... 
  283. ' Etiquette SET_INST=$900
  284. For N=0 To NPAT2-1
  285.    For P=0 To 3
  286.       AP=Deek(APAT+2+NPAT1*8+N*8+P*2)+APAT
  287.       Do 
  288.          B=Deek(AP) : Add AP,2
  289.          Exit If B=$8000
  290.          If Btst(15,B)=0
  291.             If Btst(14,B)
  292.                Add AP,2
  293.             End If 
  294.          Else 
  295.             If(B and $7F00)=$900
  296.                I=B and $FF
  297.                B=$8900+I2(I)
  298.                Doke AP-2,B
  299.             End If 
  300.          End If 
  301.       Loop 
  302.    Next 
  303. Next 
  304. '
  305. PAT1$="" : PAT2$=""
  306. APOKE=SPOKE
  307. Return 
  308. Procedure STRPOKE[S$]
  309.    For P=1 To Len(S$)
  310.       Poke APOKE,Asc(Mid$(S$,P,1))
  311.       Inc APOKE
  312.    Next 
  313. End Proc
  314. '
  315. Procedure BDOKE[P]
  316.    Doke APOKE,P
  317.    Add APOKE,2
  318. End Proc
  319. '
  320. Procedure BLOKE[P]
  321.    Loke APOKE,P
  322.    Add APOKE,4
  323. End Proc
  324. '
  325. Procedure SCOPY[FILE,POS,LONG]
  326.    Pof(FILE)=POS : A=0
  327.    While A<LONG
  328.       L=1024 : If A+L>LONG : L=LONG-A : End If 
  329.       A$=Input$(FILE,L)
  330.       Copy Varptr(A$),Varptr(A$)+L To SPOKE+A
  331.       Add A,L
  332.    Wend 
  333.    Add SPOKE,LONG
  334. End Proc