setting final duration, code cleanup, and tweaks

main
mwinter 4 years ago
parent b6ab8e625c
commit 02adb42def

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,177 @@
\version "2.19.83"
#(define (override-color-for-all-grobs color)
(lambda (context)
(let loop ((x all-grob-descriptions))
(if (not (null? x))
(let ((grob-name (caar x)))
(ly:context-pushpop-property context grob-name 'color color)
(loop (cdr x)))))))
#(define-markup-command (relMark layout props mus) (ly:music?)
#:properties ((size -2))
(interpret-markup layout props
#{
\markup {
\score {
\new Staff { $mus }
\layout {
\context {
\Staff
\remove Time_signature_engraver
fontSize = #-2
\hide Stem
\override TextScript.outside-staff-priority = ##f
\override StaffSymbol.staff-space = #(magstep -2)
\override StaffSymbol.thickness = #(magstep -2)
\override TextScript.self-alignment-X = #-0.4
\override TextScript.staff-padding = #1
}
\context {
\Score
proportionalNotationDuration = #(ly:make-moment 1/16)
\remove "Separating_line_group_engraver"
\override SpacingSpanner.strict-note-spacing = ##t
\override RehearsalMark.self-alignment-X = #-1
\override RehearsalMark.Y-offset = #10
\override RehearsalMark.X-offset = #10
}
\context {
\Voice
\consists "Horizontal_bracket_engraver"
\override HorizontalBracket.direction = #UP
}
indent = 0
line-width = 4\cm
}
}
}
#}))
\paper {
#(set-paper-size "a4" 'portrait)
top-margin = 1 \cm
bottom-margin = 1 \cm
left-margin = 2 \cm
ragged-bottom = ##t
top-system-spacing =
#'((basic-distance . 15 )
(minimum-distance . 15 )
(padding . 0 )
(stretchability . 0))
system-system-spacing =
#'((basic-distance . 35 )
(minimum-distance . 35 )
(padding . 0 )
(stretchability . 0))
last-bottom-spacing =
#'((basic-distance . 10 )
(minimum-distance . 10 )
(padding . 0 )
(stretchability . 0))
%systems-per-page = 3
first-page-number = 1
print-first-page-number = ##t
print-page-number = ##t
oddHeaderMarkup = \markup { \fill-line { \line { \on-the-fly #not-first-page {\pad-markup #2 { \concat {\italic {"to kill a monarch "} (seed: 1980072514)}}}}}}
evenHeaderMarkup = \markup { \fill-line { \line { \on-the-fly #not-first-page {\pad-markup #2 { \concat {\italic {"to kill a monarch "} (seed: 1980072514)}}}}}}
oddFooterMarkup = \markup { \fill-line {
\concat {
"-"
\fontsize #1.5
\on-the-fly #print-page-number-check-first
\fromproperty #'page:page-number-string
"-"}}}
evenFooterMarkup = \markup { \fill-line {
\concat {
"-"
\fontsize #1.5
\on-the-fly #print-page-number-check-first
\fromproperty #'page:page-number-string
"-"}}}
}
\header {
title = \markup { \italic {to kill a monarch}}
composer = \markup \right-column {"michael winter" "(berlin, germany; 2021)"}
poet = "seed: 1980072514"
tagline = ""
}
#(set-global-staff-size 11)
\layout {
indent = 0.0\cm
line-width = 17.5\cm
ragged-last = ##f
ragged-right = ##f
\context {
\Score
\override BarNumber.stencil = #(make-stencil-circler 0.1 0.25 ly:text-interface::print)
\override Stem.stemlet-length = #0.75
proportionalNotationDuration = #(ly:make-moment 1/16)
\remove "Separating_line_group_engraver"
\override RehearsalMark.self-alignment-X = #-1
\override RehearsalMark.Y-offset = #10
\override RehearsalMark.X-offset = #-8
%\override RehearsalMark.outside-staff-priority = #0
}
\context {
\Staff
\override VerticalAxisGroup.staff-staff-spacing =
#'((basic-distance . 20 )
(minimum-distance . 20 )
(padding . 0 )
(stretchability . 0))
\override VerticalAxisGroup.default-staff-staff-spacing =
#'((basic-distance . 20 )
(minimum-distance . 20 )
(padding . 0 )
(stretchability . 0))
\override TextScript.staff-padding = #2
\override TextScript.self-alignment-X = #0
}
\context {
\StaffGroup
\name "SemiStaffGroup"
\consists "Span_bar_engraver"
\override SpanBar.stencil =
#(lambda (grob)
(if (string=? (ly:grob-property grob 'glyph-name) "|")
(set! (ly:grob-property grob 'glyph-name) ""))
(ly:span-bar::print grob))
}
\context {
\Score
\accepts SemiStaffGroup
}
}
\midi { }
\score{
\new Score
<<
\new SemiStaffGroup {
<<
\include "includes/part_I.ly"
\include "includes/part_II.ly"
\include "includes/part_III.ly"
>>
}
\include "includes/part_star.ly"
>>
\layout{}
\midi{}
}

@ -1,6 +1,6 @@
(
var clockStringFunc, metronomeStringFunc, metronomeColorFunc, updateTransport, updateSubsection,
buildGenerator, buildMetronome, updateSection, buildTransport, buildTempoControl, buildMasterFader, buildTrackFader,
var clockStringFunc, metronomeStringFunc, metronomeColorFunc, updateTransport, updateSection, updateSubsection,
buildGenerator, buildMetronome, buildTransport, buildTempoControl, buildMasterFader, buildTrackFader,
buildMasterView, buildFaderView, buildHelpView, currentSection = 1, currentSubsection = 1;
// these funcs update the elements of the transport panel
@ -27,20 +27,6 @@ updateTransport = {arg clock, metronome, sectionDisplay, measure, beat, section,
{0.75.wait; {metronome.string = ""}.defer}.fork(~tempoClock, quant: 0);
}.inEnvir;
updateSubsection = {arg mod, clock, metronome, sectionDisplay, refresh = true;
if(~sectionNavDict[[currentSection, currentSubsection + mod]] != nil, {
currentSubsection = currentSubsection + mod;
if(refresh, {
updateTransport.value(clock, metronome, sectionDisplay,
~sectionNavDict[[currentSection, currentSubsection]][0], 1,
currentSection, currentSubsection
);
});
}, {
updateSection.value(mod, clock, metronome, sectionDisplay, refresh, true)
})
};
buildGenerator = {arg view;
var ranSeed;
HLayout(
@ -103,6 +89,20 @@ updateSection = {arg mod, clock, metronome, sectionDisplay, refresh = true, indi
});
};
updateSubsection = {arg mod, clock, metronome, sectionDisplay, refresh = true;
if(~sectionNavDict[[currentSection, currentSubsection + mod]] != nil, {
currentSubsection = currentSubsection + mod;
if(refresh, {
updateTransport.value(clock, metronome, sectionDisplay,
~sectionNavDict[[currentSection, currentSubsection]][0], 1,
currentSection, currentSubsection
);
});
}, {
updateSection.value(mod, clock, metronome, sectionDisplay, refresh, true)
})
};
buildTransport = {arg win, view, clock, metronome, preampBusses, accompBusses, postampBusses;
var sec, subsec, sectionDisplay, layout, player;
@ -152,7 +152,6 @@ buildTransport = {arg win, view, clock, metronome, preampBusses, accompBusses, p
[sectionDisplay, layout]
};
buildTempoControl = {arg view;
var layout, tempoField, address, updateSection;
layout = HLayout(
@ -163,7 +162,6 @@ buildTempoControl = {arg view;
[layout, tempoField]
};
buildMasterFader = {arg view;
var trackIndicators, layout, volSlider, muteButton, outMenu;
@ -191,7 +189,6 @@ buildMasterFader = {arg view;
[layout, volSlider, muteButton, outMenu]
};
buildTrackFader = {arg view, name, index;
var trackIndicator, netAddr, layout, volSlider, soloButton, muteButton, panKnob, outMenu;
@ -211,7 +208,6 @@ buildTrackFader = {arg view, name, index;
{netAddr.sendMsg("/soloer_" ++ ~hash, index)}.inEnvir).value_(0),
muteButton = Button(view).states_([["mute", Color.black], ["mute", Color.black, Color.grey]]).action_(
{arg v; var mute = (1 - v.value).abs;
//netAddr.sendMsg("/muter_" ++ ~hash, index);
~play.set(\mute_ ++ index, mute)}.inEnvir).valueAction_(if(index < 4, {1}, {0})),
VLayout(
StaticText(view).string_("pan").align_(\center),
@ -227,7 +223,6 @@ buildTrackFader = {arg view, name, index;
[layout, volSlider, soloButton, muteButton, panKnob, outMenu]
};
buildMasterView = {arg win, preampBusses, accompBusses, postampBusses;
var view, generatorLayout, clock, metronome, metronomeLayout, transportLayout,
tempoContol, auxControlsLayout, countOff, ranSeed, order, tempo, sectionDisplay, address;
@ -257,7 +252,6 @@ buildMasterView = {arg win, preampBusses, accompBusses, postampBusses;
[view, tempoContol[1]]
};
buildFaderView = {arg win, tempoField;
var view, masterIndicators, trackIndicators, master, tracks, openButton, basePath, saveButton;
var partAbbr = ["*", "III", "II", "I", "accomp_II", "accomp_I", "click"];
@ -294,10 +288,6 @@ buildFaderView = {arg win, tempoField;
});
}.defer}, '/soloer_' ++ ~hash, netAddr);
//OSCFunc.new({arg msg; {
//tracks.slice(nil, 2).do({arg solo, m; solo.value.postln; solo.value = 0});
//}.defer}, '/muter_' ++ ~hash, netAddr);
basePath = ~dir +/+ ".." +/+ "mixer_settings";
openButton = Button(view).states_([["open", Color.black]]).action_({
@ -339,12 +329,10 @@ buildFaderView = {arg win, tempoField;
view.layout_(HLayout(HLayout(master[0], nil, *tracks.slice(nil, 0)), VLayout(nil, saveButton, openButton)))
};
buildHelpView = {arg win;
TextView(win).string_(File.readAllString(~dir +/+ "tkam_readme.scd")).editable_(false);
};
~generateGUI = {arg preampBusses, accompBusses, postampBusses;
var win, tabButtonReset, transportButton, mixerButton, helpButton, masterConrol, tempoControl, masterView, faderView, helpView, tabs;
win = Window("to kill a monarch", Rect(500, 500, 1100, 575), false).front;

@ -1,5 +1,6 @@
(
var frAdd, frDiff, frToFloat, frNearestInList, frCollapse, harmonicDistance, //helper functions
// DATA GENEREATOR - this file IS the piece
var frAdd, frDiff, frToFloat, frNearestInList, frCollapse, harmonicDistance,
genMode, hdChoose, wchooseDict, collectRoots,
initModeState, advanceMode,
initTemporalState, genTemporalData,
@ -58,7 +59,6 @@ harmonicDistance = {arg fr; log2(fr[0].asFloat.product * fr[1].asFloat.product)}
//~~~~~~~~~~~~GENERATE MODE~~~~~~~~~~~~
//TODO: Play with this a bit more (should I go back to the old way)
genMode = {arg forceHS = false;
var mode, alternateProb;
alternateProb = [1, 0].wchoose([if(forceHS, {0}, {1}), 4].normalizeSum);
@ -120,18 +120,18 @@ initModeState = {
};
advanceMode = {arg lastModeState, lastCadenceState, forceHS = false;
var curModeState, curRoots, lastRoots, lastCadenceRoot, changeCount;
var curModeState, curRoots, lastRoots, lastCadenceRoot, changeCount, modSpeed;
curModeState = lastModeState.deepCopy;
curRoots = collectRoots.value(curModeState);
lastRoots = collectRoots.value(lastModeState);
lastCadenceRoot = collectRoots.value(lastCadenceState).asList[0];
changeCount = 0;
modSpeed = if(forceHS, {1}, {[1, 2, 3].wchoose([2, 3, 1].normalizeSum)});
//change either when there is a single root or a few notes have changed in the mode
while({
((curRoots == lastRoots) && (changeCount < 3)) ||
((changeCount < 2) && (curRoots.size > 1))
((curRoots == lastRoots) && (changeCount < modSpeed)) ||
((changeCount < modSpeed) && (curRoots.size > 1))
}, {
var roots, rootSel, mults, multProbs, multSel, new;
@ -169,7 +169,6 @@ advanceMode = {arg lastModeState, lastCadenceState, forceHS = false;
old = frNearestInList.value([new, rootSel], curModeState);
if(curModeState[old][\count] >= 20, {
var mode, root;
//mode = genMode.value;
root = [rootSel, curModeState[rootSel][\mode]];
curModeState.add(new ->
Dictionary.with(*[\count->1,\mode->genMode.value(forceHS), \root->root, \mult->multSel, \fr->new]));
@ -189,7 +188,6 @@ initTemporalState = {
tuple->Dictionary.with(*[\count->1])}))
};
//The temporal density could / should also be based on the parts contribution to the mode
genTemporalData = {arg lastTupleState, modeState, cadenceOverride, noParts = 4;
var cadence, curTupleState, timeToNextEvent, tuple, temporalData;
@ -207,7 +205,7 @@ genTemporalData = {arg lastTupleState, modeState, cadenceOverride, noParts = 4;
var flourishDensity, genDensity, flourish, beforeLen, before, after, buffer;
flourishDensity = if(tuple[p] == 1, {0.125 + 0.5.rand}, {3});
if((p == 0) && cadence.not, {flourishDensity = 3});
genDensity = if(p == 0, {3}, {20});
genDensity = if(p == 0, {5}, {20});
flourish = (if(cadence, {16}, {8}) + 32.rand).collect({[0, 1].wchoose([flourishDensity, 1].normalizeSum)});
buffer = 16.collect({0});
@ -270,7 +268,6 @@ genEnsemblePart = {arg partState, modeState, temporalData, roots, part, offset;
firstChange = false;
cadence = if(collectRoots.value(modeState).size == 1, {true}, {false});
lastInsRef = nil;
//if(offset == 0, {cadence = false});
ensData = [];
temporalData.do({arg val, ts;
@ -278,7 +275,7 @@ genEnsemblePart = {arg partState, modeState, temporalData, roots, part, offset;
partState[\lastDur] = partState[\lastDur] + 1;
timeStamp = ts + offset;
change = [val == 1, (val == 1) && firstChange.not].wchoose([1, 2].normalizeSum);//5 * abs((curPulse / minTotalLen).clip(0, 1) - 1)].normalizeSum);
change = [val == 1, (val == 1) && firstChange.not].wchoose([1, 2].normalizeSum);
if(
(partState[\index] == 0) &&
(frToFloat.value(partState[\lastFreqRatio]) >= 4.0) &&
@ -289,20 +286,12 @@ genEnsemblePart = {arg partState, modeState, temporalData, roots, part, offset;
if(change, {
var mult, multWeights, freq, rootFreq, insRef;
//check that this is working correctly
//this weights notes that are richer and mixes with the DCA algorithm
multWeights = mults.collect({arg fr;
var comp = frCollapse.value(frAdd.value(root, fr));
if(modeState.keys.includes(comp), {3}, {1}) * pow(partState[\multCounts][fr], 1);
});
/*
mult = if( (i == (curPhrase.size - 1)), {
hdChoose.value(mults, 3, multWeights);
}, {
hdChoose.value(mults, 0.5, multWeights);
});
*/
mult = hdChoose.value(mults, 0.5, multWeights);
mults.do({arg fr; partState[\multCounts][fr] = partState[\multCounts][fr] + 1});
partState[\multCounts][mult] = 0;
@ -312,8 +301,6 @@ genEnsemblePart = {arg partState, modeState, temporalData, roots, part, offset;
//flute special case
if((partState[\index] == 0) && cadence.not, {
var mode, continue, freqRatio;
//offset.postln;
//cadence.postln;
mode = modeState.keys.asList.collect({arg fr;
[
frCollapse.value(frAdd.value(modeState[fr][\root][0], modeState[fr][\mult])),
@ -325,6 +312,15 @@ genEnsemblePart = {arg partState, modeState, temporalData, roots, part, offset;
mode = mode ++ mode.collect({arg fr; [frAdd.value(fr[0], [[4], [1]]), fr[1], fr[2]]});
continue = true;
//check that this is working correctly
/*
while({continue && ((partState[\noteCount] % 15) > 1)}, {
# freqRatio, root, mult = mode[partState[\noteCount] % 15];
freq = 36.midicps * trans * frToFloat.value(frAdd.value([[1], [1]], freqRatio));
continue = (freq > partState[\lastFreq]) && ((partState[\noteCount] % 15) != 0);
partState[\noteCount] = partState[\noteCount] - 1;
});
continue = true;
*/
while({continue}, {
# freqRatio, root, mult = mode[partState[\noteCount] % 15];
freq = 36.midicps * trans * frToFloat.value(frAdd.value([[1], [1]], freqRatio));
@ -361,7 +357,8 @@ genAccompPart = {arg modeState, temporalData, offset, trans, part, register;
accompData = [];
temporalData.do({arg val, tS;
var change;
change = [val == 1, (val == 1) && firstChange.not].wchoose([1, if(part == 0, {5}, {3})].normalizeSum); //5 * abs((curPulse / minTotalLen).clip(0, 0.8) - 1)].normalizeSum);
change = [val == 1, (val == 1) && firstChange.not].wchoose([1, if(part == 0, {5}, {3})].normalizeSum);
//change = [val == 1, (val == 1) && firstChange.not].wchoose([1, 5].normalizeSum);
if(change, {
var sel, freq, amp;
sel = wchooseDict.value(modeState, 0.1);
@ -421,7 +418,6 @@ genAmpCurve = {arg temporalData1, temporalData2, offset1, offset2, type;
};
//~~~~~~~~~~~~GENERATE ALL MUSIC DATA~~~~~~~~~~~~
~genMusicData = {arg seed;
var minTotalDur, minSection1Dur, dUnit, curLen, cadence,
@ -436,7 +432,7 @@ genAmpCurve = {arg temporalData1, temporalData2, offset1, offset2, type;
thisThread.randSeed = seed;
# minTotalDur, minSection1Dur, dUnit, curLen, cadence = [15 * 60, 8 * 60, 8.reciprocal, 0, false];
# minTotalDur, minSection1Dur, dUnit, curLen, cadence = [23 * 60, 8 * 60, 8.reciprocal, 0, false];
# ultimateSubsection, ultimateSection, ultimateCadenceCount = [false, false, 0];
# minTotalLen, minSection1Len = [(minTotalDur / dUnit).round(16), (minSection1Dur / dUnit).round(16)];
# modeState, temporalState, partStates = [initModeState.value, initTemporalState.value, initPartStates.value];
@ -466,7 +462,7 @@ genAmpCurve = {arg temporalData1, temporalData2, offset1, offset2, type;
ensData[part] = ensData[part] ++ musicData;
partStates[part] = partState;
//use and independent random number generator for the accompaniment
//use an independent random number generator for the accompaniment
accompRoutine = Routine({
thisThread.randSeed = Date.seed;
6.do({arg register;
@ -479,7 +475,6 @@ genAmpCurve = {arg temporalData1, temporalData2, offset1, offset2, type;
});
subsectionCount = subsectionCount + 1;
//thisThread.randSeed = (seed + (sectionCount * 200) + subsectionCount);
if(curLen == 0, {
lastCadenceTemporalData = temporalData;

@ -8,13 +8,11 @@ The play button will always start from the beginning of the current section.
The transport buttons allow you to advance by subsection (<,>) and section (<<,>>).
Tempo change will only go into effect once "set tempo" button is pressed.
Tempo change will only go into effect once the enter key or "set tempo" button is pressed.
Setting the address:port will create a pipe to recieve a message to advance the subsection externally with an OSC message '/nextSubsection. This could be used to set up a foot pedal / controller for the guitarist to advance the subsections manually.
The default seed given in the application and reseeded when the "reset seed" button is pressed will generate the default music and score (as provided). Changing the seed will generate a new version with that seed once the "generate" button is pressed. After the new version is generated, new Lilypond files can be generated by pressing the "transcribe" button. This will create a tkam_score.ly file in a folder labeled "seed_[number]" which can be rendered by Lilypond. Note that the file must be rendered from that location as it dependes on files in that folder and the "includes" subfolder.
The default seed given in the application will generate the first version of the music and score (as provided). Changing the seed will generate a new version with that seed once the "generate" button is pressed. After the new version is generated, new Lilypond files can be generated by pressing the "transcribe" button. This will create a tkam_score.ly file in a folder labeled "seed_[number]" which can be rendered by Lilypond. Note that the file must be rendered from that location as it dependes on files in that folder and the "includes" subfolder.
~~~~mixer tab
This allow invidual control of each of the sonic elements. The synthesized guitar part is automatically muted is at should only be used for audition and practice. The low accompaniment has two separate tracks in case a performer cannot play both the notes. The sonification will go to outputs 1 and 2 while the click will go to outputs 3 and 4.
This allow invidual control of each of the sonic elements. The three parts that can be played on acoustic instruments are automatically muted. The outputs will go out to whatever sound card is being used by the system.
*/

@ -32,14 +32,11 @@ var formatPatternData;
sigs.collect({arg sig, i; SendReply.kr(imp, '/trackLevel_' ++ i ++ "_" ++ ~hash, values: [Amplitude.kr(sig)])});
});
sdTransport = SynthDef(\transport_ ++ ~hash, {arg measure = 0, beat = 0, section = 0, subsection = 0, gate = 1, dur = 1;
SendReply.kr(Impulse.kr(0) * (measure > 0) * (beat > 0),'/measureClock_' ++ ~hash, values: [measure, beat, section, subsection]);
//SendReply.kr(Impulse.kr(0),'/nextSubsection_' ++ ~hash);
EnvGen.kr(Env.sine(dur), gate, doneAction: 2);
});
sdClick = SynthDef(\click_ ++ ~hash, {arg beat = 0, gate = 1, dur = 1;
Out.ar(postampBusses[6], 10 * BPF.ar(WhiteNoise.ar * EnvGen.kr(Env.perc(0.01, 0.1), gate), 440 * ((beat <= 1) + 1), 0.02));
EnvGen.kr(Env.sine(dur), gate, doneAction: 2);
@ -58,8 +55,7 @@ var formatPatternData;
});
sdClip = SynthDef(\clip_ ++ ~hash, {arg dur = 1, gate = 1, bin = 0, bus = 0;
//Out.ar([0, 1], (In.ar(bin)).clip(0, 1) * pow(Line.kr(0, 1, 240), 2))
Out.ar(bus, (In.ar(bin)).clip(0, 1) * 50 * pow(Line.kr(0, 1, 10), 2))
Out.ar(bus, (In.ar(bin)).clip(0, 1) * 50)
});
sdBass = SynthDef(\bass_mono_ ++ ~hash, {arg freq = 440, ampBus = 0, bus = 0;
@ -126,7 +122,6 @@ formatPatternData = {arg musData, measureLen, rel, print = false;
\dur, Pseq(musData[1] * dUnit),
\sustain, Pseq(musData[2] * dUnit),
\amp, [1, 0.7, 0.5, 0.3][p],
//\amp, Pseq(musData[2].collect({arg item; [0, 0.25, 0.5, 0.75][item]}) * [1, 0.5, 0.25, 0.1][p] * 16);
\ampBus, preampBusses[0].index,
\bus, postampBusses[p].index,
\rel, Pseq(musData[6])
@ -140,8 +135,6 @@ formatPatternData = {arg musData, measureLen, rel, print = false;
\dur, Pseq(musData[1] * dUnit),
\sustain, Pseq(musData[2] * dUnit),
\amp, Pseq(musData[3].collect({arg item; [0, 2, 4, 8][item]}) * 0.0125 * 1),
//\attack, Pseq(musData[1] * abs(musData[3].clip(0, 0.25) * 2 - 1) * dUnit),
//\attack, Pseq(musData[2] * 1 * dUnit),
\ampBus, preampBusses[0].index,
\bout, Pseq(musData[4].collect({arg index; accompBusses[index].index})),
\rel, Pseq(musData[5])

@ -22,9 +22,8 @@ formatMusicData = {arg rawMusicData;
res
});
// make them all the same length
//make them all the same length
maxSize = maxSize.trunc(64) + 64;
//musicData = musicData.collect({arg partData, p; partData.extend(maxSize, [-1, -1, -1, partData.last[1]])});
musicData = musicData.collect({arg partData, p; partData.extend(maxSize, partData.last)});
musicData
};

Loading…
Cancel
Save