[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Accessing context properties (e.g. the current key) from a music fun
From: |
Thomas Morley |
Subject: |
Re: Accessing context properties (e.g. the current key) from a music function? |
Date: |
Fri, 1 May 2015 01:36:01 +0200 |
2015-05-01 1:23 GMT+02:00 David Nalesnik <address@hidden>:
> Hi Leah,
>
> On Thu, Apr 30, 2015 at 3:16 PM, Leah Velleman <address@hidden>
> wrote:
>>
>> I'm looking to write a \transpose-like music function that will need to be
>> able to "find out" what the current key is.
>>
>> (In case it matters: The reason I'm doing this is to make it possible to
>> enter music using movable-do solfege. The idea is to have a function
>> \movableDo that will transpose from C (i.e. "do" in a fixed-do system) to
>> the tonic of the current key, so that
>>
>> \key a \major
>> \movableDo { do re mi fa so }
>>
>>
>> will produce the same output as
>>
>> \key a \major
>>
>> a b cs d e
>>
>>
>> Of course, it would be possible to require the user to repeat the key
>> information, by writing this:
>>
>> \key a \major
>>
>> \movableDo a { do re mi fa so }
>>
>> But this is inconveniently redundant, and makes errors more likely in
>> large source files, since the key must now be written in many different
>> places. So I'm trying to avoid doing it this way if possible.)
>>
>> In any case, I'm having a very difficult time figuring out how a music
>> function can get access to the key. It seems that the issue is that the key
>> is a context property; music functions do not take a context as an argument,
>> and thus can't get access to context properties the way a function written
>> with make-apply-context could. But I can't see how to get around that
>> limitation, or indeed whether it would be possible to get around it at all.
>
>
> I think the only way you'll be able to get access to the key from a music
> function is actually to parse the music expression, looking for the relevant
> music events.
>
> Here's something that's pretty limited, but it show that such a thing is
> possible.
>
> Note that in this sketch, you have to apply the function to each key area
> individually. It would be nice if you could apply the function to the whole
> music expression, but first things first :)
>
> Hope this gets you started--
>
> David
>
> %%%%%%%%%%%%%%%%%%%%%%%%%%
>
> \version "2.18"
>
> \language "italiano" % the closest preset :)
>
> test =
> #(define-music-function (parser location music)
> (ly:music?)
> (let ((t (ly:make-pitch 0 0))) ; C is the default tonic
> (music-map
> (lambda (mus)
> (if (music-is-of-type? mus 'key-change-event)
> (set! t (ly:music-property mus 'tonic)))
> (if (music-is-of-type? mus 'note-event)
> #{
> \transpose #(ly:make-pitch 0 0) #t #mus
> #})
> mus)
> music)
> music))
>
>
> \new Staff {
> \new Voice {
> \test {
> \key re \major
> do'4 mi' sol' do'' <do' mi' sol'>1
> }
> \test {
> \key fa \major
> do'4 mi' sol' do'' <do' mi' sol'>1
> }
> \test {
> \key sol \minor
> do'4 mib' sol' do'' <do' mib' sol'>1
> }
> }
> }
>
This seems to work as well, or am I missing something?
\test
\new Staff {
\new Voice {
{
\key re \major
do'4 mi' sol' do'' <do' mi' sol'>1
}
{
\key fa \major
do'4 mi' sol' do'' <do' mi' sol'>1
}
{
\key sol \minor
do'4 mib' sol' do'' <do' mib' sol'>1
}
}
}
Cheers,
Harm