X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fmusic-scheme.cc;h=55f1333bf5dbb297d3f00426865113b7c6c5a871;hb=0b544cfb7332615ef809b71b57ab656741311ae1;hp=f8eca4a6fe4d80faa004b9bfb7d734efcfbf0807;hpb=4bb29573149a0ffa1f881c5e38a0fe68e9e76b67;p=lilypond.git diff --git a/lily/music-scheme.cc b/lily/music-scheme.cc index f8eca4a6fe..55f1333bf5 100644 --- a/lily/music-scheme.cc +++ b/lily/music-scheme.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 2005--2011 Han-Wen Nienhuys + Copyright (C) 2005--2014 Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ #include "music.hh" #include "duration.hh" +#include "program-option.hh" #include "warn.hh" LY_DEFINE (ly_music_length, "ly:music-length", @@ -73,6 +74,17 @@ LY_DEFINE (ly_music_p, "ly:music?", return scm_from_bool (unsmob_music (obj)); } +LY_DEFINE (ly_event_p, "ly:event?", + 1, 0, 0, (SCM obj), + "Is @var{obj} a proper (non-rhythmic) event object?") +{ + if (Music *m = unsmob_music (obj)) + { + return scm_from_bool (m->is_mus_type ("post-event")); + } + return SCM_BOOL_F; +} + /* todo: property args */ LY_DEFINE (ly_music_mutable_properties, "ly:music-mutable-properties", 1, 0, 0, (SCM mus), @@ -102,18 +114,30 @@ LY_DEFINE (ly_music_list_p, "ly:music-list?", LY_DEFINE (ly_music_deep_copy, "ly:music-deep-copy", 1, 0, 0, (SCM m), - "Copy @var{m} and all sub expressions of@tie{}@var{m}.") + "Copy @var{m} and all sub expressions of@tie{}@var{m}." + " @var{m} may be an arbitrary type; cons cells and music" + " are copied recursively.") { - SCM copy = m; if (unsmob_music (m)) + return unsmob_music (m)->clone ()->unprotect (); + if (scm_is_pair (m)) { - Music *mcopy = unsmob_music (m)->clone (); - copy = mcopy->unprotect (); + SCM copy = SCM_EOL; + do + { + copy = scm_cons (ly_music_deep_copy (scm_car (m)), copy); + m = scm_cdr (m); + } + while (scm_is_pair (m)); + // Oh, come on, GUILE. Why do you require the second argument + // of scm_reverse_x to be a proper list? That makes no sense. + // return scm_reverse_x (copy, ly_music_deep_copy (m)); + SCM last_cons = copy; + copy = scm_reverse_x (copy, SCM_EOL); + scm_set_cdr_x (last_cons, ly_music_deep_copy (m)); + return copy; } - else if (scm_is_pair (m)) - copy = scm_cons (ly_music_deep_copy (scm_car (m)), - ly_music_deep_copy (scm_cdr (m))); - return copy; + return m; } LY_DEFINE (ly_music_transpose, "ly:music-transpose", @@ -147,6 +171,21 @@ LY_DEFINE (ly_music_compress, "ly:music-compress", return sc->self_scm (); } +LY_DEFINE (ly_make_music_relative_x, "ly:make-music-relative!", + 2, 0, 0, (SCM music, SCM pitch), + "Make @var{music} relative to @var{pitch}," + " return final pitch.") +{ + LY_ASSERT_TYPE (unsmob_music, music, 1); + LY_ASSERT_TYPE (unsmob_pitch, pitch, 2); + + Pitch start = *unsmob_pitch (pitch); + Music *m = unsmob_music (music); + Pitch last = m->to_relative_octave (start); + + return last.smobbed_copy (); +} + LY_DEFINE (ly_music_duration_length, "ly:music-duration-length", 1, 0, 0, (SCM mus), "Extract the duration field from @var{mus} and return the"