sugarlabs / musicblocks

Music Blocks -- A musical microworld
https://musicblocks.sugarlabs.org/
GNU Affero General Public License v3.0
558 stars 757 forks source link

Note inside note #803

Closed pikurasa closed 6 years ago

pikurasa commented 7 years ago

I think we already have a ticket for this, but I cannot find at the moment.

I think that it is important to have MB do the following when one note block is nestled within another. MB should perform both notes, starting at the same time and for the specified length of the notes.

So for example:

Starting with...

{Sol4 - 1/4} {Mi4 - 1/4} {Sol4 - 1/2}

I might nestle a Do5 - 1/1 note inside of the first Sol4 - 1/4

{Sol4 - 1/4 {Do5 - 1/1}} {Mi4 - 1/4} {Sol4 - 1/2}

...this would perform two voices, one of which (Do5) would be a whole note.

Adding more nestled notes would build upon one another (with additional voices when overlapping) such that the following would be possible:

{Sol4 - 1/4 {Do5 - 1/1} {Do3 -1/2}} {Mi4 - 1/4} {Sol4 - 1/2 {Mi3 - 1/4}}

where we would essentially have three voices

Do5 ------------------------| Sol4 -- Mi4 -- Sol4 -------| Do3 ----------Mi3--|(rest)|

Why have this possibility?

This is how Lilypond would handle such voices: http://lilypond.org/doc/v2.19/Documentation/ca/lily-057f9e47.ly http://lilypond.org/doc/v2.19/Documentation/ca/lily-057f9e47.png

(from http://lilypond.org/doc/v2.19/Documentation/notation/multiple-voices)

Devin

walterbender commented 7 years ago

One question: What about notes inside of notes inside of notes? Do we flatten everything? e.g., Sol4 - 1/4 {Do5 - 1/1 {Do3 -1/2}}} {Mi4 - 1/4} {Sol4 - 1/2 {Mi3 - 1/4}}

Still? Do5 ------------------------| Sol4 -- Mi4 -- Sol4 -------| Do3 ----------Mi3--|(rest)|

walterbender commented 7 years ago

It will take a bit of book-keeping, but this is doable. One caveat: How do we disambiguate when querying the note value of a voice? (or the beat count for that matter)? Do we always assume the outermost note value?

walterbender commented 7 years ago

I think I have the basics working. But it will not transcribe properly in Lilypond yet and I don't know the implications for some of the widgets. But please do test in the note-in-note branch: https://github.com/walterbender/musicblocks/tree/note-in-note

walterbender commented 7 years ago

Note: This is perhaps a bit too complicated for a GCI task.

walterbender commented 7 years ago

Here is the Lilypond glue we'll need:

<< { \voiceOne … }
  \new Voice { \voiceTwo … }
>> \oneVoice
walterbender commented 7 years ago

I mostly kind of have the Lilypond output working... but it seems a bit scrambled. @pikurasa can you take a look?

walterbender commented 7 years ago

There is a problem with the compile code when combined with graphics in terms of the order of execution. I need to reinstate a sort based on the time stamp.

walterbender commented 7 years ago

It is kind of fun... you can add graphics to the embedded notes in parallel with the graphics you have in the other notes... check out:

