Technical Note of
"Split/Merge AudioVisual" 3 |
index@kenjikojima.com |
|
|
||
|
put URL ("binfile:" & specialFolderPath("Desktop") & "/music1.mid" ) into midDataBut we cannot read the data, then have to convert it to human readable midi data. We use function "smf2Slg (see the last part of this page).
put smf2Slg(midData, true ) into slg -- variable "slg" contains human readable midi data. ----------// the result of slg (human readable midi data) //--------------- %MIDIFILE @MThd @FORMAT 0 @TIMEBASE 61440 @END ;--------------------------------------- @MTrk 1 001|1|000 @TEMPO 0 001|1|000 1:PROG 0 001|1|000 1:A#4 127 0|060 001|1|060 1:F-1 127 0|120 001|1|180 1:C8 127 0|120 001|1|300 1:B6 127 0|060 001|1|360 1:F#2 127 0|060 001|1|420 1:C#4 127 0|120 001|1|540 1:B8 127 0|060 001|1|600 1:G#7 127 0|120 001|1|720 1:A6 127 0|060 001|1|780 1:G#4 127 0|060 001|1|840 1:E3 127 0|120 001|1|960 1:A1 127 0|060 001|1|0001020 1:D#9 127 0|060 001|1|0001080 1:G1 127 0|120 001|1|0001200 1:C#8 127 0|120 001|1|0001320 1:G#7 127 0|060 001|1|0001380 1:F#5 127 0|060 001|1|0001440 1:A#7 127 0|060 001|1|0001500 1:A#7 127 0|120 001|1|0001620 1:C9 127 0|060 001|1|0001680 1:B3 127 0|060 001|1|0001740 1:A#5 127 0|120 001|1|0001860 1:A8 127 0|120 001|1|0001980 1:A#8 127 0|060 001|1|0002040 1:E9 127 0|120 001|1|0002160 1:C2 127 0|120 001|1|0002280 1:D4 127 0|120 001|1|0002400 1:D#7 127 0|060 001|1|0002460 1:G8 127 0|060 001|1|0002520 1:B0 127 0|060 001|1|0002580 1:F0 127 0|060 001|1|0002640 1:F#7 127 0|060 001|1|0002700 1:F#8 127 0|120 001|1|0002820 1:E6 127 0|060 001|1|0002880 1:A3 127 0|060 001|1|0002940 1:F#2 127 0|120 001|1|0003060 1:A2 127 0|060 001|1|0003120 1:F5 127 0|120 001|1|0003240 1:G0 127 0|120 001|1|0003360 1:D#3 127 0|060 001|1|0003420 1:G#-1 127 0|060 001|1|0003480 1:F6 127 0|120 001|1|0003600 1:C6 127 0|060 001|1|0003660 1:E2 127 0|120 001|1|0003780 1:D#0 127 0|120 001|1|0003900 1:G3 127 0|060 001|1|0003960 1:B2 127 0|120 001|1|0004080 1:F5 127 0|120 @END --------------// END of the result //----------------
global noteArray command createNoteArray put "" into noteArray repeat with i= 0 to 127 if i mod 12 = 11 then put i &cr after NoteArray else put i & tab after noteArray end if end repeat split noteArray by row end createNoteArray function noteCharToNoteNum pNoteChar if char 2 of pNoteChar is "#" then put char 1 to 2 of pNoteChar into tNoteName delete char 1 to 2 of pNoteChar else put char 1 of pNoteChar into tNoteName delete char 1 of pNoteChar end if put pNoteChar +2 into tRowNum put noteArray[tRowNum] into tRowList set the itemDel to tab return item noteToColumnNumber(tNoteName) of tRowList end noteCharToNoteNum function noteToColumnNumber pNoteName switch pNoteName case "C" return 1 break case "C#" return 2 break case "D" return 3 break case "D#" return 4 break case "E" return 5 break case "F" return 6 break case "F#" return 7 break case "G" return 8 break case "G#" return 9 break case "A" return 10 break case "A#" return 11 break case "B" return 12 break end switch end noteToColumnNumberYou can get a musical number from a musical note character. We have to two times of them and distinguish the note length eighth or quarter for RGB value.
put noteCharToNoteNum("A#4") -- returns 70 put noteCharToNoteNum("F-1") -- returns 5 function eighthOrQuarter pNoteNum, pLength -- pNoteNum is noteCharToNoteNum() switch pLength case "0|060" -- even return pNoteNum * 2 break case "0|120" -- odd return pNoteNum * 2 + 1 break end switch end eighthOrQuarter function midDataToNoteNum slg repeat for each line tLine in slg put word -1 of tLine into tNoteLength if char 1 to 2 of tNoteLength is "0|" then put char 3 to -1 of word 2 of tLine into tNoteChar put noteCharToNoteNum(tNoteChar) into noteNum put eighthOrQuarter(noteNum, tNoteLength) & space after RGBValue end if end repeat return RGBValue end midDataToNoteNum -- you can get RGB values from slg -- slg is smf2Slg(midData, true) put midDataToNoteNum(slg) -- it returns 140 11 217 190 84 123 238 209 186 136 105 66 246 63 219 208 156 212 213 240 118 165 235 236 249 73 125 198 230 46 34 204 229 176 114 85 90 155 39 102 16 179 168 81 31 110 95 155
----------------// function smf2Slg by UDI //---------------- --smf2Slg midData, conciseList -- midData: smf binary data -- conciseList: true(omit some controls) / false(full convert) --return slg text data local lMidData function smf2Slg midData, conciseList put midData into lMidData put "" into slg put ( conciseList is true ) into conciseList -- header put "%MIDIFILE" &return& "@MThd" &return after slg delete char 1 to 8 of lMidData -- 'MThd' & headerSize(4) get binaryDecode( "S", lMidData, aNum ) if aNum <> 0 then put "@FORMAT 1" &return after slg else put "@FORMAT 0" &return after slg end if delete char 1 to 4 of lMidData -- format(2) & trackCount(2) get binaryDecode( "S", lMidData, timeBase ) delete char 1 to 2 of lMidData put "@TIMEBASE" && timeBase &return after slg put "@END" &return after slg -- put 0 into trackNum put 0 into absT put 4 into beatA put 4 into beatB put timeBase into oneBeat put oneBeat * beatA into barBeat -- repeat -- track set the cursor to watch if lMidData is "" then exit repeat put 0 into absT put "" into aSlg add 1 to trackNum put ";---------------------------------------" &return after aSlg put "@MTrk" && trackNum &return after aSlg delete char 1 to 8 of lMidData -- 'MTrk' & trackSize(4) put 0 into cursorCount repeat -- event if lMidData is "" then exit repeat if the short name of the target <> "mergeAudioVisual" then add 1 to cursorCount if ( cursorCount = 40 ) then set the cursor to busy put 0 into cursorCount end if end if add getDeltaTime() to absT -- put aByte into oldByte get binaryDecode( "C", lMidData, aByte ) if ( aByte >= 128 ) then put ( aByte div 16 ) into aEvnt put ( aByte mod 16 ) +1 into aPart delete first char of lMidData else -- running status put oldByte into aByte end if -- if ( aEvnt = 9 ) then -- $9x note on -- get binaryDecode( "CC", lMidData, aPitch, aVal ) delete char 1 to 2 of lMidData -- if ( aVal > 0 ) then put absT2barT( absT, oneBeat, barBeat ) after aSlg put rightFormatStr( aPart, 2, " " ) & ":" after aSlg put leftFormatStr( pitch2Name( aPitch ), 6, " " ) after aSlg put leftFormatStr( aVal, 8, " " ) after aSlg put "_" & aPitch &","& absT & return after aSlg else -- note off put lineOffset( ( "_" & aPitch ), aSlg ) into lineNum --2002.12.10 put item 2 of ( last word of line lineNum of aSlg ) into onTime put absT2barT2( absT - onTime, oneBeat, barBeat ) into last word of line lineNum of aSlg end if next repeat end if if ( aEvnt = 8 ) then -- $8x note off -- get binaryDecode( "C", lMidData, aPitch ) delete char 1 to 2 of lMidData -- pitch(1) & offVelocity(1) -- put lineOffset( ( "_" & aPitch ), aSlg ) into lineNum --2002.12.10 put item 2 of ( last word of line lineNum of aSlg ) into onTime put absT2barT2( absT - onTime, oneBeat, barBeat ) into last word of line lineNum of aSlg next repeat end if if ( aEvnt = 10 ) then -- $Ax Poly Key Pressure -- if ( conciseList ) then delete char 1 to 2 of lMidData else get binaryDecode( "CC", lMidData, aCtrlN, aVal ) delete char 1 to 2 of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg put rightFormatStr( aPart, 2, " " ) & ":POLY " after aSlg put leftFormatStr( aCtrlN, 6, " " ) after aSlg put leftFormatStr( aVal, 3, " " ) &return after aSlg end if next repeat end if if ( aEvnt = 11 ) then -- $Bx control -- if ( conciseList ) then delete char 1 to 2 of lMidData else get binaryDecode( "CC", lMidData, aCtrlN, aVal ) delete char 1 to 2 of lMidData -- if ( aCtrlN < 120 ) then put absT2barT( absT, oneBeat, barBeat ) after aSlg put rightFormatStr( aPart, 2, " " ) & ":CONT " after aSlg put leftFormatStr( aCtrlN, 6, " " ) after aSlg put leftFormatStr( aVal, 3, " " ) &return after aSlg end if end if next repeat end if if ( aEvnt = 12 ) then -- $Cx program change -- get binaryDecode( "C", lMidData, aVal ) delete first char of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg put rightFormatStr( aPart, 2, " " ) & ":PROG " after aSlg put leftFormatStr( aVal, 5, " " ) & return after aSlg next repeat end if if ( aEvnt = 13 ) then -- $Dx Mono Key Pressurer -- if ( conciseList ) then delete first char of lMidData else get binaryDecode( "C", lMidData, aVal ) delete first char of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg put rightFormatStr( aPart, 2, " " ) & ":MONO " after aSlg put leftFormatStr( aVal, 5, " " ) & return after aSlg end if next repeat end if if ( aEvnt = 14 ) then -- $Ex pitchbend -- if ( conciseList ) then delete char 1 to 2 of lMidData else get binaryDecode( "CC", lMidData, aNum1, aNum2 ) delete char 1 to 2 of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg put rightFormatStr( aPart, 2, " " ) & ":PITCH " after aSlg put leftFormatStr( ( aNum2 *128 + aNum1 ) - 8192, 5, " " ) & return after aSlg end if next repeat end if if ( aByte = 255 ) then -- $FF meta event -- get binaryDecode( "C", lMidData, metaNum ) delete first char of lMidData if ( metaNum > 0 ) and ( metaNum < 32 ) then -- $FF01-FF1F TextEvent -- get item metaNum of "TXT,COPYRIGHT,SEQ_NAME,INSTRUMENT,LYRIC,MARKER,CUE" put absT2barT( absT, oneBeat, barBeat ) & getTextEvent( "@"&it&" " ) &return after aSlg next repeat end if if ( metaNum = 81 ) then -- $FF51 tempo -- delete first char of lMidData --len put char 1 to 3 of lMidData into aStr delete char 1 to 3 of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg get binaryDecode( "I", numToChar(0) & aStr, aNum ) put "@TEMPO " & ( 60000000 div aNum ) & return after aSlg next repeat end if if ( metaNum = 88 ) then -- $FF58 timesign -- delete first char of lMidData --len get binaryDecode( "CC", lMidData, beatA, beatB ) delete char 1 to 4 of lMidData -- sign(2) & clock(2) put 2^beatB into beatB -- put 4 * timeBase div beatB into oneBeat put oneBeat * beatA into barBeat -- put absT2barT( absT, oneBeat, barBeat ) after aSlg put "@BEAT " & beatA &"/" & beatB &return after aSlg next repeat end if if ( metaNum = 47 ) then -- $FF2F end of track -- delete first char of lMidData --len -- put "@END" &return after aSlg exit repeat end if if ( conciseList is FALSE ) then if ( metaNum = 0 ) then -- $FF00 seq no. -- delete first char of lMidData --len put char 1 to 2 of lMidData into aStr delete char 1 to 2 of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg get binaryDecode( "S", aStr, aNum ) put "@SEQ_NO " & aNum & return after aSlg next repeat end if if ( metaNum = 84 ) then -- $FF54 SMPTE -- delete first char of lMidData --len put absT2barT( absT, oneBeat, barBeat ) after aSlg put "@SMPTE" after aSlg repeat 5 get binaryDecode( "C", lMidData, aNum ) put " " & aNum after aSlg delete first char of lMidData end repeat put return after aSlg next repeat end if if ( metaNum = 89 ) then -- $FF59 keysign -- delete first char of lMidData --len get binaryDecode( "CC", lMidData, sf, mi ) delete char 1 to 2 of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg put "@KEY " after aSlg if mi = 0 then if sf >= 0 then put ( item sf+1 of "C,G,D,A,E,B,F" ) & " Major" after aSlg else put ( item abs(sf)+1 of "C,F,B,E,A,D,G" ) & " Major" after aSlg end if else if sf >= 0 then put ( item sf+1 of "A,E,B,F,C,G,D" ) & " Minor" after aSlg else put ( item abs(sf)+1 of "A,D,G,C,F,B,E" ) & " Minor" after aSlg end if end if put return after aSlg next repeat end if if ( metaNum = 32 ) then -- $FF20 channel prefix -- delete first char of lMidData -- len get binaryDecode( "C", lMidData, aNum ) delete first char of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg put "@CH_PREFIX " & aNum & return after aSlg next repeat end if if ( metaNum = 33 ) then -- $FF21 MIDI port -- delete first char of lMidData --len get binaryDecode( "C", lMidData, aNum ) delete first char of lMidData -- put absT2barT( absT, oneBeat, barBeat ) after aSlg put "@MIDI_PORT " & aNum & return after aSlg next repeat end if end if --conciseList is FALSE -- other meta event get binaryDecode( "C", lMidData, aLen ) delete char 1 to aLen +1 of lMidData next repeat end if --aByte = 255/ $FF meta event -- if ( aByte = 240 ) then -- $F0 Sytem exclusive -- put absT2barT( absT, oneBeat, barBeat ) & "@F0 " & getSysEx() & "@EE" &return after aSlg next repeat end if if ( aByte = 247 ) then -- $F7 Sytem exclusive -- put absT2barT( absT, oneBeat, barBeat ) & "@F7 " & getSysEx() & "@EE" &return after aSlg next repeat end if end repeat put aSlg after slg end repeat delete last char of slg return slg end smf2Slg function getTextEvent tagStr get binaryDecode( "C", lMidData, aLen ) delete first char of lMidData put char 1 to aLen of lMidData into aStr delete char 1 to aLen of lMidData -- if last char of aStr is numToChar(0) then delete last char of aStr if last char of aStr is numToChar(0) then delete last char of aStr return tagStr "e& aStr "e end getTextEvent function getSysEx get binaryDecode( "C", lMidData, aLen ) delete first char of lMidData put char 1 to aLen of lMidData into tgData delete char 1 to aLen of lMidData put "" into aStr put "" into aHex repeat for each char aChar in tgData get binaryDecode( "H2", aChar, aHex ) put aHex & " " after aStr end repeat return aStr end getSysEx function getDeltaTime put 0 into aSum repeat get binaryDecode( "C", lMidData, aNum ) delete first char of lMidData if aNum > 127 then put aSum *128 + ( aNum - 128 ) into aSum else return aSum *128 + aNum end if end repeat end getDeltaTime function absT2barT absT, oneBeat, barBeat put rightFormatStr( absT div barBeat +1, 3, "000" ) & "|" into barT put ( absT mod barBeat ) div oneBeat +1 & "|" after barT put rightFormatStr( ( absT mod oneBeat ), 3, "000" ) & " " after barT return barT end absT2barT function absT2barT2 absT, oneBeat, barBeat put absT div oneBeat & "|" into barT put rightFormatStr( ( absT mod oneBeat ), 3, "000" ) & " " after barT return barT end absT2barT2 function rightFormatStr tgData, nDigit, fillChars get nDigit - length( tgData ) return ( char 1 to it of fillChars ) & tgData end rightFormatStr function leftFormatStr tgData, nDigit, fillChars return char 1 to nDigit of ( tgData & fillChars ) end leftFormatStr function pitch2Name aPitch put item ( aPitch mod 12 ) +1 of "C,C#,D,D#,E,F,F#,G,G#,A,A#,B" into aName return aName & ( aPitch div 12 ) -1 end pitch2Name ----------------// end smf2Slg //---------------- ----------------// slg2Pmd //---------------- --slg2Pmd slgData -- slgData: 'SLG' text format midi events for SC.EXE --return pmd text data local lSlgPmdTempo, lSlgPmdInst, lSlgPmdTimeSign, lSlgPmdCopyStr, lSlgPmdSeqName, lSlgPmdInfoStr local lSlgPmdBarTime, lSlgPmdBase, lSlgPmdWTime function slg2Pmd slg set the cursor to watch -- getMusicInfo slg -- lSlgPmdBase, lSlgPmdTempo, lSlgPmdBarTime, lSlgPmdTimeSign put "//pmd,1.0," & lSlgPmdTempo & return into notes put "//s " & lSlgPmdTimeSign & return after notes getTextInfo slg -- lSlgPmdCopyStr, lSlgPmdSeqName, lSlgPmdInfoStr if ( lSlgPmdCopyStr <> "" ) then put "//c " & lSlgPmdCopyStr & return after notes end if if ( lSlgPmdSeqName <> "" ) then put "//n " & lSlgPmdSeqName & return after notes end if if ( lSlgPmdInfoStr <> "" ) then repeat for each line theLine in lSlgPmdInfoStr put "//i " & theLine & return after notes end repeat end if put return after notes -- put UxGetFoundLines( slg, ":", "S" ) into slg -- put UxGetFoundLines( slg, "PITCH", "S" , "", false ) into slg put UxGetFoundLines( slg, "MONO", "S" , "", false ) into slg put UxGetFoundLines( slg, ":CONT 0", "S" ) into bankLines put UxGetFoundLines( slg, "CONT", "S" , "", false ) into slg sort lines of slg -- put 1 into pMin put 16 into pMax repeat with aPart = pMin to pMax set the cursor to watch put getBank( bankLines, aPart ) into bankOfs put pickPartData( slg, aPart ) into slg1 --lSlgPmdInst & except "PROG" if ( slg1 = "" ) then next repeat end if add bankOfs to lSlgPmdInst put "$" & lSlgPmdInst & "V8" && "// (" & aPart & ") " into pInfo -- put "$" & lSlgPmdInst & "V8" && "// (" & aPart & ") " & UxGetInst( lSlgPmdInst ) into pInfo put pInfo & slg2play( slg1 ) &return after notes end repeat return notes end slg2Pmd function slg2play slg put false into inChode put "" into pitchName put "" into stepName put 0 into currBar put lSlgPmdBarTime into nextTop replace "|" with "," in slg --RR replace ":" with "," in slg --RR put ( ( item 1 of slg ) -1 ) *lSlgPmdBarTime + ( ( item 2 of slg ) -1 ) *lSlgPmdBase + ( item 3 of ( word 1 of slg ) ) into nextTime put ( item 1 of ( last line of slg ) )+0 into maxBar -- repeat put line 1 of slg into aLine -- put nextTime into currTime put ( ( item 1 of ( line 2 of slg ) ) -1 ) *lSlgPmdBarTime + ( ( item 2 of ( line 2 of slg ) ) -1 ) *lSlgPmdBase + ( item 3 of ( word 1 of ( line 2 of slg ) ) ) into nextTime -- put currBar into oldBar put ( item 1 of aLine )+0 into currBar if ( currBar <> oldBar ) then put ( currBar -1 ) *lSlgPmdBarTime into currTop put currTop +lSlgPmdBarTime into nextTop -- repeat with b = ( oldBar +1 ) to ( currBar -1 ) put return & "/" & b && "R" & step2name( lSlgPmdBarTime, lSlgPmdWTime ) after theNotes end repeat put return & "/" & currBar after theNotes if ( currTime > currTop ) then put " R" & step2name( currTime - currTop, lSlgPmdWTime ) after theNotes end if put "*" into oldStepName --reset stepName end if -- if ( nextTime < 0 ) then put nextTop into nextTime -- put item 2 of ( word 2 of aLine ) into pitchName --SC -- put min( nextTime - currTime, nextTop - currTime ) into stepTime put ( ( item 1 of ( word 4 of aLine ) ) * lSlgPmdBase ) + ( item 2 of ( word 4 of aLine ) ) into gateTime --SC -- if ( nextTime = currTime ) then -- is chode if ( inChode is false ) then put true into inChode put " (" after theNotes end if put " " & pitchName & gate2Name( gateTime, lSlgPmdWTime ) after theNotes else -- not chode put step2name( stepTime, lSlgPmdWTime ) into stepName put ( gateTime > stepTime ) or ( stepTime > gateTime *1.2 ) into existGap if ( inChode ) then put false into inChode if ( existGap ) then put " " & pitchName & gate2Name( gateTime, lSlgPmdWTime ) & " )" after theNotes else put " " & pitchName & stepName & " )" after theNotes end if if ( stepName <> oldStepName ) then put stepName after theNotes end if else -- not inChode if ( existGap ) then put " ( " & pitchName & gate2Name( gateTime, lSlgPmdWTime ) & " )" after theNotes else put " " & pitchName after theNotes end if if ( stepName <> oldStepName ) then put stepName after theNotes end if end if put stepName into oldStepName end if -- delete line 1 of slg if slg is "" then exit repeat end if end repeat if ( inChode ) then put false into inChode put " )" & step2name( stepTime, lSlgPmdWTime ) after theNotes end if -- put gateTime - ( nextTop - currTime ) into restTime repeat if ( restTime > lSlgPmdBarTime ) then add 1 to currBar put return & "/" & currBar & " R" & gate2name( lSlgPmdBarTime, lSlgPmdWTime ) after theNotes subtract lSlgPmdBarTime from restTime else if restTime > ( lSlgPmdBase /4 ) then add 1 to currBar put return & "/" & currBar & " R" & gate2name( restTime, lSlgPmdWTime ) after theNotes end if exit repeat end if end repeat put return & "/ Re" & return after theNotes return theNotes end slg2play function step2Name stepTime, wTime put false into cntne get stepTime div wTime put "" into theResult if ( it > 0 ) then put char 1 to it of "wwwwwwww" into theResult subtract it * wTime from stepTime put true into cntne end if put wTime div 2 into wTime put "hqestxx" into steps repeat with x = 1 to 7 if ( stepTime = wTime *2/3 ) then return theResult & char x of steps & "3" end if if ( stepTime >= wTime ) then if cntne then put "." after theResult else put char x of steps after theResult end if subtract wTime from stepTime put true into cntne else put false into cntne end if put wTime div 2 into wTime end repeat -- if theResult is "" then return "x" end if return theResult end step2Name function gate2Name gateTime, wTime put "" into whole put "" into theResult get gateTime div wTime if ( it > 1 ) then put char 1 to it of "wwwwwwww" into whole subtract it * wTime from gateTime end if -- put "whqestx" into steps repeat with x = 1 to 7 if ( gateTime *1.2 >= wTime ) then put char x of steps after theResult subtract wTime from gateTime if ( the number of chars of theResult ) = 2 then exit repeat end if end if put wTime div 2 into wTime end repeat -- if ( theResult is "" ) then put "x" into theResult end if return whole & theResult end gate2Name on getMusicInfo slg get last line of UxGetFoundLines( slg, "@TIMEBASE", "S" ) if word 1 of it is "Error" then errDialog it exit to HyperCard end if if ( it <> empty ) then put last word of it into timeBase else put 480 into timeBase -- get last line of UxGetFoundLines( slg, "@BEAT", "S" ) if word 1 of it is "Error" then errDialog it exit to HyperCard end if put last word of it into lSlgPmdTimeSign if ( it <> empty ) then replace "/" with "," in it --RR put item 1 of ( last word of it ) into beatA put item 2 of ( last word of it ) into beatB else put 4 into beatA put 4 into beatB end if -- put "" into tempoItems get UxGetFoundLines( slg, "@TEMPO", "S" ) if ( word 1 of it is "Error" ) then errDialog it exit to HyperCard end if if ( it <> empty ) then put the number of lines of it into maxL put 0 into aNum repeat with L = 1 to maxL add ( last word of line L of it ) to aNum end repeat put aNum div ( maxL * 10 ) * 10 into lSlgPmdTempo else put 100 into lSlgPmdTempo end if -- put timeBase * 4 div beatB into lSlgPmdBase -- 1 beat time put lSlgPmdBase * beatA into lSlgPmdBarTime -- 1 bar time put lSlgPmdBase * beatB into lSlgPmdWTime --'W' time (lSlgPmdBase *4 *beatB div4 ) end getMusicInfo on getTextInfo slg -- lSlgPmdCopyStr, lSlgPmdSeqName, lSlgPmdInfoStr put UxGetFoundLines( slg, "@COPYRIGHT", "S" ) into cpLineStr if cpLineStr <> "" then put the value of word 3 of cpLineStr into lSlgPmdCopyStr else put "" into lSlgPmdCopyStr put UxGetFoundLines( slg, "@SEQ_NAME", "S" ) into seqName if ( seqName <> "" ) then put word 3 of seqName into lSlgPmdSeqName try put the value of lSlgPmdSeqName into lSlgPmdSeqName end try else put "" into lSlgPmdSeqName end if put UxGetFoundLines( slg, "@TXT", "S" ) into infoLinesStr put "" into lSlgPmdInfoStr repeat for each line theLine in infoLinesStr put word 3 of theLine into aStr try put the value of aStr into aStr end try put aStr & return after lSlgPmdInfoStr end repeat end getTextInfo function pickPartData slg, aPart put UxGetFoundLines( slg, " " & aPart & ":", "S" ) into slg if ( slg is "" ) then return "" -- put 1 into lSlgPmdInst if ( aPart = 10 ) then put 16385 into lSlgPmdInst else put offset( "PROG", slg ) into aOfs if ( aOfs > 0 ) then put ( char aOfs +6 to aOfs +9 of slg ) +1 into lSlgPmdInst end if end if return UxGetFoundLines( slg, "PROG", "S" , "", false ) end pickPartData function getBank slg, aPart if ( the number of chars of aPart ) = 1 then put " " before aPart end if put line 1 of UxGetFoundLines( slg, aPart & ":", "S" ) into bankLine if bankLine is "" then return 0 end if put ( char 26 to 27 of bankLine )+0 into bank if bank mod 2 <> 0 then add 1 to bank end if return bank * 128 end getBank --- XCMD substitute ---- -- UxGetFoundLines( SourceStr, findStr [ , resultForm ] [ , case ] [, condi ] ) -- 2002.12.10 function UxGetFoundLines sourceStr, findStr, resultForm, caseSence, condi put "" into returnStr if ( resultForm is "s" ) then -- strings result ---------- if ( condi is NOT false ) then -- exist lines repeat for each lines theLine in sourceStr if ( theLine contains findStr ) then put ( theLine & return ) after returnStr end repeat else -- condi=false -- NOT exist lines repeat for each line theLine in sourceStr if NOT ( theLine contains findStr ) then put ( theLine & return ) after returnStr end repeat end if else -- line number result ---------------------------------------- if ( condi is NOT false ) then -- exist lines put 0 into lineCount repeat for each line theLine in sourceStr add 1 to lineCount if ( theLine contains findStr ) then put ( lineCount & "," ) after returnStr end repeat else -- condi=false -- NOT exist lines put 0 into lineCount repeat for each line theLine in sourceStr add 1 to lineCount if NOT ( theLine contains findStr ) then put ( lineCount & "," ) after returnStr end repeat end if end if return returnStr end UxGetFoundLines -- UxGetInst( instNumber ) -- Requestment btn "Inst" -- function UxGetInst instNumber send ( "return getInstName( " & instNumber & ")" ) to btn "Inst" return the result end UxGetInst ----------------// END slg2Pmd //----------------