X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fimport.cc;h=431b1d75e79d8ef299f9f024ad0dc408fff2d1b5;hb=7ba9223f9f43e1624f6d9b86534519a5f30f976c;hp=b2b9403e0ea9a8e383046abac3fa8b7b397815a5;hpb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;p=ardour.git diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index b2b9403e0e..431b1d75e7 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -118,7 +118,9 @@ open_importable_source (const string& path, framecnt_t samplerate, ARDOUR::SrcQu } vector -Session::get_paths_for_new_sources (bool /*allow_replacing*/, const string& import_file_path, uint32_t channels) +Session::get_paths_for_new_sources (bool /*allow_replacing*/, const string& import_file_path, uint32_t channels, + vector const & smf_track_names) + { vector new_paths; const string basename = basename_nosuffix (import_file_path); @@ -129,13 +131,19 @@ Session::get_paths_for_new_sources (bool /*allow_replacing*/, const string& impo string filepath; switch (type) { - case DataType::MIDI: - if (channels > 1) { - string mchn_name = string_compose ("%1-t%2", basename, n); - filepath = new_midi_source_path (mchn_name); + case DataType::MIDI: + assert (smf_track_names.empty() || smf_track_names.size() == channels); + if (channels > 1) { + string mchn_name; + if (smf_track_names.empty() || smf_track_names[n].empty()) { + mchn_name = string_compose ("%1-t%2", basename, n); } else { - filepath = new_midi_source_path (basename); + mchn_name = string_compose ("%1-%2", basename, smf_track_names[n]); } + filepath = new_midi_source_path (mchn_name); + } else { + filepath = new_midi_source_path (basename); + } break; case DataType::AUDIO: filepath = new_audio_source_path (basename, channels, n, false, false); @@ -338,26 +346,40 @@ write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status, static void write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status, - vector >& newfiles) + vector >& newfiles, + bool split_type0) { uint32_t buf_size = 4; uint8_t* buf = (uint8_t*) malloc (buf_size); status.progress = 0.0f; + uint16_t num_tracks; + bool type0 = source->is_type0 () && split_type0; + const std::set& chn = source->channels (); - assert (newfiles.size() == source->num_tracks()); + if (type0) { + num_tracks = source->channels().size(); + } else { + num_tracks = source->num_tracks(); + } + assert (newfiles.size() == num_tracks); try { vector >::iterator s = newfiles.begin(); + std::set::const_iterator cur_chan = chn.begin(); - for (unsigned i = 1; i <= source->num_tracks(); ++i) { + for (unsigned i = 1; i <= num_tracks; ++i) { boost::shared_ptr smfs = boost::dynamic_pointer_cast (*s); Glib::Threads::Mutex::Lock source_lock(smfs->mutex()); smfs->drop_model (source_lock); - source->seek_to_track (i); + if (type0) { + source->seek_to_start (); + } else { + source->seek_to_track (i); + } uint64_t t = 0; uint32_t delta_t = 0; @@ -385,6 +407,17 @@ write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status, continue; } + // type-0 files separate by channel + if (type0) { + uint8_t type = buf[0] & 0xf0; + uint8_t chan = buf[0] & 0x0f; + if (type >= 0x80 && type <= 0xE0) { + if (chan != *cur_chan) { + continue; + } + } + } + if (first) { smfs->mark_streaming_write_started (source_lock); first = false; @@ -393,7 +426,7 @@ write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status, smfs->append_event_beats( source_lock, Evoral::Event( - 0, + Evoral::MIDI_EVENT, Evoral::Beats::ticks_at_rate(t, source->ppqn()), size, buf)); @@ -417,10 +450,13 @@ write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status, break; } } else { - info << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->num_tracks()) << endmsg; + info << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, num_tracks) << endmsg; } ++s; // next source + if (type0) { + ++cur_chan; + } } } catch (exception& e) { @@ -456,6 +492,7 @@ Session::import_files (ImportStatus& status) boost::shared_ptr afs; boost::shared_ptr smfs; uint32_t channels = 0; + vector smf_names; status.sources.clear (); @@ -480,8 +517,26 @@ Session::import_files (ImportStatus& status) } else { try { smf_reader = std::auto_ptr(new Evoral::SMF()); - smf_reader->open(*p); - channels = smf_reader->num_tracks(); + + if (smf_reader->open(*p)) { + throw Evoral::SMF::FileError (*p); + } + + if (smf_reader->is_type0 () && status.split_midi_channels) { + channels = smf_reader->channels().size(); + } else { + channels = smf_reader->num_tracks(); + switch (status.midi_track_name_source) { + case SMFTrackNumber: + break; + case SMFTrackName: + smf_reader->track_names (smf_names); + break; + case SMFInstrumentName: + smf_reader->instrument_names (smf_names); + break; + } + } } catch (...) { error << _("Import: error opening MIDI file") << endmsg; status.done = status.cancel = true; @@ -494,7 +549,7 @@ Session::import_files (ImportStatus& status) continue; } - vector new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels); + vector new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels, smf_names); Sources newfiles; framepos_t natural_position = source ? source->natural_position() : 0; @@ -525,7 +580,7 @@ Session::import_files (ImportStatus& status) write_audio_data_to_new_files (source.get(), status, newfiles); } else if (smf_reader.get()) { // midi status.doing_what = string_compose(_("Loading MIDI file %1"), *p); - write_midi_data_to_new_files (smf_reader.get(), status, newfiles); + write_midi_data_to_new_files (smf_reader.get(), status, newfiles, status.split_midi_channels); } ++status.current;