how to show symbols on top of LilyPond scores? - lilypond

Santa offered a toy keyboard to my 4-year-old. He enjoys the provided scores, but I'd like to add some songs that we sing together and that are not included in the basic set. Every Key has a symbol (circle, triangle, square) and a color (blue, yellow, purple, red, orange) that is displayed on top of the music score, to help him figure out which keys to press.
I'm not a musician, but I do have a basic understanding on how to write music scores. I've never used lilypond, but I'm a developer and I know latex.
I tried searching for a way to add extra symbols, but I'm not sure this is feasible.

You can draw theses symbols by using some of the various graphics commands found on this page:
https://lilypond.org/doc/v2.24/Documentation/notation/graphic
Store these as markup macros at the top of the LilyPond file, and then call them in the score at the appropriate places.
\version "2.24.0"
blueTriangle = \markup {
\left-align
\with-color "blue"
\triangle ##t
}
orangeCircle = \markup {
\left-align
\with-color "orange"
\draw-circle #1 #0 ##t
}
purpleCircle = \markup {
\left-align
\with-color "purple"
\draw-circle #1 #0 ##t
}
greenSquare = \markup {
\left-align
\with-color "green"
\filled-box #'(0 . 2) #'(0 . 2) #0
}
\new Staff {
g4^\blueTriangle
d'^\orangeCircle
b'^\purpleCircle
f''^\greenSquare
}
This will be a bit tedious if you are placing a symbol above every note. But if you know Scheme you can probably devise a function that reads the note letters and octaves and places the correct symbol in automatically.

Related

Sentence-count function not returning total count

