]> git.donarmstrong.com Git - lilypond.git/commitdiff
partial: 0.0.33.jcn
authorJan Nieuwenhuizen <janneke@gnu.org>
Thu, 20 Feb 1997 23:15:12 +0000 (00:15 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Thu, 20 Feb 1997 23:15:12 +0000 (00:15 +0100)
hdr/midicolumn.hh [new file with mode: 0644]
hdr/mididef.hh [new file with mode: 0644]
hdr/midiitem.hh [new file with mode: 0644]
hdr/midistaff.hh [new file with mode: 0644]
hdr/midistream.hh [new file with mode: 0644]
src/mididef.cc [new file with mode: 0644]
src/midiitem.cc [new file with mode: 0644]
src/midistream.cc [new file with mode: 0644]

diff --git a/hdr/midicolumn.hh b/hdr/midicolumn.hh
new file mode 100644 (file)
index 0000000..8d8b635
--- /dev/null
@@ -0,0 +1,28 @@
+//
+// 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
+
diff --git a/hdr/mididef.hh b/hdr/mididef.hh
new file mode 100644 (file)
index 0000000..a2efdbe
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+  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 //
+
diff --git a/hdr/midiitem.hh b/hdr/midiitem.hh
new file mode 100644 (file)
index 0000000..9527c53
--- /dev/null
@@ -0,0 +1,67 @@
+//
+//  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 //
+
diff --git a/hdr/midistaff.hh b/hdr/midistaff.hh
new file mode 100644 (file)
index 0000000..51053e8
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+  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
+
+
+
+
+
diff --git a/hdr/midistream.hh b/hdr/midistream.hh
new file mode 100644 (file)
index 0000000..34e9c9b
--- /dev/null
@@ -0,0 +1,32 @@
+//
+//  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 //
diff --git a/src/mididef.cc b/src/mididef.cc
new file mode 100644 (file)
index 0000000..56ee59e
--- /dev/null
@@ -0,0 +1,64 @@
+//
+// 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;
+}
diff --git a/src/midiitem.cc b/src/midiitem.cc
new file mode 100644 (file)
index 0000000..e7d5ccc
--- /dev/null
@@ -0,0 +1,178 @@
+//
+// 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() );
+}
+
diff --git a/src/midistream.cc b/src/midistream.cc
new file mode 100644 (file)
index 0000000..73fe2e4
--- /dev/null
@@ -0,0 +1,87 @@
+//
+// 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_ + "\'" );
+}