X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fmidi-chunk.cc;h=aed9e2b7ddf7bc6fd2ceec5e1cd5a1c8bc92c8cd;hb=750b714488c5af6eae22d07163bba8b554734ac6;hp=d6ad38e31555997a89e9f41b5855bdbc50cece37;hpb=8cab78caa0db1ba14f2e52e4c1ddbb541ea0e5cb;p=lilypond.git diff --git a/lily/midi-chunk.cc b/lily/midi-chunk.cc index d6ad38e315..aed9e2b7dd 100644 --- a/lily/midi-chunk.cc +++ b/lily/midi-chunk.cc @@ -1,10 +1,21 @@ -/* - midi-chunk.cc -- implement Midi_chunk - - source file of the GNU LilyPond music typesetter - - (c) 2007--2009 Han-Wen Nienhuys - +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2007--2015 Han-Wen Nienhuys + + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "midi-chunk.hh" @@ -13,7 +24,8 @@ #include "std-string.hh" #include "string-convert.hh" -Midi_track::Midi_track () +Midi_track::Midi_track (int number, bool port) + : number_ (number) { // 4D 54 72 6B MTrk // 00 00 00 3B chunk length (59) @@ -29,22 +41,27 @@ Midi_track::Midi_track () // mi = 0: major key // mi = 1: minor key - number_ = 0; - char const *data_str0 = "" - // "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" - ; + // "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_string; // only for format 0 (currently using format 1)? data_string += String_convert::hex2bin (data_str0); + if (port) + { + string port = "00" "ff" "21" "01" + + String_convert::int2hex (number_, 2, '0'); + data_string += String_convert::hex2bin (port); + } + char const *footer_str0 = "00" "ff2f" "00"; string footer_string = String_convert::hex2bin (footer_str0); @@ -57,7 +74,48 @@ Midi_track::add (int delta_ticks, Midi_item *midi) assert (delta_ticks >= 0); Midi_event *e = new Midi_event (delta_ticks, midi); - events_.push_back (e); + + // Insertion position for the new event in the track. + vector::iterator position (events_.end ()); + if (delta_ticks == 0 + && (! dynamic_cast (midi) + || dynamic_cast (midi))) + { + // If the new event occurs at the same time as the most recently added + // one, and the event does not represent the start of a note, insert the + // new event before all notes (if any) already starting at this time. + // This is to force notes to be started only after all other events + // (such as changes in instruments) which occur at the same time have + // taken effect. + while (position != events_.begin ()) + { + vector::iterator previous (position - 1); + if (! dynamic_cast ((*previous)->midi_) + || dynamic_cast ((*previous)->midi_)) + { + // Found an event that does not represent the start of a note. + // Exit the loop to insert the new event in the track after this + // event. + break; + } + else if ((*previous)->delta_ticks_ != 0) + { + // Found the start of a new note with delta_ticks_ != 0. Prepare + // to insert the new event before this event, swapping the + // delta_ticks_ fields of the events to keep the sequence of + // deltas consistent. + e->delta_ticks_ = (*previous)->delta_ticks_; + (*previous)->delta_ticks_ = 0; + position = previous; + break; + } + // Otherwise, the event in the track is the start of a note occurring + // at the same time as the new event: continue searching for the + // insertion position. + position = previous; + } + } + events_.insert (position, e); } string @@ -65,18 +123,17 @@ Midi_track::data_string () const { string str = Midi_chunk::data_string (); - for (vector::const_iterator i (events_.begin ()); - i != events_.end (); i ++) + for (vector::const_iterator i (events_.begin ()); + i != events_.end (); i++) { str += (*i)->to_string (); } return str; } - Midi_track::~Midi_track () { - junk_pointers (events_); + junk_pointers (events_); } /**************************************************************** @@ -93,12 +150,11 @@ Midi_event::to_string () const { string delta_string = int2midi_varint_string (delta_ticks_); string midi_string = midi_->to_string (); - assert (midi_string.length ()); return delta_string + midi_string; } /**************************************************************** header -*/ +*/ Midi_header::Midi_header (int format, int tracks, int clocks_per_4) { @@ -116,17 +172,16 @@ Midi_header::Midi_header (int format, int tracks, int clocks_per_4) set ("MThd", str, ""); } - /**************************************************************** chunk */ Midi_chunk::~Midi_chunk () { - + } void -Midi_chunk::set (string header_string, string data_string, string footer_string) +Midi_chunk::set (const string &header_string, const string &data_string, const string &footer_string) { data_string_ = data_string; footer_string_ = footer_string; @@ -145,7 +200,7 @@ Midi_chunk::to_string () const string str = header_string_; string dat = data_string (); string length_string = String_convert::int2hex (dat.length () - + footer_string_.length (), 8, '0'); + + footer_string_.length (), 8, '0'); length_string = String_convert::hex2bin (length_string); str += length_string;