X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_audio_import.cc;h=2145b24352ba4a48c34fddb48072ab355b96c491;hb=d69e177076aa10e19992c8f6133a8928c24c81e2;hp=53438b9dcbfac8c6eef95a8dbae74d7bc839eadb;hpb=bb9cc45cd22af67ac275a5e73accbe14fee664d8;p=ardour.git diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 53438b9dcb..2145b24352 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -29,9 +29,9 @@ #include "pbd/pthread_utils.h" #include "pbd/basename.h" #include "pbd/shortpath.h" +#include "pbd/stateful_diff_command.h" #include -#include #include "ardour/session.h" #include "ardour/session_directory.h" @@ -47,6 +47,7 @@ #include "ardour/region_factory.h" #include "ardour/source_factory.h" #include "ardour/session.h" +#include "ardour/smf_source.h" #include "pbd/memento_command.h" #include "ardour_ui.h" @@ -58,13 +59,13 @@ #include "session_import_dialog.h" #include "utils.h" #include "gui_thread.h" +#include "interthread_progress_window.h" #include "i18n.h" using namespace std; using namespace ARDOUR; using namespace PBD; -using namespace sigc; using namespace Gtk; using namespace Gtkmm2ext; using namespace Editing; @@ -75,14 +76,14 @@ using Glib::ustring; void Editor::add_external_audio_action (ImportMode mode_hint) { - if (session == 0) { + if (_session == 0) { MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded.")); msg.run (); return; } - + if (sfbrowser == 0) { - sfbrowser = new SoundFileOmega (*this, _("Add existing media"), session, 0, true, mode_hint); + sfbrowser = new SoundFileOmega (*this, _("Add Existing Media"), _session, 0, true, mode_hint); } else { sfbrowser->set_mode (mode_hint); } @@ -96,7 +97,7 @@ Editor::external_audio_dialog () vector paths; uint32_t track_cnt; - if (session == 0) { + if (_session == 0) { MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded.")); msg.run (); return; @@ -115,7 +116,7 @@ Editor::external_audio_dialog () } if (sfbrowser == 0) { - sfbrowser = new SoundFileOmega (*this, _("Add existing media"), session, track_cnt, true); + sfbrowser = new SoundFileOmega (*this, _("Add Existing Media"), _session, track_cnt, true); } else { sfbrowser->reset (track_cnt); } @@ -165,7 +166,7 @@ Editor::external_audio_dialog () where = playhead_cursor->current_frame; break; case ImportAtStart: - where = session->current_start_frame(); + where = _session->current_start_frame(); break; } @@ -189,7 +190,7 @@ Editor::external_audio_dialog () void Editor::session_import_dialog () { - SessionImportDialog dialog (*session); + SessionImportDialog dialog (_session); ensure_float (dialog); dialog.run (); } @@ -213,7 +214,7 @@ Editor::check_whether_and_how_to_import(string path, bool all_or_nothing) { string wave_name (Glib::path_get_basename(path)); - SourceMap all_sources = session->get_sources(); + SourceMap all_sources = _session->get_sources(); bool wave_name_exists = false; for (SourceMap::iterator i = all_sources.begin(); i != all_sources.end(); ++i) { @@ -327,9 +328,11 @@ Editor::do_import (vector paths, ImportDisposition chns, ImportMode mod vector to_import; int nth = 0; - if (interthread_progress_window == 0) { - build_interthread_progress_window (); - } + current_interthread_info = &import_status; + import_status.current = 1; + import_status.total = paths.size (); + + ImportProgressWindow ipw (&import_status, _("Import"), _("Cancel Import")); if (chns == Editing::ImportMergeFiles) { @@ -347,47 +350,69 @@ Editor::do_import (vector paths, ImportDisposition chns, ImportMode mod } if (!cancel) { - import_sndfiles (paths, mode, quality, pos, 1, 1, track, false, paths.size()); + import_sndfiles (paths, mode, quality, pos, 1, 1, track, false); } } else { - for (vector::iterator a = paths.begin(); a != paths.end(); ++a) { - - int const check = check_whether_and_how_to_import (*a, true); - - if (check != 2) { - to_import.push_back (*a); - } - } - + bool replace = false; bool ok = true; - switch (chns) { - case Editing::ImportDistinctFiles: + for (vector::iterator a = paths.begin(); a != paths.end(); ++a) { - if (mode == Editing::ImportToTrack) { - track = get_nth_selected_audio_track (nth++); + const int check = check_whether_and_how_to_import (*a, true); + + switch (check) { + case 2: + // user said skip + continue; + case 0: + fatal << "Updating existing sources should be disabled!" << endmsg; + /* NOTREACHED*/ + break; + case 1: + replace = false; + break; + default: + fatal << "Illegal return " << check << " from check_whether_and_how_to_import()!" << endmsg; + /* NOTREACHED*/ } - ok = (import_sndfiles (to_import, mode, quality, pos, 1, -1, track, false, to_import.size()) == 0); - break; - - case Editing::ImportDistinctChannels: - ok = (import_sndfiles (to_import, mode, quality, pos, -1, -1, track, false, to_import.size()) == 0); - break; - - case Editing::ImportSerializeFiles: - ok = (import_sndfiles (to_import, mode, quality, pos, 1, 1, track, false, to_import.size()) == 0); - break; - - case Editing::ImportMergeFiles: - // Not entered, handled in earlier if() branch - break; - } + switch (chns) { + case Editing::ImportDistinctFiles: + + to_import.clear (); + to_import.push_back (*a); + + if (mode == Editing::ImportToTrack) { + track = get_nth_selected_audio_track (nth++); + } + + ok = (import_sndfiles (to_import, mode, quality, pos, 1, -1, track, replace) == 0); + break; + + case Editing::ImportDistinctChannels: + + to_import.clear (); + to_import.push_back (*a); + + ok = (import_sndfiles (to_import, mode, quality, pos, -1, -1, track, replace) == 0); + break; + + case Editing::ImportSerializeFiles: + + to_import.clear (); + to_import.push_back (*a); + + ok = (import_sndfiles (to_import, mode, quality, pos, 1, 1, track, replace) == 0); + break; + + case Editing::ImportMergeFiles: + // Not entered, handled in earlier if() branch + break; + } + } } - - interthread_progress_window->hide_all (); } void @@ -433,7 +458,7 @@ Editor::do_embed (vector paths, ImportDisposition chns, ImportMode mode if (embed_sndfiles (paths, multi, check_sample_rate, mode, pos, 1, 1, track) < -1) { goto out; } - break; + break; case Editing::ImportSerializeFiles: for (vector::iterator a = paths.begin(); a != paths.end(); ++a) { @@ -452,22 +477,14 @@ Editor::do_embed (vector paths, ImportDisposition chns, ImportMode mode out: if (ok) { - session->save_state (""); + _session->save_state (""); } } int Editor::import_sndfiles (vector paths, ImportMode mode, SrcQuality quality, nframes64_t& pos, - int target_regions, int target_tracks, boost::shared_ptr track, bool replace, uint32_t total) + int target_regions, int target_tracks, boost::shared_ptr& track, bool replace) { - WindowTitle title = string_compose (_("importing %1"), paths.front()); - - interthread_progress_window->set_title (title.get_string()); - interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE); - interthread_progress_bar.set_fraction (0.0f); - interthread_cancel_label.set_text (_("Cancel Import")); - current_interthread_info = &import_status; - import_status.paths = paths; import_status.done = false; import_status.cancel = false; @@ -475,7 +492,6 @@ Editor::import_sndfiles (vector paths, ImportMode mode, SrcQuality qual import_status.done = 0.0; import_status.quality = quality; import_status.replace_existing_source = replace; - import_status.total = total; import_status.mode = mode; import_status.pos = pos; @@ -483,8 +499,6 @@ Editor::import_sndfiles (vector paths, ImportMode mode, SrcQuality qual import_status.target_regions = target_regions; import_status.track = track; import_status.replace = replace; - interthread_progress_connection = Glib::signal_timeout().connect - (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 500); track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); gdk_flush (); @@ -494,16 +508,14 @@ Editor::import_sndfiles (vector paths, ImportMode mode, SrcQuality qual (the GUI) to direct additional steps after that. */ - pthread_create_and_store ("import", &import_status.thread, 0, _import_thread, this); + pthread_create_and_store ("import", &import_status.thread, _import_thread, this); pthread_detach (import_status.thread); while (!import_status.done && !import_status.cancel) { gtk_main_iteration (); } - interthread_progress_window->hide (); import_status.done = true; - interthread_progress_connection.disconnect (); if (!import_status.cancel && !import_status.sources.empty()) { if (add_sources (import_status.paths, @@ -512,8 +524,8 @@ Editor::import_sndfiles (vector paths, ImportMode mode, SrcQuality qual import_status.mode, import_status.target_regions, import_status.target_tracks, - import_status.track, false) == 0) { - session->save_state (""); + track, false) == 0) { + _session->save_state (""); } /* update position from results */ @@ -545,35 +557,38 @@ Editor::embed_sndfiles (vector paths, bool multifile, ustring path = *p; - /* lets see if we can link it into the session */ - - sys::path tmp = session->session_directory().sound_path() / Glib::path_get_basename(path); - linked_path = tmp.to_string(); - - path_to_use = linked_path; - - if (link (path.c_str(), linked_path.c_str()) == 0) { - - /* there are many reasons why link(2) might have failed. - but if it succeeds, we now have a link in the - session sound dir that will protect against - unlinking of the original path. nice. - */ - - path = linked_path; - path_to_use = Glib::path_get_basename (path); - - } else { - - /* one possible reason is that its already linked */ - - if (errno == EEXIST) { - struct stat sb; + if (Config->get_try_link_for_embed()) { + + /* lets see if we can link it into the session */ + + sys::path tmp = _session->session_directory().sound_path() / Glib::path_get_basename(path); + linked_path = tmp.to_string(); + + path_to_use = linked_path; + + if (link (path.c_str(), linked_path.c_str()) == 0) { + + /* there are many reasons why link(2) might have failed. + but if it succeeds, we now have a link in the + session sound dir that will protect against + unlinking of the original path. nice. + */ + + path = linked_path; + path_to_use = Glib::path_get_basename (path); + + } else { - if (stat (linked_path.c_str(), &sb) == 0) { - if (sb.st_nlink > 1) { // its a hard link, assume its the one we want - path = linked_path; - path_to_use = Glib::path_get_basename (path); + /* one possible reason is that its already linked */ + + if (errno == EEXIST) { + struct stat sb; + + if (stat (linked_path.c_str(), &sb) == 0) { + if (sb.st_nlink > 1) { // its a hard link, assume its the one we want + path = linked_path; + path_to_use = Glib::path_get_basename (path); + } } } } @@ -588,7 +603,7 @@ Editor::embed_sndfiles (vector paths, bool multifile, goto out; } - if (check_sample_rate && (finfo.samplerate != (int) session->frame_rate())) { + if (check_sample_rate && (finfo.samplerate != (int) _session->frame_rate())) { vector choices; if (multifile) { @@ -597,9 +612,11 @@ Editor::embed_sndfiles (vector paths, bool multifile, choices.push_back (_("Embed all without questions")); Gtkmm2ext::Choice rate_choice ( + _("Sample rate"), string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), short_path (path, 40)), - choices, false); + choices, false + ); int resx = rate_choice.run (); @@ -624,8 +641,10 @@ Editor::embed_sndfiles (vector paths, bool multifile, choices.push_back (_("Embed it anyway")); Gtkmm2ext::Choice rate_choice ( + _("Sample rate"), string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path), - choices, false); + choices, false + ); int resx = rate_choice.run (); @@ -651,12 +670,12 @@ Editor::embed_sndfiles (vector paths, bool multifile, boost::shared_ptr s; - if ((s = session->source_by_path_and_channel (path, n)) == 0) { + if ((s = _session->source_by_path_and_channel (path, n)) == 0) { source = boost::dynamic_pointer_cast ( - SourceFactory::createReadable (DataType::AUDIO, *session, - path_to_use, false, n, - (mode == ImportAsTapeTrack + SourceFactory::createReadable (DataType::AUDIO, *_session, + path_to_use, n, + (mode == ImportAsTapeTrack ? Source::Destructive : Source::Flag (0)), true, true)); @@ -703,13 +722,14 @@ Editor::add_sources (vector paths, SourceList& sources, nframes64 if (sources[0]->natural_position() != 0) { pos = sources[0]->natural_position(); } else { - pos = get_preferred_edit_position (); + pos = _session->current_start_frame(); } } // kludge (for MIDI we're abusing "channel" for "track" here) - if (paths.front().rfind(".mid") != Glib::ustring::npos) + if (SMFSource::safe_midi_file_extension (paths.front())) { target_regions = -1; + } if (target_regions == 1) { @@ -717,8 +737,16 @@ Editor::add_sources (vector paths, SourceList& sources, nframes64 region_name = region_name_from_path (paths.front(), (sources.size() > 1), false); - boost::shared_ptr r = RegionFactory::create (sources, 0, sources[0]->length(pos), region_name, 0, - Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)); + PropertyList plist; + + plist.add (ARDOUR::Properties::start, 0); + plist.add (ARDOUR::Properties::length, sources[0]->length (pos)); + plist.add (ARDOUR::Properties::name, region_name); + plist.add (ARDOUR::Properties::layer, 0); + plist.add (ARDOUR::Properties::whole_file, true); + plist.add (ARDOUR::Properties::external, true); + + boost::shared_ptr r = RegionFactory::create (sources, plist); if (use_timestamp && boost::dynamic_pointer_cast(r)) { boost::dynamic_pointer_cast(r)->special_set_position(sources[0]->natural_position()); @@ -742,8 +770,16 @@ Editor::add_sources (vector paths, SourceList& sources, nframes64 region_name = region_name_from_path ((*x)->path(), false, false, sources.size(), n); - boost::shared_ptr r = RegionFactory::create (just_one, 0, (*x)->length(pos), region_name, 0, - Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)); + PropertyList plist; + + plist.add (ARDOUR::Properties::start, 0); + plist.add (ARDOUR::Properties::length, (*x)->length (pos)); + plist.add (ARDOUR::Properties::name, region_name); + plist.add (ARDOUR::Properties::layer, 0); + plist.add (ARDOUR::Properties::whole_file, true); + plist.add (ARDOUR::Properties::external, true); + + boost::shared_ptr r = RegionFactory::create (just_one, plist); if (use_timestamp && boost::dynamic_pointer_cast(r)) { boost::dynamic_pointer_cast(r)->special_set_position((*x)->natural_position()); @@ -764,7 +800,7 @@ Editor::add_sources (vector paths, SourceList& sources, nframes64 } if (Config->get_output_auto_connect() & AutoConnectMaster) { - output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan); + output_chan = (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan); } else { output_chan = input_chan; } @@ -818,12 +854,12 @@ Editor::finish_bringing_in_material (boost::shared_ptr region, uint32_t } } - boost::shared_ptr playlist = existing_track->diskstream()->playlist(); - boost::shared_ptr copy (RegionFactory::create (region)); + boost::shared_ptr playlist = existing_track->playlist(); + boost::shared_ptr copy (RegionFactory::create (region, region->properties())); begin_reversible_command (_("insert file")); - XMLNode &before = playlist->get_state(); + playlist->clear_history (); playlist->add_region (copy, pos); - session->add_command (new MementoCommand(*playlist, &before, &playlist->get_state())); + _session->add_command (new StatefulDiffCommand (playlist)); commit_reversible_command (); break; } @@ -832,7 +868,7 @@ Editor::finish_bringing_in_material (boost::shared_ptr region, uint32_t { if (!existing_track) { if (ar) { - list > at (session->new_audio_track (in_chans, out_chans, Normal, 0, 1)); + list > at (_session->new_audio_track (in_chans, out_chans, Normal, 0, 1)); if (at.empty()) { return -1; @@ -840,7 +876,7 @@ Editor::finish_bringing_in_material (boost::shared_ptr region, uint32_t existing_track = at.front(); } else if (mr) { - list > mt (session->new_midi_track (Normal, 0, 1)); + list > mt (_session->new_midi_track (Normal, 0, 1)); if (mt.empty()) { return -1; @@ -853,7 +889,7 @@ Editor::finish_bringing_in_material (boost::shared_ptr region, uint32_t } boost::shared_ptr copy (RegionFactory::create (region)); - existing_track->diskstream()->playlist()->add_region (copy, pos); + existing_track->playlist()->add_region (copy, pos); break; } @@ -863,11 +899,11 @@ Editor::finish_bringing_in_material (boost::shared_ptr region, uint32_t if (!ar) return -1; - list > at (session->new_audio_track (in_chans, out_chans, Destructive)); + list > at (_session->new_audio_track (in_chans, out_chans, Destructive)); if (!at.empty()) { boost::shared_ptr copy (RegionFactory::create (region)); at.front()->set_name (basename_nosuffix (copy->name())); - at.front()->diskstream()->playlist()->add_region (copy, pos); + at.front()->playlist()->add_region (copy, pos); } break; } @@ -879,7 +915,7 @@ Editor::finish_bringing_in_material (boost::shared_ptr region, uint32_t void * Editor::_import_thread (void *arg) { - PBD::notify_gui_about_thread_creation (pthread_self(), X_("Import")); + SessionEvent::create_per_thread_pool ("import events", 64); Editor *ed = (Editor *) arg; return ed->import_thread (); @@ -888,48 +924,8 @@ Editor::_import_thread (void *arg) void * Editor::import_thread () { - session->import_audiofiles (import_status); + _session->import_audiofiles (import_status); pthread_exit_pbd (0); /*NOTREACHED*/ return 0; } - -gint -Editor::import_progress_timeout (void */*arg*/) -{ - bool reset = false; - - if (!interthread_progress_window->is_visible()) { - interthread_progress_window->show_all (); - reset = true; - } - - interthread_progress_label.set_text (import_status.doing_what); - - if (import_status.freeze) { - interthread_cancel_button.set_sensitive(false); - } else { - interthread_cancel_button.set_sensitive(true); - } - - if (import_status.doing_what == "building peak files") { - interthread_progress_bar.pulse (); - return FALSE; - } else { - float val = import_status.progress; - interthread_progress_bar.set_fraction (min (max (0.0f, val), 1.0f)); - } - - if (reset) { - - /* the window is now visible, speed up the updates */ - - interthread_progress_connection.disconnect (); - interthread_progress_connection = Glib::signal_timeout().connect - (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100); - return false; - } else { - return !(import_status.done || import_status.cancel); - } -} -