So i've been trying to create a sentence-count function which will cycle through the following 'story':
let story = 'Last weekend, I took literally the most beautiful bike ride of my life. The route is called "The 9W to Nyack" and it actually stretches all the way from Riverside Park in Manhattan to South Nyack, New Jersey. It\'s really an adventure from beginning to end! It is a 48 mile loop and it basically took me an entire day. I stopped at Riverbank State Park to take some extremely artsy photos. It was a short stop, though, because I had a really long way left to go. After a quick photo op at the very popular Little Red Lighthouse, I began my trek across the George Washington Bridge into New Jersey. The GW is actually very long - 4,760 feet! I was already very tired by the time I got to the other side. An hour later, I reached Greenbrook Nature Sanctuary, an extremely beautiful park along the coast of the Hudson. Something that was very surprising to me was that near the end of the route you actually cross back into New York! At this point, you are very close to the end.';
And I realise the problem I'm having but I cannot find a way around this. Basically I want my code to return a the total sCount below but seeing as I've returned my sCount after my loop, it's only adding and returning the one count as a total:
const sentenceTotal = (word) => {
let sCount = 0;
if (word[word.length-1] === "." || word[word.length-1] === "!" || word[word.length-1] === "?") {
sCount += 1;
};
return sCount;
};
// console.log(sentenceTotal(story)) returns '1'.
I've tried multiple ways around this, such as returning sentenceTotal(word) instead of sCount but console.log will just log the function name.
I can make it return the correct sCount total if I remove the function element of it, but that's not what I want.
I don't see any loop or iterator which would go through story to count the number of occurrences of ., ?, or !.
Having recently tackled "counting sentences" myself I know it is a non-trivial problem with many edge cases.
For a simple use-case though you can use split and a regular expression;
story.split(/[?!.]/).length
So you could wrap that in your function like so:
const sentenceTotal = (word) => {
return word.split(/[?.!]/).length
};
let story = 'Last weekend, I took literally the most beautiful bike ride of my life. The route is called "The 9W to Nyack" and it actually stretches all the way from Riverside Park in Manhattan to South Nyack, New Jersey. It\'s really an adventure from beginning to end! It is a 48 mile loop and it basically took me an entire day. I stopped at Riverbank State Park to take some extremely artsy photos. It was a short stop, though, because I had a really long way left to go. After a quick photo op at the very popular Little Red Lighthouse, I began my trek across the George Washington Bridge into New Jersey. The GW is actually very long - 4,760 feet! I was already very tired by the time I got to the other side. An hour later, I reached Greenbrook Nature Sanctuary, an extremely beautiful park along the coast of the Hudson. Something that was very surprising to me was that near the end of the route you actually cross back into New York! At this point, you are very close to the end.';
sentenceTotal(story)
=> 13
There a several strange things about you question so I'll do it in 3 steps :
First step : The syntax.
What you wrote is the assignement to a const of an anonymous variable. So what it does is :
Create a const name 'sentenceCount'
To this const, assign the anonymous function (words) => {...}
Now you have this : sentenceCount(words){...}
And that's all. Because what you wrote : ()=>{} is not the calling of a function, but the declaration of an anonym function, you should read this : https://www.w3schools.com/js/js_function_definition.asp
If you want a global total, you must have a global total variable(not constant) so that the total isn't lost. So :
let sCount = 0; //<-- have sCount as a global variable not a const
function isEndOfSentence(word) {
if (word[word.length-1] === "." || word[word.length-1] === "!" || word[word.length-1] === "?") {
sCount += 1;
};
};
If you are forbidden from using a global variable (and it's best to not do so), then you have to register the total as a return of your function and store the total in the calling 'CountWords(sentence)' function.
function isEndOfSentence(words) {...}
callingFunction(){
//decalaration
let total;
//...inside your loop
total += isEndOfSentence(currentWord)
}
The algorithm
Can you provide more context as how you use you function ?
If your goal is to count the words until there is a delimiter to mark the end of a sentence, your function will not be of great usage .
As it is written, your function will only ever be able to return 0 or 1. As it does the following :
The function is called.
It create a var called sCount and set it to 0
It increment or not sCount
It return sCount so 1 or 0
It's basically a 'isEndOfSentence' function that would return a boolean. It's usage should be in an algorithm like :
// var totalSentence = 0
// for each word
// if(isEndOfSentence(word))
// totalSentence + totalSentence = 1
// endfor
Also this comes back to just counting the punctuation to count the number of sentence.
The quick and small solution
Also I tried specifically to keep the program in an algorithm explicit form since I guess that's what you're dealing with.
But I feel that you wanted to write something small and with as little characters as possible so for your information, there are faster way of doing this with a tool called regex and the native JS 'split(separator)' function of a string.
A regex is a description of a string that it can match to and when used can return those match. And it can be used in JS to split a string:
story.split(/[?!.]/) //<-- will return an array of the sentences of your story.
story.split(/[?!.]/).length //<-- will return the number of element of the array of the sentences of your story, so the sentence count
That does what you wanted but with one line of code. But If you want to be smart about you problem, remember that I said
Also this comes back to just counting the punctuation to count the number of sentence.
So we'll just do that right ?
story.match(/(\.\.\.)|[.?!]/g).length
Have fun here ;) : https://regexr.com/
I hope that helps you ! Good luck !

Custom note heads in LilyPond

