Commands_at 1
Input_command 1
Time_description 1
-Melodic_req 0
-Stem_req 0
+Melodic_req 1
+Midi_walker 0
+Stem_req 1
Group_change_req 1
Script_req 1
Colinfo 1
keyword.hh leastsquares.hh lexer.hh linespace.hh \
localkeyitem.hh localkeyreg.hh lookup.hh \
lyriccolumn.hh lyricitem.hh lyricstaff.hh lyricwalker.hh\
- main.hh meter.hh meterreg.hh misc.hh\
+ main.hh meter.hh meterreg.hh\
+ midicolumn.hh mididef.hh midiitem.hh midistaff.hh midistream.hh\
+ midiwalker.hh midiscorewalker.hh\
+ misc.hh\
molecule.hh moment.hh musicalrequest.hh\
notehead.hh notename.hh offset.hh paperdef.hh\
parseconstruct.hh pcol.hh proto.hh pscore.hh pstaff.hh qlp.hh\
localkeyitem.cc localkeyreg.cc lookup.cc\
lyriccolumn.cc lyricitem.cc lyricstaff.cc lyricwalker.cc\
main.cc meter.cc meterreg.cc\
+ mididef.cc midicolumn.cc midiitem.cc midistaff.cc midistream.cc\
+ midiwalker.cc midiscorewalker.cc\
misc.cc molecule.cc mylexer.cc note.cc notehead.cc notename.cc\
paperdef.cc pcol.cc pscore.cc pstaff.cc qlp.cc qlpsolve.cc\
register.cc request.cc rest.cc sccol.cc score.cc\
Assoc<String, Identifier*> *the_id_tab;
Keyword_table * keytable;
Notename_tab * defaulttab;
- char const* data_ch_c_l_;
int errorlevel_i_;
/* *************** */
int ret_notename(int *p, String text, int octave_mod);
//
// lyriccolumn.hh -- declare Lyric_column
//
-// copyright 1997 Jan Nieuwenhuizen <jan@digicash.nl>
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-#ifndef LYRICCOLUMN_HH
-#define LYRICCOLUMN_HH
+#ifndef LYRIC_COLUMN_HH
+#define LYRIC_COLUMN_HH
#include "key.hh"
#include "stcol.hh"
Lyric_column(Lyric_staff*rs);
};
-#endif // LYRICSTAFF_HH
+#endif // LYRIC_COLUMN_HH
--- /dev/null
+//
+// midicolumn.hh -- declare Midi_column
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+
+#ifndef MIDI_COLUMN_HH
+#define MIDI_COLUMN_HH
+
+#include "key.hh"
+#include "stcol.hh"
+#include "staff.hh"
+
+/// (mcol)
+struct Midi_column : Staff_column {
+
+ Array<Melodic_req*> melreq_l_array_;
+ Midi_staff* mstaff_l_;
+
+ void note_on( Midi_track* midi_track_l );
+ void note_off( Midi_track* midi_track_l, Moment next );
+ virtual void setup_one_request(Request*);
+
+ Midi_column(Midi_staff*rs);
+};
+
+#endif // MIDI_COLUMN_HH
+
--- /dev/null
+/*
+ mididef.hh -- declare
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+
+#ifndef MIDIDEF_HH
+#define MIDIDEF_HH
+#include "proto.hh"
+#include "real.hh"
+#include "string.hh"
+#include "moment.hh"
+
+
+/**
+ */
+struct Mididef {
+ /// output file name
+ String outfile_str_;
+
+ /// duration of whole note
+ Real whole_seconds_f_;
+
+ Mididef();
+ Mididef(Mididef const& midi_c_r);
+ ~Mididef();
+
+ Real duration_to_seconds_f(Moment);
+ int get_tempo_i( Moment moment );
+ void set_tempo( Moment moment, int count_per_minute_i );
+ void print() const;
+};
+
+#endif // MIDIDEF_HH //
+
--- /dev/null
+//
+// midiitem.hh -- part of LilyPond
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MIDI_ITEM_HH
+#define MIDI_ITEM_HH
+
+struct Midi_item {
+ /* *************** */
+ static String int2varlength_str( int i );
+ virtual void output_midi( Midi_stream& midi_stream_r );
+ virtual String str() = 0;
+};
+
+struct Midi_note : public Midi_item {
+ /* *************** */
+ int const c0_pitch_i_c_ = 60;
+ Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo );
+
+ virtual String str();
+
+ int channel_i_;
+ int on_bo_;
+ int pitch_i_;
+};
+
+struct Midi_duration : public Midi_item {
+ /* *************** */
+ Midi_duration( Real seconds_f );
+
+ virtual String str();
+
+ Real seconds_f_;
+};
+
+struct Midi_chunk : Midi_item {
+ /* *************** */
+ Midi_chunk();
+
+ void add( String str );
+ void set( String header_str, String data_str, String footer_str );
+ virtual String str();
+
+private:
+ String data_str_;
+ String footer_str_;
+ String header_str_;
+};
+
+struct Midi_header : Midi_chunk {
+ /* *************** */
+ Midi_header( int format_i, int tracks_i, int tempo_i );
+};
+
+struct Midi_track : Midi_chunk {
+ /* *************** */
+ int number_i_;
+ Midi_track( int number_i );
+
+ void add( int delta_time_i, String event );
+// void add( Moment delta_time_moment, Midi_item& mitem_r );
+ void add( Moment delta_time_moment, Midi_item* mitem_l );
+};
+
+#endif // MIDI_ITEM_HH //
+
--- /dev/null
+//
+// midiscorewalker.hh -- declare Midi_score_walker
+//
+// (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen <jan@digicash.com>
+//
+
+#ifndef MIDI_SCORE_WALKER_HH
+#define MIDI_SCORE_WALKER_HH
+
+#include "proto.hh"
+#include "grouping.hh"
+#include "scorewalker.hh"
+#include "midiitem.hh"
+
+/// a simple walker which collects midi stuff, and then outputs
+struct Midi_score_walker : Score_walker {
+ Midi_stream* midi_stream_l_;
+
+ /* *************** */
+ virtual void process();
+
+ Midi_score_walker( Score* score_l, Midi_stream* midi_stream_l );
+};
+
+
+#endif // MIDI_SCORE_WALKER_HH
+
+
--- /dev/null
+/*
+ midistaff.hh -- part of LilyPond
+
+ copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+ */
+
+#ifndef MIDI_STAFF_HH
+#define MIDI_STAFF_HH
+
+#include "staff.hh"
+
+///(mstaff)
+struct Midi_staff : Staff {
+// PStaff* pstaff_l_;
+
+ Staff_column* create_col();
+ virtual void set_output(PScore *);
+ void midi( Midi_stream* midi_stream_l, int track_i );
+ virtual Staff_walker *get_walker_p();
+ Midi_staff();
+};
+
+#endif // MIDI_STAFF_HH
+
+
+
+
+
--- /dev/null
+//
+// midistream.hh -- part of LilyPond
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MIDI_STREAM_HH
+#define MIDI_STREAM_HH
+
+#include <iostream.h>
+#include "string.hh"
+
+/// Midi output
+struct Midi_stream {
+ ostream* os_p_;
+ String filename_str_;
+ int tempo_i_;
+ int tracks_i_;
+
+ Midi_stream( String filename_str, int tracks_i, int tempo_i );
+ ~Midi_stream();
+
+ Midi_stream& operator <<( String str );
+ Midi_stream& operator <<( Midi_item& mitem_r );
+ Midi_stream& operator <<( int i );
+
+ void header();
+ void open();
+
+//private:
+// Midi_stream(Midi_stream const&);
+};
+#endif // MIDI_STREAM_HH //
--- /dev/null
+//
+// midiwalker.hh -- declare Midi_walker
+//
+// (c) 1996,97 Han-Wen Nienhuys, Jan Nieuwenhuizen <jan@digicash.com>
+//
+
+#ifndef MIDIWALKER_HH
+#define MIDIWALKER_HH
+
+#include "proto.hh"
+#include "grouping.hh"
+#include "staffwalker.hh"
+
+/// a simple walker which collects midi stuff, and then outputs
+struct Midi_walker: Staff_walker {
+// Midi_stream* midi_stream_l_;
+ /* *************** */
+ virtual void process_requests();
+
+ Midi_walker( Midi_staff* mstaff_l );
+ Midi_column* mcol_l();
+ Midi_staff* mstaff_l();
+};
+
+
+#endif // MIDIWALKER_HH
+
+
/// return height from central c (in halflines)
int height()const;
+ /// return pitch from central c (in halfnotes)
+ int pitch()const;
Melodic_req();
REQUESTMETHODS(Melodic_req,melodic);
};
+/// request for backward plet generation
+struct Plet_req : Request {
+ char type_c_;
+ int dur_i_;
+ int type_i_;
+ Plet_req();
+
+ REQUESTMETHODS(Plet_req,plet);
+};
+/**
+*/
/** Start / stop a beam at this note. if #nplet# is set, the staff will try to put an
appropriate number over the beam
-
/*
proto.hh -- part of LilyPond
struct Absdynamic_req;
struct Accidental;
struct Atom;
+struct Bar;
+struct Bar_register;
struct Barcheck_req;
+struct Bar_req;
struct Beam;
struct Beam_req;
struct Box;
struct Bracket_req;
-struct CNote_info;
+struct Cadenza_req;
struct Chord;
-struct Clef;
+struct Clef_change_req;
+struct Clef_register;
struct Clef_item;
struct Col_hpositions;
struct Colinfo;
-struct Command;
-struct Commands_at ;
struct Complex_column;
struct Complex_music;
struct Complex_staff;
struct Complex_walker;
struct Cresc_req;
struct Decresc_req;
+struct Durational_req;
struct Dynamic;
struct Group_change_req;
struct Group_feature_req;
struct Idealspacing;
struct Identifier;
-struct Input_command;
-struct Input_commands;
struct Input_file;
struct Input_music;
struct Input_score;
struct Input_staff;
struct Item;
struct Key;
-struct Keyitem;
+struct Key_register;
+struct Key_change_req;
+struct Key_item;
struct Keyword;
struct Keyword_table;
struct Line_of_score;
struct Line_of_staff;
struct Linestaff;
struct Local_key;
+struct Local_key_register;
struct Local_key_item;
struct Lookup;
+struct Lyric_item;
struct Lyric_req;
-struct Lyric_req;
-struct Mark_req;
struct Melodic_req;
+struct Measure_grouping_req;
+struct Meter_change_req;
+struct Meter;
+struct Meter_register;
+struct Midi_column;
+struct Mididef;
+struct Midi_duration;
+struct Midi_header;
+struct Midi_item;
+struct Midi_pitch;
+struct Midi_staff;
+struct Midi_stream;
+struct Midi_track;
+struct Midi_walker;
struct Mixed_qp;
struct Molecule;
+struct Musical_req;
struct Music_general_chord;
struct Music_voice;
+struct Nonmusical_req;
struct Note_req;
struct Notehead;
+struct Notehead_register;
struct Notename_tab;
struct Offset;
struct Output;
struct PCol;
+struct Plet_req;
struct PScore;
struct PStaff;
struct Paperdef;
-struct Parametric_symbol;
+struct Partial_measure_req;
struct Rational;
struct Request;
struct Request_register;
struct Rest;
struct Rest_req;
struct Rhythmic_grouping;
+struct Rhythmic_grouping_req;
struct Rhythmic_req;
struct Score;
struct Score_column;
+struct Score_walker;
struct Script_def;
struct Script;
+struct Script_register;
struct Script_req;
struct Simple_music;
+struct Skip_req;
struct Slur;
+struct Slur_register;
struct Slur_req;
-class Source;
-class Source_file;
+struct Source;
+struct Source_file;
struct Spacing_req ;
struct Span_req;
struct Spanner;
struct Blank_req;
struct Staff;
struct Staff_column;
-struct Staff_command_req;
-struct Staff_commands;
-struct Staff_commands_at ;
struct Staff_elem;
struct Staff_elem_info;
+struct Staff_symbol;
struct Staff_walker;
struct Stem;
struct Stem_req;
struct Text_item ;
struct Text_def;
struct Text_gob;
+struct Text_register;
struct Text_req;
+struct Timing_req;
struct Time_description;
struct Voice;
struct Voice_element;
/// when does the last *musical* element finish?
Moment last() const;
+// /// extract midi info
+// Midi_track* midi_track_p();
+
/// remove unused cols
void clean_cols() ;
Staff();
alto = music {
$
\duration{ 8 }
- \key {$bes es as$}
+ \key {bes es as}
- } \clef "alto"
+ \clef "alto"
% these are chords (i.e. non-divisi)
% that-s why i-d rather type chords,
% but how to type slurs?
+include "this-is-hopefully-a-nonexisting-file"
+
mwa = music {
$
[ a8 a8 a8 a8 a8 ] %
[ a8 ] %
+% segfault
+% { \music{ [ bes^"1"( )a bes-. g-. ] a4-.^"4" } \music{ [ e ] } \music{ [ c ] } } |
a ) b ] c % warning
& % ok; error
a b ) ] % ok; error
}
commands {
meter {2*4}
- key $fis$
+% key $fis$
skip 56*2
- key $bes es as$
+% key $bes es as$
skip 8*2
meter {6*8}
skip 48*8
meter {2*4}
skip 16*2
- key $fis$
+% key $fis$
}
paper {
% unitspace 16mm
width 195mm
output "martien.out"
}
+ staff {
+ midi_track
+ music { alto }
+ }
+ staff {
+ midi_track
+ music { violin1 }
+ }
+ staff {
+ midi_track
+ music { violin2 }
+ }
+ staff {
+ midi_track
+ music { cello }
+ }
+ midi {
+ tempo 4:80
+ }
}
\duration{16}
\clef\alto
\octave{}
+ \key{fis}
%1
[ `b8. `a ] [ `g8 `b c ] |
%2
%44
[ `b8. c32 `b32 ] `a4 |
%45
- \plet{ 4/6 } [ `g `a `g `a `g `a ] \plet{ 1/1 } \plet{ 4/6 } [ `g `b c d e fis ] \plet{ 1/1 } |
+ [ `g `a `g `a `g `a ]4/6 [ `g `b c d e fis ]4/6 |
%46
- \plet{ 4/6 } [ g fis e d `b `g ] \plet{ 1/1 } [ `a8 `g8 ] |
+ [ g fis e d `b `g ]4/6 [ `a8 `g8 ] |
%47
- \plet{ 4/6 } [ g fis e d c `b ] \plet{ 1/1 } \plet{ 4/6 } [ e d c `b `a `g ] \plet{ 1/1 } |
+ [ g fis e d c `b ]4/6 [ e d c `b `a `g ]4/6 |
%48
- \plet{ 4/6 } [ d e d d `b `g ] \plet{ 1/1 } [ `a8 `g8 ] |
+ [ d e d d `b `g ]4/6 [ `a8 `g8 ] |
%theme 2
\duration{8}
%49
- \plet{ 2/3 } [ f e d ] \plet{ 1/1 } f4 |
+ [ f e d ]2/3 f4 |
%50
- \plet{ 2/3 } [ e d c ] \plet{ 1/1 } e4 |
+ [ e d c ]2/3 e4 |
%51
- \plet{ 2/3 } [ d g `g ] \plet{ 1/1 } \plet{ 2/3 } [ `g `a `b ] \plet{ 1/1 } |
+ [ d g `g ]2/3 [ `g `a `b ]2/3 |
%52
d4 e4 |
%53
- \plet{ 2/3 } [ f e d ] \plet{ 1/1 } f4 |
+ [ f e d ]2/3 f4 |
%54
- \plet{ 2/3 } [ e d c ] \plet{ 1/1 } e4 |
+ [ e d c ]2/3 e4 |
%55
- \plet{ 2/3 } [ d g `g ] \plet{ 1/1 } \plet{ 2/3 } [ `g `a `b ] \plet{ 1/1 } |
+ [ d g `g ]2/3 [ `g `a `b ]2/3 |
%56
- `b4 c4 | % || \key\Es
+ `b4 c4 \key{bes es as} | % || \key\Es
%57
[ `b d ] [ `g `b ] |
%58
`b2 |
%88
\textstyle "italic"
- c2_"dacapo" |
+ c2_"dacapo" \key{fis} |
\textstyle "roman"
%\scoreverb{\mulooseness=1}
% \key\G ||
$
\clef"bass" \octave{`}
\duration{4}
+ \key{fis}
%%1
g `g |
%%2
%%49
\textstyle "italic"
r4_"arco"
- \plet{ 2/3 } [ `g `g `g ] \plet{ 1/1 } |
+ [ `g `g `g ]2/3 |
\textstyle "roman"
%%50
- r4 \plet{ 2/3 } [ c c c ] \plet{ 1/1 } |
+ r4 [ c c c ]2/3 |
%%51
g2 |
%%52
c2 |
%%53
- r4 \plet{ 2/3 } [ `g `g `g ] \plet{ 1/1 } |
+ r4 [ `g `g `g ]2/3 |
%%54
- r4 \plet{ 2/3 } [ c c c ] \plet{ 1/1 } |
+ r4 [ c c c ]2/3 |
%%55
g2 |
%%56
- `g4 `c4 |
+ `g4 `c4 \key{bes es as}|
% \key\`es ||
%%57
g r g r |
d |
%%88
\textstyle "italic"
- d_"dacapo"
+ d_"dacapo" \key{fis} |
\textstyle "roman"
% \key\`g ||
$
%
violin1 = music {
$
-\clef "violin"
+ \clef "violin"
\octave{}
\duration{4}
+ \key{fis}
%1
g [ b8. a16 ] |
%2
%theme 2
%49
\textstyle "italic"
- r4_"arco" \plet{ 2/3 } [ b8 b b ] \plet{ 1/1 }
+ r4_"arco" [ b8 b b ]2/3
\textstyle "roman" |
%50
- r4 \plet{ 2/3 } [ g g g ] \plet{ 1/1 } |
+ r4 [ g g g ]2/3 |
%51
b2 |
%52
'c2 |
%53
- r4 \plet{ 2/3 } [ b b b ] \plet{ 1/1 } |
+ r4 [ b b b ]2/3 |
%54
- r4 \plet{ 2/3 } [ g g g ] \plet{ 1/1 } |
+ r4 [ g g g ]2/3 |
%55
b2 |
%56
- g2 |
+ g2 \key{bes es as}|
% \key\Es ||
%57
f r f r |
'c r 'c4 |
%61
\duration{16}
- \plet{ 4/6 } [ as f d f as 'd ] \plet{ 1/1 } \plet{ 4/6 } [ as f d `as d f ] \plet{ 1/1 } |
+ [ as f d f as 'd ]4/6 [ as f d `as d f ]4/6 |
%62
- \plet{ 4/6 } [ g es c `g c es ] \plet{ 1/1 } \plet{ 4/6 } [ g 'c 'es 'c g es ] \plet{ 1/1 } |
+ [ g es c `g c es ]4/6 [ g 'c 'es 'c g es ]4/6 |
%63
- \plet{ 4/6 } [ g d g bes 'd 'g ] \plet{ 1/1 } \plet{ 4/6 } [ 'f 'd bes g f d ] \plet{ 1/1 } |
+ [ g d g bes 'd 'g ]4/6 [ 'f 'd bes g f d ]4/6 |
%64
\duration{8}
[ c g ] g4 |
'c r 'c4 |
%77
\duration{16}
- \plet{ 4/6 } [ as f d f as 'd ] \plet{ 1/1 } \plet{ 4/6 } [ as f d `as d f ] \plet{ 1/1 } |
+ [ as f d f as 'd ]4/6 [ as f d `as d f ]4/6 |
%78
- \plet{ 4/6 } [ g es c `g c es ] \plet{ 1/1 } \plet{ 4/6 } [ f 'c 'es 'c g es ] \plet{ 1/1 } |
+ [ g es c `g c es ]4/6 [ f 'c 'es 'c g es ]4/6 |
%79
- \plet{ 4/6 } [ g d f b 'd 'g ] \plet{ 1/1 } \plet{ 4/6 } [ 'f 'd b g f d ] \plet{ 1/1 } |
+ [ g d f b 'd 'g ]4/6 [ 'f 'd b g f d ]4/6 |
%80
[ c8 g8 ] g4 |
%81
\textstyle "italic"
a_"dacapo"
\textstyle "roman"
+ \key{fis} |
% \key\G ||
$
}
$
\clef "violin" \octave{}
\duration{4}
+ \key{fis}
%1
d2 |
%2
%35
[ g8 e e ] [ e8 g g ] |
%36
- b4 fis4 |
+ b4 fis4 |
%37
[ a8 a a ] [ a8 a a ] |
%38
\textstyle "italic"
r4_"arco"
\textstyle "roman"
- \plet{ 2/3 } [ d8 d d ] \plet{ 1/1 } |
+ [ d8 d d ]2/3 |
%50
- r4 \plet{ 2/3 } [ g8 g g ] \plet{ 1/1 } |
+ r4 [ g8 g g ]2/3 |
%51
d2 |
%52
c2 |
%53
- r4 \plet{ 2/3 } [ d8 d d ] \plet{ 1/1 } |
+ r4 [ d8 d d ]2/3 |
%54
- r4 \plet{ 2/3 } [ e e e ] \plet{ 1/1 } |
+ r4 [ e e e ]2/3 |
%55
d2 |
%56
- f4 e4 |
+ f4 e4 \key{bes es as}|
% \key\Es ||
%57
d r `b r |
%74
`g r es r |
%75
- g r g r |
+ g r g r |
%76
- g r es4 |
+ g r es4 |
%77
\duration{2}
f |
% = g |
%88
\textstyle "italic"
- fis_"dacapo" |
+ fis_"dacapo" \key{fis}|
\textstyle "roman"
% \key\G ||
$
c c | g g | a a | g g |
f f | e e | d d8.( e16 | )c2 % :|
+ \bar ":|"
$
}
c 'c | 'e 'c | 'f 'c | 'e 'c |
'd b | 'c a | f g | c2
+ \bar ":|"
$
}
}
commands {
meter {2 * 4}
- skip 24*2
- bar "||"
+% skip 24*2
+% bar "||"
+ }
+ staff { midi_track music { melodie } }
+ staff { midi_track music { begeleiding } }
+ midi {
+ tempo 4:120
}
}
--- /dev/null
+#include "musicalrequest.hh"
+#include "voice.hh"
+#include "staffwalker.hh"
+#include "debug.hh"
+#include "staff.hh"
+#include "midistaff.hh"
+#include "midicolumn.hh"
+#include "midiitem.hh"
+#include "sccol.hh"
+#include "pscore.hh"
+#include "main.hh"
+
+Midi_column::Midi_column(Midi_staff* mstaff_l)
+{
+ mstaff_l_ = mstaff_l;
+}
+
+void
+Midi_column::setup_one_request(Request*req_l)
+{
+ if ( req_l->melodic() )
+ melreq_l_array_.push( req_l->melodic() );
+}
+
+void
+Midi_column::note_off( Midi_track* midi_track_l, Moment next )
+{
+ Moment delta_t = next - when();
+ for ( int i = 0; i < melreq_l_array_.size(); i++ ) {
+ Midi_note midi_note( melreq_l_array_[ i ], midi_track_l->number_i_, false );
+ midi_track_l->add( delta_t, &midi_note );
+ delta_t = 0.0;
+ }
+}
+
+void
+Midi_column::note_on( Midi_track* midi_track_l )
+{
+ Moment delta_t = 0.0;
+ for ( int i = 0; i < melreq_l_array_.size(); i++ ) {
+ Midi_note midi_note( melreq_l_array_[ i ], midi_track_l->number_i_, true );
+ midi_track_l->add( delta_t, &midi_note );
+ }
+}
--- /dev/null
+//
+// mididef.cc -- implement midi output
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <math.h>
+#include "misc.hh"
+#include "mididef.hh"
+#include "debug.hh"
+
+// classes, alphasorted
+// statics
+// constructors
+// destructor
+// routines, alphasorted
+
+Mididef::Mididef()
+{
+ set_tempo( Moment( 1, 4 ), 60 );
+ outfile_str_ = "lelie.midi";
+}
+
+Mididef::Mididef( Mididef const& midi_c_r )
+{
+ whole_seconds_f_ = midi_c_r.whole_seconds_f_;
+ outfile_str_ = midi_c_r.outfile_str_;
+}
+
+Mididef::~Mididef()
+{
+}
+
+Real
+Mididef::duration_to_seconds_f( Moment moment )
+{
+ if (!moment)
+ return 0;
+
+ return whole_seconds_f_ * moment;
+}
+
+int
+Mididef::get_tempo_i( Moment moment )
+{
+ return Moment( whole_seconds_f_ ) * Moment( 60 ) * moment;
+}
+
+void
+Mididef::print() const
+{
+#ifndef NPRINT
+ mtor << "Midi {4/min: " << Real( 60 ) / ( whole_seconds_f_ * 4 );
+ mtor << "out: " << outfile_str_;
+ mtor << "}\n";
+#endif
+}
+
+void
+Mididef::set_tempo( Moment moment, int count_per_minute_i )
+{
+ whole_seconds_f_ = Moment( count_per_minute_i ) / Moment( 60 ) / moment;
+}
--- /dev/null
+//
+// midiitem.cc
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <limits.h>
+#include "plist.hh"
+#include "pcol.hh"
+#include "debug.hh"
+#include "misc.hh"
+#include "request.hh"
+#include "musicalrequest.hh"
+#include "voice.hh"
+#include "midiitem.hh"
+#include "midistream.hh"
+
+Midi_chunk::Midi_chunk()
+{
+}
+
+void
+Midi_chunk::add( String str )
+{
+ data_str_ += str;
+}
+
+void
+Midi_chunk::set( String header_str, String data_str, String footer_str )
+{
+ data_str_ = data_str;
+ footer_str_ = footer_str;
+ header_str_ = header_str;
+}
+
+String
+Midi_chunk::str()
+{
+ String str = header_str_;
+ String length_str = StringConversion::int2hex_str( data_str_.length_i() + footer_str_.length_i(), 8, '0' );
+ length_str = StringConversion::hex2bin_str( length_str );
+ str += length_str;
+ str += data_str_;
+ str += footer_str_;
+ return str;
+}
+
+Midi_duration::Midi_duration( Real seconds_f )
+{
+ seconds_f_ = seconds_f;
+}
+
+String
+Midi_duration::str()
+{
+ return String( "<duration: " ) + String( seconds_f_ ) + ">";
+}
+
+Midi_header::Midi_header( int format_i, int tracks_i, int tempo_i )
+{
+ String str;
+
+ String format_str = StringConversion::int2hex_str( format_i, 4, '0' );
+ str += StringConversion::hex2bin_str( format_str );
+
+ String tracks_str = StringConversion::int2hex_str( tracks_i, 4, '0' );
+ str += StringConversion::hex2bin_str( tracks_str );
+
+ String tempo_str = StringConversion::int2hex_str( tempo_i, 4, '0' );
+ str += StringConversion::hex2bin_str( tempo_str );
+
+ set( "MThd", str, "" );
+}
+
+String
+Midi_item::int2varlength_str( int i )
+{
+ int buffer_i = i & 0x7f;
+ while ( (i >>= 7) > 0 ) {
+ buffer_i <<= 8;
+ buffer_i |= 0x80;
+ buffer_i += (i & 0x7f);
+ }
+
+ String str;
+ while ( 1 ) {
+ str += (char)buffer_i;
+ if ( buffer_i & 0x80 )
+ buffer_i >>= 8;
+ else
+ break;
+ }
+ return str;
+}
+
+void
+Midi_item::output_midi( Midi_stream& midi_stream_r )
+{
+ midi_stream_r << str();
+}
+
+
+Midi_note::Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo )
+{
+ pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;
+ channel_i_ = channel_i;
+ on_bo_ = on_bo;
+}
+
+String
+Midi_note::str()
+{
+ if ( pitch_i_ != INT_MAX ) {
+ Byte status_by = ( on_bo_ ? 0x90 : 0x80 ) + channel_i_;
+ String str = String( (char)status_by );
+ str += (char)pitch_i_;
+ // poor man-s staff dynamics:
+ Byte dynamic_by = 0x64 - 0x10 * channel_i_;
+ str += (char)dynamic_by;
+ return str;
+ }
+ return String( "" );
+}
+
+Midi_track::Midi_track( int number_i )
+{
+// 4D 54 72 6B MTrk
+// 00 00 00 3B chunk length (59)
+// 00 FF 58 04 04 02 18 08 time signature
+// 00 FF 51 03 07 A1 20 tempo
+
+// FF 59 02 sf mi Key Signature
+// sf = -7: 7 flats
+// sf = -1: 1 flat
+// sf = 0: key of C
+// sf = 1: 1 sharp
+// sf = 7: 7 sharps
+// mi = 0: major key
+// mi = 1: minor key
+
+ number_i_ = number_i;
+
+ char const* data_ch_c_l = "00" "ff58" "0404" "0218" "08"
+ "00" "ff51" "0307" "a120"
+// why a key at all, in midi?
+// key: C
+ "00" "ff59" "02" "00" "00"
+// key: F (scsii-menuetto)
+// "00" "ff59" "02" "ff" "00"
+ ;
+
+ String data_str;
+ // only for format 0 (currently using format 1)?
+ data_str += StringConversion::hex2bin_str( data_ch_c_l );
+
+ char const* footer_ch_c_l = "00" "ff2f" "00";
+ String footer_str = StringConversion::hex2bin_str( footer_ch_c_l );
+
+ set( "MTrk", data_str, footer_str );
+}
+
+void
+Midi_track::add( int delta_time_i, String event_str )
+{
+ Midi_chunk::add( int2varlength_str( delta_time_i ) + event_str );
+}
+
+void
+Midi_track::add( Moment delta_time_moment, Midi_item* mitem_l )
+{
+ // silly guess: 24 midi clocks per 4 note
+ // huh?
+// int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 24 );
+ int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 96 );
+ add( delta_time_i, mitem_l->str() );
+}
+
--- /dev/null
+/*
+ midiscorewalker.cc -- implement Midi_score_walker
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>, Jan Nieuwehuizen <jan@digicash.com>
+*/
+#include "plist.hh"
+#include "debug.hh"
+#include "score.hh"
+#include "staffwalker.hh"
+#include "staff.hh"
+#include "sccol.hh"
+#include "midistream.hh"
+#include "midiscorewalker.hh"
+
+Midi_score_walker::Midi_score_walker( Score* score_l, Midi_stream* midi_stream_l )
+ :Score_walker( score_l )
+{
+ midi_stream_l_ = midi_stream_l;
+}
+
+Midi_score_walker::~Midi_score_walker()
+{
+}
+
+void
+Midi_score_walker::process()
+{
+}
+
--- /dev/null
+#include "musicalrequest.hh"
+#include "voice.hh"
+#include "staffwalker.hh"
+#include "debug.hh"
+#include "staff.hh"
+#include "midistaff.hh"
+#include "midicolumn.hh"
+#include "midiwalker.hh"
+#include "midiitem.hh"
+#include "midistream.hh"
+
+Midi_staff::Midi_staff()
+{
+}
+
+Staff_column*
+Midi_staff::create_col()
+{
+ return new Midi_column(this);
+}
+
+Staff_walker*
+Midi_staff::get_walker_p()
+{
+ return new Midi_walker(this);
+}
+
+void
+Midi_staff::midi( Midi_stream* midi_stream_l, int track_i )
+{
+ Midi_track midi_track( track_i );
+ Midi_column* last_mcol_l = 0;
+ for ( Midi_walker w( this ); w.ok(); w++ ) {
+ Midi_column* mcol_l = (Midi_column*)*w;
+ if ( last_mcol_l )
+ last_mcol_l->note_off( &midi_track, w->when() );
+ mcol_l->note_on( &midi_track );
+ last_mcol_l = mcol_l;
+ }
+ if ( last_mcol_l )
+ last_mcol_l->note_off( &midi_track, last() );
+ *midi_stream_l << midi_track;
+}
+
+void
+Midi_staff::set_output(PScore*pscore_l)
+{
+ //i don-t want no pscore!
+}
+
--- /dev/null
+//
+// midistream.cc
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <fstream.h>
+#include <time.h>
+#include "main.hh"
+#include "misc.hh"
+#include "midiitem.hh"
+#include "midistream.hh"
+#include "debug.hh"
+
+Midi_stream::Midi_stream( String filename_str, int tracks_i, int tempo_i )
+{
+ filename_str_ = filename_str;
+ tracks_i_ = tracks_i;
+ tempo_i_ = tempo_i;
+ open();
+ header();
+}
+
+Midi_stream::~Midi_stream()
+{
+ delete os_p_;
+}
+
+Midi_stream&
+Midi_stream::operator <<( String str )
+{
+ // still debugging...
+ if ( check_debug )
+ str = StringConversion::bin2hex_str( str );
+ // string now 1.0.26-2 handles binary streaming
+ *os_p_ << str;
+ return *this;
+}
+
+Midi_stream&
+Midi_stream::operator <<( Midi_item& mitem_r )
+{
+ mitem_r.output_midi( *this );
+ if ( check_debug )
+ *os_p_ << "\n";
+ return *this;
+}
+
+Midi_stream&
+Midi_stream::operator <<( int i )
+{
+ // output binary string ourselves
+ *this << Midi_item::int2varlength_str( i );
+ return *this;
+}
+
+void
+Midi_stream::header()
+{
+// *os_p_ << "% Creator: " << get_version();
+// *os_p_ << "% Automatically generated, at ";
+// time_t t(time(0));
+// *os_p_ << ctime(&t);
+
+// 4D 54 68 64 MThd
+// String str = "MThd";
+// 00 00 00 06 chunk length
+// 00 01 format 1
+// 00 01 one track
+// 00 60 96 per quarter-note
+
+// char const ch_c_l = "0000" "0006" "0001" "0001" "0060";
+// str += StringConversion::hex2bin_str( ch_c_l );
+// *os_p_ << str;
+
+// *this << Midi_header( 1, 1, tempo_i_ );
+ *this << Midi_header( 1, tracks_i_, tempo_i_ );
+}
+
+void
+Midi_stream::open()
+{
+ os_p_ = new ofstream( filename_str_ );
+ if ( !*os_p_ )
+ error ("can't open `" + filename_str_ + "\'" );
+}
--- /dev/null
+/*
+ midiwalker.cc -- implement Midi_walker
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>, Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+#include "misc.hh"
+#include "musicalrequest.hh"
+#include "voice.hh"
+#include "pscore.hh"
+#include "staff.hh"
+#include "midicolumn.hh"
+#include "midistaff.hh"
+#include "midiwalker.hh"
+#include "debug.hh"
+#include "midiitem.hh"
+#include "midistream.hh"
+
+Midi_walker::Midi_walker( Midi_staff* mstaff_l )
+ : Staff_walker( mstaff_l, 0 )
+{
+}
+
+Midi_column*
+Midi_walker::mcol_l()
+{
+ return (Midi_column*) *(*this);
+}
+
+Midi_staff*
+Midi_walker::mstaff_l()
+{
+ return (Midi_staff*)staff_l_;
+}
+
+void
+Midi_walker::process_requests()
+{
+ allow_break();
+}
+
"key", KEY,
"meter", METER,
+ "midi", MIDI,
"mm", MM_T,
"multivoice", MULTIVOICE,
"octave", OCTAVECOMMAND,
"table", TABLE,
"symboltables", SYMBOLTABLES,
"notenames", NOTENAMES,
+ "tempo", TEMPO,
"texid", TEXID,
"textstyle", TEXTSTYLE,
"unitspace", UNITSPACE,
{
text.lower();
char const* ch_c_l = here_ch_c_l();
- ch_c_l--;
- while ( ( *ch_c_l == ' ' ) || ( *ch_c_l == '\t' ) || ( *ch_c_l == '\n' ) )
+ if ( ch_c_l ) {
ch_c_l--;
- ch_c_l++;
+ while ( ( *ch_c_l == ' ' ) || ( *ch_c_l == '\t' ) || ( *ch_c_l == '\n' ) )
+ ch_c_l--;
+ ch_c_l++;
+ }
lookup_notename(p[0], p[1], text);
p[2] = octave_mod;
if (p[0] < 0) {
errorlevel_i_ |= 1;
- warning( String( "notename does not exist: " ) + YYText(), ch_c_l );
+ error( String( "notename does not exist: " ) + YYText(), ch_c_l );
p[0] = p[1] = 0;
}
return NOTENAME;
keytable = new Keyword_table(the_key_tab);
the_id_tab = new Assoc<String, Identifier*>;
defaulttab = 0;
- data_ch_c_l_ = 0;
errorlevel_i_ = 0;
}
char const*
My_flex_lexer::here_ch_c_l()
{
- return data_ch_c_l_ ? data_ch_c_l_ + yyin->tellg() : 0;
+ return include_stack.top()->sourcefile_l_->ch_c_l() + yyin->tellg();
}
void
ch_c_l++;
}
errorlevel_i_ |= 1;
- warning( s, ch_c_l );
+ error( s, ch_c_l );
}
}
Input_file *newin = new Input_file(s);
include_stack.push(newin);
switch_streams(newin->is);
- if ( newin->sourcefile_l_ )
- data_ch_c_l_ = newin->sourcefile_l_->ch_c_l();
- else
- data_ch_c_l_ = 0;
yylineno = 1;
}
#include "source.hh"
#include "sourcefile.hh"
#include "scorewalker.hh"
+#include "mididef.hh"
+#include "midiitem.hh"
+#include "midistream.hh"
+#include "midicolumn.hh"
+#include "midistaff.hh"
+#include "midiwalker.hh"
void
Score::setup_music()
{
*mlog << "\nSetting up music ..." << flush;
if (last() == Moment(0)) {
- warning("Need to have music in a score.", defined_ch_c_l_);
+ errorlevel_i_ |= 1;
+ error("Need to have music in a score.", defined_ch_c_l_);
}
pscore_p_ = new PScore(paper_p_);
*mlog << "Processing music ..." << flush;
for (Score_walker w(this); w.ok(); w++) {
w.process();
- }
+ }
}
void
Score::process()
{
setup_music();
+
process_music();
// do this after processing, staffs first have to generate PCols.
return l;
}
+void
+Score::set(Mididef* midi_p)
+{
+ delete midi_p_;
+ midi_p_ = midi_p;
+}
+
void
Score::OK() const
{
{
pscore_p_=0;
paper_p_ = paper_p;
+ midi_p_ = 0;
errorlevel_i_ = 0;
defined_ch_c_l_ = 0;
}
{
delete pscore_p_;
delete paper_p_;
+ delete midi_p_;
}
void
pscore_p_->output(the_output);
}
+void
+Score::midi()
+{
+ if (!midi_p_)
+ return;
+
+ *mlog << "midi output to " << midi_p_->outfile_str_ << "...\n";
+
+ int track_i = 0;
+ for ( PCursor<Staff*> staff_l_pcur( staffs_.top() ); staff_l_pcur.ok(); staff_l_pcur++ ) {
+ Midi_staff* mstaff_l = (Midi_staff*)*staff_l_pcur;
+ if ( !mstaff_l->pscore_l_ ) // we _are_ a midi-staff, ugh
+ track_i++;
+ }
+ Midi_stream midi_stream( midi_p_->outfile_str_, track_i, midi_p_->get_tempo_i( Moment( 1, 4 ) ) );
+
+ track_i = 0;
+ for ( PCursor<Staff*> staff_l_pcur( staffs_.top() ); staff_l_pcur.ok(); staff_l_pcur++ ) {
+ Midi_staff* mstaff_l = (Midi_staff*)*staff_l_pcur;
+ if ( !mstaff_l->pscore_l_ ) // we _are_ a midi-staff, ugh
+ mstaff_l->midi( &midi_stream, track_i++ );
+ }
+}
void
Score::add(Staff*s)
s_p->print ();
s_p->process();
s_p->output(outfn);
+ s_p->midi();
delete s_p;
}
score_array_global.set_size(0);
#include "debug.hh"
#include "musicalrequest.hh"
#include "commandrequest.hh" // todo
+#include "midistream.hh"
void
Staff::add(PointerList<Voice*> const &l)
}
}
+// Midi_track*
+// Staff::midi_track_p()
+// {
+// Midi_track_p midi_track_p = new Midi_track;
+// Midi_walker( *this );
+// }
+
Staff_column *
Staff::get_col(Moment w, PCursor<Staff_column*> *last)
{
return l;
}
-
void
Staff::print() const
{