You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
11 KiB
Plaintext

(
~transcribe = {arg scoreData;
var rawMusicData, timeSigData, sectionData, dir, basePath, maxSize, openStrings, musicData;
rawMusicData = scoreData[0];
timeSigData = scoreData[1];
sectionData = scoreData[2];
dir = thisProcess.nowExecutingPath.dirname;
basePath = dir +/+ ".." +/+ "lilypond";
openStrings = [1/1, 3/2, 2/1, 5/2, 35/12, 7/2];
maxSize = 0;
musicData = rawMusicData.collect({arg partData, p;
var res;
res = partData.collect({arg item, i;
var note, rest;
switch(p,
0, {
var string, fret, dur, sus;
string = item[0];
fret = item[1];
dur = item[2];
sus = item[3];
note = sus.collect({[string, fret, i]});
//rest = (dur - sus).collect({[-1, -1]});
},
1, {
var freq, dur, sus;
freq = item[0];
dur = item[1];
sus = item[2];
note = sus.collect({[freq, i]});
if(p < rawMusicData.size, {rest = (dur - sus).collect({[-1, i]})}, {[]});
},
2, {
var freq1, freq2, dur, sus;
freq1 = item[0];
freq2 = item[1];
dur = item[2];
sus = 4;
note = sus.collect({[[freq1, freq2 - freq1], i]});
if(p < rawMusicData.size, {rest = (dur - sus).collect({[-1, i]})}, {[]});
}
);
note ++ rest
}).flatten;
if(res.size > maxSize, {maxSize = res.size});
//res = res.extend(res.size.trunc(16) + 16, res.last)
res
});
musicData = musicData.collect({arg partData, p;
var lastSectionSize, lastSectionSizeTrunc, finalSectionSize, ext;
partData[(partData.size - 10)..];
lastSectionSize = (maxSize - sectionData.last[0]);
lastSectionSizeTrunc = lastSectionSize.trunc(16);
finalSectionSize = if(lastSectionSize != lastSectionSizeTrunc, {lastSectionSizeTrunc + 16}, {lastSectionSize});
ext = finalSectionSize - lastSectionSize;
partData.extend((maxSize + ext), if(p == 0, {partData.last}, {[-1, partData.last[1]]}))
});
musicData.do({arg part, p;
var amps, harm, modi, timeSigIndex, sectionCount, sectionIndex, subSectionIndex, curTimeSig,
lilyFile, lilyString, voices, lastVal, lilyNotes, lilyOcts, lilyGString, isHarmonic, measureCount,
lilyNote, lilyDur, lilyRest, lilyBeatingMark, curTime = 0, noteTuples, markupSuffixes;
//create file
lilyFile = switch(p,
0, {File(basePath +/+ "includes" +/+ "cicc_guitar.ly".standardizePath,"w")},
1, {File(basePath +/+ "includes" +/+ "cicc_high.ly".standardizePath,"w")},
2, {File(basePath +/+ "includes" +/+ "cicc_low.ly".standardizePath,"w")}
);
//start lilypond directives
lilyString = "";
lastVal = nil;
//start voice
lilyString = lilyString ++ "\n{ ";
lilyString = lilyString ++ "\n\\set Score.markFormatter = #format-mark-box-numbers ";
lilyString = lilyString + "\\tempo 8 = 90\n";
if(p != 1, {lilyString = lilyString + "\\override Staff.TimeSignature #'stencil = ##f"});
//lilyString = lilyString + "\\numericTimeSignature \\time 4/4\n \\mark \\default \n";
lilyString = lilyString + "\\numericTimeSignature \\time 4/4\n";
lilyString = switch(p,
0, {lilyString + "\\clef treble\n"},
1, {lilyString + "\\clef \"treble^8\"\n"},
2, {lilyString + "\\clef bass\n"}
);
lilyNotes = ["c", "cis", "d", "dis","e", "f", "fis", "g", "gis", "a", "ais", "b"];
lilyOcts = [",,", ",", "", "'", "''", "'''", "''''"];
timeSigIndex = 0;
sectionCount = 0;
sectionIndex = 1;
subSectionIndex = 1;
curTimeSig = 4;
measureCount = 0;
part.clump(4).do({arg beat, i;
var gSum = 0;
//beat.postln;
beat.separate({arg a, b; ((a[0] != -1) || (b[0] != -1)) && (a != b)}).do({arg group, g; var noteLength, target = 0;
noteLength = group.size;
gSum = gSum + noteLength;
//add ties
lilyString = lilyString ++ if((group[0] == lastVal) && (group[0][0] != -1), {"~ "}, {""});
//add barcheck count
lilyString = lilyString ++ if((curTime % curTimeSig == 0) && (i != 0), {measureCount = measureCount + 1; "| "}, {""});
//lilyString = lilyString ++ if((curTime % curTimeSig == 0) && ((measureCount % 4) == 0) && (i != 0), {"\n\\break \n"}, {""});
if((i == (sectionData[sectionCount][0] / 4)) && (g == 0),{
var barType, pageBreak;
barType = switch(sectionData[sectionCount][1], 0, {"\"||\""}, 1, {"\".|\""}, -1, {"\"|.|\""});
pageBreak = switch(sectionData[sectionCount][1], 0, {""}, 1, {""}, -1, {measureCount = 0; "\n\\pageBreak \n"});
isHarmonic = switch(sectionData[sectionCount][1], 0, {false}, 1, {true}, -1, {false});
lilyString = lilyString + " \\bar " ++ barType ++ " \\mark \\markup { \\bold \\box " ++ sectionIndex ++ "." ++ subSectionIndex ++ " }" ++ pageBreak;
if(sectionCount < (sectionData.size - 1), {sectionCount = sectionCount + 1});
switch(sectionData[sectionCount][1],
0, {subSectionIndex = subSectionIndex + 1},
1, {subSectionIndex = subSectionIndex + 1},
-1, {sectionIndex = sectionIndex + 1; subSectionIndex = 1})
});
if((i == (timeSigData[timeSigIndex][0] / 4)) && (g == 0),{
timeSigData[timeSigIndex][0];
curTimeSig = timeSigData[timeSigIndex][1];
lilyString = lilyString + "\n\\time " ++ curTimeSig.asString ++ "/4\n";
if(timeSigIndex < (timeSigData.size - 1), {timeSigIndex = timeSigIndex + 1});
curTime = 0;
});
switch(p,
0, {
lilyNote = lilyNotes[(((62.midicps * openStrings[group[0][0]]).cpsmidi + group[0][1]).round(1) % 12)];// * 2];
lilyNote = lilyNote ++ lilyOcts[(((62.midicps * openStrings[group[0][0]]).cpsmidi + group[0][1]).round(1) / 12).asInteger - 2];
},
1, {
if(group[0][0] != -1, {
lilyNote = lilyNotes[((group[0][0].cpsmidi).round(1) % 12)];// * 2];
lilyNote = lilyNote ++ lilyOcts[(((group[0][0]).cpsmidi).round(1) / 12).asInteger - 2];
},{lilyNote = "r"});
},
2, {
if(group[0][0] != -1, {
lilyNote = lilyNotes[((group[0][0][0].cpsmidi).round(1) % 12)];// * 2];
lilyNote = lilyNote ++ lilyOcts[(((group[0][0][0]).cpsmidi).round(1) / 12).asInteger - 2];
lilyBeatingMark = "^ \\markup{ " ++ group[0][0][1].round(0.1) ++ " } ";
},{lilyNote = "r"});
}
);
//duration
lilyDur = switch(noteLength, 1, {"16 "}, 2, {"8 "}, 3, {"8. "}, 4, {"4 "});
//append rest directive
lilyRest = "";
lilyGString = if(((group[0] != lastVal) && (p == 0)), {
var stringString, fretString;
stringString = ["VI ", "V ", "IV ", "III ", "II ", "I "][group[0][0]];
fretString = group[0][1].asString;
if(isHarmonic, {fretString = "\\musicglyph \"noteheads.s0harmonic\""});
"_\\markup{\\concat{ " ++ stringString ++ " \\super " ++ fretString ++ "}} "
}, {""});
if((p != 2) || (lilyNote == "r"), {
lilyString = lilyString ++ lilyNote ++ lilyDur ++ lilyGString;
}, {
lilyString = lilyString ++ " <<{ " ++ lilyNote ++ lilyDur ++ lilyBeatingMark ++ " } \\new Voice { \\voiceTwo " ++
lilyNote ++ lilyDur ++ " }>> \\oneVoice " ++ lilyGString;
});
//beam group
if((g == 0) && (noteLength != 4), {lilyString = lilyString ++ " [ "});
if((gSum == 4) && (noteLength != 4), {lilyString = lilyString ++ " ] "});
lastVal = group[0];
curTime = curTime + (noteLength / 4);
});
});
//end voice
lilyString = lilyString ++ " ] \\bar \"|.\" } \n";
noteTuples = [lilyNotes, lilyOcts].allTuples.collect({arg val; val.join}).join("|");
markupSuffixes = ["VI ", "V ", "IV ", "III ", "II ", "I "].collect({arg stringString;
(["\\\\musicglyph \\\"noteheads.s0harmonic\\\""] ++ (0..14)).collect({arg fret;
"_\\\\markup{\\\\concat{ " ++ stringString ++ " \\\\super " ++ fret.asString ++ "}}"})}).flatten.join("|");
lilyString.findRegexp(
"(" ++ noteTuples ++ ")4 (" ++ markupSuffixes ++ ") ~ " ++
"(" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4"
).clump(7).do({arg match;
lilyString = lilyString.replace(match[0][1], match[1][1] ++ "2. " ++ match[2][1] ++ " ~ " ++ match[1][1] ++ "2")});
lilyString.findRegexp(
"(" ++ noteTuples ++ ")4 (" ++ markupSuffixes ++ ") ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4"
).clump(6).do({arg match;
lilyString = lilyString.replace(match[0][1], match[1][1] ++ "1 " ++ match[2][1])});
lilyString.findRegexp(
"(" ++ noteTuples ++ ")4 (" ++ markupSuffixes ++ ") ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4"
).clump(5).do({arg match;
lilyString = lilyString.replace(match[0][1], match[1][1] ++ "2. " ++ match[2][1])});
lilyString.findRegexp("(" ++ noteTuples ++ ")4 (" ++ markupSuffixes ++ ") ~ (" ++ noteTuples ++ ")4").clump(4).do({arg match;
lilyString = lilyString.replace(match[0][1], match[1][1] ++ "2 " ++ match[2][1])});
//consolidate notes
lilyString.findRegexp(
"(" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4"
).clump(6).do({arg match;
lilyString = lilyString.replace(match[0][1], match[1][1] ++ "2. ~ " ++ match[1][1] ++ "2")});
lilyString.findRegexp(
"(" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4"
).clump(5).do({arg match;
lilyString = lilyString.replace(match[0][1], match[1][1] ++ "1")});
lilyString.findRegexp("(" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4").clump(4).do({arg match;
lilyString = lilyString.replace(match[0][1], match[1][1] ++ "2.")});
lilyString.findRegexp("(" ++ noteTuples ++ ")4 ~ (" ++ noteTuples ++ ")4").clump(3).do({arg match;
lilyString = lilyString.replace(match[0][1], match[1][1] ++ "2")});
//consolidate rests
lilyString.findRegexp("r4 r4 r4 r4 r4").clump(2).do({arg match;
lilyString = lilyString.replace(match[0][1], "r2. r2")});
lilyString.findRegexp("r4 r4 r4 r4").clump(2).do({arg match;
lilyString = lilyString.replace(match[0][1], "r1")});
lilyString.findRegexp("r4 r4 r4").clump(2).do({arg match;
lilyString = lilyString.replace(match[0][1], "r2.")});
lilyString.findRegexp("r4 r4").clump(2).do({arg match;
lilyString = lilyString.replace(match[0][1], "r2")});
lilyString.findRegexp("\\| r1").clump(2).do({arg match;
lilyString = lilyString.replace(match[0][1], "| R1")});
lilyString.findRegexp("4\nr1").clump(2).do({arg match;
lilyString = lilyString.replace(match[0][1], "4\n R1")});
//write file
lilyFile.write(lilyString);
lilyFile.close;
});
};
~genScoreData = {arg guitarSeq, accompLowSeq, accompHighSeq, timeSigInsSeq, sectionSeq;
var stringSeq, fretSeq, durSeq,
partData, timeSigData, sectionData;
stringSeq = guitarSeq.slice(nil, 0);
fretSeq = guitarSeq.slice(nil, 1);
durSeq = guitarSeq.slice(nil, 2);
partData = [
[stringSeq, fretSeq, durSeq, durSeq].flop,
accompHighSeq.collect({arg item; [item[0], (item[1] / 0.08).round.asInteger, (item[2] / 0.08).round.asInteger]}),
accompLowSeq
];
timeSigData = timeSigInsSeq;
sectionData = sectionSeq;
[partData, timeSigData, sectionData]
};
)