[[0,["start",{"collapsed":false,"xcor":197.22197561553025,"ycor":-98.99014559659099,"heading":0,"color":20,"shade":50,"pensize":5,"grey":100}],194,82,[null,1,null]],[1,["newnote",{}],207.5,122.5,[0,2,5,9]],[2,["divide",{}],303.72119140625,122.5,[1,3,4]],[3,["number",{"value":1}],389.22119140625,122.5,[2]],[4,["number",{"value":4}],389.22119140625,154,[2]],[5,["vspace",{}],221,154,[1,43]],[6,["pitch",{}],221,217,[43,7,8,28]],[7,["solfege",{"value":"sol"}],294.5,217,[6]],[8,["number",{"value":4}],294.5,248.5,[6]],[9,["hidden",{}],207.5,595,[1,10]],[10,["newnote",{}],207.5,595,[9,11,14,18]],[11,["divide",{}],303.72119140625,595,[10,12,13]],[12,["number",{"value":1}],389.22119140625,595,[11]],[13,["number",{"value":4}],389.22119140625,626.5,[11]],[14,["vspace",{}],221,626.5,[10,45]],[15,["pitch",{}],221,689.5,[45,16,17,null]],[16,["solfege",{"value":"mi"}],294.5,689.5,[15]],[17,["number",{"value":4}],294.5,721,[15]],[18,["hidden",{}],207.5,784,[10,19]],[19,["newnote",{}],207.5,784,[18,20,23,27]],[20,["divide",{}],303.72119140625,784,[19,21,22]],[21,["number",{"value":1}],389.22119140625,784,[20]],[22,["number",{"value":2}],389.22119140625,815.5,[20]],[23,["vspace",{}],221,815.5,[19,47]],[24,["pitch",{}],221,878.5,[47,25,26,null]],[25,["solfege",{"value":"sol"}],294.5,878.5,[24]],[26,["number",{"value":4}],294.5,910,[24]],[27,["hidden",{}],207.5,973,[19,null]],[28,["newnote",{}],221,280,[6,29,32,36]],[29,["divide",{}],317.22119140625,280,[28,30,31]],[30,["number",{"value":1}],402.72119140625,280,[29]],[31,["number",{"value":1}],402.72119140625,311.5,[29]],[32,["vspace",{}],234.5,311.5,[28,33]],[33,["pitch",{}],234.5,343,[32,34,35,41]],[34,["solfege",{"value":"fa"}],308,343,[33]],[35,["number",{"value":4}],308,374.5,[33]],[36,["hidden",{}],221,563.5,[28,null]],[37,["forward",{}],248,437.5,[41,38,39]],[38,["number",{"value":100}],326.51708984375,437.5,[37]],[39,["right",{}],248,469,[37,40,null]],[40,["number",{"value":90}],321.5,469,[39]],[41,["repeat",{}],234.5,406,[33,42,37,null]],[42,["number",{"value":4}],306.5,406,[41]],[43,["setcolor",{}],221,185.5,[5,44,6]],[44,["number",{"value":70}],306.189453125,185.5,[43]],[45,["setcolor",{}],221,658,[14,46,15]],[46,["number",{"value":40}],306.189453125,658,[45]],[47,["setcolor",{}],221,847,[23,48,24]],[48,["number",{"value":20}],306.189453125,847,[47]]]
walterbender commented 7 years ago

Also, any idea how to make this work for ABC output?

walterbender commented 7 years ago

@pikurasa have you had a chance to try this yet? Any comments/feedback?

walterbender commented 6 years ago

Fixed a couple of issues with the P-T-Matrix and Timbre widgets. Re the P-T-M, the behavior is not really correct in that the embedded notes are added before the containing note rather than in parallel. It would be a lot of work to add multiple overlapping rhythms to the P-T-M. Not sure it is worthwhile and certainly not worth holding up landing of this patch.

pikurasa commented 6 years ago

When I tested, I was on 5f09f01... put in placeholder for multivoice code

One thing that I expect to do is to have some notes play for longer than their "written" value (and thus do not need two different notes--see the .tb code to see what I tried), so I transcribed Bach's Minuette 2 from his 1st Cello Suite in G Major.

The sound seems to work correctly, but the Lilypond output is off. The note values for the original voice seems to be dictating the value for the contrapuntal voice. Image below and lilypond code underneath (with .tb code embedded).

screenshot from 2017-09-30 15 47 32

