[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: triggering translation from engraver
From: |
David Kastrup |
Subject: |
Re: triggering translation from engraver |
Date: |
Wed, 23 Aug 2017 18:33:15 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (gnu/linux) |
David Kastrup <address@hidden> writes:
> David Kastrup <address@hidden> writes:
>
>> Jan-Peter Voigt <address@hidden> writes:
>>
>>> Do you have another idea how to do that?
>>
>> Timing is established by iterators and they work on music expressions,
>> not events. So you need to have an iterator in the race from the start.
>> Few iterators have variable length. The sequential iterator can have an
>> elements-callback delivering music expressions. Those can have a
>> structure and/or length determined at callback time.
>>
>> Kicking this into orderly operation does not seem like it would be
>> reasonably workable.
>>
>> Iterators are not user-definable at the moment. Either a general
>> facility or a more specific "wait-iterator" would seem warranted.
>
> You might want to use \lyricsto to add your private control context to
> the Score context. When switching off everything that can track
> melismata, you might get woken up once per event regardless of how long
> your actual expressions are.
>
> But it might make more sense to work on actual infrastructure for this
> rather than fudging around with existing facilities not intended for it.
As an example: I've created a \waitFor music function that does
something similar to what you want. It was just quite useless in the
original state since it waited for a particular expression, and you
cannot use it to wait for \mark "B" when the mark has been generated
with \mark \default .
It turns out, looking at it, that the C++ code already does something
more useful, namely taking the "procedure" callback for evaluating a
triggering condition. While the LilyPond code does not yet match the
C++ code: so I probably gave up for some reason after noticing that this
still wasn't what I could be using.
So this definitely needs fleshing out into something more useful. But
it illustrates the kind of iterator you likely want to be using: I seem
to remember that I was able to make the original version (before fudging
the procedure callback into the C++ code) do something.
>From eda3025f4aebd5b400a40de3fe72bf4e58baf363 Mon Sep 17 00:00:00 2001
From: David Kastrup <address@hidden>
Date: Fri, 17 Jul 2015 17:23:17 +0200
Subject: [PATCH] Create a wait music function.
---
lily/wait-iterator.cc | 112 +++++++++++++++++++++++++++++++++++++++++++++
ly/music-functions-init.ly | 11 +++++
scm/define-music-types.scm | 6 +++
3 files changed, 129 insertions(+)
create mode 100644 lily/wait-iterator.cc
diff --git a/lily/wait-iterator.cc b/lily/wait-iterator.cc
new file mode 100644
index 0000000000..939ba34c9b
--- /dev/null
+++ b/lily/wait-iterator.cc
@@ -0,0 +1,112 @@
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2016 David Kastrup <address@hidden>
+
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "lily-guile.hh"
+#include "context.hh"
+#include "input.hh"
+#include "international.hh"
+#include "moment.hh"
+#include "music.hh"
+#include "music-iterator.hh"
+
+class Wait_iterator : public Music_wrapper_iterator
+{
+ bool triggered_;
+ SCM procedure_;
+protected:
+ virtual void derived_mark () const;
+ virtual Moment pending_moment () const;
+ virtual void process (Moment);
+ virtual bool ok () const;
+ virtual bool run_always () const;
+public:
+ Wait_iterator ();
+ DECLARE_SCHEME_CALLBACK (constructor, ());
+ virtual void construct_children ();
+};
+
+Wait_iterator::Wait_iterator ()
+ : triggered_ (false), procedure_ (SCM_UNDEFINED)
+{
+}
+
+void
+Wait_iterator::derived_mark () const
+{
+ scm_gc_mark (procedure_);
+}
+
+Moment
+Wait_iterator::pending_moment () const
+{
+ if (triggered_)
+ return Moment (0);
+ Moment m;
+ m.set_infinite (1);
+ return m;
+}
+
+bool
+Wait_iterator::run_always () const
+{
+ return triggered
+ || !Music_wrapper_iterator::ok ()
+ || Music_wrapper_iterator::run_always ();
+}
+
+void
+Wait_iterator::process (Moment m)
+{
+ if (triggered_)
+ return;
+ if (scm_is_true (scm_call_1 (procedure_, get_outlet ()->self_scm ())))
+ {
+ triggered_ = true;
+ return;
+ }
+ if (!Music_wrapper_iterator::ok ())
+ {
+ Music_wrapper_iterator::construct_children ();
+ if (!Music_wrapper_iterator::ok ())
+ return;
+ }
+ Music_wrapper_iterator::process (m);
+}
+
+bool
+Wait_iterator::ok () const
+{
+ return !triggered_;
+}
+
+void
+Wait_iterator::construct_children ()
+{
+ procedure_ = get_music ()->get_property ("procedure");
+ if (!ly_is_procedure (procedure_))
+ {
+ get_music ()->origin ()->warning (_ ("Bad procedure"));
+ triggered_ = true;
+ return;
+ }
+
+ Music_iterator::construct_children ();
+}
+
+IMPLEMENT_CTOR_CALLBACK (Wait_iterator)
diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly
index d41da5b5b6..e87196957b 100644
--- a/ly/music-functions-init.ly
+++ b/ly/music-functions-init.ly
@@ -2014,6 +2014,17 @@ void =
Use this if you want to have a scheme expression evaluated
because of its side-effects, but its value ignored."))
+waitFor =
+#(define-music-function (music) (ly:music?)
+ (_i "Wait for the occurence of the given @var{music} in the
+current context. Use it, for example, as
address@hidden
+\\context Score \\waitFor \\mark "A"
address@hidden example
+")
+ (make-music 'WaitMusic
+ 'element music))
+
withMusicProperty =
#(define-music-function (sym val music)
(symbol? scheme? ly:music?)
diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm
index 348bcd0e87..61689a3701 100644
--- a/scm/define-music-types.scm
+++ b/scm/define-music-types.scm
@@ -753,6 +753,12 @@ Syntax: @code{\\\\}")
(length-callback . ,ly:repeated-music::volta-music-length)
(types . (repeated-music volta-repeated-music))
))
+
+ (WaitMusic
+ . ((description . "Waits for the given event.")
+ (iterator-ctor . ,ly:wait-iterator::constructor)
+ (types . (wait-music))
+ ))
))
(set! music-descriptions
--
2.11.0
--
David Kastrup
Re: triggering translation from engraver, Kieren MacMillan, 2017/08/23