X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_audio_import.cc;h=0ace7263e2091e17a80926ea6d002e8c2043d891;hb=79731a716deae9a90be646695480f06f92c268f5;hp=237fb6776d99d36940340b8f34e22501a55142bc;hpb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;p=ardour.git diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 237fb6776d..0ace7263e2 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -31,7 +31,7 @@ #include "pbd/shortpath.h" #include "pbd/stateful_diff_command.h" -#include +#include "widgets/choice.h" #include "ardour/audio_track.h" #include "ardour/audiofilesource.h" @@ -39,6 +39,7 @@ #include "ardour/midi_region.h" #include "ardour/midi_track.h" #include "ardour/operations.h" +#include "ardour/profile.h" #include "ardour/region_factory.h" #include "ardour/smf_source.h" #include "ardour/source_factory.h" @@ -261,12 +262,67 @@ Editor::get_nth_selected_midi_track (int nth) const return mtv->midi_track(); } +void +Editor::import_smf_tempo_map (Evoral::SMF const & smf, samplepos_t pos) +{ + if (!_session) { + return; + } + + const size_t num_tempos = smf.num_tempos (); + + if (num_tempos == 0) { + return; + } + + const samplecnt_t sample_rate = _session->sample_rate (); + TempoMap new_map (sample_rate); + Meter last_meter (4.0, 4.0); + bool have_initial_meter = false; + + for (size_t n = 0; n < num_tempos; ++n) { + + Evoral::SMF::Tempo* t = smf.nth_tempo (n); + assert (t); + + Tempo tempo (t->tempo(), 32.0 / (double) t->notes_per_note); + Meter meter (t->numerator, t->denominator); + Timecode::BBT_Time bbt; /* 1|1|0 which is correct for the no-meter case */ + + if (have_initial_meter) { + new_map.add_tempo (tempo, t->time_pulses/ (double)smf.ppqn() / 4.0, 0, MusicTime); + if (!(meter == last_meter)) { + bbt = new_map.bbt_at_quarter_note (t->time_pulses/(double)smf.ppqn()); + new_map.add_meter (meter, bbt, 0, MusicTime); + } + + } else { + new_map.replace_meter (new_map.meter_section_at_sample (0), meter, bbt, pos, AudioTime); + new_map.replace_tempo (new_map.tempo_section_at_sample (0), tempo, 0.0, pos, AudioTime); + have_initial_meter = true; + + } + + last_meter = meter; + + cerr << "@ " << t->time_pulses/(double)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 paths, ImportDisposition disposition, ImportMode mode, SrcQuality quality, - framepos_t& pos, + MidiTrackNameSource midi_track_name_source, + MidiTempoMapDisposition smf_tempo_disposition, + samplepos_t& pos, ARDOUR::PluginInfoPtr instrument) { boost::shared_ptr track; @@ -274,10 +330,30 @@ Editor::do_import (vector 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::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, pos); + smf.close (); + break; + } + smf.close (); + } + } + current_interthread_info = &import_status; import_status.current = 1; import_status.total = paths.size (); import_status.all_done = false; + import_status.midi_track_name_source = midi_track_name_source; ImportProgressWindow ipw (&import_status, _("Import"), _("Cancel Import")); @@ -385,7 +461,7 @@ Editor::do_import (vector paths, } void -Editor::do_embed (vector paths, ImportDisposition import_as, ImportMode mode, framepos_t& pos, ARDOUR::PluginInfoPtr instrument) +Editor::do_embed (vector paths, ImportDisposition import_as, ImportMode mode, samplepos_t& pos, ARDOUR::PluginInfoPtr instrument) { boost::shared_ptr track; bool check_sample_rate = true; @@ -471,7 +547,7 @@ Editor::import_sndfiles (vector paths, ImportDisposition disposition, ImportMode mode, SrcQuality quality, - framepos_t& pos, + samplepos_t& pos, int target_regions, int target_tracks, boost::shared_ptr& track, @@ -484,6 +560,7 @@ Editor::import_sndfiles (vector paths, import_status.freeze = false; import_status.quality = quality; import_status.replace_existing_source = replace; + import_status.split_midi_channels = (disposition == Editing::ImportDistinctChannels); import_status.mode = mode; import_status.pos = pos; @@ -540,7 +617,7 @@ Editor::embed_sndfiles (vector paths, bool& check_sample_rate, ImportDisposition disposition, ImportMode mode, - framepos_t& pos, + samplepos_t& pos, int target_regions, int target_tracks, boost::shared_ptr& track, @@ -552,7 +629,7 @@ Editor::embed_sndfiles (vector paths, SoundFileInfo finfo; CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); - gdk_flush (); + gdk_flush (); for (vector::iterator p = paths.begin(); p != paths.end(); ++p) { @@ -566,7 +643,7 @@ Editor::embed_sndfiles (vector paths, return -3; } - if (check_sample_rate && (finfo.samplerate != (int) _session->frame_rate())) { + if (check_sample_rate && (finfo.samplerate != (int) _session->sample_rate())) { vector choices; if (multifile) { @@ -574,7 +651,7 @@ Editor::embed_sndfiles (vector paths, choices.push_back (_("Don't embed it")); choices.push_back (_("Embed all without questions")); - Gtkmm2ext::Choice rate_choice ( + ArdourWidgets::Choice rate_choice ( _("Sample rate"), string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), short_path (path, 40)), @@ -600,7 +677,7 @@ Editor::embed_sndfiles (vector paths, choices.push_back (_("Cancel")); choices.push_back (_("Embed it anyway")); - Gtkmm2ext::Choice rate_choice ( + ArdourWidgets::Choice rate_choice ( _("Sample rate"), string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path), choices, false @@ -662,7 +739,7 @@ Editor::embed_sndfiles (vector paths, int Editor::add_sources (vector paths, SourceList& sources, - framepos_t& pos, + samplepos_t& pos, ImportDisposition disposition, ImportMode mode, int target_regions, @@ -710,7 +787,7 @@ Editor::add_sources (vector paths, if (use_timestamp && boost::dynamic_pointer_cast(r)) { boost::dynamic_pointer_cast(r)->special_set_position(sources[0]->natural_position()); - } + } regions.push_back (r); @@ -780,12 +857,12 @@ Editor::add_sources (vector paths, /* Fudge region length to ensure it is non-zero; make it 1 beat at 120bpm for want of a better idea. It can't be too small, otherwise if this - is a MIDI region the conversion from frames -> beats -> frames will + is a MIDI region the conversion from samples -> beats -> samples will round it back down to 0 again. */ - framecnt_t len = (*x)->length (pos); + samplecnt_t len = (*x)->length (pos); if (len == 0) { - len = (60.0 / 120.0) * _session->frame_rate (); + len = (60.0 / 120.0) * _session->sample_rate (); } plist.add (ARDOUR::Properties::start, 0); @@ -822,7 +899,7 @@ Editor::add_sources (vector paths, } int n = 0; - framepos_t rlen = 0; + samplepos_t rlen = 0; begin_reversible_command (Operations::insert_file); @@ -836,33 +913,33 @@ Editor::add_sources (vector paths, boost::shared_ptr ar = boost::dynamic_pointer_cast (*r); if (use_timestamp) { - if (ar) { - - /* get timestamp for this region */ - - const boost::shared_ptr s (ar->sources().front()); - const boost::shared_ptr as = boost::dynamic_pointer_cast (s); - - assert (as); - - if (as->natural_position() != 0) { - pos = as->natural_position(); - } else if (target_tracks == 1) { - /* hmm, no timestamp available, put it after the previous region - */ - if (n == 0) { - pos = get_preferred_edit_position (); - } else { - pos += rlen; - } - } else { - pos = get_preferred_edit_position (); - } - } else { - /* should really get first position in MIDI file, but for now, use edit position*/ - pos = get_preferred_edit_position (); - } - } + if (ar) { + + /* get timestamp for this region */ + + const boost::shared_ptr s (ar->sources().front()); + const boost::shared_ptr as = boost::dynamic_pointer_cast (s); + + assert (as); + + if (as->natural_position() != 0) { + pos = as->natural_position(); + } else if (target_tracks == 1) { + /* hmm, no timestamp available, put it after the previous region + */ + if (n == 0) { + pos = get_preferred_edit_position (); + } else { + pos += rlen; + } + } else { + pos = get_preferred_edit_position (); + } + } else { + /* should really get first position in MIDI file, but for now, use edit position*/ + pos = get_preferred_edit_position (); + } + } finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track, track_names[n], instrument); @@ -893,7 +970,7 @@ int Editor::finish_bringing_in_material (boost::shared_ptr region, uint32_t in_chans, uint32_t out_chans, - framepos_t& pos, + samplepos_t& pos, ImportMode mode, boost::shared_ptr& existing_track, const string& new_track_name, @@ -952,7 +1029,8 @@ Editor::finish_bringing_in_material (boost::shared_ptr region, } else if (mr) { list > mt ( _session->new_midi_track (ChanCount (DataType::MIDI, 1), - ChanCount (DataType::MIDI, 1), + ChanCount (DataType::MIDI, 1), + Config->get_strict_io () || Profile->get_mixbus (), instrument, (Plugin::PresetRecord*) 0, (RouteGroup*) 0, 1, @@ -962,11 +1040,6 @@ Editor::finish_bringing_in_material (boost::shared_ptr region, if (mt.empty()) { return -1; } - if (Config->get_strict_io ()) { - for (list >::iterator i = mt.begin(); i != mt.end(); ++i) { - (*i)->set_strict_io (true); - } - } // TODO set strict_io from preferences existing_track = mt.front();