`\version "2.18.2"

% **** % % WHAT IS THIS? -- This is a LilyPond file generated from Music % Blocks software (Read about it at www.musicblocks.net). % % DOWNLOAD LILYPOND -- In order to create notation with this file, % you will need to download and install LilyPond software onto your % computer (http://lilypond.org/download.html). Frescobaldi % software is also handy for editing LilyPond files % (http://frescobaldi.org/download). % % LILYPOND INSTRUCTIONS -- For instructions on how to further % manipulate musical notation using LilyPond software, please % read the Introduction (http://lilypond.org/text-input.html) and % the Manual % (http://lilypond.org/doc/v2.18/Documentation/learning/index.html). % % GLOSSARY -- A glossary with helpful examples may be found here % (http://www.lilypond.org/doc/v2.19/Documentation/music-glossary/). % % MUTOPIA -- You may also benefit from studying scores from the % Mutopia Project website, which has freely sharable music notation % generated with LilyPond (http://www.mutopiaproject.org/). % % LILYBIN -- You can explore your Lilypond output in a web browser at % (http://lilybin.com/). % % COMMENTS -- Some of the code below is commented out. You can % enable it by deleting the % that precedes the text or, in the % case of a commented section, deleting the %{ and %} that surrounds % the section. % % ****

% Please add your own name, the title of your musical creation, % and the intended copyright below. % The copyright is great for sharing (and re-sharing)! % Read more about it here (http://creativecommons.org/licenses/by-sa/4.0/). % Of course, you can use any copyright you like -- you made it! \header { dedication = \markup { \abs-fontsize #8 \sans "Made with LilyPond and Music Blocks" \with-url #"http://walterbender.github.io/musicblocks/" { \abs-fontsize #8 \sans "(http://walterbender.github.io/musicblocks/)" } } title = "My Music Blocks Creation" % subtitle = "Subtitle" % instrument = "Instrument" composer = "Mr. Mouse" % arranger = "Arranger" copyright = "Mr. Mouse (c) 2017 -- CC-BY-SA" tagline = "Made from Music Blocks v.2.0" footer = \markup { \with-url #"http://walterbender.github.io/musicblocks/" "Made with Music Blocks Software v.2.0." Engraved on \simple #(strftime "%Y-%m-%d" (localtime (current-time))) } currentYear = \markup { \simple #(strftime "%Y" (localtime (current-time))) } copyTag = " free to distribute, modify, and perform" copyType = \markup { \with-url #"http://creativecommons.org/licenses/by-sa/3.0/" "Creative Commons Attribution ShareAlike 3.0 (Unported) License " } copyright = \markup { \override #'(baseline-skip . 0 ) \right-column { \sans \bold \with-url #"http://musicblocks.net" { \abs-fontsize #9 "Music " \concat { \abs-fontsize #12 \with-color #white \char ##x01C0 \abs-fontsize #9 "Blocks " } } } \override #'(baseline-skip . 0 ) \center-column { \abs-fontsize #11.9 \with-color #grey \bold { \char ##x01C0 \char ##x01C0 } } \override #'(baseline-skip . 0 ) \column { \abs-fontsize #8 \sans \concat { " Typeset using " \with-url #"http://www.lilypond.org" "LilyPond software " \char ##x00A9 " " \currentYear " by " \composer " " \char ##x2014 " " \footer } \concat { \concat { \abs-fontsize #8 \sans { " " \copyType \char ##x2014 \copyTag } } \abs-fontsize #13 \with-color #white \char ##x01C0 } } } tagline = ##f }

% To change the meter make adjustments in the following section. % You must also delete the % before \meter everywhere it appears below. meter = { % \time 3/4 % \key c \minor \numericTimeSignature % \partial 4 % \tempo "Andante" 4=90 }

% You can change the MIDI instruments below to anything on logo list: % (http://lilypond.org/doc/v2.18/documentation/notation/midi-instruments)

mouse = { \meter bes8 a8 << { \voiceTwo bes2 } \new Voice { \voiceOne bes8 }

\oneVoice d8 << { \voiceTwo ees4 } \new Voice { \voiceOne ees8 } \oneVoice g, 8 << { \voiceTwo f, 2. } \new Voice { \voiceOne f, 4 } \oneVoice a4 d4 \bar "|." }

mouseVoice = \new Staff \with { \clef "bass_8" instrumentName = "mouse" shortInstrumentName = "m" midiInstrument = "acoustic grand"

\remove "Note_heads_engraver" \consists "Completion_heads_engraver" \remove "Rest_engraver" \consists "Completion_rest_engraver" } { \clef "bass_8" \mouse }

\score { << \mouseVoice

% GUITAR TAB SECTION % Delete the %{ and %} below to include guitar tablature output. %{ \new TabStaff = "guitar tab" << \clef moderntab \context TabVoice = "mouse" \mouse

%}

\layout {}

% MIDI SECTION % Delete the %{ and %} below to include MIDI output. %{ \midi { \tempo 4=90 } %}

}

% MUSIC BLOCKS CODE % Below is the code for the Music Blocks project that generated logo Lilypond file. %{

[[0,["start",{"collapsed":false,"xcor":0,"ycor":0,"heading":0,"color":0,"shade":50,"pensize":5,"grey":100}],280.6666666666667,67,[null,100,null]], [1,["newnote",{}],307.6666666666667,170.5,[104,2,5,9]], [2,["divide",{}],403.8878580729167,170.5,[1,3,4]], [3,["number",{"value":1}],489.3878580729167,170.5,[2]], [4,["number",{"value":8}],489.3878580729167,202,[2]], [5,["vspace",{}],321.1666666666667,202,[1,6]], [6,["pitch",{}],321.1666666666667,233.5,[5,7,8,null]], [7,["solfege",{"value":"ti♭"}],394.6666666666667,233.5,[6]], [8,["number",{"value":4}],394.6666666666667,265,[6]], [9,["hidden",{}],307.6666666666667,328,[1,10]], [10,["newnote",{}],307.6666666666667,328,[9,11,14,18]], [11,["divide",{}],403.8878580729167,328,[10,12,13]], [12,["number",{"value":1}],489.3878580729167,328,[11]], [13,["number",{"value":8}],489.3878580729167,359.5,[11]], [14,["vspace",{}],321.1666666666667,359.5,[10,15]], [15,["pitch",{}],321.1666666666667,391,[14,16,17,null]], [16,["solfege",{"value":"la"}],394.6666666666667,391,[15]], [17,["number",{"value":4}],394.6666666666667,422.5,[15]], [18,["hidden",{}],307.6666666666667,485.5,[10,19]], [19,["newnote",{}],307.6666666666667,485.5,[18,20,23,24]], [20,["divide",{}],403.8878580729167,485.5,[19,21,22]], [21,["number",{"value":1}],489.3878580729167,485.5,[20]], [22,["number",{"value":8}],489.3878580729167,517,[20]], [23,["vspace",{}],321.1666666666667,517,[19,106]], [24,["hidden",{}],307.6666666666667,800.5,[19,52]], [25,["newnote",{}],321.1666666666667,611.5,[106,26,29,33]], [26,["divide",{}],417.3878580729167,611.5,[25,27,28]], [27,["number",{"value":1}],502.8878580729167,611.5,[26]], [28,["number",{"value":2}],502.8878580729167,643,[26]], [29,["vspace",{}],334.6666666666667,643,[25,30]], [30,["pitch",{}],334.6666666666667,674.5,[29,31,32,null]], [31,["solfege",{"value":"ti♭"}],408.1666666666667,674.5,[30]], [32,["number",{"value":4}],408.1666666666667,706,[30]], [33,["hidden",{}],321.1666666666667,769,[25,null]], [34,["newnote",{}],307.6666666666667,1273,[69,35,38,42]], [35,["divide",{}],403.8878580729167,1273,[34,36,37]], [36,["number",{"value":1}],489.3878580729167,1273,[35]], [37,["number",{"value":8}],489.3878580729167,1304.5,[35]], [38,["vspace",{}],321.1666666666667,1304.5,[34,39]], [39,["pitch",{}],321.1666666666667,1336,[38,40,41,null]], [40,["solfege",{"value":"sol"}],394.6666666666667,1336,[39]], [41,["number",{"value":3}],394.6666666666667,1367.5,[39]], [42,["hidden",{}],307.6666666666667,1430.5,[34,43]], [43,["newnote",{}],307.6666666666667,1430.5,[42,44,47,51]], [44,["divide",{}],403.8878580729167,1430.5,[43,45,46]], [45,["number",{"value":1}],489.3878580729167,1430.5,[44]], [46,["number",{"value":4}],489.3878580729167,1462,[44]], [47,["vspace",{}],321.1666666666667,1462,[43,112]], [48,["pitch",{}],334.6666666666667,1619.5,[98,49,50,null]], [49,["solfege",{"value":"fa"}],408.1666666666667,1619.5,[48]], [50,["number",{"value":3}],408.1666666666667,1651,[48]], [51,["hidden",{}],307.6666666666667,1745.5,[43,76]], [52,["newnote",{}],307.6666666666667,800.5,[24,53,56,60]], [53,["divide",{}],403.8878580729167,800.5,[52,54,55]], [54,["number",{"value":1}],489.3878580729167,800.5,[53]], [55,["number",{"value":8}],489.3878580729167,832,[53]], [56,["vspace",{}],321.1666666666667,832,[52,57]], [57,["pitch",{}],321.1666666666667,863.5,[56,58,59,null]], [58,["solfege",{"value":"re"}],394.6666666666667,863.5,[57]], [59,["number",{"value":4}],394.6666666666667,895,[57]], [60,["hidden",{}],307.6666666666667,958,[52,61]], [61,["newnote",{}],307.6666666666667,958,[60,62,65,69]], [62,["divide",{}],403.8878580729167,958,[61,63,64]], [63,["number",{"value":1}],489.3878580729167,958,[62]], [64,["number",{"value":8}],489.3878580729167,989.5,[62]], [65,["vspace",{}],321.1666666666667,989.5,[61,109]], [66,["pitch",{}],334.6666666666667,1147,[74,67,68,null]], [67,["solfege",{"value":"mi♭"}],408.1666666666667,1147,[66]], [68,["number",{"value":4}],408.1666666666667,1178.5,[66]], [69,["hidden",{}],307.6666666666667,1273,[61,34]], [70,["newnote",{}],321.1666666666667,1084,[109,71,74,75]], [71,["divide",{}],417.3878580729167,1084,[70,72,73]], [72,["number",{"value":1}],502.8878580729167,1084,[71]], [73,["number",{"value":4}],502.8878580729167,1115.5,[71]], [74,["vspace",{}],334.6666666666667,1115.5,[70,66]], [75,["hidden",{}],321.1666666666667,1241.5,[70,null]], [76,["newnote",{}],307.6666666666667,1745.5,[51,77,80,84]], [77,["divide",{}],403.8878580729167,1745.5,[76,78,79]], [78,["number",{"value":1}],489.3878580729167,1745.5,[77]], [79,["number",{"value":4}],489.3878580729167,1777,[77]], [80,["vspace",{}],321.1666666666667,1777,[76,81]], [81,["pitch",{}],321.1666666666667,1808.5,[80,82,83,null]], [82,["solfege",{"value":"la"}],394.6666666666667,1808.5,[81]], [83,["number",{"value":4}],394.6666666666667,1840,[81]], [84,["hidden",{}],307.6666666666667,1903,[76,85]], [85,["newnote",{}],307.6666666666667,1903,[84,86,89,93]], [86,["divide",{}],403.8878580729167,1903,[85,87,88]], [87,["number",{"value":1}],489.3878580729167,1903,[86]], [88,["number",{"value":4}],489.3878580729167,1934.5,[86]], [89,["vspace",{}],321.1666666666667,1934.5,[85,90]], [90,["pitch",{}],321.1666666666667,1966,[89,91,92,null]], [91,["solfege",{"value":"re"}],394.6666666666667,1966,[90]], [92,["number",{"value":4}],394.6666666666667,1997.5,[90]], [93,["hidden",{}],307.6666666666667,2060.5,[85,null]], [94,["newnote",{}],321.1666666666667,1556.5,[112,95,98,99]], [95,["divide",{}],417.3878580729167,1556.5,[94,96,97]], [96,["number",{"value":3}],502.8878580729167,1556.5,[95]], [97,["number",{"value":4}],502.8878580729167,1588,[95]], [98,["vspace",{}],334.6666666666667,1588,[94,48]], [99,["hidden",{}],321.1666666666667,1714,[94,null]], [100,["settransposition",{}],294.1666666666667,107.5,[0,101,104,105]], [101,["multiply",{}],450.4098307291667,107.5,[100,102,103]], [102,["number",{"value":12}],535.9098307291667,107.5,[101]], [103,["number",{"value":-1}],535.9098307291667,139,[101]], [104,["vspace",{}],307.6666666666667,139,[100,1]], [105,["hidden",{}],294.1666666666667,2092,[100,null]], [106,["pitch",{}],321.1666666666667,548.5,[23,107,108,25]], [107,["solfege",{"value":"ti♭"}],394.6666666666667,548.5,[106]], [108,["number",{"value":4}],394.6666666666667,580,[106]], [109,["pitch",{}],321.1666666666667,1021,[65,110,111,70]], [110,["solfege",{"value":"mi♭"}],394.6666666666667,1021,[109]], [111,["number",{"value":4}],394.6666666666667,1052.5,[109]], [112,["pitch",{}],321.1666666666667,1493.5,[47,113,114,94]], [113,["solfege",{"value":"fa"}],394.6666666666667,1493.5,[112]], [114,["number",{"value":3}],394.6666666666667,1525,[112]], [115,0,[0,"notes","Bb3",0.3333333333333333,"default",null,null]], [116,0,[0.3333333333333333,"notes","A3",0.3333333333333333,"default",null,null]], [117,0,[0.6666666666666666,"notes","Bb3",1.3333333333333333,"default",null,null]], [118,0,[0.6666666666666666,"notes","Bb3",0.3333333333333333,"default",null,null]], [119,0,[1,"notes","D3",0.3333333333333333,"default",null,null]], [120,0,[1.3333333333333333,"notes","Eb3",0.6666666666666666,"default",null,null]], [121,0,[1.3333333333333333,"notes","Eb3",0.3333333333333333,"default",null,null]], [122,0,[1.6666666666666665,"notes","G2",0.3333333333333333,"default",null,null]], [123,0,[1.9999999999999998,"notes","F2",2,"default",null,null]], [124,0,[1.9999999999999998,"notes","F2",0.6666666666666666,"default",null,null]], [125,0,[2.6666666666666665,"notes","A3",0.6666666666666666,"default",null,null]], [126,0,[3.333333333333333,"notes","D3",0.6666666666666666,"default",null,null]]] %}

`

