+1.3.36.jcn4
+===========
+
+* Added instrument-equaliser for MIDI output, see scm/midi.scm, and
+ properties midiMinimumVolume, midiMaximumVolume, ranges [0,1].
+
+* Changed absolute midi volume settings into factor of full scale.
+
+* Fixed another dynamic-line-spanner bug, it gets hairy.
+
+* Added warning for spanners with dubiously narrow parents.
+
1.3.36.jcn3
===========
MAJOR_VERSION=1
MINOR_VERSION=3
PATCH_LEVEL=36
-MY_PATCH_LEVEL=jcn3
+MY_PATCH_LEVEL=jcn4
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
key_ = k;
}
-Audio_dynamic::Audio_dynamic (int volume)
+Audio_dynamic::Audio_dynamic (Real volume)
{
- volume_i_ = volume;
+ volume_ = volume;
}
Audio_tempo::Audio_tempo (int per_minute_4_i)
* direction of text-dynamic-request if not equalt to direction
of line-spanner
+
+ * FIXME: this has gotten a bit too hairy.
*/
class Dynamic_line_spanner : public Spanner
Dynamic_line_spanner* finished_line_spanner_;
Moment last_request_mom_;
- Note_column* pending_column_;
+ Array<Note_column*> pending_column_arr_;
Link_array<Score_element> pending_element_arr_;
void typeset_all ();
finished_line_spanner_ = 0;
span_start_req_l_ = 0;
cresc_p_ =0;
- pending_column_ = 0;
text_req_l_ = 0;
span_req_l_drul_[START] = 0;
text_req_l_ = 0;
span_req_l_drul_[START] = 0;
span_req_l_drul_[STOP] = 0;
-
- /* ugr; we must attach the Dynamic_line_spanner to something
- to be sure that the linebreaker will not be confused
- */
- // if (line_spanner_)
- // line_spanner_->add_column (LEFT, get_staff_info ().command_pcol_l ());
}
bool
&& pending_element_arr_.size ())
{
line_spanner_ = new Dynamic_line_spanner;
- assert (pending_column_);
- line_spanner_->add_column (pending_column_);
+ for (int i = 0; i < pending_column_arr_.size (); i++)
+ line_spanner_->add_column (pending_column_arr_[i]);
+ pending_column_arr_.clear ();
announce_element (Score_element_info
(line_spanner_,
text_req_l_ ? text_req_l_ : span_req_l_drul_[START]));
}
if (span_req_l_drul_[START] || span_req_l_drul_[STOP] || text_req_l_)
- last_request_mom_ = now_mom ();
+ {
+ last_request_mom_ = now_mom ();
+ }
+ /*
+ TODO: This should be optionised:
+ * break when group of dynamic requests ends
+ * break now (only if no cresc. in progress)
+ * continue through piece */
else
{
-
-#if 0
/*
+ During a (de)crescendo, pending request will not be cleared,
+ and a line-spanner will always be created, as \< \! are already
+ two requests.
+
Maybe always creating a line-spanner for a (de)crescendo (see
below) is not a good idea:
Urg, but line-spanner must always have at least same duration
as (de)crecsendo, b.o. line-breaking.
*/
- if (now_mom () > last_request_mom_)
-#else
- /*
- During a (de)crescendo, pending request will not be cleared,
- and a line-spanner will always be created, as \< \! are already
- two requests.
- */
if (now_mom () > last_request_mom_ && !span_start_req_l_)
-#endif
{
for (int i = 0; i < pending_element_arr_.size (); i++)
{
e->set_elt_property ("minimum-space", s);
}
pending_element_arr_.clear ();
- finished_line_spanner_ = line_spanner_;
- line_spanner_ = 0;
+ if (line_spanner_)
+ {
+ for (int i = 0; i < pending_column_arr_.size (); i++)
+ line_spanner_->add_column (pending_column_arr_[i]);
+ pending_column_arr_.clear ();
+ finished_line_spanner_ = line_spanner_;
+ line_spanner_ = 0;
+ }
}
}
else
{
assert (!finished_cresc_p_);
- cresc_p_->set_bound(RIGHT, get_staff_info ().musical_pcol_l ());
+ cresc_p_->set_bound (RIGHT, get_staff_info ().musical_pcol_l ());
finished_cresc_p_ = cresc_p_;
cresc_p_ = 0;
span_start_req_l_ = 0;
+ "Spanner", SCM_UNDEFINED);
}
- cresc_p_->set_bound(LEFT, get_staff_info ().musical_pcol_l ());
+ cresc_p_->set_bound (LEFT, get_staff_info ().musical_pcol_l ());
/*
typeset_element (text_p_);
text_p_ = 0;
}
-
- /*
- TODO: This should be optionised:
- * break when group of dynamic requests ends
- * break now
- * continue through piece */
- // if (line_spanner_ && last_request_mom_ < now_mom ())
if (finished_line_spanner_)
{
side_position (finished_line_spanner_).add_staff_support ();
}
else
{
- pending_column_ = n;
+ pending_column_arr_.push (n);
}
}
}
(ly_symbol2scm ("dynamic-absolute-volume"),
ly_quote_scm (ly_str02scm (text_script_req_l_->text_str_.ch_C ())),
SCM_UNDEFINED));
- int volume = gh_scm2int (ly_eval_str ("dynamic-default-volume"));
+ Real volume = gh_scm2double (ly_eval_str ("dynamic-default-volume"));
if (gh_number_p (s))
- volume = gh_scm2int (s);
+ volume = gh_scm2double (s);
+
+ /*
+ urg, code duplication:: staff_performer
+ */
+ s = get_property ("midiInstrument");
+
+ if (!gh_string_p(s))
+ s = get_property ("instrument");
+
+ if (!gh_string_p(s))
+ s = ly_str02scm ("piano");
+
+ /*
+ properties override default equaliser setting
+ */
+ SCM min = get_property ("midiMinimumVolume");
+ SCM max = get_property ("midiMaximumVolume");
+ if (gh_number_p (min) || gh_number_p (max))
+ {
+ Interval iv (0, 1);
+ if (gh_number_p (min))
+ iv[MIN] = gh_scm2double (min);
+ if (gh_number_p (max))
+ iv[MAX] = gh_scm2double (max);
+ volume = iv[MIN] + iv.length () * volume;
+ }
+ else
+ {
+ s = scm_eval (gh_list (ly_symbol2scm ("instrument-equaliser"),
+ s, SCM_UNDEFINED));
+ if (gh_pair_p (s))
+ {
+ Interval iv;
+ iv[MIN] = gh_scm2double (gh_car (s));
+ iv[MAX] = gh_scm2double (gh_cdr (s));
+ volume = iv[MIN] + iv.length () * volume;
+ }
+ }
+
audio_p_ = new Audio_dynamic (volume);
Audio_element_info info (audio_p_, text_script_req_l_);
announce_element (info);
class Audio_dynamic : public Audio_item
{
public:
- Audio_dynamic (int volume);
+ Audio_dynamic (Real volume);
- int volume_i_;
+ Real volume_;
};
class Audio_key : public Audio_item
07 MSB
27 LSB
*/
+ static Real const full_scale = 127;
+
str += to_str ((char)0x07);
- str += to_str ((char)audio_l_->volume_i_);
+ int volume = (int)(audio_l_->volume_*full_scale);
+ str += to_str ((char)volume);
return str;
}
Span_dynamic_performer::do_process_music ()
{
if (finished_dynamic_tuple_arr_.size () > 1
- && finished_dynamic_tuple_arr_.top ().audio_l_->volume_i_)
+ && finished_dynamic_tuple_arr_.top ().audio_l_->volume_)
{
- Real start_volume = finished_dynamic_tuple_arr_[0].audio_l_->volume_i_;
- Real dv = finished_dynamic_tuple_arr_.top ().audio_l_->volume_i_
+ Real start_volume = finished_dynamic_tuple_arr_[0].audio_l_->volume_;
+ Real dv = finished_dynamic_tuple_arr_.top ().audio_l_->volume_
- start_volume;
/*
urg.
*/
if (!dv || sign (dv) != finished_dir_)
{
- // urg. about one volume step
- dv = (int)finished_dir_ * 13;
+ // urg. 10%: about one volume step
+ dv = (Real)finished_dir_ * 0.1;
if (!start_volume)
start_volume = finished_dynamic_tuple_arr_.top
- ().audio_l_->volume_i_ - dv;
+ ().audio_l_->volume_ - dv;
}
Moment start_mom = finished_dynamic_tuple_arr_[0].mom_;
Moment dt = finished_dynamic_tuple_arr_.top ().mom_ - start_mom;
Audio_dynamic_tuple* a = &finished_dynamic_tuple_arr_[i];
Real volume = start_volume + dv * (Real)(a->mom_ - start_mom)
/ (Real)dt;
- a->audio_l_->volume_i_ = (int)volume;
+ a->audio_l_->volume_ = volume;
}
finished_dynamic_tuple_arr_.clear ();
}
#include "line-of-score.hh"
#include "break-align-item.hh"
+
void
-Spanner::do_break_processing()
+Spanner::do_break_processing ()
{
//break_into_pieces
+ Item * left = spanned_drul_[LEFT];
+ Item * right = spanned_drul_[RIGHT];
+
+ if (left == right)
+ {
+ warning (_f ("Spanner `%s' has equal left and right spanpoints",
+ classname (this)));
+ }
+
+ /*
+ Check if our parent in X-direction spans equally wide
+ or wider than we do.
+ */
+ for (int a = X_AXIS; a < NO_AXES; a ++)
+ {
+ if (Spanner* parent = dynamic_cast<Spanner*> (parent_l ((Axis)a)))
+ {
+#if 1
+ /*
+ Urg, should use instantiate-compare, or maybe mysterious
+ column_width/contains functions?
+ */
+ if (spanned_drul_[LEFT] && spanned_drul_[RIGHT]
+ && parent->spanned_drul_[LEFT] && parent->spanned_drul_[RIGHT])
+ {
+ if (parent->spanned_drul_[LEFT]->column_l ()->rank_i ()
+ > spanned_drul_[LEFT]->column_l ()->rank_i () > 0
+ || parent->spanned_drul_[RIGHT]->column_l ()->rank_i ()
+ < spanned_drul_[RIGHT]->column_l ()->rank_i ())
+ {
+ warning (_f ("Spanner `%s' is not fully contained in parent spanner `%s'.",
+ classname (this), classname (parent)));
+ }
+ }
+#else
+ /*
+ column_width (), contains ()?
+ */
+ if (!parent->column_width ().contains (this->column_width ()))
+ {
+ warning (_f ("Spanner `%s' is not fully contained in parent spanner `%s'.",
+ classname (this), classname (parent)));
+ }
+#endif
+ }
+ }
if (line_l () || broken_b ())
return;
-
- Item * left = spanned_drul_[LEFT];
- Item * right = spanned_drul_[RIGHT];
if (left == right)
{
- warning (_ ("Left spanpoint is right spanpoint"));
-
/*
FIXME: this is broken.
*/
if (spanned_drul_[Direction(-d)] == spanned_drul_[d]
&& i)
- warning (_f ("Spanner `%s' has equal left and right spanpoints", classname (this)));
+ warning (_f ("Spanner `%s' has equal left and right spanpoints",
+ classname (this)));
}
}
\translator {
\ScoreContext
- %textEmptyDimension = ##t
- textStyle = #"italic"
+ %% URG: this changes dynamics too
+ %%textStyle = #"italic"
timeSignatureStyle = #"C"
}
\translator { \OrchestralScoreContext }
}
\translator {
\ScoreContext skipBars = ##t
- %textEmptyDimension = ##t
- textStyle = #"italic"
+ %% URG: this changes dynamics too
+ %%textStyle = #"italic"
timeSignatureStyle = #"C"
}
}
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2000-03-15 19:34+0100\n"
+"POT-Creation-Date: 2000-03-20 16:31+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "unknown clef type"
msgstr ""
-#: collision.cc:99
+#: collision.cc:101
msgid "Too many clashing notecolumns. Ignoring them."
msgstr ""
msgid "NaN"
msgstr ""
-#: dynamic-engraver.cc:244 span-dynamic-performer.cc:114
+#: dynamic-engraver.cc:285 span-dynamic-performer.cc:116
msgid "can't find start of (de)crescendo"
msgstr ""
-#: dynamic-engraver.cc:263
+#: dynamic-engraver.cc:304
msgid "already have a crescendo"
msgstr ""
-#: dynamic-engraver.cc:264
+#: dynamic-engraver.cc:305
msgid "already have a decrescendo"
msgstr ""
-#: dynamic-engraver.cc:339
+#: dynamic-engraver.cc:380
msgid "unterminated (de)crescendo"
msgstr ""
msgid "no Grace context available"
msgstr ""
-#: grace-position-engraver.cc:91
+#: grace-position-engraver.cc:93
msgid "Unattached grace notes. Attaching to last musical column."
msgstr ""
msgid "Braces don't match"
msgstr ""
-#: paper-column.cc:48
+#: paper-column.cc:49
msgid "Must set spring between differing columns"
msgstr ""
-#: paper-def.cc:69
+#: paper-def.cc:70
#, c-format
msgid "unknown paper variable: `%s'"
msgstr ""
-#: paper-def.cc:73
+#: paper-def.cc:74
msgid "not a real variable"
msgstr ""
-#: paper-def.cc:180
+#: paper-def.cc:184
#, c-format
msgid "paper output to %s..."
msgstr ""
msgid "too many notes for rest collision"
msgstr ""
-#: score-engraver.cc:139
+#: score-engraver.cc:141
#, c-format
msgid "unbound spanner `%s'"
msgstr ""
msgid "Slur over rest?"
msgstr ""
-#: spanner.cc:34
-msgid "Left spanpoint is right spanpoint"
+#: spanner.cc:31 spanner.cc:170
+#, c-format
+msgid "Spanner `%s' has equal left and right spanpoints"
msgstr ""
-#: spanner.cc:128
+#: spanner.cc:56 spanner.cc:66
#, c-format
-msgid "Spanner `%s' has equal left and right spanpoints"
+msgid "Spanner `%s' is not fully contained in parent spanner `%s'."
msgstr ""
#: stem-engraver.cc:124
#
msgid ""
msgstr ""
-"POT-Creation-Date: 2000-03-15 19:34+0100\n"
+"POT-Creation-Date: 2000-03-20 16:31+0100\n"
"Content-Type: text/plain; charset=\n"
"Date: 1998-05-26 11:26:28+0200\n"
"From: <janneke@gnu.org>\n"
msgid "unknown clef type"
msgstr "onbekend type sleutel"
-#: collision.cc:99
+#: collision.cc:101
msgid "Too many clashing notecolumns. Ignoring them."
msgstr "Te veel botsende nootkolommen. Negeer ze."
msgid "NaN"
msgstr "NaN"
-#: dynamic-engraver.cc:244 span-dynamic-performer.cc:114
+#: dynamic-engraver.cc:285 span-dynamic-performer.cc:116
msgid "can't find start of (de)crescendo"
msgstr "kan start van (de)crescendo niet vinden"
-#: dynamic-engraver.cc:263
+#: dynamic-engraver.cc:304
msgid "already have a crescendo"
msgstr "heb al een crescendo"
-#: dynamic-engraver.cc:264
+#: dynamic-engraver.cc:305
msgid "already have a decrescendo"
msgstr "heb al een decrescendo"
-#: dynamic-engraver.cc:339
+#: dynamic-engraver.cc:380
msgid "unterminated (de)crescendo"
msgstr "onbeëindigd (de)crescendo"
msgid "no Grace context available"
msgstr "geen Grace context voor handen"
-#: grace-position-engraver.cc:91
+#: grace-position-engraver.cc:93
msgid "Unattached grace notes. Attaching to last musical column."
msgstr "Losse grace noten. Maak ze vast aan vorige muziekale kolom."
#: local-key-engraver.cc:83 time-signature-engraver.cc:29
#: translator-group.cc:416 translator-group.cc:425
+#, c-format
msgid "can't find: `%s'"
msgstr "kan niet vinden: `%s'"
msgstr "Vertolk context met leeg type"
#: music-output-def.cc:84
+#, c-format
msgid "can't find `%s' context"
msgstr "kan `%s' context niet vinden"
msgid "Braces don't match"
msgstr "Haakjes paren niet"
-#: paper-column.cc:48
+#: paper-column.cc:49
msgid "Must set spring between differing columns"
msgstr "Moet veertje zetten tussen verschillende kolommen"
-#: paper-def.cc:69
+#: paper-def.cc:70
#, c-format
msgid "unknown paper variable: `%s'"
msgstr "onbekende papier veranderlijke: `%s'"
-#: paper-def.cc:73
+#: paper-def.cc:74
msgid "not a real variable"
msgstr "niet een reële veranderlijke"
-#: paper-def.cc:180
+#: paper-def.cc:184
#, c-format
msgid "paper output to %s..."
msgstr "papier uitvoer naar %s..."
msgstr "Huh? Geen Request: `%s'"
#: request-iterator.cc:20
+#, c-format
msgid "Junking music: `%s'"
msgstr "Schroot muziek: `%s'"
msgid "too many notes for rest collision"
msgstr "te veel noten voor bosting met rusten"
-#: score-engraver.cc:139
+#: score-engraver.cc:141
#, c-format
msgid "unbound spanner `%s'"
msgstr "ongebonden spanner `%s'"
msgstr "onbeëindigde bindingsboog"
#: slur-engraver.cc:77
+#, c-format
msgid "can't find both ends of %s"
msgstr "kan niet beide uiteinden vinden van %s"
msgid "Slur over rest?"
msgstr "Boogje over rust?"
-#: spanner.cc:34
-msgid "Left spanpoint is right spanpoint"
-msgstr "Linker spanpunt is rechter spanpunt"
-
-#: spanner.cc:128
+#: spanner.cc:31 spanner.cc:170
#, c-format
msgid "Spanner `%s' has equal left and right spanpoints"
msgstr "Spanner `%s' heeft gelijke linker en rechter spanpunten"
+#: spanner.cc:56 spanner.cc:66
+#, c-format
+msgid "Spanner `%s' is not fully contained in parent spanner `%s'."
+msgstr "Spanner `%s' is niet volledig opgenomen in parent spanner `%s'."
+
#: stem-engraver.cc:124
#, c-format
msgid "Adding note head to incompatible stem (type = %d)"
"%s: TFM bestand heeft %u parameters, wat meer is dan de %u die ik aan kan"
#: tfm.cc:70
+#, c-format
msgid "can't find ascii character: `%d'"
msgstr "kan teken niet vinden: `%s'"
msgstr "Bevat reeds: `%s'"
#: translator-group.cc:210
+#, c-format
msgid "can't find or create `%s' called `%s'"
msgstr "kan niet vinden of scheppen `%s' genaamd `%s'"
#: translator-group.cc:322
+#, c-format
msgid "can't find or create: `%s'"
msgstr "kan niet vinden of scheppen: `%s'"
msgid "% from input file: "
msgstr "% van invoerbestand: "
+#~ msgid "Left spanpoint is right spanpoint"
+#~ msgstr "Linker spanpunt is rechter spanpunt"
+
#~ msgid "(search path: `%s'"
#~ msgstr "(zoekpad: `%s')"
;;; (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
+
(define absolute-volume-alist '())
(set! absolute-volume-alist
(append
'(
- ("sf" . 115)
- ("fff" . 102)
- ("ff" . 90)
- ("f" . 77)
- ("mf" . 64)
- ("mp" . 51)
- ("p" . 38)
- ("pp" . 26)
- ("ppp" . 13)
+ ("sf" . 1.00)
+ ("ffff" . 0.91)
+ ("fff" . 0.81)
+ ("ff" . 0.71)
+ ("f" . 0.61)
+ ("mf" . 0.50)
+ ("mp" . 0.40)
+ ("p" . 0.30)
+ ("pp" . 0.20)
+ ("ppp" . 0.10)
)
absolute-volume-alist))
(if entry
(cdr entry))))
-;; 90 is supposed to be the default value
+(define instrument-equaliser-alist '())
+(set! instrument-equaliser-alist
+ (append
+ '(
+ ("flute" . (0 . 1))
+ ("oboe" . (0 . 1))
+ ("clarinet" . (0 . 1))
+ ("bassoon" . (0 . 1))
+ ("french horn" . (0 . 1))
+ ("trumpet" . (0 . 1))
+ ("timpani" . (0 . 1))
+ ("violin" . (0 . 1))
+ ("viola" . (0 . 1))
+ ("cello" . (0 . 1))
+ ("contrabass" . (0 . 1))
+ )
+ instrument-equaliser-alist))
+
+(define (instrument-equaliser s)
+ (let ((entry (assoc s absolute-volume-alist)))
+ (if entry
+ (cdr entry))))
+
+(define instrument-equaliser-alist '())
+
+;; 90 == 90/127 == 0.71 is supposed to be the default value
;; urg: we should set this at start of track
-(define dynamic-default-volume 90)
+(define dynamic-default-volume 0.71)