I am attempting to replace the default note heads with custom graphics in Lilypond. I've read the documentation under A. 10.3 Graphic which explains how to use \markup to add graphics to a score, however I'm stuck at being able to use those to replace note heads. My question is how can I replace the default note heads for custom ones?
If I understand correctly, you want to make some noteheads substituted by arbitrary graphics. Assuming you already have the graphic in EPS format as sol.eps, this code uses it to change a 'g' to a picture of a sun ('sol' is Spanish for 'sun'):
cabezaSol = {
\once \override NoteHead #'stencil = #ly:text-interface::print
\once \override NoteHead #'text =
\markup {
\general-align #Y #CENTER {
\epsfile #X #2 #"./sol.eps"
}
}
}
{ e'4 f' \cabezaSol g' }

Multiple dynamic markings under one note

I am working with Lilypond and can't figure out how to place two dynamic markings under a whole note. I want it to start piano and then become forte but I don't want to use a crescendo. I'd also rather not indicate two tied half notes. Just p then f under a whole note. This is common in older notation which I am typesetting. Thank you.
You can add one single markup that contains multiple elements to a single note:
\version "2.18.2"
{
f'1 _\markup { \dynamic { f p } }
}
There's an example in the Notation Reference, where it says: "Spacer rests are needed to engrave multiple marks on one note."
If you adapt it to your case, you might write:
\version "2.18.2"
{
R1 |
<< f'1\p { s1\f } >> |
}
However, this triggers the following warning:
warning: Two simultaneous absolute-dynamic events, junking this one
and only the first dynamic mark is printed.
So you must place the second dynamic mark on a different musical moment:
\version "2.18.2"
{
R1 |
<< f'1\p { s4. s16\f s s2 } >> |
}

Lyrics for additional verses in LilyPond?

Is there a way in LilyPond to simply list the lyrics corresponding to
additional verses after the end of the music, with one paragraph per verse?
(N.B. This exact question has been asked before, in 2001, but the first answer ("read this book") references a dead URL, while the second (use \context Lyrics) does not work for me, I get LilyPond syntax errors.)
Here's a song under which I want to write the additional verses.
\header{
title = "Hello World"
}
\score {
\relative {
\time 2/4
\clef treble
\key a \major
cis''2 | a4 fis \bar "|."
}
\addlyrics {
He -- | llo world
}
\layout { }
\midi { }
}
\version "2.18.2"
(Sorry about the syntax highlighting, <!-- language: lang-lilypond --> is not yet supported in the Google Code Prettyfier that SO uses.)
I'd like to add verses 2, 3, and 4 underneath, separated from the music, just as words.
I got an answer from Knute Snortum on the LiliyPond mailing list here
After my score block I can add a markup block like this
\markup {
\column {
\line { \null }
\line { 2. Here I go }
}
}
It turns out that this is covered in the LilyPond documentation (printing stanzas at the end) but they use the term 'stanza' and so my searching for 'verse' did not lead me there.
(It is also worth noting this discussion on meta. Posting LilyPond questions here is likely to lead to down-votes since it is not considered programming by many of the SO community. A better Stack Exchange site to post LilyPond questions to is the Music: Practice and Theory Stack Exchange, though, as I found, the LilyPond mailing list is currently the place most likely to elicit full and prompt answers.)

Getting/comparing Flash color filters dynamically

I know I can apply a Color Filter in Flash by hand, and then copy it to other movieclips dynamically, like so:
newMovieClip.filters = oldMovieClip.filters;
What I would love to do now is be able to check if two movieclips have the same filter.
Something like this:
if (newerMovieClip.filters == oldMovieClip.filters)
...that always comes out as false, even if the two have the same filter. I know I can make this work if I use a colorTransform instead, but I can't in this case. The graphics have lines and shading that are all changing color together, and the brightness/hue/contrast are all important so filters are key.
(What I'm doing: I have clothing items in the menu that the user "colors" by picking a filtered button from a palette I made. When they click the item, and it's not already on the avatar in that color, I want it to appear and/or turn that color. If it's already on the avatar and the same color, I want it to come off... hence the filter check)
EDIT: I see now that you are only dealing with a Color Filter. Ahh. I understand what trying to do now.
this can make things a little easier if that is the only filter on each Movieclip.
In this case we can get each ColorMatrixFilter of each movieclip by moiveclip.filters[0]
then:
function compareColorFilters(a:ColorMatrixFilter, b:ColorMatrixFilter) : Boolean
{
var length:uint = (a.matrix.length > b.matrix.length)?a.matrix.length:b.matrix.length;
for(var i:uint = 0; i < length; ++i)
{
if(a.matrix[i] != b.matrix[i]) { return false; }
}
return true;
}
then to compare to movieclips would be
if(compareColorFilters(ColorMatrixFilter(oldClip.filters[0]), ColorMatrixFilter(newClip.filters[0])) {
//do stuff
}
As you can see you are getting each ColorMatrixFilters from each moveiClip. Then comparing there matrices (which is just an array) element by element. If the Matrices are the same... The colors, brightness, and hues are also the exact same. If confused at all by this, leave a comment.
Hope this helps!
-Travis