]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.1.13
authorfred <fred>
Tue, 26 Mar 2002 21:45:08 +0000 (21:45 +0000)
committerfred <fred>
Tue, 26 Mar 2002 21:45:08 +0000 (21:45 +0000)
17 files changed:
Documentation/tex/engraving.bib
TODO
init/chord-modifiers.ly [new file with mode: 0644]
init/declarations.ly
init/nederlands.ly
input/test/c.ly [new file with mode: 0644]
input/test/chords.ly [new file with mode: 0644]
input/twinkle-pop.ly
lily/chord-name-engraver.cc [new file with mode: 0644]
lily/include/musical-pitch.hh
lily/include/my-lily-lexer.hh
lily/include/my-lily-parser.hh
lily/lexer.ll
lily/musical-pitch.cc
lily/my-lily-lexer.cc
lily/my-lily-parser.cc
lily/parser.yy

index a234775e2e2078f3531f3df2d2db69bdcf336b95..560647d93bf0e4e49b511fdcacb1f04724f9124d 100644 (file)
 }
 
 
-
+@Book{banter,
+  author =     {Harald Banter},
+  title =      {Akkord Lexikon},
+  publisher =  {Schott's S\"ohne},
+  year =       {1987},
+  isbn =       {ISBN 3-7957-2095-8},
+  note =       {Comprehensive overview of commonly used
+  chords.  Suggests (and uses) a unification for all different kinds
+  of chord names.},
+  address =    {Mainz, Germany},
+}
 
 
 @Book {read78,
diff --git a/TODO b/TODO
index 587a96c2e50ff7776512a6a5ad536c71f4272d24..dc35057fb1799e5aeb300228dbba2b9664734241 100644 (file)
--- a/TODO
+++ b/TODO
@@ -21,7 +21,6 @@ BUGS:
        * who is trying to print too (small/big) piano braces all the time?
            warning: piano brace too small (16.000pt)
 
-
        * latex bla.tex broken (titles / \lilyfooter stuff?)
 
        * msgfmt -o check?
@@ -44,7 +43,7 @@ BUGS:
 
        * space after bars?
 
-       * [/3 c8 c16 c c c]/1
+       * \type Voice \times 2/3 { [c8 c16 c16 c16 c16] }
 
        * fix singleStaffBracket
 
@@ -52,7 +51,7 @@ BUGS:
 
        * The time signature warnings still remain, will be fixed later.
 
-ii     Summary of minor spelling irregularities:
+       Summary of minor spelling irregularities:
        -  capitalization/use of underscores in property names
 
        * fix SkipBars  -> skipBars
@@ -92,9 +91,7 @@ STUFF
 
        * typo checks on property names?
 
-       * make engraver hacking robust.
-
-       * --safe:  disallow backslashes, disallow \include.
+       * --safe:  disallow backslashes
 
        * use streambufs and iostream
        to provide IO handling for TeX stream, mudela stream, data-file.
@@ -325,6 +322,8 @@ ydirection and hshift preset
 
 3RD PARTY BUGS:
 
+       * make GCC warn about ctor that leaves member vars  uninitialised.
+
        * redhat (v?) graphical install bomb-out?
 
        * GNU diff 2.7: diff -rN does not see a new directory with empty file
diff --git a/init/chord-modifiers.ly b/init/chord-modifiers.ly
new file mode 100644 (file)
index 0000000..48cc2f0
--- /dev/null
@@ -0,0 +1,15 @@
+%{
+ chord modifiers
+%}
+
+\chordmodifiers {
+       m       = \musicalpitch { 0 2 -1 }
+       min     = \musicalpitch { 0 2 -1 }
+       aug     = \musicalpitch { 0 4 1 }
+       dim     = \musicalpitch { 0 4 -1 }
+       % urg, not actually a chord-modifier, but it works
+       % c7 -> <c bes>, c 7+ -> c b
+       maj     = \musicalpitch { 0 6 1 }
+       % sus4 should delete 2 too...
+       sus     = \musicalpitch { 0 3 0 }
+}
index 15573483f78349327d723d2dc1b93556ed8327c2..69b33ac2ce1d4d04dc3217a81f933b89e4e4213a 100644 (file)
@@ -5,6 +5,7 @@ longa = \duration { -2 0 }
 
 \include "dynamic.ly"
 \include "nederlands.ly"               % dutch
+\include "chord-modifiers.ly"
 \include "script.ly"
 
 
index 35b568d30e83352c16c7c9c99898defa5cec7248..9b652a6bd2297e55044f4c3913d29e51e3f2fbe3 100644 (file)
@@ -97,3 +97,4 @@
 
 
 }
+
diff --git a/input/test/c.ly b/input/test/c.ly
new file mode 100644 (file)
index 0000000..a2259fa
--- /dev/null
@@ -0,0 +1,51 @@
+\version "1.0.12";
+
+%{
+Would this be acceptable/good enough/convenient for entry?
+
+   Convention/Standard    Lily
+   
+   C#                     cis
+   Cb                     ces
+   Cm; Cmin               c3-; c m; c min
+   Caug                   c5+; c aug;
+   Cdim                   c5-; c dim
+   Cmaj7                  c7+; c maj
+   C7                     c7
+   Csus; Csus4            c4; c sus
+%}
+
+scales = \notes\transpose c''\chords{
+               <c1 e g>
+               @1c m @c min @4c dim @c aug @c sus @c maj
+                @1c6 @4c7 @c9 @c11 @c13
+               @1c @g @d @a @e @b @fis
+                @1c @f @bes @es @as @des @ges
+       }
+
+keys = \notes{
+                s1
+                s1 s1 s1
+                s1 s1
+                s1
+                \key g; s1
+                \key d; s1 
+                \key a; s1 
+                \key e; s1 
+                \key b; s1 
+                \key fis; s1
+                \key c; s1 
+                \key f; s1 
+                \key bes; s1
+                \key es; s1
+                \key as; s1
+                \key des; s1
+                \key ges; s1
+       }
+
+\score{
+       <
+               \type ChordNames \scales
+               \type Staff < \scales \keys >
+       >
+}
diff --git a/input/test/chords.ly b/input/test/chords.ly
new file mode 100644 (file)
index 0000000..e3c0c4d
--- /dev/null
@@ -0,0 +1,29 @@
+\version "1.0.12";
+
+%{
+Would this be acceptable/good enough/convenient for entry?
+
+   Convention/Standard    Logical/Lily(?)
+   
+   C#                     cis
+   Cb                     ces
+   Cm/Cmin                c3-     
+   Caug                   c5+
+   Cdim                   c5-
+   Cmaj7                  c7
+   C7                     c7-
+   Csus/Csus4             c4^3
+%}
+
+scales = \notes\transpose c''\chords{
+               *c *g *d *a *e *b *fis
+               *c *f *bes *es *as *des *ges
+                *c6 *c7 *c9 *c11 *c13
+       }
+
+\score{
+       <
+               \type ChordNames \scales
+               \type Staff \scales
+       >
+}
index 1e95a8d65fb75c4ad904b38b2d735fe0d30e198b..0f3ef80c6fa990a2f3b6859330de6ed8399d4967 100644 (file)
@@ -1,9 +1,8 @@
 \header{
-filename =      "twinkle.ly";
+filename =      "twinkle-pop.ly";
 title =         "Ah, vous dirais-je, maman ";
 description =   "twinkle twinkle in pop-song-settings";
 composer =      "traditional";
-
 enteredby =     "HWN, chords by Johan Vromans";
 copyright =     "public domain";
 }
@@ -14,16 +13,28 @@ Tested Features             lyrics and chords
 
 \version "1.0.10";
 
-melodie = \notes\relative c {
-        \clef"violin";
+melodie = \notes\relative c'' {
+        \clef "violin";
         \time 2/4 ;
 
-        c''4^"C" c |    g'    g |       a^"F"  a |      g2^"C"   |
-        f4^"F" f |      e^"C" e |       d^"G7" d |      c2^"C"   |
-        g'4^"G" g |      f^"F" f |       e^"C"  e |      d^"G7" d |
-        g^"G"  g |      f^"F" f |       e^"C"  e |      d^"G7" d |
-        c4^"C" c |      g'    g |       a^"F"  a |      g2^"C"   |
-        f4^"F" f |      e^"C" e |       d^"G7" d |      c2^"C"   |
+        c4 c  | g' g | a a | g2  |
+        f4 f  | e e  | d d | c2  |
+        g'4 g | f f  | e e | d d |
+        g  g  | f f  | e e | d d |
+       % copy 1-8
+        c4 c  | g' g | a a | g2  |
+        f4 f  | e e  | d d | c2  |
+}
+
+acc = \chords {
+       % why don't \skip, s4 work?
+        @2c @c @f @c
+        @f @c @g7 @c
+       @g @f @c  @g7 % urg, bug!
+        @g @f @c  @g7
+       % copy 1-8
+        @2c @c @f @c
+        @f @c @g7 @c
 }
 
 text = \lyrics{ 
@@ -39,8 +50,11 @@ text = \lyrics{
 }
 
 \score {
-        <  \notes \type Staff \melodie
-           \lyrics   \type Lyrics \text
+        <  
+          \chords \type ChordNames \acc
+%         \notes \type Staff=chords \acc
+          \notes \type Staff=melody \melodie
+           \lyrics \type Lyrics \text
         >
         \paper {  }
 }
diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc
new file mode 100644 (file)
index 0000000..7bf7c05
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+  chord-name-engraver.cc -- implement Chord_name_engraver
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#include "chord-name-engraver.hh"
+#include "musical-request.hh"
+#include "text-item.hh"
+#include "paper-def.hh"
+#include "lookup.hh"
+#include "paper-def.hh"
+#include "main.hh"
+#include "dimensions.hh"
+
+ADD_THIS_TRANSLATOR (Chord_name_engraver);
+
+Chord_name_engraver::Chord_name_engraver ()
+{
+}
+
+void
+Chord_name_engraver::acknowledge_element (Score_element_info i)
+{
+  if (Note_req* n = dynamic_cast<Note_req*> (i.req_l_))
+    pitch_arr_.push (n->pitch_);
+}
+
+bool
+Chord_name_engraver::do_try_music (Music* m)
+{
+  if (Note_req* n = dynamic_cast<Note_req*> (m))
+    {
+      pitch_arr_.push (n->pitch_);
+      return true;
+    }
+  return false;
+}
+
+void
+Chord_name_engraver::do_process_requests ()
+{
+  if (text_p_arr_.size ())
+    return;
+  if (!pitch_arr_.size ())
+    return;
+
+  /*
+   Banter style chord names (almost).
+   TODO:
+     - don't print inclusive scale (i.e. no "9" in c 9/11)
+     - handle c7 / cmaj7
+     - use #,b iso -es -is on tonica
+     - switch on property, add american (?) chordNameStyle
+
+  Scalar chordNameStyle = get_property ("chordNameStyle");
+  if (chordNameStyle == "Banner")
+     chord = pitches_to_banner (pitch_arr_.size ());
+
+   */
+
+  Scalar style = get_property ("textstyle");
+  Scalar alignment = get_property ("textalignment");
+  Text_def* text_p = new Text_def;
+  text_p->align_dir_ = LEFT;
+  if (style.length_i ())
+    text_p->style_str_ = style;
+  if (alignment.isnum_b())
+    text_p->align_dir_= (Direction)(int)alignment;
+
+  Musical_pitch tonic = pitch_arr_[0];
+
+  Array<Musical_pitch> scale;
+  scale.push (Musical_pitch (0)); // c
+  scale.push (Musical_pitch (1)); // d
+  scale.push (Musical_pitch (2)); // e
+  scale.push (Musical_pitch (3)); // f
+  scale.push (Musical_pitch (4)); // g
+  scale.push (Musical_pitch (5)); // a
+  // 7 always means 7-...
+  scale.push (Musical_pitch (6, -1)); // b
+
+  for (int i = 0; i < scale.size (); i++)
+    scale[i].transpose (tonic);
+
+  //urg, should do translation in scheme.
+  char const *acc[] = {"\\textflat\\textflat", "\\textflat", "", "\\textsharp" , "\\textsharp\\textsharp"};
+  String tonic_str = tonic.str ();
+  tonic_str = tonic_str.left_str (1).upper_str ()
+    + acc[tonic.accidental_i_ + 2];
+
+  String add_str;
+  String sep_str;
+  for (int i=1; i < pitch_arr_.size (); i++)
+    {
+      Musical_pitch p = pitch_arr_[i];
+      int trap = p.notename_i_ - tonic.notename_i_ 
+        + (p.octave_i_ - tonic.octave_i_) * 7 + 1;
+      int accidental = p.accidental_i_ - scale[(trap - 1) % 7].accidental_i_;
+      if ((trap == 3) && (accidental == -1))
+        tonic_str += "m"; // hmm
+      else if (accidental || (!(trap % 2) || ((i + 1 == pitch_arr_.size ()) && (trap > 5))))
+        {
+         add_str += sep_str;
+          if ((trap == 7) && (accidental == 1))
+            add_str += "maj7";
+          else
+            {
+              add_str += to_str (trap);
+              if (accidental)
+                add_str += accidental < 0 ? "-" : "+";
+            }
+         sep_str = "/";
+       }
+    }
+
+  text_p->text_str_ = tonic_str + "$^{" + add_str + "}$";
+  Text_item* item_p =  new Text_item (text_p);
+  item_p->dir_ = DOWN;
+  item_p->fat_b_ = true;
+  text_p_arr_.push (item_p);
+  announce_element (Score_element_info (item_p, 0));
+}
+
+void
+Chord_name_engraver::do_pre_move_processing ()
+{
+  for (int i=0; i < text_p_arr_.size (); i++)
+    {
+      typeset_element (text_p_arr_[i]);
+    }
+  text_p_arr_.clear ();
+  pitch_arr_.clear ();
+}
+
index a46471fd61d5f35b5514a51f1f17dba0ce7710a0..7a5fd5b5b129b1c8ffd98dc20a23bd257c6bf70d 100644 (file)
 */
 struct Musical_pitch : public Input
 {
-  Musical_pitch ();
+  Musical_pitch (int notename=0, int accidental=0, int octave=0, bool cautionary=false);
 
   /// 0 is c, 6 is b
   int notename_i_;
-  /// 0 is central c
-  int octave_i_;
   /// 0 natural, 1 sharp, etc
   int accidental_i_;
+  /// 0 is central c
+  int octave_i_;
   /// Used for cautionary accidentals
   bool cautionary_b_;
 
-  void init () ;
   Musical_pitch to_relative_octave (Musical_pitch);
   void transpose (Musical_pitch);
   static int compare (Musical_pitch const&,Musical_pitch const&);
index 3030a09eb45871a36e5981af2fdddd8f161697a8..70dc4623c8f697dcbda3f80db15e8845b5545d15 100644 (file)
@@ -37,19 +37,25 @@ public:
   String main_input_str_;
   void * lexval_l;
   Scope * toplevel_scope_p_;
+  bool main_input_b_;
   
   Notename_table *note_tab_p_;
   Array<Scope*> scope_l_arr_;
   Keyword_table * keytable_p_;
   int errorlevel_i_;
-
-
+  Notename_table *chordmodifier_tab_p_;
+  Musical_pitch lookup_notename (String s);
   void start_main_input ();
   void set_notename_table(Notename_table*tab_p);
+  bool chordmodifier_b (String) const;
+  void set_chordmodifier_table (Notename_table*tab_p);
+  Musical_pitch lookup_chordmodifier (String s);
+   
   bool notename_b(String) const;
   Identifier*lookup_identifier (String s);
   Musical_pitch lookup_pitch (String s);
   void push_note_state();
+  void push_chord_state();
   void push_lyric_state();
   void pop_state();
   void LexerError (char const *);
@@ -60,6 +66,7 @@ public:
   void print_declarations (bool init_b) const;
   void add_notename (String, Musical_pitch);
   bool note_state_b() const;
+  bool chord_state_b() const;
   bool lyric_state_b() const;
 };
 
index 4e82dc909e19c1bdbd5fb6123ac047ae371b7d43..1c40332452c3b068f17f886d32e85593b7502665 100644 (file)
 #include "array.hh"
 #include "input.hh"
 
-class My_lily_parser {
-  char const* here_ch_C() const;
-  Array<Input> define_spot_array_;
-  String init_str_;
-
-  void add_requests (Simultaneous_music*v);
+class My_lily_parser 
+{
+public:
+  My_lily_parser (Sources * sources_l);
+  ~My_lily_parser();
 
-  Simultaneous_music * get_note_element (Note_req * ,Duration *);
-  Simultaneous_music* get_rest_element (String, Duration *);
-  Simultaneous_music* get_word_element (String, Duration*);
-  Melodic_req* get_melodic_req (Melodic_req* melodic, int quotes);
-  String notename_str (Melodic_req* melodic);
-  void set_last_duration (Duration const *);
-  void set_abbrev_beam (int type_i);
-  friend int yyparse (void*);
+  void do_init_file();
+  void parse_file ( String init_str, String file_str);
+  void set_version_check (bool ignore);
 
 public:
   int abbrev_beam_type_i_;
@@ -53,7 +47,6 @@ public:
   My_lily_lexer * lexer_p_;
  
   Moment plet_mom();
-  void add_notename (String, Musical_pitch req_p);
   Input here_input() const;
   void remember_spot();
   Input pop_spot();
@@ -68,12 +61,23 @@ public:
   void set_debug();
   void set_yydebug (bool);
   bool ignore_version_b_;
-public:
-  void do_init_file();
-  void parse_file ( String init_str, String file_str);
-  My_lily_parser (Sources * sources_l);
-  ~My_lily_parser();
-  void set_version_check (bool ignore);
+
+private:
+  char const* here_ch_C() const;
+  Array<Input> define_spot_array_;
+  String init_str_;
+
+  void add_requests (Simultaneous_music*v);
+
+  Simultaneous_music * get_note_element (Note_req * ,Duration *);
+  Simultaneous_music * get_chord (Musical_pitch, Array<Musical_pitch>*, Array<Musical_pitch>*, Duration);
+  Simultaneous_music* get_rest_element (String, Duration *);
+  Simultaneous_music* get_word_element (String, Duration*);
+  Melodic_req* get_melodic_req (Melodic_req* melodic, int quotes);
+  String notename_str (Melodic_req* melodic);
+  void set_last_duration (Duration const *);
+  void set_abbrev_beam (int type_i);
+  friend int yyparse (void*);
 };
 
 #endif // MY_LILY_PARSER_HH
index 551cf48aec682c7a4f755e35fae5912a76c05bf6..3d2a87f6012c52b99cfeccfc0520e44d4e571a9c 100644 (file)
@@ -62,6 +62,7 @@ LYRICS                ({AA}|{TEX})[^0-9 \t\n\f]*
 %option never-interactive 
 %option warn
 
+%x chords
 %x incl
 %x lyrics
 %x notes
@@ -102,7 +103,7 @@ EXTENDER    [_][_]
        // windows-suck-suck-suck
 }
 
-<notes,incl,INITIAL,lyrics>{
+<INITIAL,chords,incl,lyrics,notes>{
   "%{" {
        yy_push_state (longcomment);
   }
@@ -136,11 +137,17 @@ EXTENDER  [_][_]
 }
 
 
-<notes,INITIAL,lyrics>\\maininput           {
-       start_main_input ();
+<INITIAL,chords,lyrics,notes>\\maininput           {
+       if (!main_input_b_)
+       {
+               start_main_input ();
+               main_input_b_ = true;
+       }
+       else
+               error ("\\maininput disallowed outside init files.");
 }
 
-<notes,INITIAL,lyrics>\\include           {
+<INITIAL,chords,lyrics,notes>\\include           {
        yy_push_state (incl);
 }
 <incl>\"[^"]*\";?   { /* got the include file name */
@@ -184,29 +191,27 @@ EXTENDER  [_][_]
 <notes>R               {
        return MEASURES;
 }
-<INITIAL,lyrics,notes>\\\${BLACK}*{WHITE}      {
+<INITIAL,chords,lyrics,notes>\\\${BLACK}*{WHITE}       {
        String s=YYText () + 2;
        s=s.left_str (s.length_i () - 1);
        return scan_escaped_word (s); 
 }
-<INITIAL,lyrics,notes>\${BLACK}*{WHITE}                {
+<INITIAL,chords,lyrics,notes>\${BLACK}*{WHITE}         {
        String s=YYText () + 1;
        s=s.left_str (s.length_i () - 1);
        return scan_bare_word (s);
 }
-<INITIAL,lyrics,notes>\\\${BLACK}*             { // backup rule
+<INITIAL,chords,lyrics,notes>\\\${BLACK}*              { // backup rule
        cerr << _ ("white expected") << endl;
        exit (1);
 }
-<INITIAL,lyrics,notes>\${BLACK}*               { // backup rule
+<INITIAL,chords,lyrics,notes>\${BLACK}*                { // backup rule
        cerr << _ ("white expected") << endl;
        exit (1);
 }
 <notes>{
-
        {ALPHAWORD}     {
                return scan_bare_word (YYText ());
-
        }
 
        {NOTECOMMAND}   {
@@ -249,7 +254,6 @@ EXTENDER    [_][_]
 }
 
 <lyrics>{
-
        \" {
                start_quote ();
        }
@@ -281,6 +285,21 @@ EXTENDER   [_][_]
                return yylval.c = YYText ()[0];
        }
 }
+<chords>{
+       {ALPHAWORD}     {
+               return scan_bare_word (YYText ());
+       }
+       {NOTECOMMAND}   {
+               return scan_escaped_word (YYText () + 1);
+       }
+       {UNSIGNED}              {
+               yylval.i = String_convert::dec2_i (String (YYText ()));
+               return UNSIGNED;
+       }
+       . {
+               return yylval.c = YYText ()[0];
+       }
+}
 
 <<EOF>> {
        DOUT << "<<eof>>";
@@ -363,11 +382,18 @@ My_lily_lexer::push_note_state ()
        yy_push_state (notes);
 }
 
+void
+My_lily_lexer::push_chord_state ()
+{
+       yy_push_state (chords);
+}
+
 void
 My_lily_lexer::push_lyric_state ()
 {
        yy_push_state (lyrics);
 }
+
 void
 My_lily_lexer::pop_state ()
 {
@@ -389,14 +415,13 @@ My_lily_lexer::scan_escaped_word (String str)
                yylval.id = id;
                return id->token_code_i_;
        }
-       if (YYSTATE != notes) {
-               if (notename_b (str))
-                       {
-                       yylval.pitch = new Musical_pitch (lookup_pitch (str));
+       if ((YYSTATE != notes) && (YYSTATE != chords)) {
+               if (notename_b (str)) {
+                       yylval.pitch = new Musical_pitch (lookup_notename (str));
                        yylval.pitch->set_spot (Input (source_file_l (), 
                          here_ch_C ()));
                        return NOTENAME_PITCH;
-                       }
+               }
        }
        if (check_debug)
                print_declarations (true);
@@ -412,13 +437,19 @@ int
 My_lily_lexer::scan_bare_word (String str)
 {
        DOUT << "word: `" << str<< "'\n";       
-       if (YYSTATE == notes){
+       if ((YYSTATE == notes) || (YYSTATE == chords)) {
                if (notename_b (str)) {
                    DOUT << "(notename)\n";
-                   yylval.pitch = new Musical_pitch (lookup_pitch (str));
+                   yylval.pitch = new Musical_pitch (lookup_notename (str));
                    yylval.pitch->set_spot (Input (source_file_l (), 
                      here_ch_C ()));
                    return NOTENAME_PITCH;
+               } else if (chordmodifier_b (str)) {
+                   DOUT << "(chordmodifier)\n";
+                   yylval.pitch = new Musical_pitch (lookup_chordmodifier (str));
+                   yylval.pitch->set_spot (Input (source_file_l (), 
+                     here_ch_C ()));
+                   return CHORDMODIFIER_PITCH;
                }
        }
 
@@ -432,6 +463,12 @@ My_lily_lexer::note_state_b () const
        return YY_START == notes;
 }
 
+bool
+My_lily_lexer::chord_state_b () const
+{
+       return YY_START == chords;
+}
+
 bool
 My_lily_lexer::lyric_state_b () const
 {
index 9603e025d9a6397108665b87c33b5813b5006a59..f3dde21fcef4402e7c93cb963f8bf9f34e337609 100644 (file)
 #include "debug.hh"
 #include "main.hh"
 
-Musical_pitch::Musical_pitch ()
+Musical_pitch::Musical_pitch (int n, int a, int o, bool c)
 {
-  init ();
-}
-
-void
-Musical_pitch::init ()
-{
-  notename_i_ = 0;
-  octave_i_ = 0;
-  accidental_i_ = 0;
-  cautionary_b_ = false;
+  notename_i_ = n;
+  accidental_i_ = a;
+  octave_i_ = o;
+  cautionary_b_ = c;
 }
 
 void
index b87694b7294e746e3543190a37d7bfb153b371b0..6446083926c2f2afbb43fd690eb6d4fb9ac7c100 100644 (file)
@@ -28,6 +28,8 @@ static Keyword_ent the_key_tab[]={
   {"alternative", ALTERNATIVE},
   {"bar", BAR},
   {"cadenza", CADENZA},
+  {"chordmodifiers", CHORDMODIFIERS},
+  {"chords", CHORDS},
   {"clef", CLEF},
   {"cm", CM_T},
   {"consists", CONSISTS},
@@ -80,6 +82,8 @@ My_lily_lexer::My_lily_lexer()
   scope_l_arr_.push (toplevel_scope_p_);
   errorlevel_i_ = 0;
   note_tab_p_ = new Notename_table;
+  chordmodifier_tab_p_ = new Notename_table;
+  main_input_b_ = false;
 }
 
 int
@@ -105,7 +109,10 @@ My_lily_lexer::start_main_input ()
   if (!monitor->silent_b ("InitLexer") && check_debug)
     set_debug (1);
 
+
   new_input (main_input_str_, source_global_l);
+  if (safe_global_b)
+    allow_includes_b_ = false;
   
   print_declarations(true);
 }
@@ -167,11 +174,17 @@ My_lily_lexer::LexerError (char const *s)
 }
 
 Musical_pitch
-My_lily_lexer::lookup_pitch (String s)
+My_lily_lexer::lookup_notename (String s)
 {
   return (*note_tab_p_)[s];
 }
 
+Musical_pitch
+My_lily_lexer::lookup_chordmodifier (String s)
+{
+  return (*chordmodifier_tab_p_)[s];
+}
+
 bool
 My_lily_lexer::notename_b (String s) const
 {
@@ -179,16 +192,23 @@ My_lily_lexer::notename_b (String s) const
 }
 
 void
-My_lily_lexer::add_notename (String s, Musical_pitch p)
+My_lily_lexer::set_notename_table (Notename_table *p)
 {
-  (*note_tab_p_)[s] = p;
+  delete note_tab_p_;
+  note_tab_p_ = p;
+}
+
+bool
+My_lily_lexer::chordmodifier_b (String s) const
+{
+  return chordmodifier_tab_p_->elem_b (s);
 }
 
 void
-My_lily_lexer::set_notename_table(Notename_table *p)
+My_lily_lexer::set_chordmodifier_table (Notename_table *p)
 {
-  delete note_tab_p_;
-  note_tab_p_ = p;
+  delete chordmodifier_tab_p_;
+  chordmodifier_tab_p_ = p;
 }
 
 char
index 86270bf7c38fc8b368f448da97e6a9c9ecb134cd..75ff14f5c7df4930f5f50e54c383adc2c85b76a8 100644 (file)
@@ -4,6 +4,7 @@
   source file of the GNU LilyPond music typesetter
 
   (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+       Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
 #include "my-lily-parser.hh"
@@ -157,6 +158,133 @@ My_lily_parser::get_rest_element (String s,  Duration * duration_p)
   return velt_p;
 }
 
+Simultaneous_music *
+My_lily_parser::get_chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p, Duration d)
+{
+  Simultaneous_music*v = new Request_chord;
+  v->set_spot (here_input ());
+
+  Note_req* n = new Note_req;
+  n->pitch_ = tonic;
+  n->duration_ = d;
+  v->add_music (n);
+
+  for (int i = 0; i < add_arr_p->size (); i++)
+    {
+      Musical_pitch p = tonic;
+      Musical_pitch q = (*add_arr_p)[i];
+      // duh, c7 should mean <c bes>
+      if (q.notename_i_ == 6)
+        q.accidental_i_--;
+      p.transpose (q);
+      (*add_arr_p)[i] = p;
+    }
+  add_arr_p->sort (Musical_pitch::compare);
+  for (int i = 0; i < sub_arr_p->size (); i++)
+    {
+      Musical_pitch p = tonic;
+      Musical_pitch q = (*add_arr_p)[i];
+      // duh, c7 should mean <c bes>
+      if (q.notename_i_ == 6)
+        q.accidental_i_--;
+      p.transpose (q);
+      (*sub_arr_p)[i] = p;
+    }
+  sub_arr_p->sort (Musical_pitch::compare);
+
+  Musical_pitch third (2);
+  Musical_pitch mthird (2, -1);
+  Musical_pitch missing;
+  missing = tonic;
+  missing.transpose (third);
+
+  Musical_pitch p;
+  p = tonic;
+  p.transpose (third);
+  p.transpose (mthird);
+
+  /*
+   must have minimum at 5 (3 is added automatically as missing)
+   */
+  if (!add_arr_p->size ())
+    add_arr_p->push (p);
+  else if ((add_arr_p->top () < p) && (add_arr_p->top ().notename_i_ != p.notename_i_))
+    add_arr_p->push (p);
+  add_arr_p->sort (Musical_pitch::compare);
+
+  Array<Musical_pitch> triads;
+  triads.push (third);   // c e 
+  triads.push (mthird);  // d f 
+  triads.push (mthird);  // e g 
+  triads.push (third);   // f a 
+  // 7 always seems means 7-...
+  triads.push (third);   // g b 
+//  triads.push (mthird);   // g bes
+  triads.push (mthird);  // a c 
+  triads.push (mthird);  // b d 
+
+  /*
+    if first addition is 4, assume sus4 and don't add third implicitely
+   */
+  Musical_pitch sus (3);
+  sus.transpose (tonic);
+  if (add_arr_p->size ())
+    if ((*add_arr_p)[0] == sus)
+      missing.transpose (mthird);
+
+  /*
+   add missing triads
+   */
+  for (int i = 0; i < add_arr_p->size (); i++)
+    {
+      Musical_pitch p = (*add_arr_p)[i];
+      if (p > missing)
+        while (p > missing)
+         {
+           if (p.notename_i_ != missing.notename_i_)
+             {
+               if ((missing.notename_i_ - tonic.notename_i_ + 7) % 7 == 6)
+                 {
+                   Musical_pitch special_seven = missing;
+                   Musical_pitch lower (0, -1);
+                   special_seven.transpose (lower);
+                   add_arr_p->insert (special_seven, i++);
+                 }
+               else
+                 add_arr_p->insert (missing, i++);
+             }
+           missing.transpose (triads[(missing.notename_i_ - tonic.notename_i_ + 7) % 7]);
+         }
+      else
+       i++;
+    }
+
+  /*
+   add all that aren't subtracted
+   */
+  for (int i = 0; i < add_arr_p->size (); i++)
+    {
+      Musical_pitch p = (*add_arr_p)[i];
+      Note_req* n = new Note_req;
+      n->pitch_ = p;
+      n->duration_ = d;
+      for (int j = 0; j < sub_arr_p->size (); j++)
+        {
+         if (p == (*sub_arr_p)[j])
+           {
+             delete n;
+             n = 0;
+             break;
+           }
+       }
+      if (n)
+       v->add_music (n);
+    }
+
+  v->set_spot (here_input ());
+  return v;
+}
+
 Simultaneous_music *
 My_lily_parser::get_note_element (Note_req *rq, Duration * duration_p)
 {
@@ -308,13 +436,6 @@ My_lily_parser::here_input() const
   return Input (f_l, here_ch_C());
 }
 
-void
-My_lily_parser::add_notename (String s, Musical_pitch p)
-{
-  lexer_p_->add_notename (s, p);
-
-}
-
 Paper_def*
 My_lily_parser::default_paper_p ()
 {
index b2b807ac8f76a50beb2f6525a8f71dc4b051e638..2cf38355e3fa835fd64e0db4f5bc9b315d2d6deb 100644 (file)
@@ -47,7 +47,7 @@
 
 // mmm
 Mudela_version oldest_version ("1.0.7");
-Mudela_version version ("1.0.11");
+Mudela_version version ("1.0.12");
 
 
 // needed for bison.simple's malloc() and free()
@@ -104,11 +104,12 @@ Paper_def* current_paper = 0;
     Array<Musical_pitch> *pitch_arr;
     Array<String> * strvec;
     Array<int> *intvec;
+    Atom * symbol;
     Box *box;
-    Simultaneous_music *chord;
+    Notename_table *chordmodifiertab;
     Duration *duration;
+    General_script_def * script;
     Identifier *id;
-    Translator* trans;
     Music *music;
     Music_list *music_list;
     Score *score;
@@ -124,14 +125,14 @@ Paper_def* current_paper = 0;
     Paper_def *paper;
     Real real;
     Request * request;
-    General_script_def * script;
     Scalar *scalar;
+    Simultaneous_music *chord;
     String *string;
-    Atom * symbol;
     Symtable * symtable;
     Symtables* symtables;
-    Text_def * textdef;
     Tempo_req *tempo;
+    Text_def * textdef;
+    Translator* trans;
     char c;
     const char *consstr;
     int i;
@@ -163,6 +164,8 @@ yylex (YYSTYPE *s,  void * v_l)
 %token BAR
 %token BEAMPLET
 %token CADENZA
+%token CHORDMODIFIERS
+%token CHORDS
 %token CLEF
 %token CM_T
 %token CONSISTS
@@ -220,6 +223,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %type <i>      dots
 %token <i>     DIGIT
 %token <pitch> NOTENAME_PITCH
+%token <pitch> CHORDMODIFIER_PITCH
 %token <id>    DURATION_IDENTIFIER
 %token <id>    IDENTIFIER
 %token <id>    NOTENAME_TABLE_IDENTIFIER
@@ -264,6 +268,9 @@ yylex (YYSTYPE *s,  void * v_l)
 %type <pitch>   explicit_musical_pitch steno_musical_pitch musical_pitch absolute_musical_pitch
 %type <notereq>        steno_notepitch
 %type <pitch_arr>      pitch_list
+%type <music>  chord
+%type <pitch_arr>       chord_additions chord_subtractions
+%type <pitch>           chord_note
 %type <midi>   midi_block midi_body
 %type <duration>       duration_length
 
@@ -288,8 +295,9 @@ yylex (YYSTYPE *s,  void * v_l)
 %type <symtable>       symtable symtable_body
 %type <trans>  translator_spec translator_spec_body
 %type <tempo>  tempo_request
-%type <notenametab> notenames_body notenames_block
-%expect 4
+%type <notenametab> notenames_body notenames_block chordmodifiers_block
+
+%expect 6
 
 
 %left '-' '+'
@@ -309,6 +317,9 @@ toplevel_expression:
        notenames_block                 {
                THIS->lexer_p_->set_notename_table ($1);
        }
+       | chordmodifiers_block                  {
+               THIS->lexer_p_->set_chordmodifier_table ($1);
+       }
        | mudela_header {
                delete header_global_p;
                header_global_p = $1;
@@ -355,6 +366,11 @@ check_version:
        ;
 
 
+chordmodifiers_block:
+       CHORDMODIFIERS '{' notenames_body '}'  {  $$ = $3; }
+       ;
+
+
 notenames_block:
        NOTENAMES '{' notenames_body '}'  {  $$ = $3; }
        ;
@@ -421,6 +437,9 @@ block_identifier:
                $$ = new Score_identifier ($1, SCORE_IDENTIFIER);
 
        }
+       | chordmodifiers_block {
+               $$ = new Notename_table_identifier ($1, NOTENAME_TABLE_IDENTIFIER);
+       }
        | notenames_block {
                $$ = new Notename_table_identifier ($1, NOTENAME_TABLE_IDENTIFIER);
        }
@@ -807,7 +826,13 @@ Composite_music:
                { $$ = $3;
                  THIS->lexer_p_->pop_state ();
                }
-
+       | CHORDS
+               { THIS->lexer_p_->push_chord_state (); }
+       Music
+               {
+                 $$ = $3;
+                 THIS->lexer_p_->pop_state ();
+       }
        | LYRICS
                { THIS->lexer_p_->push_lyric_state (); }
        Music
@@ -1400,7 +1425,8 @@ abbrev_type:
 
 simple_element:
        steno_notepitch notemode_duration  {
-               if (!THIS->lexer_p_->note_state_b ())
+               if (!THIS->lexer_p_->note_state_b ()
+                 && !THIS->lexer_p_->chord_state_b ())
                        THIS->parser_error (_ ("have to be in Note mode for notes"));
                $1->duration_ = *$2;
                $$ = THIS->get_note_element ($1, $2);
@@ -1425,8 +1451,68 @@ simple_element:
                $$ = THIS->get_word_element (*$1, $2);
                delete $1;
        }
+       | '@' chord {
+               if (!THIS->lexer_p_->chord_state_b ())
+                       THIS->parser_error (_ ("have to be in Chord mode for chords"));
+               $$ = $2;
+       }
+       ;
+
+
+chord:
+        notemode_duration steno_musical_pitch chord_additions chord_subtractions {
+                $$ = THIS->get_chord (*$2, $3, $4, *$1);
+        };
+
+chord_additions:
+       {
+               $$ = new Array<Musical_pitch>;
+       } 
+       | chord_additions chord_note {
+               $1->push (*$2);
+               $$ = $1;
+       }
+       | chord_additions CHORDMODIFIER_PITCH {
+               /* 
+                 urg, this is kind of ugly.
+                 all but "sus" chord modifiers can be
+                 handled as chord_additions...
+                */
+               $1->push (*$2);
+               $$ = $1;
+       }
        ;
 
+chord_note:
+        UNSIGNED {
+               $$ = new Musical_pitch;
+               $$->notename_i_ = ($1 - 1) % 7;
+               $$->octave_i_ = $1 > 7 ? 1 : 0;
+               $$->accidental_i_ = 0;
+        } 
+       | UNSIGNED '+' {
+               $$ = new Musical_pitch;
+               $$->notename_i_ = ($1 - 1) % 7;
+               $$->octave_i_ = $1 > 7 ? 1 : 0;
+               $$->accidental_i_ = 1;
+       }
+       | UNSIGNED '-' {
+               $$ = new Musical_pitch;
+               $$->notename_i_ = ($1 - 1) % 7;
+               $$->octave_i_ = $1 > 7 ? 1 : 0;
+               $$->accidental_i_ = -1;
+       }
+        ;
+
+chord_subtractions:
+       {
+               $$ = new Array<Musical_pitch>;
+       }
+       | '^' chord_subtractions chord_note {
+               $2->push (*$3);
+               $$ = $2;
+       }
+       ;
 
 /*
        UTILITIES