Returns a FoscObject.
This is the base class for all Fosc objects.
| == | Is true when ID of object equals ID of Fosc object. Otherwise false. |
| !- | |
| > | |
| >= | |
| > | |
| >= | |
| add | (python: add) |
| asInteger | |
| concat | (python: add) |
| div | (python: __div_) |
| dup | (python: mult) |
| mul | (python: mul) |
| sub | (python: sub) |
| difference | //!!! - must be an override at a lower point in the hierarchy |
| intersection | |
| symmetricDifference | |
| union | |
| format | Formats Fosc object. |
| ps | |
| str |
| annotate | Annotates receiver with annotation. |
| attach | !!!TODO: attaches to FoscComponents and FoscSelections? can this method be moved lower in the tree? |
| detach | |
| iterate | |
| mutate | |
| override | Adds a LilyPond override to receiver. |
| setting | |
| set | |
| select | |
| show | Shows object. |
| tweak | Attaches LilyPond tweak to receiver. |
| write | |
| writeLY | |
| writeMIDI | |
| writePDF | |
| writePNG |
| doComponents | |
| doLeaves | |
| doLogicalTies | FIXME find better way to display or capture post output in these examples |
| doRuns | |
| doTimeline | |
| doTimelineByLogicalTies | |
| leafAt | |
| selectComponents | |
| selectLeaves | |
| selectLogicalTies | Selects logical ties. |
| selectRuns | Select runs. |
| isPlaying | |
| pause | |
| play | |
| resume | |
| stop |
Is true when ID of object equals ID of Fosc object. Otherwise false.
Returns true or false.
(python: add)
(python: add)
(python: __div_)
(python: mult)
(python: mul)
(python: sub)
//!!! - must be an override at a lower point in the hierarchy
Formats Fosc object.
Returns string.
Annotates receiver with annotation.
Annotates note with a clef.
a = FoscNote(60, 1/4);
a.annotate('foo', FoscClef('bass'));
FoscInspection(a).annotation('foo').class.postln;FoscClef!!!TODO: attaches to FoscComponents and FoscSelections? can this method be moved lower in the tree? !!! if not, then add a test for a valid receiver type to the top of the method.
Attaches attachment to receiver.
First form attaches indicator to single leaf.
Second form attaches spanner to leaf selection.
Third form attaches grace container to leaf.
Fourth form attaches time signature to measure.
Fifth form attaches wrapper to unknown (?).
Returns nil.
Attaches clef to first note in staff
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
a[0].attach(FoscClef('bass'));
a[0].wrappers;
a.format;\new Staff {
\clef "bass"
c'4
d'4
e'4
f'4
}Attaches accent to last note in staff
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
a[3].attach(FoscArticulation('>'));
a.format;\new Staff {
c'4
d'4
e'4
f'4
-\accent
}Detach by class
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
a[0].attach(FoscArticulation('>'));
a.format;\new Staff {
c'4
-\accent
d'4
e'4
f'4
}a[0].detach(FoscArticulation);
a.format;\new Staff {
c'4
d'4
e'4
f'4
}Detach by instance
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
i = FoscArticulation('>');
a[0].attach(i);
a.format;\new Staff {
c'4
-\accent
d'4
e'4
f'4
}a[0].detach(i);
a.format;\new Staff {
c'4
d'4
e'4
f'4
}Adds a LilyPond override to receiver.
Example
a = FoscNote(60, 1/4);
override(a).noteHead.color = 'red';
override(a).noteHead.size = 12;
a.format;\once \override NoteHead.color = #red
\once \override NoteHead.size = #12
c'4Example
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], 1/8));
set(a).instrumentName = FoscMarkup("Violin");
a.show;
Shows object.
Makes LilyPond input files and output PDF.
Writes LilyPond input file and output PDF to Fosc output directory.
Opens output PDF.
Example
a = FoscNote(60, 1/4);
a.show;
Attaches LilyPond tweak to receiver.
Tweak markup
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
m = FoscMarkup('Allegro assai', direction: 'above');
tweak(m).color = 'red';
m.format;- \tweak color #red
^\markup { "Allegro assai" }a[0].attach(m);
a.format;\new Staff {
c'4
- \tweak color #red
^\markup { "Allegro assai" }
d'4
e'4
f'4
}Survives copy
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
m = FoscMarkup('Allegro assai', direction: 'above');
tweak(m).color = 'red';
n = m.copy;
a.leafAt(0).attach(n);
a.format;\new Staff {
c'4
- \tweak color #red
^\markup { "Allegro assai" }
d'4
e'4
f'4
}Survives dot-chaining
!!!TODO: DOES NOT SURVIVE DOT-CHAINING
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
m = FoscMarkup('Allegro assai', direction: 'above');
tweak(m).color = 'red';
m = m.italic;
a.leafAt(0).attach(m);
a.format;\new Staff {
c'4
^\markup {
\italic
"Allegro assai"
}
d'4
e'4
f'4
}Works for opposite-directed coincident markup
!!!TODO: DOES NOT WORK FOR OPPOSITE-DIRECTED COINCIDENT MARKUP
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
m = FoscMarkup('Allegro assai', direction: 'above');
tweak(m).color = 'red';
a.leafAt(0).attach(m);
n = FoscMarkup('... ma non troppo', direction: 'below');
tweak(n).color = 'blue';
tweak(n).staffPadding = 4;
a.leafAt(0).attach(n);
a.format;\new Staff {
c'4
- \tweak color #red
^\markup { "Allegro assai" }
- \tweak color #blue
- \tweak staff-padding #4
_\markup { "... ma non troppo" }
d'4
e'4
f'4
}Ignored for same-directed coincident markup
!!!TODO: NOT WORKING
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65], [1/4]));
m = FoscMarkup('Allegro assai', direction: 'above');
tweak(m).color = 'red';
a.leafAt(0).attach(m);
n = FoscMarkup('... ma non troppo', direction: 'above');
tweak(n).color = 'blue';
tweak(n).staffPadding = 4;
a.leafAt(0).attach(n);
a.format;\new Staff {
c'4
- \tweak color #red
^\markup { "Allegro assai" }
- \tweak color #blue
- \tweak staff-padding #4
^\markup { "... ma non troppo" }
d'4
e'4
f'4
}Tweaks note-head
!!!TODO: NOT YET IMPLEMENTED FOR FoscComponents
a = FoscStaff(FoscLeafMaker().(#[60,61,62,63], [1/4]));
tweak(a[1].noteHead).color = 'red';
a.format;\new Staff {
c'4
\tweak color #red
cs'4
d'4
ef'4
}a.show;
Tweaks grob aggregated to note-head
!!!TODO: NOT YET IMPLEMENTED FOR FoscComponents
a = FoscStaff(FoscLeafMaker().(#[60,61,62,63], [1/4]));
tweak(a[1].noteHead).accidental.color = 'red';
a.format;\new Staff {
c'4
cs'4
d'4
ef'4
}a.show;
Returns LilyPond tweak manager
m = FoscMarkup('Allegro assai', direction: 'above');
tweak(m).postln;FoscLilypondTweakManager().prSetState(())Tweak object sessions work like this
!!!TODO
Example
a = FoscHairpin('p < f'); // FIXME class not defined
b = FoscLilypondTweakManager();
b.setTweaks(a, #[['dynamicLineSpanner', 5]]);
a.tweaks;
a.tweaks.prGetAttributePairs;Example
a = FoscHorizontalBracket(); // FIXME class not defined
tweak(a).color = 'red';
tweak(a).staffPadding = 5;
a.tweaks.prGetAttributePairs;Iterate notes in a selection
a = FoscLeafMaker().(#[60,62,64,65,67,69], [1/8]);
a.doComponents({ |each, i| each.cs.postln }, FoscNote);FoscSelection([ FoscNote(FoscPitch("C4"), FoscDuration(1, 8)), FoscNote(FoscPitch("D4"), FoscDuration(1, 8)), FoscNote(FoscPitch("E4"), FoscDuration(1, 8)), FoscNote(FoscPitch("F4"), FoscDuration(1, 8)), FoscNote(FoscPitch("G4"), FoscDuration(1, 8)), FoscNote(FoscPitch("A4"), FoscDuration(1, 8)) ])Reverse iterate notes in a selection
a = FoscLeafMaker().(#[60,62,64,65,67,69], [1/8]);
a.doComponents({ |each, i| each.cs.postln }, FoscNote, reverse: true);FoscSelection([ FoscNote(FoscPitch("C4"), FoscDuration(1, 8)), FoscNote(FoscPitch("D4"), FoscDuration(1, 8)), FoscNote(FoscPitch("E4"), FoscDuration(1, 8)), FoscNote(FoscPitch("F4"), FoscDuration(1, 8)), FoscNote(FoscPitch("G4"), FoscDuration(1, 8)), FoscNote(FoscPitch("A4"), FoscDuration(1, 8)) ])Iterate notes in a staff
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65,67,69], [1/8]));
a.doComponents({ |each, i| each.cs.postln }, FoscNote);FoscStaff([ ], 'Staff', false)Iterate all components in a staff
a = FoscStaff(FoscLeafMaker().(#[60,62,64,65,67,69], [1/8]));
a.doComponents({ |each, i| each.cs.postln });FoscStaff([ ], 'Staff', false)Iterate leaf
a = FoscNote(60, 1/4);
a.doComponents({ |each, i| each.cs.postln }, FoscNote);FoscNote('C4', 1/4)Throw error
a = FoscDynamic('p');
a.doComponents({ |each, i| each.cs.postln });ERROR: doComponents: receiver is not iterable: a FoscDynamic.Iterate all leaves
a = FoscLeafMaker().(#[60,62,nil,65,67,nil], [1/8]);
a.doLeaves { |each| each.cs.postln };FoscSelection([ FoscNote(FoscPitch("C4"), FoscDuration(1, 8)), FoscNote(FoscPitch("D4"), FoscDuration(1, 8)), FoscRest(FoscDuration(1, 8)), FoscNote(FoscPitch("F4"), FoscDuration(1, 8)), FoscNote(FoscPitch("G4"), FoscDuration(1, 8)), FoscRest(FoscDuration(1, 8)) ])Iterate pitched leaves
a = FoscLeafMaker().(#[60,62,nil,65,67,nil], [1/8]);
a.doLeaves({ |each| each.cs.postln }, pitched: true);FoscSelection([ FoscNote(FoscPitch("C4"), FoscDuration(1, 8)), FoscNote(FoscPitch("D4"), FoscDuration(1, 8)), FoscRest(FoscDuration(1, 8)), FoscNote(FoscPitch("F4"), FoscDuration(1, 8)), FoscNote(FoscPitch("G4"), FoscDuration(1, 8)), FoscRest(FoscDuration(1, 8)) ])Iterate non-pitched leaves
a = FoscLeafMaker().(#[60,62,nil,65,67,nil], [1/8]);
a.doLeaves({ |each| each.cs.postln }, pitched: false);FoscSelection([ FoscNote(FoscPitch("C4"), FoscDuration(1, 8)), FoscNote(FoscPitch("D4"), FoscDuration(1, 8)), FoscRest(FoscDuration(1, 8)), FoscNote(FoscPitch("F4"), FoscDuration(1, 8)), FoscNote(FoscPitch("G4"), FoscDuration(1, 8)), FoscRest(FoscDuration(1, 8)) ])FIXME find better way to display or capture post output in these examples
Example
a = FoscStaff(FoscLeafMaker().(#[60,60,62,nil,64,64], [1/4,1/24,1/12,1/8,1/4,1/4]));
m = a.selectLeaves;
tie(m[0..1]);
tie(m[4..]);
a.show;
a.selectLogicalTies.items.collect { |each| each.items.collect { |each| each.cs }}.postln;[ [ "FoscNote('C4', 1/4)", "FoscNote('C4', 1/16)" ], [ "FoscNote('D4', 1/8)" ], [ "FoscRest(1/8)" ], [ "FoscNote('E4', 1/4)", "FoscNote('E4', 1/4)" ] ]Iterate all logicalTies
a.doLogicalTies { |each| each.items.collect { |each| each.postcs } };FoscStaff([ ], 'Staff', false)Iterate pitched logicalTies
a.doLogicalTies({ |each| each.items.collect { |each| each.cs }.postln }, pitched: true);FoscStaff([ ], 'Staff', false)Iterate non-pitched logicalTies
a.doLogicalTies({ |each| each.items.collect { |each| each.cs }.postln }, pitched: false);FoscStaff([ ], 'Staff', false)iterate nontrivial logicalTies
a.doLogicalTies({ |each| each.items.collect { |each| each.cs }.postln }, nontrivial: true);FoscStaff([ ], 'Staff', false)Iterate trivial logicalTies
a.doLogicalTies({ |each| each.items.collect { |each| each.cs }.postln }, nontrivial: false);FoscStaff([ ], 'Staff', false)Iterate logicalTies in reverse order
a.doLogicalTies({ |each| each.items.collect { |each| each.cs }.postln }, reverse: true);FoscStaff([ ], 'Staff', false)Attach horizontal bracket to each run.
a = FoscStaff(FoscLeafMaker().(#[60,60,62,nil,64,64], [1/4,1/24,1/12,1/8,1/4,1/4]));
a.consistsCommands.add('Horizontal_bracket_engraver');
m = a.selectLeaves;
tie(m[0..1]);
tie(m[4..]);
t = #['bracket-flare', [0,0], 'color', 'red', 'direction', 'up', 'staff-padding', 5];
a.doRuns { |each| each.horizontalBracket(tweaks: t) };
a.show;
Iterate all leaves
a = FoscStaff(FoscLeafMaker().((60..67), [1/8]));
b = FoscStaff(FoscLeafMaker().((60..63), [1/4]));
c = FoscScore([a, b]);
c.doTimeline { |each, i| each.attach(FoscMarkup(i.asString, 'above')) };
c.show;
Iterate all leaves in reverse
a = FoscStaff(FoscLeafMaker().((60..67), [1/8]));
b = FoscStaff(FoscLeafMaker().((60..63), [1/4]));
c = FoscScore([a, b]);
c.doTimeline({ |each, i| each.attach(FoscMarkup(i.asString, 'above')) }, reverse: true);
c.show;
Iterate pitched leaves
a = FoscStaff(FoscLeafMaker().([60,61,nil,63,nil,nil,65], [1/8]));
b = FoscStaff(FoscLeafMaker().((60..63), [1/4]));
c = FoscScore([a, b]);
c.doTimeline({ |each, i| each.attach(FoscMarkup(i, 'above')) }, pitched: true);
c.show;
Iterate non-pitched leaves
a = FoscStaff(FoscLeafMaker().([60,61,nil,63,nil,nil,65], [1/8]));
b = FoscStaff(FoscLeafMaker().((60..63), [1/4]));
c = FoscScore([a, b]);
c.doTimeline({ |each, i| each.attach(FoscMarkup(i, 'above')) }, pitched: false);
c.show;
Iterate logical ties
a = FoscStaff(FoscLeafMaker().((60..67), [5/32]));
b = FoscStaff(FoscLeafMaker().((60..63), [5/16]));
c = FoscScore([a, b]);
c.doTimelineByLogicalTies({ |each, i| each.head.attach(FoscMarkup(i, 'above')) });
c.show;
Iterate pitched logical ties
a = FoscStaff(FoscLeafMaker().(#[60,61,nil,63,nil,nil,65], [5/32]));
b = FoscStaff(FoscLeafMaker().((60..63), [5/16]));
c = FoscScore([a, b]);
c.doTimelineByLogicalTies({ |each, i| each.head.attach(FoscMarkup(i, 'above')) }, pitched: true);
c.show;
Selection
a = FoscSelection([FoscNote(60, 1/4), FoscNote(62, 1/4)]);
a.leafAt(1).str.postln;d'4Selection: pitched
a = FoscSelection([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
a.leafAt(0, pitched: true).str.postln;c'4Container
a = FoscStaff([FoscNote(60, 1/4), FoscNote(62, 1/4)]);
a.leafAt(1).str.postln;d'4Container: pitched
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
a.leafAt(0, pitched: true).str.postln;c'4Select all components
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
b = a.selectComponents;
b.do { |each| each.str.postln };FoscSelection([ FoscStaff([ ], 'Staff', false), FoscRest(FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("D4"), FoscDuration(1, 4)) ])Select notes
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
b = a.selectComponents(prototype: FoscNote);
b.do { |each| each.str.postln };FoscSelection([ FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("D4"), FoscDuration(1, 4)) ])Select notes and rests
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
b = a.selectComponents(prototype: [FoscNote, FoscRest]);
b.do { |each| each.str.postln };FoscSelection([ FoscRest(FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("D4"), FoscDuration(1, 4)) ])Select notes and rests in reverse order
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
b = a.selectComponents(prototype: [FoscNote, FoscRest], reverse: true);
b.do { |each| each.str.postln };FoscSelection([ FoscNote(FoscPitch("D4"), FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscRest(FoscDuration(1, 4)) ])Select all leaves
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
b = a.selectLeaves;
b.do { |each| each.str.postln };FoscSelection([ FoscRest(FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("D4"), FoscDuration(1, 4)) ])Select pitched leaves
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
b = a.selectLeaves(pitched: true);
b.do { |each| each.str.postln };FoscSelection([ FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("D4"), FoscDuration(1, 4)) ])Select non-pitched leaves
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
b = a.selectLeaves(pitched: false);
b.do { |each| each.str.postln };FoscSelection([ FoscRest(FoscDuration(1, 4)) ])Select leaves in reverse order
a = FoscStaff([FoscRest(1/4), FoscNote(60, 1/4), FoscNote(62, 1/4)]);
b = a.selectLeaves(reverse: true);
b.do { |each| each.str.postln };FoscSelection([ FoscNote(FoscPitch("D4"), FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscRest(FoscDuration(1, 4)) ])Selects logical ties.
Returns new selection.
Example
a = FoscStaff(FoscLeafMaker().(#[60,60,62,nil,64,64], [1/4,1/24,1/12,1/8,1/4,1/4]));
m = a.selectLeaves;
tie(m[0..1]);
tie(m[4..]);
a.show;
Select all logicalTies
b = a.selectLogicalTies;
b.do { |each| each.items.collect { |each| each.cs }.postln };FoscSelection([ FoscLogicalTie([ FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 16)) ]), FoscLogicalTie([ FoscNote(FoscPitch("D4"), FoscDuration(1, 8)) ]), FoscLogicalTie([ FoscRest(FoscDuration(1, 8)) ]), FoscLogicalTie([ FoscNote(FoscPitch("E4"), FoscDuration(1, 4)), FoscNote(FoscPitch("E4"), FoscDuration(1, 4)) ]) ])Select pitched logicalTies
b = a.selectLogicalTies(pitched: true);
b.do { |each| each.items.collect { |each| each.cs }.postln };FoscSelection([ FoscLogicalTie([ FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 16)) ]), FoscLogicalTie([ FoscNote(FoscPitch("D4"), FoscDuration(1, 8)) ]), FoscLogicalTie([ FoscNote(FoscPitch("E4"), FoscDuration(1, 4)), FoscNote(FoscPitch("E4"), FoscDuration(1, 4)) ]) ])Select non-pitched logicalTies
b = a.selectLogicalTies(pitched: false);
b.do { |each| each.items.collect { |each| each.cs }.postln };FoscSelection([ FoscLogicalTie([ FoscRest(FoscDuration(1, 8)) ]) ])Select nontrivial logicalTies
b = a.selectLogicalTies(nontrivial: true);
b.do { |each| each.items.collect { |each| each.cs }.postln };FoscSelection([ FoscLogicalTie([ FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 16)) ]), FoscLogicalTie([ FoscNote(FoscPitch("E4"), FoscDuration(1, 4)), FoscNote(FoscPitch("E4"), FoscDuration(1, 4)) ]) ])Select trivial logicalTies
b = a.selectLogicalTies(nontrivial: false);
b.do { |each| each.items.collect { |each| each.cs }.postln };FoscSelection([ FoscLogicalTie([ FoscNote(FoscPitch("D4"), FoscDuration(1, 8)) ]), FoscLogicalTie([ FoscRest(FoscDuration(1, 8)) ]) ])Select logicalTies in reverse order
b = a.selectLogicalTies(reverse: true);
b.do { |each| each.items.collect { |each| each.cs }.postln };FoscSelection([ FoscLogicalTie([ FoscNote(FoscPitch("E4"), FoscDuration(1, 4)), FoscNote(FoscPitch("E4"), FoscDuration(1, 4)) ]), FoscLogicalTie([ FoscRest(FoscDuration(1, 8)) ]), FoscLogicalTie([ FoscNote(FoscPitch("D4"), FoscDuration(1, 8)) ]), FoscLogicalTie([ FoscNote(FoscPitch("C4"), FoscDuration(1, 4)), FoscNote(FoscPitch("C4"), FoscDuration(1, 16)) ]) ])Select runs.
Attach horizontal bracket to each run.
a = FoscStaff(FoscLeafMaker().(#[60,60,62,nil,64,64], [1/4,1/24,1/12,1/8,1/4,1/4]));
a.consistsCommands.add('Horizontal_bracket_engraver');
m = a.selectLeaves;
tie(m[0..1]);
tie(m[4..]);
a.selectRuns.do { |each| each.horizontalBracket(tweaks: #[['direction', 'up']]) };
a.show;