walterbender commented 6 years ago

@pikurasa Think you could generate the correct lillypond code by hand? Then I can try to model it in code.

walterbender commented 6 years ago

The lilypond bug seems to be due to some code we added to enable automatic splitting of notes across measure. Eliminating that code makes everything work.

pikurasa commented 6 years ago

I figured out how we do more complex structures.

The example on the website is:

<< { \voiceOne … }
  \new Voice { \voiceTwo … }
>> \oneVoice

...but this does not describe what to do when layering multiple voices.

So, I thought about it and tried the following:

…

<< { \voiceOne … 

<< { \voiceThree … }
  \new Voice { \voiceFour … }
>> \oneVoice

}
  \new Voice { \voiceTwo … }
>> \oneVoice

It works!

I applied it to the Bach example and I get the results I am looking for (I am sure this could be cleaner, but it works):

\version "2.18.2"
  \new Voice = "melody" {
    \clef bass
    \time 3/4
%%{
% option to merge note heads together; on by default when note-in-note is used in code.
 \mergeDifferentlyHeadedOn
 \mergeDifferentlyDottedOn
%}
{ \voiceOne bes8 a8
<<
{ \voiceOne bes8 d8 

<< { \voiceOne ees8 g,8 }
  \new Voice
  { \voiceFour ees4 }
>> \oneVoice }

\new Voice 
 { \voiceTwo bes2 }
 { \voiceOne }
>> \oneVoice

\voiceOne
<< \new Voice { \voiceOne f, 4 

<< { \voiceThree a4 d4 }
  \new Voice { \voiceFour a }
>> \oneVoice }

{ \voiceTwo f, 2. }
>> \oneVoice

}
\bar "|."
}

Note:

walterbender commented 6 years ago

I am creating a new ticket: Improve Lilypond output for multiple voices