initial attempt at importing SMF tempo maps during MIDI import.
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 16 Dec 2016 16:49:52 +0000 (16:49 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 16 Dec 2016 16:49:52 +0000 (16:49 +0000)
Still with debug output

gtk2_ardour/editor.h
gtk2_ardour/editor_audio_import.cc

index b64e4bda72dee0531802e7035eee641ec0847758..5475e78fdad9b8bdcf1b7cc60ad55644204e7a4f 100644 (file)
@@ -67,6 +67,10 @@ namespace Gtkmm2ext {
        class Bindings;
 }
 
+namespace Evoral {
+       class SMF;
+}
+
 namespace ARDOUR {
        class AudioPlaylist;
        class AudioRegion;
@@ -1413,7 +1417,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
 
        void import_audio (bool as_tracks);
        void do_import (std::vector<std::string> paths, bool split, bool as_tracks);
-
+       void import_smf_tempo_map (Evoral::SMF const &);
        void move_to_start ();
        void move_to_end ();
        void center_playhead ();
index bec9946c2d816e258a3b78c8deb141794161edb9..8e2e476d15727095e70947d474640b78b26fa3c7 100644 (file)
@@ -261,6 +261,48 @@ Editor::get_nth_selected_midi_track (int nth) const
        return mtv->midi_track();
 }
 
+void
+Editor::import_smf_tempo_map (Evoral::SMF const & smf)
+{
+       if (!_session) {
+               return;
+       }
+
+       const size_t num_tempos = smf.num_tempos ();
+
+       if (num_tempos == 0) {
+               return;
+       }
+
+       const framecnt_t sample_rate = _session->frame_rate ();
+       TempoMap new_map (sample_rate);
+       bool have_meter = false;
+
+       for (size_t n = 0; n < num_tempos; ++n) {
+
+               Evoral::SMF::Tempo* t = smf.nth_tempo (n);
+               assert (t);
+
+               Tempo tempo (60 * (1000000 / t->microseconds_per_quarter_note), 4.0);
+               new_map.add_tempo (tempo, (t->time_pulses/smf.ppqn()) / 4.0, 0, TempoSection::Constant, MusicTime);
+
+               Meter meter (t->numerator, t->denominator);
+               Timecode::BBT_Time bbt; /* 1|1|0 which is correct for the no-meter case */
+               if (have_meter) {
+                       bbt  = new_map.bbt_at_beat ((t->time_pulses/smf.ppqn()));
+               }
+               new_map.add_meter (meter, t->time_pulses, bbt, MusicTime);
+
+               cerr << "@ " << t->time_pulses/smf.ppqn() << " ("
+                    << t->time_seconds << ") Add T " << tempo << " M " << meter << endl;
+       }
+
+       cerr << "NEW MAP:\n";
+       new_map.dump (cerr);
+
+       _session->tempo_map() = new_map;
+}
+
 void
 Editor::do_import (vector<string>        paths,
                    ImportDisposition     disposition,
@@ -276,6 +318,25 @@ Editor::do_import (vector<string>        paths,
        int nth = 0;
        bool use_timestamp = (pos == -1);
 
+       if (smf_tempo_disposition == SMFTempoUse) {
+               /* Find the first MIDI file with a tempo map, and import it
+                  before we do anything else.
+               */
+
+               for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
+                       Evoral::SMF smf;
+                       if (smf.open (*a)) {
+                               continue;
+                       }
+                       if (smf.num_tempos() > 0) {
+                               import_smf_tempo_map (smf);
+                               smf.close ();
+                               break;
+                       }
+                       smf.close ();
+               }
+       }
+
        current_interthread_info = &import_status;
        import_status.current = 1;
        import_status.total = paths.size ();
@@ -714,7 +775,7 @@ Editor::add_sources (vector<string>            paths,
 
                if (use_timestamp && boost::dynamic_pointer_cast<AudioRegion>(r)) {
                        boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position(sources[0]->natural_position());
-               }
+               }
 
                regions.push_back (r);