Preferences/Config changes for image-surface settings
[ardour.git] / gtk2_ardour / editor_audio_import.cc
index 8e2e476d15727095e70947d474640b78b26fa3c7..24e7f49775c4ac344d12333bba78ebf55f47870f 100644 (file)
@@ -1,21 +1,27 @@
 /*
-    Copyright (C) 2000-2006 Paul Davis
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
+ * Copyright (C) 2006-2014 David Robillard <d@drobilla.net>
+ * Copyright (C) 2006-2017 Paul Davis <paul@linuxaudiosystems.com>
+ * Copyright (C) 2006 Taybin Rutkin <taybin@taybin.com>
+ * Copyright (C) 2007 Tim Mayberry <mojofunk@gmail.com>
+ * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
+ * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2013-2014 Colin Fletcher <colin.m.fletcher@googlemail.com>
+ * Copyright (C) 2015-2017 Nick Mainsbridge <mainsbridge@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -31,7 +37,7 @@
 #include "pbd/shortpath.h"
 #include "pbd/stateful_diff_command.h"
 
-#include <gtkmm2ext/choice.h>
+#include "widgets/choice.h"
 
 #include "ardour/audio_track.h"
 #include "ardour/audiofilesource.h"
 #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"
 #include "ardour/utils.h"
 #include "pbd/memento_command.h"
 
+#include "ardour_message.h"
 #include "ardour_ui.h"
 #include "cursor_context.h"
 #include "editor.h"
@@ -74,7 +82,7 @@ void
 Editor::add_external_audio_action (ImportMode mode_hint)
 {
        if (_session == 0) {
-               MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
+               ArdourMessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
                msg.run ();
                return;
        }
@@ -96,7 +104,7 @@ Editor::external_audio_dialog ()
        uint32_t midi_track_cnt;
 
        if (_session == 0) {
-               MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
+               ArdourMessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
                msg.run ();
                return;
        }
@@ -177,7 +185,7 @@ Editor::check_whether_and_how_to_import(string path, bool all_or_nothing)
                        message = string_compose (_("The session already contains a source file named %1.  Do you want to import %2 as a new source, or skip it?"), wave_name, wave_name);
 
                }
-               MessageDialog dialog(message, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true);
+               ArdourMessageDialog dialog(message, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true);
 
                if (all_or_nothing) {
                        // disabled
@@ -191,10 +199,7 @@ Editor::check_whether_and_how_to_import(string path, bool all_or_nothing)
 
                //dialog.add_button("Skip all", 4); // All or rest?
 
-               dialog.show();
-
                function = dialog.run ();
-
                dialog.hide();
        }
 
@@ -262,7 +267,7 @@ Editor::get_nth_selected_midi_track (int nth) const
 }
 
 void
-Editor::import_smf_tempo_map (Evoral::SMF const & smf)
+Editor::import_smf_tempo_map (Evoral::SMF const & smf, samplepos_t pos)
 {
        if (!_session) {
                return;
@@ -274,26 +279,37 @@ Editor::import_smf_tempo_map (Evoral::SMF const & smf)
                return;
        }
 
-       const framecnt_t sample_rate = _session->frame_rate ();
+       const samplecnt_t sample_rate = _session->sample_rate ();
        TempoMap new_map (sample_rate);
-       bool have_meter = false;
+       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 (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);
-
+               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_meter) {
-                       bbt  = new_map.bbt_at_beat ((t->time_pulses/smf.ppqn()));
+
+               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;
+
                }
-               new_map.add_meter (meter, t->time_pulses, bbt, MusicTime);
 
-               cerr << "@ " << t->time_pulses/smf.ppqn() << " ("
+               last_meter = meter;
+
+               cerr << "@ " << t->time_pulses/(double)smf.ppqn() << " ("
                     << t->time_seconds << ") Add T " << tempo << " M " << meter << endl;
        }
 
@@ -304,14 +320,14 @@ Editor::import_smf_tempo_map (Evoral::SMF const & smf)
 }
 
 void
-Editor::do_import (vector<string>        paths,
-                   ImportDisposition     disposition,
-                   ImportMode            mode,
-                   SrcQuality            quality,
-                   MidiTrackNameSource   midi_track_name_source,
+Editor::do_import (vector<string>          paths,
+                   ImportDisposition       disposition,
+                   ImportMode              mode,
+                   SrcQuality              quality,
+                   MidiTrackNameSource     midi_track_name_source,
                    MidiTempoMapDisposition smf_tempo_disposition,
-                   framepos_t&           pos,
-                   ARDOUR::PluginInfoPtr instrument)
+                   samplepos_t&            pos,
+                   ARDOUR::PluginInfoPtr   instrument)
 {
        boost::shared_ptr<Track> track;
        vector<string> to_import;
@@ -329,7 +345,7 @@ Editor::do_import (vector<string>        paths,
                                continue;
                        }
                        if (smf.num_tempos() > 0) {
-                               import_smf_tempo_map (smf);
+                               import_smf_tempo_map (smf, pos);
                                smf.close ();
                                break;
                        }
@@ -449,7 +465,7 @@ Editor::do_import (vector<string>        paths,
 }
 
 void
-Editor::do_embed (vector<string> paths, ImportDisposition import_as, ImportMode mode, framepos_t& pos, ARDOUR::PluginInfoPtr instrument)
+Editor::do_embed (vector<string> paths, ImportDisposition import_as, ImportMode mode, samplepos_t& pos, ARDOUR::PluginInfoPtr instrument)
 {
        boost::shared_ptr<Track> track;
        bool check_sample_rate = true;
@@ -535,7 +551,7 @@ Editor::import_sndfiles (vector<string>            paths,
                          ImportDisposition         disposition,
                          ImportMode                mode,
                          SrcQuality                quality,
-                         framepos_t&               pos,
+                         samplepos_t&              pos,
                          int                       target_regions,
                          int                       target_tracks,
                          boost::shared_ptr<Track>& track,
@@ -605,7 +621,7 @@ Editor::embed_sndfiles (vector<string>            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>& track,
@@ -617,7 +633,7 @@ Editor::embed_sndfiles (vector<string>            paths,
        SoundFileInfo finfo;
 
        CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
-        gdk_flush ();
+       gdk_flush ();
 
        for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
 
@@ -631,7 +647,13 @@ Editor::embed_sndfiles (vector<string>            paths,
                        return -3;
                }
 
-               if (check_sample_rate  && (finfo.samplerate != (int) _session->frame_rate())) {
+               if (!finfo.seekable) {
+                       ArdourMessageDialog msg (string_compose (_("%1\nThis audiofile cannot be embedded. It must be imported!"), short_path (path, 40)), false, Gtk::MESSAGE_ERROR);
+                       msg.run ();
+                       return -2;
+               }
+
+               if (check_sample_rate  && (finfo.samplerate != (int) _session->sample_rate())) {
                        vector<string> choices;
 
                        if (multifile) {
@@ -639,7 +661,7 @@ Editor::embed_sndfiles (vector<string>            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)),
@@ -665,7 +687,7 @@ Editor::embed_sndfiles (vector<string>            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
@@ -727,7 +749,7 @@ Editor::embed_sndfiles (vector<string>            paths,
 int
 Editor::add_sources (vector<string>            paths,
                      SourceList&               sources,
-                     framepos_t&               pos,
+                     samplepos_t&              pos,
                      ImportDisposition         disposition,
                      ImportMode                mode,
                      int                       target_regions,
@@ -845,12 +867,12 @@ Editor::add_sources (vector<string>            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);
@@ -887,7 +909,7 @@ Editor::add_sources (vector<string>            paths,
        }
 
        int n = 0;
-       framepos_t rlen = 0;
+       samplepos_t rlen = 0;
 
        begin_reversible_command (Operations::insert_file);
 
@@ -901,33 +923,33 @@ Editor::add_sources (vector<string>            paths,
                boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (*r);
 
                if (use_timestamp) {
-                        if (ar) {
-
-                                /* get timestamp for this region */
-
-                                const boost::shared_ptr<Source> s (ar->sources().front());
-                                const boost::shared_ptr<AudioSource> as = boost::dynamic_pointer_cast<AudioSource> (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<Source> s (ar->sources().front());
+                               const boost::shared_ptr<AudioSource> as = boost::dynamic_pointer_cast<AudioSource> (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);
 
@@ -958,7 +980,7 @@ int
 Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
                                      uint32_t                  in_chans,
                                      uint32_t                  out_chans,
-                                     framepos_t&               pos,
+                                     samplepos_t&               pos,
                                      ImportMode                mode,
                                      boost::shared_ptr<Track>& existing_track,
                                      const string&             new_track_name,
@@ -1017,7 +1039,8 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
                        } else if (mr) {
                                list<boost::shared_ptr<MidiTrack> > 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,
@@ -1027,11 +1050,6 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
                                if (mt.empty()) {
                                        return -1;
                                }
-                               if (Config->get_strict_io ()) {
-                                       for (list<boost::shared_ptr<MidiTrack> >::iterator i = mt.begin(); i != mt.end(); ++i) {
-                                               (*i)->set_strict_io (true);
-                                       }
-                               }
 
                                // TODO set strict_io from preferences
                                existing_track = mt.front();