diff options
-rw-r--r-- | gtk2_ardour/editor_audio_import.cc | 27 | ||||
-rw-r--r-- | gtk2_ardour/lv2_plugin_ui.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/mixer_strip.cc | 243 | ||||
-rw-r--r-- | libs/ardour/ardour/caimportable.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/importable_source.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/lv2_plugin.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/resampled_source.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/sndfileimportable.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/sndfilesource.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/source.h | 2 | ||||
-rw-r--r-- | libs/ardour/import.cc | 5 | ||||
-rw-r--r-- | libs/ardour/sndfileimportable.cc | 36 | ||||
-rw-r--r-- | libs/gtkmm2ext/gtkmm2ext/barcontroller.h | 2 |
13 files changed, 278 insertions, 49 deletions
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index a71f3dcc98..8459ccba6e 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -695,8 +695,11 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64 ustring region_name; uint32_t input_chan = 0; uint32_t output_chan = 0; + bool use_timestamp; + + use_timestamp = (pos == -1); - if (pos == -1) { // "use timestamp" + if (use_timestamp) { if (sources[0]->natural_position() != 0) { pos = sources[0]->natural_position(); } else { @@ -714,8 +717,15 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64 region_name = region_name_from_path (paths.front(), (sources.size() > 1), false); - regions.push_back (RegionFactory::create (sources, 0, sources[0]->length(pos), region_name, 0, - Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))); + boost::shared_ptr<Region> r = RegionFactory::create (sources, 0, sources[0]->length(pos), region_name, 0, + Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)); + + 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); + } else if (target_regions == -1 || target_regions > 1) { @@ -732,9 +742,14 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64 region_name = region_name_from_path ((*x)->path(), false, false, sources.size(), n); - regions.push_back (RegionFactory::create (just_one, 0, (*x)->length(pos), region_name, 0, - Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))); - + boost::shared_ptr<Region> r = RegionFactory::create (just_one, 0, (*x)->length(pos), region_name, 0, + Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)); + + if (use_timestamp && boost::dynamic_pointer_cast<AudioRegion>(r)) { + boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position((*x)->natural_position()); + } + + regions.push_back (r); } } diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc index 7791d7a0a9..94cf0e61f3 100644 --- a/gtk2_ardour/lv2_plugin_ui.cc +++ b/gtk2_ardour/lv2_plugin_ui.cc @@ -68,7 +68,7 @@ void LV2PluginUI::on_external_ui_closed(LV2UI_Controller controller) me->_screen_update_connection.disconnect(); //me->insert->set_gui(0); - for (vector<struct lv2_external_ui*>::iterator it = g_external_uis.begin() ; it < g_external_uis.end(); it++) { + for (std::vector<struct lv2_external_ui*>::iterator it = g_external_uis.begin() ; it < g_external_uis.end(); it++) { if (*it == me->_external_ui_ptr) { g_external_uis.erase(it); } diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 947ad61223..fd6cb81e98 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -878,51 +878,226 @@ MixerStrip::connect_to_pan () panners.pan_changed (this); } + +/* + * Output port labelling + * ===================== + * + * Case 1: Each output has one connection, all connections are to system:playback_%i + * out 1 -> system:playback_1 + * out 2 -> system:playback_2 + * out 3 -> system:playback_3 + * Display as: 1/2/3 + * + * Case 2: Each output has one connection, all connections are to ardour:track_x/in 1 + * out 1 -> ardour:track_x/in 1 + * out 2 -> ardour:track_x/in 2 + * Display as: track_x + * + * Case 3: Each output has one connection, all connections are to Jack client "program x" + * out 1 -> program x:foo + * out 2 -> program x:foo + * Display as: program x + * + * Case 4: No connections (Disconnected) + * Display as: - + * + * Default case (unusual routing): + * Display as: *number of connections* + * + * Tooltips + * ======== + * .-----------------------------------------------. + * | Mixdown | + * | out 1 -> ardour:master/in 1, jamin:input/in 1 | + * | out 2 -> ardour:master/in 2, jamin:input/in 2 | + * '-----------------------------------------------' + * .-----------------------------------------------. + * | Guitar SM58 | + * | Disconnected | + * '-----------------------------------------------' + */ + void -MixerStrip::update_input_display () +MixerStrip::update_io_button (boost::shared_ptr<ARDOUR::Route> route, Width width, bool for_input) { - ARDOUR::BundleList const c = _route->input()->bundles_connected(); + uint32_t io_count; + uint32_t io_index; + Port *port; + vector<string> connections; + + uint32_t connection_index; + uint32_t total_connection_count = 0; + uint32_t io_connection_count = 0; + uint32_t ardour_connection_count = 0; + uint32_t system_connection_count = 0; + uint32_t other_connection_count = 0; + + ostringstream label; + string label_string; + char * label_cstr; + + bool have_label = false; + bool each_io_has_one_connection = true; + + string connection_name; + string ardour_track_name; + string other_connection_type; + string system_ports; + string system_port; + + ostringstream tooltip; + char * tooltip_cstr; + + tooltip << route->name(); - if (c.size() > 1) { - input_label.set_text (_("Inputs")); - } else if (c.size() == 1) { - input_label.set_text (c[0]->name ()); + if (for_input) { + io_count = route->n_inputs().n_total(); } else { - switch (_width) { - case Wide: - input_label.set_text (_(" Input")); - break; - case Narrow: - input_label.set_text (_("I")); - break; + io_count = route->n_outputs().n_total(); + } + + for (io_index = 0; io_index < io_count; ++io_index) { + if (for_input) { + port = route->input()->nth (io_index); + } else { + port = route->output()->nth (io_index); + } + + port->get_connections(connections); + io_connection_count = 0; + + if (!connections.empty()) { + for (vector<string>::iterator i = connections.begin(); i != connections.end(); ++i) { + string& connection_name (*i); + + if (connection_index == 0) { + tooltip << endl << port->name().substr(port->name().find("/") + 1) << " -> " << connection_name; + } else { + tooltip << ", " << connection_name; + } + + if (connection_name.find("ardour:") == 0) { + if (ardour_track_name.empty()) { + // "ardour:Master/in 1" -> "ardour:Master/" + ardour_track_name = connection_name.substr(0, connection_name.find("/") + 1); + } + + if (connection_name.find(ardour_track_name) == 0) { + ++ardour_connection_count; + } + } else if (connection_name.find("system:") == 0) { + if (for_input) { + // "system:capture_123" -> "123" + system_port = connection_name.substr(15); + } else { + // "system:playback_123" -> "123" + system_port = connection_name.substr(16); + } + + if (system_ports.empty()) { + system_ports += system_port; + } else { + system_ports += "/" + system_port; + } + + ++system_connection_count; + } else { + if (other_connection_type.empty()) { + // "jamin:in 1" -> "jamin:" + other_connection_type = connection_name.substr(0, connection_name.find(":") + 1); + } + + if (connection_name.find(other_connection_type) == 0) { + ++other_connection_count; + } + } + + ++total_connection_count; + ++io_connection_count; + } + } + + if (io_connection_count != 1) { + each_io_has_one_connection = false; } } - panners.setup_pan (); + + if (total_connection_count == 0) { + tooltip << endl << _("Disconnected"); + } + + tooltip_cstr = new char[tooltip.str().size() + 1]; + strcpy(tooltip_cstr, tooltip.str().c_str()); + + if (for_input) { + ARDOUR_UI::instance()->set_tip (&input_button, tooltip_cstr, ""); + } else { + ARDOUR_UI::instance()->set_tip (&output_button, tooltip_cstr, ""); + } + + if (each_io_has_one_connection) { + if ((total_connection_count == ardour_connection_count)) { + // all connections are to the same track in ardour + // "ardour:Master/" -> "Master" + label << ardour_track_name.substr(7, ardour_track_name.find("/") - 7); + have_label = true; + } + else if (total_connection_count == system_connection_count) { + // all connections are to system ports + label << system_ports; + have_label = true; + } + else if (total_connection_count == other_connection_count) { + // all connections are to the same external program eg jamin + // "jamin:" -> "jamin" + label << other_connection_type.substr(0, other_connection_type.size() - 1); + have_label = true; + } + } + + if (!have_label) { + if (total_connection_count == 0) { + // Disconnected + label << "-"; + } else { + // Odd configuration + label << "*" << total_connection_count << "*"; + } + } + + switch (width) { + case Wide: + label_string = label.str().substr(0, 6); + break; + case Narrow: + label_string = label.str().substr(0, 3); + break; + } + + label_cstr = new char[label_string.size() + 1]; + strcpy(label_cstr, label_string.c_str()); + + if (for_input) { + input_label.set_text (label_cstr); + } else { + output_label.set_text (label_cstr); + } } void -MixerStrip::update_output_display () +MixerStrip::update_input_display () { - ARDOUR::BundleList const c = _route->output()->bundles_connected (); - - /* XXX: how do we represent >1 connected bundle? */ - if (c.size() > 1) { - output_label.set_text (_("Outputs")); - } else if (c.size() == 1) { - output_label.set_text (c[0]->name()); - } else { - switch (_width) { - case Wide: - output_label.set_text (_("Output")); - break; - case Narrow: - output_label.set_text (_("O")); - break; - } - } + update_io_button (_route, _width, true); + panners.setup_pan (); +} - gpm.setup_meters (); - panners.setup_pan (); +void +MixerStrip::update_output_display () +{ + update_io_button (_route, _width, false); + gpm.setup_meters (); + panners.setup_pan (); } void diff --git a/libs/ardour/ardour/caimportable.h b/libs/ardour/ardour/caimportable.h index bb3e2ae191..2cc20d21b7 100644 --- a/libs/ardour/ardour/caimportable.h +++ b/libs/ardour/ardour/caimportable.h @@ -38,6 +38,7 @@ class CAImportableSource : public ImportableSource { nframes_t length() const; nframes_t samplerate() const; void seek (nframes_t pos); + nframes64_t natural_position() const { return 0; } protected: mutable CAAudioFile af; diff --git a/libs/ardour/ardour/importable_source.h b/libs/ardour/ardour/importable_source.h index f55c9a5711..26c840b60f 100644 --- a/libs/ardour/ardour/importable_source.h +++ b/libs/ardour/ardour/importable_source.h @@ -36,6 +36,7 @@ public: virtual nframes_t length() const = 0; virtual nframes_t samplerate() const = 0; virtual void seek (nframes_t pos) = 0; + virtual nframes64_t natural_position() const = 0; }; } diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index 219712799c..e354599485 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -176,6 +176,7 @@ struct LV2World { SLV2Value srate; SLV2Value gtk_gui; SLV2Value external_gui; + SLV2Value logarithmic; }; diff --git a/libs/ardour/ardour/resampled_source.h b/libs/ardour/ardour/resampled_source.h index c8fff0d594..1f6947aeac 100644 --- a/libs/ardour/ardour/resampled_source.h +++ b/libs/ardour/ardour/resampled_source.h @@ -40,6 +40,7 @@ class ResampledImportableSource : public ImportableSource nframes_t length() const { return source->length(); } nframes_t samplerate() const { return source->samplerate(); } void seek (nframes_t pos) { source->seek (pos); } + nframes64_t natural_position() const { return source->natural_position(); } static const uint32_t blocksize; diff --git a/libs/ardour/ardour/sndfileimportable.h b/libs/ardour/ardour/sndfileimportable.h index 9eb67c0dea..42ce83c0ee 100644 --- a/libs/ardour/ardour/sndfileimportable.h +++ b/libs/ardour/ardour/sndfileimportable.h @@ -38,11 +38,13 @@ class SndFileImportableSource : public ImportableSource { nframes_t length() const; nframes_t samplerate() const; void seek (nframes_t pos); + nframes64_t natural_position() const; protected: SF_INFO sf_info; boost::shared_ptr<SNDFILE> in; - + nframes_t timecode; + int64_t get_timecode_info (SNDFILE*, SF_BROADCAST_INFO*, bool&); }; } diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index 7d04e7de25..d3c6cdb85a 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -46,7 +46,7 @@ class SndFileSource : public AudioFileSource { int update_header (sframes_t when, struct tm&, time_t); int flush_header (); - sframes_t natural_position () const; + nframes64_t natural_position () const; sframes_t last_capture_start_frame() const; void mark_capture_start (sframes_t); diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index 968a92a804..d6c68edf90 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -66,7 +66,7 @@ class Source : public SessionObject, public boost::noncopyable virtual const Glib::ustring& path() const = 0; - virtual sframes_t natural_position() const { return 0; } + virtual nframes64_t natural_position() const { return 0; } void mark_for_remove(); diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index 735127e588..23ad3a23ad 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -211,7 +211,8 @@ map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/, static bool create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess, - uint samplerate, vector<boost::shared_ptr<Source> >& newfiles) + uint samplerate, vector<boost::shared_ptr<Source> >& newfiles, + nframes64_t timeline_position) { for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) @@ -436,7 +437,7 @@ Session::import_audiofiles (ImportStatus& status) fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl; status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this); } else { - status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles); + status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, source->natural_position()); } // copy on cancel/failure so that any files that were created will be removed below diff --git a/libs/ardour/sndfileimportable.cc b/libs/ardour/sndfileimportable.cc index 3328eddb23..d741dd008b 100644 --- a/libs/ardour/sndfileimportable.cc +++ b/libs/ardour/sndfileimportable.cc @@ -1,14 +1,42 @@ #include "ardour/sndfileimportable.h" #include <sndfile.h> #include <iostream> +#include <cstring> using namespace ARDOUR; using namespace std; +/* FIXME: this was copied from sndfilesource.cc, at some point these should be merged */ +int64_t +SndFileImportableSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists) +{ + if (sf_command (sf, SFC_GET_BROADCAST_INFO, binfo, sizeof (*binfo)) != SF_TRUE) { + exists = false; + return 0; + } + + exists = true; + int64_t ret = (uint32_t) binfo->time_reference_high; + ret <<= 32; + ret |= (uint32_t) binfo->time_reference_low; + return ret; +} + SndFileImportableSource::SndFileImportableSource (const string& path) - : in (sf_open (path.c_str(), SFM_READ, &sf_info), sf_close) { + memset(&sf_info, 0 , sizeof(sf_info)); + in.reset( sf_open(path.c_str(), SFM_READ, &sf_info), sf_close); if (!in) throw failed_constructor(); + + SF_BROADCAST_INFO binfo; + bool timecode_exists; + + memset (&binfo, 0, sizeof (binfo)); + timecode = get_timecode_info (in.get(), &binfo, timecode_exists); + + if (!timecode_exists) { + timecode = 0; + } } SndFileImportableSource::~SndFileImportableSource () @@ -46,3 +74,9 @@ SndFileImportableSource::seek (nframes_t /*pos*/) { sf_seek (in.get(), 0, SEEK_SET); } + +nframes64_t +SndFileImportableSource::natural_position () const +{ + return timecode; +} diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h index 176580dece..f3eb2f41cd 100644 --- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h +++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h @@ -87,8 +87,6 @@ class BarController : public Gtk::Frame virtual bool expose (GdkEventExpose *); virtual bool scroll (GdkEventScroll *); virtual bool entry_focus_out (GdkEventFocus*); - virtual bool entry_input (double *); - virtual bool entry_output (); gint mouse_control (double x, GdkWindow* w, double scaling); |