merge from 2.0-ongoing @ 3581
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 10 Sep 2008 15:03:30 +0000 (15:03 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 10 Sep 2008 15:03:30 +0000 (15:03 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@3711 d708f5d6-7413-0410-9779-e7cbd77b26cf

283 files changed:
SConstruct
gtk2_ardour/SConscript
gtk2_ardour/actions.cc
gtk2_ardour/actions.h
gtk2_ardour/analysis_window.cc
gtk2_ardour/ardour-sae.menus
gtk2_ardour/ardour.menus
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui2.cc
gtk2_ardour/ardour_ui_dialogs.cc
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/ardour_ui_mixer.cc
gtk2_ardour/ardour_ui_options.cc
gtk2_ardour/au_pluginui.mm
gtk2_ardour/audio_clock.cc
gtk2_ardour/audio_clock.h
gtk2_ardour/audio_region_view.cc
gtk2_ardour/audio_region_view.h
gtk2_ardour/audio_streamview.cc
gtk2_ardour/audio_streamview.h
gtk2_ardour/audio_time_axis.h
gtk2_ardour/automation_controller.cc
gtk2_ardour/automation_line.cc
gtk2_ardour/automation_line.h
gtk2_ardour/automation_region_view.cc
gtk2_ardour/automation_streamview.cc
gtk2_ardour/automation_streamview.h
gtk2_ardour/automation_time_axis.cc
gtk2_ardour/automation_time_axis.h
gtk2_ardour/axis_view.h
gtk2_ardour/bundle_manager.cc
gtk2_ardour/canvas_vars.h
gtk2_ardour/crossfade_view.cc
gtk2_ardour/editing.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_audiotrack.cc
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_canvas_events.cc
gtk2_ardour/editor_cursors.cc
gtk2_ardour/editor_export_audio.cc
gtk2_ardour/editor_imageframe.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/editor_mixer.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/editor_route_list.cc
gtk2_ardour/editor_rulers.cc
gtk2_ardour/editor_selection.cc
gtk2_ardour/editor_tempodisplay.cc
gtk2_ardour/editor_timefx.cc
gtk2_ardour/engine_dialog.cc
gtk2_ardour/export_dialog.cc
gtk2_ardour/export_range_markers_dialog.cc
gtk2_ardour/gain_meter.cc
gtk2_ardour/gain_meter.h
gtk2_ardour/ghostregion.cc
gtk2_ardour/imageframe_time_axis.cc
gtk2_ardour/imageframe_time_axis.h
gtk2_ardour/imageframe_time_axis_view.cc
gtk2_ardour/imageframe_view.cc
gtk2_ardour/io_selector.cc
gtk2_ardour/keyboard.cc
gtk2_ardour/keyboard.h
gtk2_ardour/keyeditor.cc
gtk2_ardour/latency_gui.cc
gtk2_ardour/latency_gui.h
gtk2_ardour/level_meter.cc
gtk2_ardour/location_ui.cc
gtk2_ardour/location_ui.h
gtk2_ardour/main.cc
gtk2_ardour/marker.cc
gtk2_ardour/marker_time_axis.cc
gtk2_ardour/marker_time_axis.h
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h
gtk2_ardour/midi_streamview.cc
gtk2_ardour/midi_streamview.h
gtk2_ardour/midi_time_axis.cc
gtk2_ardour/mixer_strip.cc
gtk2_ardour/mixer_ui.cc
gtk2_ardour/mnemonic-us.bindings.in
gtk2_ardour/option_editor.cc
gtk2_ardour/option_editor.h
gtk2_ardour/panner.cc
gtk2_ardour/panner2d.cc
gtk2_ardour/panner_ui.cc
gtk2_ardour/panner_ui.h
gtk2_ardour/plugin_interest.h [new file with mode: 0644]
gtk2_ardour/plugin_selector.cc
gtk2_ardour/plugin_selector.h
gtk2_ardour/plugin_ui.cc
gtk2_ardour/plugin_ui.h
gtk2_ardour/po/sv_SE.po
gtk2_ardour/processor_box.cc
gtk2_ardour/processor_box.h
gtk2_ardour/public_editor.cc
gtk2_ardour/public_editor.h
gtk2_ardour/region_view.cc
gtk2_ardour/region_view.h
gtk2_ardour/rhythm_ferret.cc
gtk2_ardour/rhythm_ferret.h
gtk2_ardour/route_params_ui.cc
gtk2_ardour/route_time_axis.cc
gtk2_ardour/route_time_axis.h
gtk2_ardour/route_ui.cc
gtk2_ardour/route_ui.h
gtk2_ardour/send_ui.cc
gtk2_ardour/send_ui.h
gtk2_ardour/sfdb_ui.cc
gtk2_ardour/sfdb_ui.h
gtk2_ardour/streamview.cc
gtk2_ardour/streamview.h
gtk2_ardour/tape_region_view.cc
gtk2_ardour/time_axis_view.cc
gtk2_ardour/time_axis_view.h
gtk2_ardour/time_axis_view_item.cc
gtk2_ardour/time_axis_view_item.h
gtk2_ardour/ui_config.cc
gtk2_ardour/utils.cc
gtk2_ardour/utils.h
gtk2_ardour/visual_time_axis.cc
gtk2_ardour/visual_time_axis.h
libs/appleutility/CAAudioUnit.cpp
libs/appleutility/CAAudioUnit.h
libs/appleutility/SConscript
libs/ardour/SConscript
libs/ardour/ardour/ardour.h
libs/ardour/ardour/audio_track.h
libs/ardour/ardour/audio_unit.h
libs/ardour/ardour/audioengine.h
libs/ardour/ardour/auto_bundle.h
libs/ardour/ardour/buffer.h
libs/ardour/ardour/bundle.h
libs/ardour/ardour/configuration_vars.h
libs/ardour/ardour/io.h
libs/ardour/ardour/meter.h
libs/ardour/ardour/midi_track.h
libs/ardour/ardour/onset_detector.h [new file with mode: 0644]
libs/ardour/ardour/osc.h
libs/ardour/ardour/plugin.h
libs/ardour/ardour/plugin_insert.h
libs/ardour/ardour/plugin_manager.h
libs/ardour/ardour/port.h
libs/ardour/ardour/port_insert.h
libs/ardour/ardour/processor.h
libs/ardour/ardour/route.h
libs/ardour/ardour/send.h
libs/ardour/ardour/session.h
libs/ardour/ardour/track.h
libs/ardour/ardour/user_bundle.h
libs/ardour/audio_diskstream.cc
libs/ardour/audio_library.cc
libs/ardour/audio_track.cc
libs/ardour/audio_unit.cc
libs/ardour/audioengine.cc
libs/ardour/audioregion.cc
libs/ardour/audiosource.cc
libs/ardour/auto_bundle.cc
libs/ardour/configuration.cc
libs/ardour/crossfade.cc
libs/ardour/globals.cc
libs/ardour/import.cc
libs/ardour/io.cc
libs/ardour/location.cc
libs/ardour/lv2_plugin.cc
libs/ardour/meter.cc
libs/ardour/midi_track.cc
libs/ardour/onset_detector.cc [new file with mode: 0644]
libs/ardour/osc.cc
libs/ardour/panner.cc
libs/ardour/plugin.cc
libs/ardour/plugin_insert.cc
libs/ardour/plugin_manager.cc
libs/ardour/po/sv_SE.po
libs/ardour/port_insert.cc
libs/ardour/processor.cc
libs/ardour/rb_effect.cc
libs/ardour/recent_sessions.cc
libs/ardour/region.cc
libs/ardour/region_factory.cc
libs/ardour/route.cc
libs/ardour/send.cc
libs/ardour/session.cc
libs/ardour/session_butler.cc
libs/ardour/session_command.cc
libs/ardour/session_export.cc
libs/ardour/session_process.cc
libs/ardour/session_state.cc
libs/ardour/session_transport.cc
libs/ardour/sndfilesource.cc
libs/ardour/source_factory.cc
libs/ardour/track.cc
libs/ardour/user_bundle.cc
libs/ardour/utils.cc
libs/ardour/vst_plugin.cc
libs/cairomm/SConscript
libs/clearlooks/SConscript
libs/fst/SConscript
libs/glibmm2/SConscript
libs/glibmm2/glib/glibmmconfig.h
libs/gtkmm2/atk/SConscript
libs/gtkmm2/gdk/SConscript
libs/gtkmm2/gtk/SConscript
libs/gtkmm2/pango/SConscript
libs/gtkmm2ext/SConscript
libs/gtkmm2ext/barcontroller.cc
libs/gtkmm2ext/binding_proxy.cc
libs/gtkmm2ext/fastmeter.cc
libs/gtkmm2ext/gtk_ui.cc
libs/gtkmm2ext/gtkmm2ext/barcontroller.h
libs/gtkmm2ext/gtkmm2ext/bindable_button.h
libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
libs/gtkmm2ext/gtkmm2ext/hexentry.h [deleted file]
libs/gtkmm2ext/gtkmm2ext/pathlist.h [deleted file]
libs/gtkmm2ext/gtkmm2ext/slider_controller.h
libs/gtkmm2ext/hexentry.cc [deleted file]
libs/gtkmm2ext/pathlist.cc [deleted file]
libs/gtkmm2ext/slider_controller.cc
libs/libgnomecanvasmm/SConscript
libs/libsndfile/SConscript
libs/midi++2/SConscript
libs/midi++2/midi.cc
libs/pbd/SConscript
libs/pbd/base_ui.cc
libs/pbd/enumwriter.cc
libs/pbd/fpu.cc
libs/pbd/mountpoint.cc
libs/pbd/pathscanner.cc
libs/pbd/pbd/functor_command.h
libs/pbd/pool.cc
libs/pbd/stacktrace.cc
libs/pbd/undo.cc
libs/sigc++2/SConscript
libs/sigc++2/missing
libs/soundtouch/AAFilter.cpp
libs/soundtouch/FIFOSampleBuffer.cpp
libs/soundtouch/FIFOSamplePipe.h
libs/soundtouch/FIRFilter.cpp
libs/soundtouch/RateTransposer.cpp
libs/soundtouch/SConscript
libs/soundtouch/TDStretch.cpp
libs/surfaces/control_protocol/SConscript
libs/surfaces/control_protocol/basic_ui.cc
libs/surfaces/control_protocol/control_protocol/basic_ui.h
libs/surfaces/frontier/tranzport/SConscript
libs/surfaces/generic_midi/SConscript
libs/surfaces/mackie/SConscript
libs/surfaces/powermate/SConscript
libs/surfaces/powermate/powermate.cc
libs/surfaces/tranzport/SConscript
libs/surfaces/tranzport/screen.cc
libs/vamp-plugins/Onset.cpp [new file with mode: 0644]
libs/vamp-plugins/Onset.h [new file with mode: 0644]
libs/vamp-plugins/SConscript
libs/vamp-plugins/plugins.cpp
libs/vamp-sdk/SConscript
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp
manual/xml/editor_aligning_key_bindings.xml
manual/xml/editor_canvas_key_bindings.xml
manual/xml/editor_edit_cursor_position_key_bindings.xml
manual/xml/editor_locations_marks_key_bindings.xml
manual/xml/editor_marker_bindings.xml [new file with mode: 0644]
manual/xml/editor_miscellaneous_key_bindings.xml
manual/xml/editor_nudging_key_bindings.xml
manual/xml/editor_play_position_key_bindings.xml
manual/xml/editor_range_operations_key_bindings.xml
manual/xml/editor_region_operations_key_bindings.xml
manual/xml/editor_selection_key_bindings.xml [new file with mode: 0644]
manual/xml/editor_zoom_key_bindings.xml
manual/xml/general_key_bindings.xml
manual/xml/key_bindings.xml
manual/xml/transport_key_bindings.xml
manual/xml/window_key_bindings.xml [new file with mode: 0644]
svn_revision.h
tools/synthesize_sources.pl
vst/SConscript

index db2c0952504b513f8406f282a8a8469c01ee6d47..c887145a0c03c958c12628a545be8935e138a518 100644 (file)
@@ -5,6 +5,7 @@
 #
 
 import os
+import os.path
 import sys
 import re
 import shutil
@@ -35,7 +36,6 @@ opts.AddOptions(
     BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
     BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
     BoolOption('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0),
-    BoolOption('NATIVE_OSX_KEYS', 'Build key bindings file that matches OS X conventions', 0),
     BoolOption('OLDFONTS', 'Old school font sizes', 0),
     BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
     BoolOption('STL_DEBUG', 'Set to build with Standard Template Library Debugging', 0),
@@ -57,7 +57,8 @@ opts.AddOptions(
     BoolOption('LV2', 'Compile with support for LV2 (if slv2 is available)', 0),
     BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
     BoolOption('FREEDESKTOP', 'Install MIME type, icons and .desktop file as per the freedesktop.org spec (requires xdg-utils and shared-mime-info). "scons uninstall" removes associations in desktop database', 0),
-    BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
+    BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1),
+    BoolOption('AUBIO', "Use Paul Brossier's aubio library for feature detection (if available)", 1)
 )
 
 #----------------------------------------------------------------------
@@ -450,7 +451,8 @@ deps = \
        'raptor'               : '1.4.2',
        'lrdf'                 : '0.4.0',
        'jack'                 : '0.109.0',
-       'libgnomecanvas-2.0'   : '2.0'
+       'libgnomecanvas-2.0'   : '2.0',
+        'aubio'                : '0.3.2'
 }
 
 def DependenciesRequiredMessage():
@@ -523,6 +525,13 @@ if conf.CheckPKGExists ('fftw3'):
     libraries['fftw3'] = LibraryInfo()
     libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
 
+if conf.CheckPKGExists ('aubio'):
+    libraries['aubio'] = LibraryInfo()
+    libraries['aubio'].ParseConfig('pkg-config --cflags --libs aubio')
+    env['AUBIO'] = 1
+else:
+    env['AUBIO'] = 0
+
 env = conf.Finish ()
 
 if env['FFT_ANALYSIS']:
@@ -828,8 +837,9 @@ def prep_libcheck(topenv, libinfo):
        # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
        #            All libraries needed should be built against this location
        if topenv['GTKOSX']:
-               libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
-               libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
+               gtkroot = os.path.expanduser ("~");
+               libinfo.Append(CPPPATH="$GTKROOT/include", LIBPATH="$GTKROOT/lib")
+               libinfo.Append(CXXFLAGS="-I$GTKROOT/include", LINKFLAGS="-L$GTKROOT/lib")
        libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
        libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
 
@@ -921,7 +931,7 @@ prep_libcheck(env, libraries['boost'])
 libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
 conf = Configure (libraries['boost'])
 if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
-        print "Boost header files do not appear to be installed."
+        print "Boost header files do not appear to be installed. You also might be running a buggy version of scons. Try scons 0.97 if you can."
         sys.exit (1)
     
 libraries['boost'] = conf.Finish ()
@@ -1081,7 +1091,8 @@ if env['SYSLIBS']:
                                             CPPPATH='#libs/appleutility')
     
     coredirs = [
-        'templates'
+        'templates',
+        'manual'
     ]
     
     subdirs = [
@@ -1155,7 +1166,8 @@ else:
                                             CPPPATH='#libs/appleutility')
 
     coredirs = [
-        'templates'
+        'templates',
+       'manual'
     ]
     
     subdirs = [
index ebc4529490c1816521e18f4a3d702853aeb0d5fd..836755c0644f4d4ddbc90917f57376b0595cdbb6 100644 (file)
@@ -6,8 +6,8 @@ import glob
 
 Import('env install_prefix final_prefix config_prefix libraries i18n ardour_version')
 
-gtkardour = env.Copy()
-gtkmmtests = env.Copy()
+gtkardour = env.Clone()
+gtkmmtests = env.Clone()
 
 #
 # this defines the version number of the GTK interface to ardour
@@ -409,7 +409,7 @@ my_subst_dict = { }
 
 keybindings_dict = { }
 
-if gtkardour['GTKOSX'] and gtkardour['NATIVE_OSX_KEYS']:
+if gtkardour['GTKOSX']:
        #
        # Command(Meta), Alt(Mod1), Ctrl, Shift
        # **** as of february 4th 2008, OUR VERSION OF *****
@@ -487,6 +487,7 @@ env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour3'
 env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour3', 'pixmaps'), pixmap_files))
 env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour3', 'icons'), icon_files))
 env.Alias ('version', gtkardour.VersionBuild(['version.cc','version.h'], []))
+env.Alias ('version', gtkardour.VersionBuild(['version.cc','version.h'], []))
 
 # This will install icons and MIME type as per freedesktop.org specs. #
 if env['FREEDESKTOP']:
index f25dc1c9b201f4c4283d257b6677c6791e1c6f23..fcfc6d75ce1cdb22c52ee39b0b77e3cd814c83f9 100644 (file)
@@ -162,6 +162,50 @@ struct SortActionsByLabel {
     }
 };
 
+void
+ActionManager::get_all_actions (vector<string>& groups, vector<string>& names, vector<AccelKey>& bindings)
+{
+       /* the C++ API for functions used here appears to be broken in
+          gtkmm2.6, so we fall back to the C level.
+       */
+
+       GList* list = gtk_ui_manager_get_action_groups (ui_manager->gobj());
+       GList* node;
+       GList* acts;
+
+       for (node = list; node; node = g_list_next (node)) {
+               
+               GtkActionGroup* group = (GtkActionGroup*) node->data;
+               
+               /* first pass: collect them all */
+               
+               typedef std::list<Glib::RefPtr<Gtk::Action> > action_list;
+               action_list the_acts;
+
+               for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
+                       GtkAction* action = (GtkAction*) acts->data;
+                       the_acts.push_back (Glib::wrap (action, true));
+               }
+               
+               /* now sort by label */
+               
+               SortActionsByLabel cmp;
+               the_acts.sort (cmp);
+
+               for (action_list::iterator a = the_acts.begin(); a != the_acts.end(); ++a) {
+
+                       string accel_path = (*a)->get_accel_path ();
+
+                       groups.push_back (gtk_action_group_get_name(group));
+                       names.push_back (accel_path.substr (accel_path.find_last_of ('/') + 1));
+                       
+                       AccelKey key;
+                       lookup_entry (accel_path, key);
+                       bindings.push_back (AccelKey (key.get_key(), Gdk::ModifierType (key.get_mod())));
+               }
+       }
+}
+
 void
 ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, vector<string>& keys, vector<AccelKey>& bindings)
 {
@@ -226,6 +270,19 @@ ActionManager::get_widget (const char * name)
        return ui_manager->get_widget (name);
 }
 
+RefPtr<Action>
+ActionManager::get_action (const char* path)
+{
+       GtkAction* _act;
+       RefPtr<Action> act;
+
+       if ((_act = gtk_ui_manager_get_action (ui_manager->gobj(), path)) != 0) {
+               return Glib::wrap (_act, true);
+       }
+
+       return act;
+}
+
 RefPtr<Action>
 ActionManager::get_action (const char* group_name, const char* action_name)
 {
index e05f3194bd84b81dc7c8c9d7550ed457b1e335af..d8b2c64edad14a244ff11dd0f713089d3a157492 100644 (file)
@@ -70,6 +70,7 @@ class ActionManager
 
        static Gtk::Widget* get_widget (const char * name);
        static Glib::RefPtr<Gtk::Action> get_action (const char* group, const char* name);
+       static Glib::RefPtr<Gtk::Action> get_action (const char* path);
 
        static void add_action_group (Glib::RefPtr<Gtk::ActionGroup>);
 
@@ -100,6 +101,10 @@ class ActionManager
                                     std::vector<std::string>& keys, 
                                     std::vector<Gtk::AccelKey>& bindings);
 
+       static void get_all_actions (std::vector<std::string>& groups, 
+                                    std::vector<std::string>& paths, 
+                                    std::vector<Gtk::AccelKey>& bindings);
+
        static void uncheck_toggleaction (const char * actionname);
 };
 
index 8f84febbba011d6fbff446de695d9f1703d89076..b76a1b356e1c17998c9cdd0249a16794a80bd1a0 100644 (file)
@@ -262,7 +262,8 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                                continue;
 
                        RouteUI *rui = dynamic_cast<RouteUI *>(*i);
-                       
+                       int n_inputs = rui->route()->n_inputs().n_audio(); // FFT is audio only
+
                        // Busses don't have playlists, so we need to check that we actually are working with a playlist
                        if (!pl || !rui)
                                continue;
@@ -275,29 +276,31 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                                
                                for (std::list<AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
 
-                                       nframes_t i = 0;
                                        int n;
-                       
-                                       while ( i < (*j).length() ) {
-                                               // TODO: What about stereo+ channels? composite all to one, I guess
+                                       for (int channel = 0; channel < n_inputs; channel++) {
+                                               nframes_t x = 0;
 
-                                               n = fft_graph.windowSize();
+                                               while ( x < (*j).length() ) {
+                                                       // TODO: What about stereo+ channels? composite all to one, I guess
 
-                                               if (i + n >= (*j).length() ) {
-                                                       n = (*j).length() - i;
-                                               }
-                               
-                                               n = pl->read(buf, mixbuf, gain, (*j).start + i, n);
-       
-                                               if ( n < fft_graph.windowSize()) {
-                                                       for (int j = n; j < fft_graph.windowSize(); j++) {
-                                                               buf[j] = 0.0;
+                                                       n = fft_graph.windowSize();
+
+                                                       if (x + n >= (*j).length() ) {
+                                                               n = (*j).length() - x;
+                                                       }
+
+                                                       n = pl->read(buf, mixbuf, gain, (*j).start + x, n, channel);
+
+                                                       if ( n < fft_graph.windowSize()) {
+                                                               for (int j = n; j < fft_graph.windowSize(); j++) {
+                                                                       buf[j] = 0.0;
+                                                               }
                                                        }
+
+                                                       res->analyzeWindow(buf);
+
+                                                       x += n;
                                                }
-       
-                                               res->analyzeWindow(buf);
-                               
-                                               i += n;
                                        }
                                }
                        } else if (source_selection_regions_rb.get_active()) {
@@ -316,28 +319,36 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                                                continue;
 
 //                                     cerr << " - " << (*j)->region().name() << ": " << (*j)->region().length() << " samples starting at " << (*j)->region().position() << endl;
-                                       nframes_t i = 0;
                                        int n;
+                                       for (int channel = 0; channel < n_inputs; channel++) {
 
-                                       while ( i < arv->region()->length() ) {
-                                               // TODO: What about stereo+ channels? composite all to one, I guess
+                                               nframes_t x = 0;
 
-                                               n = fft_graph.windowSize();
-                                               if (i + n >= arv->region()->length() ) {
-                                                       n = arv->region()->length() - i;
-                                               }
+                                               nframes_t length = arv->region()->length();
 
-                                               n = arv->audio_region()->read_at(buf, mixbuf, gain, arv->region()->position() + i, n);
-       
-                                               if ( n < fft_graph.windowSize()) {
-                                                       for (int j = n; j < fft_graph.windowSize(); j++) {
-                                                               buf[j] = 0.0;
+                                               while ( x < length ) {
+                                                       // TODO: What about stereo+ channels? composite all to one, I guess
+
+                                                       n = fft_graph.windowSize();
+                                                       if (x + n >= length ) {
+                                                               n = length - x;
                                                        }
+
+                                                       n = arv->audio_region()->read_at(buf, mixbuf, gain, arv->region()->position() + x, n, channel);
+
+                                                       if (n == 0)
+                                                               break;
+
+                                                       if ( n < fft_graph.windowSize()) {
+                                                               for (int j = n; j < fft_graph.windowSize(); j++) {
+                                                                       buf[j] = 0.0;
+                                                               }
+                                                       }
+
+                                                       res->analyzeWindow(buf);
+
+                                                       x += n;
                                                }
-       
-                                               res->analyzeWindow(buf);
-                               
-                                               i += n;
                                        }
 //                                     cerr << "Found: " << (*j)->get_item_name() << endl;
 
index dc9d7d1b5fa325754a7df86d1d56713c56490d83..c2721f2a29f81126b506f78044441e450d482126 100644 (file)
 
      </menubar>
 
+<<<<<<< .working
      <popup action="RulerMenuPopup">
          <menuitem action="toggle-minsec-ruler"/>
          <menuitem action="toggle-samples-ruler"/>
      </popup>
 
      <popup name='processormenu'>
+=======
+     <popup action="RulerMenuPopup">
+         <menuitem action="toggle-minsec-ruler"/>
+         <menuitem action="toggle-samples-ruler"/>
+          <menuitem action="toggle-bbt-ruler"/>
+         <separator/>
+         <menuitem action="toggle-meter-ruler"/>
+         <menuitem action="toggle-tempo-ruler"/>
+         <menuitem action="toggle-loop-punch-ruler"/>
+         <menuitem action="toggle-cd-marker-ruler"/>
+         <menuitem action="toggle-marker-ruler"/>
+     </popup>
+
+     <popup name='redirectmenu'>
+>>>>>>> .merge-right.r3622
         <menuitem action='newplugin'/>
         <menuitem action='newinsert'/>
         <menuitem action='newsend'/>
index e9b4800ae9235318943cbe0007e2dbaec1e0392d..8e316de05cf2c37ad995681192b80968d7642163 100644 (file)
@@ -56,7 +56,6 @@
                <menuitem action='TransitionToReverse'/>
               <separator/>
 
-              
               <menu action="MovePlayHeadMenu">
                   <menuitem action='set-playhead'/>
                    <menuitem action='playhead-to-edit'/>
@@ -82,6 +81,8 @@
                   <menuitem action='GotoZero'/>
                   <menuitem action='GotoStart'/>
                   <menuitem action='GotoEnd'/>
+                  <menuitem action='GotoWallClock'/>
+
               </menu>
 
               <menu action="MoveActiveMarkMenu">
        </menu>
 
         <menu name='View' action = 'View'>
+              <menu action="ZoomMenu">
+                            <menuitem action='temporal-zoom-in'/>
+                            <menuitem action='temporal-zoom-out'/>
+                            <menuitem action='zoom-to-session'/>
+                            <menuitem action='zoom-to-region'/>
+                            <menuitem action='zoom-to-region-both-axes'/>
+                            <menuitem action='toggle-zoom'/>
+              </menu>
                <menu name='ZoomFocus' action='ZoomFocus'>
                    <menuitem action='zoom-focus-left'/>
                    <menuitem action='zoom-focus-right'/>
                     <menuitem action="toggle-cd-marker-ruler"/>
                     <menuitem action="toggle-marker-ruler"/>
               </menu>
-              <menu action="ZoomMenu">
-                            <menuitem action='temporal-zoom-in'/>
-                            <menuitem action='temporal-zoom-out'/>
-                            <menuitem action='zoom-to-session'/>
-                            <menuitem action='zoom-to-region'/>
-                            <menuitem action='toggle-zoom'/>
-              </menu>
               <menu action="ScrollMenu">
                             <menuitem action='scroll-tracks-down'/>
                             <menuitem action='scroll-tracks-up'/>
                             <menuitem action='scroll-forward'/>
                             <menuitem action='scroll-backward'/>
               </menu>
+              <menu action="SavedViewMenu">
+                            <menuitem action='save-visual-state-1'/>
+                            <menuitem action='goto-visual-state-1'/>
+                            <menuitem action='save-visual-state-2'/>
+                            <menuitem action='goto-visual-state-2'/>
+                            <menuitem action='save-visual-state-3'/>
+                            <menuitem action='goto-visual-state-3'/>
+                            <menuitem action='save-visual-state-4'/>
+                            <menuitem action='goto-visual-state-4'/>
+                            <menuitem action='save-visual-state-5'/>
+                            <menuitem action='goto-visual-state-5'/>
+                            <menuitem action='save-visual-state-6'/>
+                            <menuitem action='goto-visual-state-6'/>
+                            <menuitem action='save-visual-state-7'/>
+                            <menuitem action='goto-visual-state-7'/>
+                            <menuitem action='save-visual-state-8'/>
+                            <menuitem action='goto-visual-state-8'/>
+                            <menuitem action='save-visual-state-9'/>
+                            <menuitem action='goto-visual-state-9'/>
+                            <menuitem action='save-visual-state-10'/>
+                            <menuitem action='goto-visual-state-10'/>
+                            <menuitem action='save-visual-state-11'/>
+                            <menuitem action='goto-visual-state-11'/>
+                            <menuitem action='save-visual-state-12'/>
+                            <menuitem action='goto-visual-state-12'/>
+              </menu>
 
               <menuitem action='ToggleMaximalEditor'/>
               <menuitem action='show-editor-mixer'/>
                           <menuitem action='ToggleTapeMachineMode'/>
                </menu>
               <menu action='Metering'>
+                       <menuitem action='ShowTrackMeters'/>
                    <menu action='MeteringFallOffRate'>
                        <menuitem action='MeterFalloffOff'/>
                        <menuitem action='MeterFalloffSlowest'/>
           <menuitem action="toggle-loop-punch-ruler"/>
      </popup>
 
-     <popup name='processormenu'>
+     <popup name='redirectmenu'>
         <menuitem action='newplugin'/>
         <menuitem action='newinsert'/>
         <menuitem action='newsend'/>
index 8ca22b2dd5a5cf1a5fc5f4d121a4c801fd121abc..1e55d2be1fcf14fef963e73cbd4fa4c34166a36c 100644 (file)
@@ -25,6 +25,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <unistd.h>
+#include <time.h>
 #include <cerrno>
 #include <fstream>
 
@@ -72,6 +73,8 @@
 #include <ardour/filesystem_paths.h>
 #include <ardour/filename_extensions.h>
 
+typedef uint64_t microseconds_t;
+
 #include "actions.h"
 #include "ardour_ui.h"
 #include "public_editor.h"
@@ -88,6 +91,8 @@
 #include "gui_thread.h"
 #include "theme_manager.h"
 #include "bundle_manager.h"
+#include "gain_meter.h"
+#include "route_time_axis.h"
 
 #include "i18n.h"
 
@@ -114,10 +119,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
          preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
          postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
 
-         /* adjuster table */
-
-         adjuster_table (3, 3),
-
          /* preroll stuff */
 
          preroll_button (_("pre\nroll")),
@@ -129,14 +130,14 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
 
          /* transport */
 
-         roll_controllable ("transport roll", *this, TransportControllable::Roll),
-         stop_controllable ("transport stop", *this, TransportControllable::Stop),
-         goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
-         goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
-         auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
-         play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
-         rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
-         shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
+         roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)),
+         stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)),
+         goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)),
+         goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)),
+         auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)),
+         play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)),
+         rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)),
+         shuttle_controllable (new TransportControllable ("shuttle", *this, TransportControllable::ShuttleControl)),
          shuttle_controller_binding_proxy (shuttle_controllable),
 
          roll_button (roll_controllable),
@@ -210,8 +211,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
        last_speed_displayed = -1.0f;
        ignore_dual_punch = false;
 
-       last_configure_time.tv_sec = 0;
-       last_configure_time.tv_usec = 0;
+       last_configure_time= 0;
 
        shuttle_grabbed = false;
        shuttle_fract = 0.0;
@@ -220,8 +220,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
        shuttle_style_menu = 0;
        shuttle_unit_menu = 0;
 
-       gettimeofday (&last_peak_grab, 0);
-       gettimeofday (&last_shuttle_request, 0);
+        // We do not have jack linked in yet so;
+        
+       last_shuttle_request = last_peak_grab = 0; //  get_microseconds();
 
        ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
        ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
@@ -249,6 +250,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
                Config->set_current_owner (ConfigVariableBase::Interface);
                setup_profile ();
 
+               GainMeter::setup_slider_pix ();
+               RouteTimeAxisView::setup_slider_pix ();
+
        } catch (failed_constructor& err) {
                error << _("could not initialize Ardour.") << endmsg;
                // pass it on up
@@ -417,21 +421,15 @@ ARDOUR_UI::pop_back_splash ()
 gint
 ARDOUR_UI::configure_timeout ()
 {
-       struct timeval now;
-       struct timeval diff;
-
-       if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
+       if (last_configure_time == 0) {
                /* no configure events yet */
                return TRUE;
        }
 
-       gettimeofday (&now, 0);
-       timersub (&now, &last_configure_time, &diff);
-
        /* force a gap of 0.5 seconds since the last configure event
         */
 
-       if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
+       if (get_microseconds() - last_configure_time < 500000) {
                return TRUE;
        } else {
                have_configure_timeout = false;
@@ -444,7 +442,7 @@ gboolean
 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
 {
        if (have_configure_timeout) {
-               gettimeofday (&last_configure_time, 0);
+               last_configure_time = get_microseconds();
        } else {
                Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
                have_configure_timeout = true;
@@ -459,28 +457,28 @@ ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
        const XMLProperty* prop;
 
        if ((prop = node.property ("roll")) != 0) {
-               roll_controllable.set_id (prop->value());
+               roll_controllable->set_id (prop->value());
        }
        if ((prop = node.property ("stop")) != 0) {
-               stop_controllable.set_id (prop->value());
+               stop_controllable->set_id (prop->value());
        }
        if ((prop = node.property ("goto_start")) != 0) {
-               goto_start_controllable.set_id (prop->value());
+               goto_start_controllable->set_id (prop->value());
        }
        if ((prop = node.property ("goto_end")) != 0) {
-               goto_end_controllable.set_id (prop->value());
+               goto_end_controllable->set_id (prop->value());
        }
        if ((prop = node.property ("auto_loop")) != 0) {
-               auto_loop_controllable.set_id (prop->value());
+               auto_loop_controllable->set_id (prop->value());
        }
        if ((prop = node.property ("play_selection")) != 0) {
-               play_selection_controllable.set_id (prop->value());
+               play_selection_controllable->set_id (prop->value());
        }
        if ((prop = node.property ("rec")) != 0) {
-               rec_controllable.set_id (prop->value());
+               rec_controllable->set_id (prop->value());
        }
        if ((prop = node.property ("shuttle")) != 0) {
-               shuttle_controllable.set_id (prop->value());
+               shuttle_controllable->set_id (prop->value());
        }
 }
 
@@ -490,21 +488,21 @@ ARDOUR_UI::get_transport_controllable_state ()
        XMLNode* node = new XMLNode(X_("TransportControllables"));
        char buf[64];
 
-       roll_controllable.id().print (buf, sizeof (buf));
+       roll_controllable->id().print (buf, sizeof (buf));
        node->add_property (X_("roll"), buf);
-       stop_controllable.id().print (buf, sizeof (buf));
+       stop_controllable->id().print (buf, sizeof (buf));
        node->add_property (X_("stop"), buf);
-       goto_start_controllable.id().print (buf, sizeof (buf));
+       goto_start_controllable->id().print (buf, sizeof (buf));
        node->add_property (X_("goto_start"), buf);
-       goto_end_controllable.id().print (buf, sizeof (buf));
+       goto_end_controllable->id().print (buf, sizeof (buf));
        node->add_property (X_("goto_end"), buf);
-       auto_loop_controllable.id().print (buf, sizeof (buf));
+       auto_loop_controllable->id().print (buf, sizeof (buf));
        node->add_property (X_("auto_loop"), buf);
-       play_selection_controllable.id().print (buf, sizeof (buf));
+       play_selection_controllable->id().print (buf, sizeof (buf));
        node->add_property (X_("play_selection"), buf);
-       rec_controllable.id().print (buf, sizeof (buf));
+       rec_controllable->id().print (buf, sizeof (buf));
        node->add_property (X_("rec"), buf);
-       shuttle_controllable.id().print (buf, sizeof (buf));
+       shuttle_controllable->id().print (buf, sizeof (buf));
        node->add_property (X_("shuttle"), buf);
 
        return *node;
@@ -544,13 +542,22 @@ ARDOUR_UI::save_ardour_state ()
 gint
 ARDOUR_UI::autosave_session ()
 {
-       if (!Config->get_periodic_safety_backups())
+       if (g_main_depth() > 1) {
+               /* inside a recursive main loop,
+                  give up because we may not be able to 
+                  take a lock.
+               */
                return 1;
+       }
 
-       if (session) {
-               session->maybe_write_autosave();
+        if (!Config->get_periodic_safety_backups()) {
+                return 1;
        }
 
+        if (session) {
+                session->maybe_write_autosave();
+        }
+
        return 1;
 }
 
@@ -796,8 +803,7 @@ ARDOUR_UI::ask_about_saving_session (const string & what)
        prompt_label.set_name (X_("PrompterLabel"));
        prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
 
-       dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
-;
+       dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
        dhbox.set_homogeneous (false);
        dhbox.pack_start (*dimage, false, false, 5);
        dhbox.pack_start (prompt_label, true, false, 5);
@@ -812,9 +818,6 @@ ARDOUR_UI::ask_about_saving_session (const string & what)
        prompt_label.show();
        dimage->show();
        window.show();
-
-       save_the_session = 0;
-
        window.set_keep_above (true);
        window.present ();
 
@@ -1152,33 +1155,6 @@ ARDOUR_UI::open_recent_session ()
        }
 }
 
-bool
-ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info) 
-{
-       struct stat statbuf;
-
-       if (stat (info.filename.c_str(), &statbuf) != 0) {
-               return false;
-       }
-
-       if (!S_ISDIR(statbuf.st_mode)) {
-               return false;
-       }
-
-        // XXX Portability
-        
-       string session_file = info.filename;
-       session_file += '/';
-       session_file += Glib::path_get_basename (info.filename);
-       session_file += ".ardour";
-       
-       if (stat (session_file.c_str(), &statbuf) != 0) {
-               return false;
-       }
-
-       return S_ISREG (statbuf.st_mode);
-}
-
 bool
 ARDOUR_UI::check_audioengine ()
 {
@@ -1401,6 +1377,34 @@ ARDOUR_UI::transport_goto_zero ()
        }
 }
 
+void
+ARDOUR_UI::transport_goto_wallclock ()
+{
+       if (session && editor) {
+
+               time_t now;
+               struct tm tmnow;
+               nframes64_t frames;
+               
+               time (&now);
+               localtime_r (&now, &tmnow);
+       
+               frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
+               frames += tmnow.tm_min * (60 * session->frame_rate());
+               frames += tmnow.tm_sec * session->frame_rate();
+
+               session->request_locate (frames);
+
+               /* force displayed area in editor to start no matter
+                  what "follow playhead" setting is.
+               */
+               
+               if (editor) {
+                       editor->reset_x_origin (frames - (editor->current_page_frames()/2));
+               }
+       }
+}
+
 void
 ARDOUR_UI::transport_goto_end ()
 {
@@ -1916,17 +1920,6 @@ ARDOUR_UI::save_state_canfail (string name)
        return 0;
 }
 
-void
-ARDOUR_UI::restore_state (string name)
-{
-       if (session) {
-               if (name.length() == 0) {
-                       name = session->name();
-               }
-               session->restore_state (name);
-       }
-}
-
 void
 ARDOUR_UI::primary_clock_value_changed ()
 {
@@ -1951,37 +1944,6 @@ ARDOUR_UI::secondary_clock_value_changed ()
        }
 }
 
-void
-ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
-{
-       if (session && dstream && dstream->record_enabled()) {
-
-               Session::RecordState rs;
-               
-               rs = session->record_status ();
-
-               switch (rs) {
-               case Session::Disabled:
-               case Session::Enabled:
-                       if (w->get_state() != STATE_SELECTED) {
-                               w->set_state (STATE_SELECTED);
-                       }
-                       break;
-
-               case Session::Recording:
-                       if (w->get_state() != STATE_ACTIVE) {
-                               w->set_state (STATE_ACTIVE);
-                       }
-                       break;
-               }
-
-       } else {
-               if (w->get_state() != STATE_NORMAL) {
-                       w->set_state (STATE_NORMAL);
-               }
-       }
-}
-
 void
 ARDOUR_UI::transport_rec_enable_blink (bool onoff) 
 {
@@ -2352,10 +2314,13 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be
                fontconfig_dialog();
 
                if (!backend_audio_is_running) {
-                       if (new_session_dialog->engine_control.setup_engine ()) {
-                               new_session_dialog->hide ();
+                       int ret = new_session_dialog->engine_control.setup_engine ();
+                       if (ret < 0) {
                                return false;
-                       } 
+                       } else if (ret > 0) {
+                               response = Gtk::RESPONSE_REJECT;
+                               goto try_again;
+                       }
                }
                
                if (create_engine ()) {
@@ -2459,7 +2424,7 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be
                        }
                }
 
-       } while (response == Gtk::RESPONSE_NONE);
+       } while (response == Gtk::RESPONSE_NONE || response == Gtk::RESPONSE_REJECT);
 
   done:
        show();
@@ -2861,8 +2826,11 @@ After cleanup, unused audio files will be moved to a \
        }
 
        if (session->cleanup_sources (rep)) {
+               editor->finish_cleanup ();
                return;
        }
+       
+       editor->finish_cleanup ();
 
        checker.hide();
        display_cleanup_results (rep, 
@@ -2876,8 +2844,6 @@ release an additional\n\
 %4 %5bytes of disk space.\n"
                                         ));
 
-
-
 }
 
 void
@@ -3024,7 +2990,6 @@ ARDOUR_UI::keyboard_settings () const
 void
 ARDOUR_UI::create_xrun_marker(nframes_t where)
 {
-       ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::create_xrun_marker), where));
        editor->mouse_add_new_marker (where, false, true);
 }
 
@@ -3039,6 +3004,8 @@ ARDOUR_UI::halt_on_xrun_message ()
 void
 ARDOUR_UI::xrun_handler(nframes_t where)
 {
+       ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
+
        if (Config->get_create_xrun_marker() && session->actively_recording()) {
                create_xrun_marker(where);
        }
index 442d319f770283fa6ec6bce2ef45d1dae50ea9bd..6be85f6a803dfc33cb6931c55414bae6f37d8bbc 100644 (file)
@@ -59,6 +59,7 @@
 #include <ardour/ardour.h>
 #include <ardour/session.h>
 #include <ardour/configuration.h>
+#include <ardour/types.h>
 
 #include "audio_clock.h"
 #include "ardour_dialog.h"
@@ -152,7 +153,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
 
        int  save_state_canfail (string state_name = "");
        void save_state (const string & state_name = "");
-       void restore_state (string state_name = "");
 
        static double gain_to_slider_position (ARDOUR::gain_t g);
        static ARDOUR::gain_t slider_position_to_gain (double pos);
@@ -181,12 +181,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        static sigc::signal<void>      SuperRapidScreenUpdate;
        static sigc::signal<void,nframes_t, bool, nframes_t> Clock;
 
-       /* this is a helper function to centralize the (complex) logic for
-          blinking rec-enable buttons.
-       */
-
-       void rec_enable_button_blink (bool onoff, ARDOUR::AudioDiskstream *, Gtk::Widget *w);
-
        void name_io_setup (ARDOUR::AudioEngine&, string&, ARDOUR::IO& io, bool in);
 
        static gint hide_and_quit (GdkEventAny *ev, ArdourDialog *);
@@ -309,9 +303,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        Gtk::ToggleButton   preroll_button;
        Gtk::ToggleButton   postroll_button;
 
-       Gtk::Table          transport_table;
-       Gtk::Table          option_table;
-
        int  setup_windows ();
        void setup_transport ();
        void setup_clock ();
@@ -324,7 +315,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
 
        void finish();
        int  ask_about_saving_session (const string & why);
-       int  save_the_session;
 
        /* periodic safety backup, to be precise */
        gint autosave_session();
@@ -361,9 +351,11 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void manage_window (Gtk::Window&);
 
        AudioClock   big_clock;
-       Gtk::Frame   big_clock_frame;
        Gtk::Window* big_clock_window;
 
+       void float_big_clock (Gtk::Window* parent);
+       bool main_window_state_event_handler (GdkEventWindowState*, bool window_was_editor);
+
        void update_transport_clocks (nframes_t pos);
        void record_state_changed ();
 
@@ -412,14 +404,14 @@ class ARDOUR_UI : public Gtkmm2ext::UI
            ToggleType type;
        };
 
-       TransportControllable roll_controllable;
-       TransportControllable stop_controllable;
-       TransportControllable goto_start_controllable;
-       TransportControllable goto_end_controllable;
-       TransportControllable auto_loop_controllable;
-       TransportControllable play_selection_controllable;
-       TransportControllable rec_controllable;
-       TransportControllable shuttle_controllable;
+       boost::shared_ptr<TransportControllable> roll_controllable;
+       boost::shared_ptr<TransportControllable> stop_controllable;
+       boost::shared_ptr<TransportControllable> goto_start_controllable;
+       boost::shared_ptr<TransportControllable> goto_end_controllable;
+       boost::shared_ptr<TransportControllable> auto_loop_controllable;
+       boost::shared_ptr<TransportControllable> play_selection_controllable;
+       boost::shared_ptr<TransportControllable> rec_controllable;
+       boost::shared_ptr<TransportControllable> shuttle_controllable;
        BindingProxy shuttle_controller_binding_proxy;
 
        void set_transport_controllable_state (const XMLNode&);
@@ -589,6 +581,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void transport_goto_zero ();
        void transport_goto_start ();
        void transport_goto_end ();
+       void transport_goto_wallclock ();
        void transport_stop ();
        void transport_stop_and_forget_capture ();
        void transport_record (bool roll);
@@ -675,11 +668,11 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void flush_trash ();
 
        bool have_configure_timeout;
-       struct timeval last_configure_time;
+       ARDOUR::microseconds_t last_configure_time;
        gint configure_timeout ();
 
-       struct timeval last_peak_grab;
-       struct timeval last_shuttle_request;
+       ARDOUR::microseconds_t last_peak_grab;
+       ARDOUR::microseconds_t last_shuttle_request;
 
        bool have_disk_speed_dialog_displayed;
        void disk_speed_dialog_gone (int ignored_response, Gtk::MessageDialog*);
@@ -698,9 +691,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        Gtk::MenuItem* jack_reconnect_item;
        Gtk::Menu*     jack_bufsize_menu;
 
-       int make_session_clean ();
-       bool filter_ardour_session_dirs (const Gtk::FileFilter::Info&);
-
        Glib::RefPtr<Gtk::ActionGroup> common_actions;
 
        void editor_realized ();
@@ -742,6 +732,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void toggle_ShowTrackMeters ();
        void toggle_only_copy_imported_files ();
        void toggle_use_narrow_ms();
+       void toggle_NameNewMarkers ();
        void toggle_rubberbanding_snaps_to_grid ();
        void toggle_auto_analyse_audio ();
        void toggle_TapeMachineMode();
index b497d6ab32c62ea2b8fee152ee89a32868c58d0d..568bfb54edfb6816dcf9a1fe187f5145a56b6afa 100644 (file)
@@ -773,17 +773,13 @@ ARDOUR_UI::set_shuttle_fract (double f)
 void
 ARDOUR_UI::use_shuttle_fract (bool force)
 {
-       struct timeval now;
-       struct timeval diff;
+       microseconds_t now = get_microseconds();
        
        /* do not attempt to submit a motion-driven transport speed request
           more than once per process cycle.
         */
 
-       gettimeofday (&now, 0);
-       timersub (&now, &last_shuttle_request, &diff);
-
-       if (!force && (diff.tv_usec + (diff.tv_sec * 1000000)) < engine->usecs_per_cycle()) {
+       if (!force && (last_shuttle_request - now) < (microseconds_t) engine->usecs_per_cycle()) {
                return;
        }
        
index 32b9f5adc75fd1597559b13af9a8ac730604b4d1..f87ce85476438c0612de095b21e066c372ffa87c 100644 (file)
@@ -433,3 +433,24 @@ ARDOUR_UI::handle_locations_change (Location* ignored)
                }
        }
 }
+
+bool
+ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
+{
+       if (window_was_editor) {
+
+               if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) && 
+                   (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
+                       float_big_clock (editor);
+               }
+
+       } else {
+
+               if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) && 
+                   (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
+                       float_big_clock (mixer);
+               }
+       }
+
+       return false;
+}
index 7eb13892ee4ace88c312264fac35e7d7b599c10e..504205dbf43035e0139e7a8c67df71ec45d0f0c8 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/window_title.h>
+#include <gtk/gtk.h>
 
 #include "ardour_ui.h"
 #include "public_editor.h"
@@ -73,6 +74,7 @@ ARDOUR_UI::create_editor ()
        }
 
        editor->Realized.connect (mem_fun (*this, &ARDOUR_UI::editor_realized));
+       editor->signal_window_state_event().connect (sigc::bind (mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), true));
 
        return 0;
 }
@@ -303,6 +305,9 @@ ARDOUR_UI::install_actions ()
        act = ActionManager::register_action (transport_actions, X_("GotoEnd"), _("Goto End"), mem_fun(*this, &ARDOUR_UI::transport_goto_end));
        ActionManager::session_sensitive_actions.push_back (act);
        ActionManager::transport_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (transport_actions, X_("GotoWallClock"), _("Goto Wall Clock"), mem_fun(*this, &ARDOUR_UI::transport_goto_wallclock));
+       ActionManager::session_sensitive_actions.push_back (act);
+       ActionManager::transport_sensitive_actions.push_back (act);
 
        act = ActionManager::register_action (transport_actions, X_("focus-on-clock"), _("Focus On Clock"), mem_fun(primary_clock, &AudioClock::focus));
        ActionManager::session_sensitive_actions.push_back (act);
@@ -460,6 +465,7 @@ ARDOUR_UI::install_actions ()
        ActionManager::register_toggle_action (option_actions, X_("AutoAnalyseAudio"), _("Auto-analyse new audio"), mem_fun (*this, &ARDOUR_UI::toggle_auto_analyse_audio));
 
        ActionManager::register_toggle_action (option_actions, X_("DefaultNarrowMS"), _("Use narrow mixer strips"), mem_fun (*this, &ARDOUR_UI::toggle_use_narrow_ms));
+       ActionManager::register_toggle_action (option_actions, X_("NameNewMarkers"), _("Name New Markers"), mem_fun (*this, &ARDOUR_UI::toggle_NameNewMarkers));
 
        RadioAction::Group denormal_group;
 
@@ -864,3 +870,16 @@ ARDOUR_UI::setup_clock ()
 
        manage_window (*big_clock_window);
 }
+
+void
+ARDOUR_UI::float_big_clock (Gtk::Window* parent)
+{
+       if (big_clock_window) {
+               if (parent) {
+                       big_clock_window->set_transient_for (*parent);
+               } else {
+                       gtk_window_set_transient_for (big_clock_window->gobj(), (GtkWindow*) 0);
+               }
+       }
+}
+
index dfc5d644b0765fb924f846eb59d7ffc2d5d35d7c..6373bc8b8ccdaa53ec504c4a9351299c5799a852 100644 (file)
@@ -41,6 +41,8 @@ ARDOUR_UI::create_mixer ()
                return -1;
        }
 
+       mixer->signal_window_state_event().connect (bind (mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), false));
+
        return 0;
 }
 
index 75d33d941608ce67b5fb28ddca1b5bec9c6128a2..4c1aae1583b46480fb377e58fe5e89f034474c5f 100644 (file)
@@ -587,6 +587,12 @@ ARDOUR_UI::toggle_use_narrow_ms()
        ActionManager::toggle_config_state ("options", "DefaultNarrowMS", &Configuration::set_default_narrow_ms, &Configuration::get_default_narrow_ms);
 }
 
+void
+ARDOUR_UI::toggle_NameNewMarkers()
+{
+       ActionManager::toggle_config_state ("options", "NameNewMarkers", &Configuration::set_name_new_markers, &Configuration::get_name_new_markers);
+}
+
 void
 ARDOUR_UI::toggle_rubberbanding_snaps_to_grid ()
 {
index ab14d4aafdb9ecdf1ee557902bb26cf56e94837c..977e5762a7363c75c8ed1ae347b2444350574627 100644 (file)
@@ -518,6 +518,8 @@ AUPluginUI::parent_cocoa_window ()
                return -1;
        }
 
+       [win setAutodisplay:YES]; // turn of GTK stuff for this window
+
        Gtk::Container* toplevel = get_toplevel();
 
        if (!toplevel || !toplevel->is_toplevel()) {
@@ -530,6 +532,7 @@ AUPluginUI::parent_cocoa_window ()
 
        NSView* view = gdk_quartz_window_get_nsview (low_box.get_window()->gobj());
        
+
        [view setFrame:packFrame];
        [view addSubview:packView]; 
 
index 5ce5159e7299bdf914c1344c64b24c6958cb260b..a3dbc1d3d0761e3620d03ba66c6bbf7e02e1f8fa 100644 (file)
@@ -828,13 +828,15 @@ AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
                break;
 
        case GDK_Tab:
+       case GDK_Return:
+       case GDK_KP_Enter:
                move_on = true;
                break;
 
        case GDK_Escape:
-       case GDK_Return:
-       case GDK_KP_Enter:
+               key_entry_state = 0;
                clock_base.grab_focus ();
+               ChangeAborted();  /*  EMIT SIGNAL  */
                return true;
 
        default:
@@ -960,6 +962,13 @@ AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
 
        }
 
+       //if user hit Enter, lose focus
+       switch (ev->keyval) {
+       case GDK_Return:
+       case GDK_KP_Enter:
+               clock_base.grab_focus ();
+       }
+
        return true;
 }
 
index 426b2f02fc44cc4f29845780f4b0b4efa60a509b..fe3eef30dc524cc8663ffc0dfefadd4e3af759a3 100644 (file)
@@ -61,6 +61,7 @@ class AudioClock : public Gtk::HBox
        void set_session (ARDOUR::Session *s);
 
        sigc::signal<void> ValueChanged;
+       sigc::signal<void> ChangeAborted;
 
        static sigc::signal<void> ModeChanged;
        static std::vector<AudioClock*> clocks;
index e66b184adb4c375ff30bdd70b3816eb23b4e6afc..3a269c04bcb97934f6181238cd5b31402e0871d3 100644 (file)
@@ -78,9 +78,10 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView
 {
 }
 
+
 AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu, 
-                                 Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
-       : RegionView (parent, tv, r, spu, basic_color, visibility)
+                                 Gdk::Color& basic_color, bool recording, TimeAxisViewItem::Visibility visibility)
+       : RegionView (parent, tv, r, spu, basic_color, recording, visibility)
        , sync_mark(0)
        , zero_line(0)
        , fade_in_shape(0)
@@ -213,7 +214,7 @@ AudioRegionView::init (Gdk::Color& basic_color, bool wfd)
 
        gain_line->reset ();
 
-       set_y_position_and_height (0, trackview.height);
+       set_y_position_and_height (0, trackview.current_height());
 
        region_muted ();
        region_sync_changed ();
@@ -264,6 +265,7 @@ void
 AudioRegionView::region_changed (Change what_changed)
 {
        ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioRegionView::region_changed), what_changed));
+       //cerr << "AudioRegionView::region_changed() called" << endl;
 
        RegionView::region_changed(what_changed);
 
@@ -434,32 +436,53 @@ AudioRegionView::region_muted ()
 }
 
 void
-AudioRegionView::set_y_position_and_height (double y, double h)
+AudioRegionView::setup_fade_handle_positions()
 {
-       RegionView::set_y_position_and_height(y, h - 1);
+       /* position of fade handle offset from the top of the region view */
+       double const handle_pos = 2;
+       /* height of fade handles */
+       double const handle_height = 5;
+
+       if (fade_in_handle) {
+               fade_in_handle->property_y1() = _y_position + handle_pos;
+               fade_in_handle->property_y2() = _y_position + handle_pos + handle_height;
+       }
        
-       const uint32_t wcnt = waves.size();
+       if (fade_out_handle) {
+               fade_out_handle->property_y1() = _y_position + handle_pos;
+               fade_out_handle->property_y2() = _y_position + handle_pos + handle_height;
+       }
+}
+
+void
+AudioRegionView::set_y_position_and_height (double y, double h)
+{
+       RegionView::set_y_position_and_height (y, h - 1);
+
+       /* XXX why is this code here */
 
        _y_position = y;
        _height = h;
 
-       for (uint32_t n = 0; n < wcnt; ++n) {
-               double ht;
+       const uint32_t wcnt = waves.size();
+       
+       for (uint32_t n=0; n < wcnt; ++n) {
+               gdouble ht;
 
-               if (h <= NAME_HIGHLIGHT_THRESH) {
-                       ht = ((_height - 2 * wcnt) / (double) wcnt);
+               if ((h) < NAME_HIGHLIGHT_THRESH) {
+                       ht = ((_height-2*wcnt) / (double) wcnt);
                } else {
-                       ht = (((_height - 2 * wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
+                       ht = (((_height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
                }
                
-               double const yoff = n * (ht + 1);
+               gdouble yoff = n * (ht+1);
                
                waves[n]->property_height() = ht;
-               waves[n]->property_y() = _y_position + yoff + 2;
+               waves[n]->property_y() = yoff + 2;
        }
 
        if (gain_line) {
-               if ((_height / wcnt) < NAME_HIGHLIGHT_SIZE) {
+               if ((_height/wcnt) < NAME_HIGHLIGHT_THRESH) {
                        gain_line->hide ();
                } else {
                        if (_flags & EnvelopeVisible) {
@@ -469,7 +492,6 @@ AudioRegionView::set_y_position_and_height (double y, double h)
                gain_line->set_y_position_and_height ((uint32_t) _y_position, (uint32_t) rint (_height - NAME_HIGHLIGHT_SIZE));
        }
 
-       setup_fade_handle_positions ();
        manage_zero_line ();
        reset_fade_shapes ();
        
@@ -478,25 +500,6 @@ AudioRegionView::set_y_position_and_height (double y, double h)
        }
 }
 
-void
-AudioRegionView::setup_fade_handle_positions()
-{
-       /* position of fade handle offset from the top of the region view */
-       double const handle_pos = 2;
-       /* height of fade handles */
-       double const handle_height = 5;
-
-       if (fade_in_handle) {
-               fade_in_handle->property_y1() = _y_position + handle_pos;
-               fade_in_handle->property_y2() = _y_position + handle_pos + handle_height;
-       }
-       
-       if (fade_out_handle) {
-               fade_out_handle->property_y1() = _y_position + handle_pos;
-               fade_out_handle->property_y2() = _y_position + handle_pos + handle_height;
-       }
-}
-
 void
 AudioRegionView::manage_zero_line ()
 {
@@ -573,7 +576,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
 
        points = get_canvas_points ("fade in shape", npoints+3);
 
-       if (_height > NAME_HIGHLIGHT_THRESH) {
+       if (_height >= NAME_HIGHLIGHT_THRESH) {
                h = _height - NAME_HIGHLIGHT_SIZE;
        } else {
                h = _height;
@@ -657,7 +660,7 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
        float curve[npoints];
        audio_region()->fade_out()->curve().get_vector (0, audio_region()->fade_out()->back()->when, curve, npoints);
 
-       if (_height > NAME_HIGHLIGHT_THRESH) {
+       if (_height >= NAME_HIGHLIGHT_THRESH) {
                h = _height - NAME_HIGHLIGHT_SIZE;
        } else {
                h = _height;
@@ -853,6 +856,7 @@ AudioRegionView::create_waves ()
                        if (audio_region()->audio_source(n)->peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
                                // cerr << "\tData is ready\n";
                                cerr << "\tData is ready\n";
+                               // cerr << "\tData is ready\n";
                                create_one_wave (n, true);
                        } else {
                                // cerr << "\tdata is not ready\n";
@@ -878,10 +882,10 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
        uint32_t nwaves = std::min (nchans, audio_region()->n_channels());
        gdouble ht;
 
-       if (trackview.height < NAME_HIGHLIGHT_SIZE) {
-               ht = ((trackview.height) / (double) nchans);
+       if (trackview.current_height() < NAME_HIGHLIGHT_THRESH) {
+               ht = ((trackview.current_height()) / (double) nchans);
        } else {
-               ht = ((trackview.height - NAME_HIGHLIGHT_SIZE) / (double) nchans);
+               ht = ((trackview.current_height() - NAME_HIGHLIGHT_SIZE) / (double) nchans);
        }
 
        gdouble yoff = which * ht;
@@ -900,8 +904,15 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
        wave->property_height() =  (double) ht;
        wave->property_samples_per_unit() =  samples_per_unit;
        wave->property_amplitude_above_axis() =  _amplitude_above_axis;
-       wave->property_wave_color() = _region->muted() ? UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_WaveForm.get(), MUTED_ALPHA) : ARDOUR_UI::config()->canvasvar_WaveForm.get();
-       wave->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill.get();
+
+       if (_recregion) {
+               wave->property_wave_color() = _region->muted() ? UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_RecWaveForm.get(), MUTED_ALPHA) : ARDOUR_UI::config()->canvasvar_RecWaveForm.get();
+               wave->property_fill_color() = ARDOUR_UI::config()->canvasvar_RecWaveFormFill.get();
+       } else {
+               wave->property_wave_color() = _region->muted() ? UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_WaveForm.get(), MUTED_ALPHA) : ARDOUR_UI::config()->canvasvar_WaveForm.get();
+               wave->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill.get();
+       }
+
        wave->property_clip_color() = ARDOUR_UI::config()->canvasvar_WaveFormClip.get();
        wave->property_zero_color() = ARDOUR_UI::config()->canvasvar_ZeroLine.get();
        wave->property_region_start() = _region->start();
@@ -986,7 +997,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
 
        /* compute vertical fractional position */
 
-       y = 1.0 - ((y - _y_position) / (_height - NAME_HIGHLIGHT_SIZE));
+       y = 1.0 - (y / (trackview.current_height() - NAME_HIGHLIGHT_SIZE));
        
        /* map using gain line */
 
@@ -1275,16 +1286,31 @@ AudioRegionView::set_frame_color ()
                        }
                }
        } else {
-               UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
-               frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
-
-               for (vector<ArdourCanvas::WaveView*>::iterator w = waves.begin(); w != waves.end(); ++w) {
-                       if (_region->muted()) {
-                               (*w)->property_wave_color() = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_WaveForm.get(), MUTED_ALPHA);
-                       } else {
-                               (*w)->property_wave_color() = ARDOUR_UI::config()->canvasvar_WaveForm.get();
-                               (*w)->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill.get();
+               if (_recregion) {
+                       UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_RecordingRect.get(), &r, &g, &b, &a);
+                       frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
+
+                       for (vector<ArdourCanvas::WaveView*>::iterator w = waves.begin(); w != waves.end(); ++w) {
+                               if (_region->muted()) {
+                                       (*w)->property_wave_color() = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_RecWaveForm.get(), MUTED_ALPHA);
+                               } else {
+                                       (*w)->property_wave_color() = ARDOUR_UI::config()->canvasvar_RecWaveForm.get();
+                                       (*w)->property_fill_color() = ARDOUR_UI::config()->canvasvar_RecWaveFormFill.get();
+                               }
+                       }
+               } else {
+                       UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
+                       frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
+
+                       for (vector<ArdourCanvas::WaveView*>::iterator w = waves.begin(); w != waves.end(); ++w) {
+                               if (_region->muted()) {
+                                       (*w)->property_wave_color() = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_WaveForm.get(), MUTED_ALPHA);
+                               } else {
+                                       (*w)->property_wave_color() = ARDOUR_UI::config()->canvasvar_WaveForm.get();
+                                       (*w)->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill.get();
+                               }
                        }
                }
        }
 }
+
index 58e3c7fce68b314f959b06d08e18156879b8a973..d93534cff79dfd1b3ea69244583bac6e5e4e8400 100644 (file)
@@ -54,6 +54,14 @@ class AudioRegionView : public RegionView
                         double initial_samples_per_unit,
                         Gdk::Color& basic_color);
 
+       AudioRegionView (ArdourCanvas::Group *, 
+                    RouteTimeAxisView&,
+                    boost::shared_ptr<ARDOUR::AudioRegion>,
+                    double      samples_per_unit,
+                    Gdk::Color& basic_color,
+                        bool recording,
+                    TimeAxisViewItem::Visibility);
+
         AudioRegionView (const AudioRegionView& other);
         AudioRegionView (const AudioRegionView& other, boost::shared_ptr<ARDOUR::AudioRegion>);
 
@@ -108,13 +116,6 @@ class AudioRegionView : public RegionView
        to the TimeAxisViewItem parent class
     */
     
-    AudioRegionView (ArdourCanvas::Group *, 
-                    RouteTimeAxisView&,
-                    boost::shared_ptr<ARDOUR::AudioRegion>,
-                    double      samples_per_unit,
-                    Gdk::Color& basic_color,
-                    TimeAxisViewItem::Visibility);
-    
     enum Flags {
            EnvelopeVisible = 0x1,
            WaveformVisible = 0x4,
index 08ac532319ffa6f65d9e160f9da35548b56fa9d7..0e3dda0bd680b234e0a0800f07914ce63a996bac 100644 (file)
@@ -112,7 +112,7 @@ AudioStreamView::set_amplitude_above_axis (gdouble app)
 }
 
 RegionView*
-AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves)
+AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves, bool recording)
 {
        AudioRegionView *region_view = 0;
 
@@ -142,8 +142,13 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
 
        switch (_trackview.audio_track()->mode()) {
        case Normal:
-               region_view = new AudioRegionView (canvas_group, _trackview, region, 
+               if (recording) {
+                       region_view = new AudioRegionView (canvas_group, _trackview, region, 
+                                                  _samples_per_unit, region_color, recording, TimeAxisViewItem::Visibility(TimeAxisViewItem::ShowFrame | TimeAxisViewItem::HideFrameRight));
+               } else {
+                       region_view = new AudioRegionView (canvas_group, _trackview, region, 
                                                   _samples_per_unit, region_color);
+               }
                break;
        case Destructive:
                region_view = new TapeAudioRegionView (canvas_group, _trackview, region, 
@@ -159,7 +164,6 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
        region_view->set_amplitude_above_axis(_amplitude_above_axis);
        region_views.push_front (region_view);
 
-       
        /* if its the special single-sample length that we use for rec-regions, make it 
           insensitive to events 
        */
@@ -456,7 +460,7 @@ AudioStreamView::redisplay_diskstream ()
        
        for (RegionViewList::iterator j = copy.begin(); j != copy.end(); ++j) {
                        (*j)->enable_display(true);
-                       (*j)->set_y_position_and_height(0, height);
+                       (*j)->set_height (height);
                        region_layered (*j);
        }
 }
@@ -497,7 +501,7 @@ AudioStreamView::set_waveform_scale (WaveformScale scale)
 void
 AudioStreamView::setup_rec_box ()
 {
-       // cerr << _trackview.name() << " streamview SRB\n";
+       //cerr << _trackview.name() << " streamview SRB region_views.size() = " << region_views.size() << endl;
 
        if (_trackview.session().transport_rolling()) {
 
@@ -506,7 +510,6 @@ AudioStreamView::setup_rec_box ()
                if (!rec_active && 
                    _trackview.session().record_status() == Session::Recording && 
                    _trackview.get_diskstream()->record_enabled()) {
-
                        if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) {
 
                                /* add a new region, but don't bother if they set use_rec_regions mid-record */
@@ -578,8 +581,9 @@ AudioStreamView::setup_rec_box ()
                        rec_rect->property_x1() = xstart;
                        rec_rect->property_y1() = 1.0;
                        rec_rect->property_x2() = xend;
-                       rec_rect->property_y2() = (double) _trackview.height - 1;
-                       rec_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_RecordingRect.get();
+                       rec_rect->property_y2() = (double) _trackview.current_height() - 1;
+                       rec_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
+                       rec_rect->property_outline_what() = 0x1 | 0x2 | 0x4 | 0x8;
                        rec_rect->property_fill_color_rgba() = fill_color;
                        rec_rect->lower_to_bottom();
                        
@@ -598,11 +602,9 @@ AudioStreamView::setup_rec_box ()
                } else if (rec_active &&
                           (_trackview.session().record_status() != Session::Recording ||
                            !_trackview.get_diskstream()->record_enabled())) {
-
                        screen_update_connection.disconnect();
                        rec_active = false;
                        rec_updating = false;
-
                }
                
        } else {
@@ -688,7 +690,6 @@ void
 AudioStreamView::update_rec_regions ()
 {
        if (use_rec_regions) {
-
                uint32_t n = 0;
 
                for (list<pair<boost::shared_ptr<Region>,RegionView*> >::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) {
@@ -726,7 +727,7 @@ AudioStreamView::update_rec_regions ()
 
                                                if (origlen == 1) {
                                                        /* our special initial length */
-                                                       add_region_view_internal (region, false);
+                                                       add_region_view_internal (region, false, true);
                                                }
 
                                                /* also update rect */
@@ -751,7 +752,7 @@ AudioStreamView::update_rec_regions ()
                                                
                                                if (origlen == 1) {
                                                        /* our special initial length */
-                                                       add_region_view_internal (region, false);
+                                                       add_region_view_internal (region, false, true);
                                                }
                                                
                                                /* also hide rect */
index 326a05f2408db3937892a6a7f9eca8f7ef176739..74868ea1a27457d8c20fb8adb5efa1c54d6135fd 100644 (file)
@@ -82,7 +82,7 @@ class AudioStreamView : public StreamView
        void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr<ARDOUR::Source> src); 
        void update_rec_regions ();
        
-       RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
+       RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves, bool recording = false);
        void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
        void remove_audio_region_view (boost::shared_ptr<ARDOUR::AudioRegion> );
 
@@ -106,10 +106,15 @@ class AudioStreamView : public StreamView
        CrossfadeViewList crossfade_views;
        bool              crossfades_visible;
 
+
+       std::list<sigc::connection>                  rec_data_ready_connections;
+       nframes_t                                    last_rec_data_frame;
+       map<boost::shared_ptr<ARDOUR::Source>, bool> rec_data_ready_map;
+
+       bool outline_region;
+
        Editing::WaveformShape     _waveform_shape;
        Editing::WaveformScale     _waveform_scale;
-       
-       map<boost::shared_ptr<ARDOUR::Source>, bool> rec_data_ready_map;
 };
 
 #endif /* __ardour_audio_streamview_h__ */
index 565d7cda9fed9302f8d952352d5a82e2c4bd598a..1b090d881e6d4cdf8342c42f3d3a91de179c5288 100644 (file)
@@ -86,6 +86,8 @@ class AudioTimeAxisView : public RouteTimeAxisView
        
        void first_idle ();
 
+       XMLNode* get_child_xml_node (const string & childname);
+
        void set_waveform_shape (Editing::WaveformShape);
        void set_waveform_scale (Editing::WaveformScale);
 
index dfbdb30ffe42f348e8ebe4289497c975a136af9f..0bf1482224c2a5f983d6d1c56552c972ebf3c97e 100644 (file)
@@ -33,7 +33,7 @@ using namespace Gtk;
 
 
 AutomationController::AutomationController(boost::shared_ptr<AutomationControl> ac, Adjustment* adj)
-       : BarController(*adj, *ac)
+       : BarController(*adj, ac)
        , _ignore_change(false)
        , _controllable(ac)
        , _adjustment(adj)
index 8c721c7e849b2903d09954343ef0e68c3f365c55..b112a9481e15fcaab16a2b8df483e0db11775dcb 100644 (file)
@@ -154,17 +154,17 @@ AutomationLine::control_point_box_size ()
 }
 
 void
-AutomationLine::set_y_position_and_height (guint32 y, guint32 h)
+AutomationLine::set_y_position_and_height (double y, double h)
 {
        bool changed = false;
        
        if (y != _y_position) {
-               _y_position = y;
+               _y_position = (guint32) floor (y);
                changed = true;
        }
                
        if (h != _height) {
-               _height = h;
+               _height = (guint32) floor (h);
 
                double const bsz = control_point_box_size();
 
index 6ce548e55d7c6f95c2a619aaf7815e0124ebcf47..9e35903671a0cc3248ca8319c8ffa0de23dbc173 100644 (file)
@@ -94,7 +94,7 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoin
 
        void    show ();
        void    hide ();
-       void    set_y_position_and_height (uint32_t, uint32_t);
+       void    set_y_position_and_height (double, double);
        void    set_verbose_cursor_uses_gain_mapping (bool yn);
 
        TimeAxisView& trackview;
index f0dc23e0433a6c9341ce5f09aa0a342abe67e9b1..0ba14398e62e5eb7ea8c9ff8a09a5cd3a674b446 100644 (file)
@@ -53,7 +53,7 @@ AutomationRegionView::init (Gdk::Color& basic_color, bool wfd)
 
        reset_width_dependent_items ((double) _region->length() / samples_per_unit);
 
-       set_y_position_and_height (0, trackview.height);
+       set_height (trackview.current_height());
 
        _region->StateChanged.connect (mem_fun(*this, &AutomationRegionView::region_changed));
 
@@ -90,8 +90,8 @@ AutomationRegionView::add_automation_event (GdkEvent* event, nframes_t when, dou
 
        /* compute vertical fractional position */
 
-       const double height = trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2;
-       y = 1.0 - (y / height);
+       const double h = trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2;
+       y = 1.0 - (y / h);
 
        /* map using line */
 
index d068c51e5ee85ab51978de829f28d480686c94ec..5803d283dca8dc8dac7bed840c8a6a19d829b2d7 100644 (file)
@@ -70,7 +70,7 @@ AutomationStreamView::~AutomationStreamView ()
 
 
 RegionView*
-AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region, bool wfd)
+AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region, bool wfd, bool recording)
 {
        if ( ! region) {
                cerr << "No region" << endl;
index c5eac370217aa30ff291aba3488fdb23b02b470c..5eebfaf28d7247c0b412b23caa65d3d8125b41f4 100644 (file)
@@ -51,15 +51,16 @@ class AutomationStreamView : public StreamView
 
        void redisplay_diskstream ();
        
-       inline double contents_height() const
-               { return (_trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2); }
+       inline double contents_height() const { 
+               return (_trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2);
+       }
        
   private:
        void setup_rec_box ();
        void rec_data_range_ready (jack_nframes_t start, jack_nframes_t dur); 
        void update_rec_regions (jack_nframes_t start, jack_nframes_t dur);
        
-       RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_data);
+       RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_data, bool recording = false);
        void        display_region(AutomationRegionView* region_view);
        
        void color_handler ();
index 099a36c8224bb9f59e806ef914119899e4e27f0f..36d615453c3251e4b3c74981dceb786d485f9a68 100644 (file)
@@ -373,15 +373,19 @@ AutomationTimeAxisView::clear_clicked ()
 }
 
 void
-AutomationTimeAxisView::set_height (TrackHeight ht)
+AutomationTimeAxisView::set_height (uint32_t h)
 {
-       uint32_t h = height_to_pixels (ht);
        bool changed = (height != (uint32_t) h) || first_call_to_set_height;
        
        if (first_call_to_set_height)
                first_call_to_set_height = false;
+       bool changed_between_small_and_normal = ( (h == hSmall || h == hSmaller) ^ (height == hSmall || height == hSmaller) );
 
-       TimeAxisView::set_height (ht);
+       TimeAxisView* state_parent = get_parent_with_state ();
+       assert(state_parent);
+       XMLNode* xml_node = state_parent->get_automation_child_xml_node (_control->parameter());
+
+       TimeAxisView::set_height (h);
        _base_rect->property_y2() = h;
        
        if (_line)
@@ -392,50 +396,16 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
                _view->update_contents_y_position_and_height();
        }
 
-       TimeAxisView* state_parent = get_parent_with_state ();
-       assert(state_parent);
+       char buf[32];
+       snprintf (buf, sizeof (buf), "%u", height);
+       xml_node->add_property ("height", buf);
 
-       XMLNode* xml_node = state_parent->get_automation_child_xml_node(_control->parameter());
-       assert(xml_node);
-
-       switch (ht) {
-       case Largest:
-               xml_node->add_property ("track_height", "largest");
-               break;
-
-       case Large:
-               xml_node->add_property ("track_height", "large");
-               break;
-
-       case Larger:
-               xml_node->add_property ("track_height", "larger");
-               break;
-
-       case Normal:
-               xml_node->add_property ("track_height", "normal");
-               break;
-
-       case Smaller:
-               xml_node->add_property ("track_height", "smaller");
-               break;
-
-       case Small:
-               xml_node->add_property ("track_height", "small");
-               break;
-       }
-
-       switch (ht) {
-               case Large:
-               case Larger:
-               case Largest:
-                       _controller->show ();
-
-               case Normal:
-                       if (ht == Normal)
-                               _controller->hide();
+       if (changed_between_small_and_normal || first_call_to_set_height) {
+               first_call_to_set_height = false;
 
+               if (h >= hNormal) {
                        controls_table.remove (name_hbox);
-
+                       
                        if (plugname) {
                                if (plugname_packed) {
                                        controls_table.remove (*plugname);
@@ -450,18 +420,13 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
                        hide_name_entry ();
                        show_name_label ();
                        name_hbox.show_all ();
-
+                       
                        auto_button.show();
                        height_button.show();
                        clear_button.show();
                        hide_button.show_all();
-                       break;
-
-               case Smaller:
-                       _controller->hide();
-
-               case Small:
 
+               } else if (h >= hSmall) {
                        controls_table.remove (name_hbox);
                        if (plugname) {
                                if (plugname_packed) {
@@ -474,17 +439,17 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
                        hide_name_entry ();
                        show_name_label ();
                        name_hbox.show_all ();
-
+                       
                        auto_button.hide();
                        height_button.hide();
                        clear_button.hide();
                        hide_button.hide();
-                       break;
+               }
        }
 
        if (changed) {
                /* only emit the signal if the height really changed */
-               _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+               _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
        }
 }
 
@@ -900,10 +865,10 @@ AutomationTimeAxisView::color_handler ()
        }
 }
 
-void
+int
 AutomationTimeAxisView::set_state (const XMLNode& node)
 {
-       TimeAxisView::set_state (node);
+       return TimeAxisView::set_state (node);
        
        XMLNodeList kids;
        XMLNodeConstIterator iter;
@@ -947,7 +912,9 @@ void
 AutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
 {
        XMLNode* xml_node = get_state_node();
-       xml_node->add_property ("shown", editor_shown ? "yes" : "no");
+//     if (xml_node) {
+               xml_node->add_property ("shown", editor_shown ? "yes" : "no");
+//     }
 }
 
 guint32
index 8ddd007a3c8f4b3c2188876f0c10cc04281f3a03..fb56c400c746b51494eacebb5af649f6cbf89ef1 100644 (file)
@@ -71,7 +71,8 @@ class AutomationTimeAxisView : public TimeAxisView {
 
        ~AutomationTimeAxisView();
        
-       void set_height (TimeAxisView::TrackHeight);
+
+       void set_height (uint32_t);
        void set_samples_per_unit (double);
        std::string name() const { return _name; }
 
@@ -94,7 +95,7 @@ class AutomationTimeAxisView : public TimeAxisView {
        bool paste (nframes_t, float times, Selection&, size_t nth);
        void reset_objects (PointSelection&);
 
-       void set_state (const XMLNode&);
+       int  set_state (const XMLNode&);
        
        guint32 show_at (double y, int& nth, Gtk::VBox *parent);
        void hide ();
index e64ef99b160b216bb9d3fa136c65f07ede4f7df7..3a15e05c994fb0c8432d4aeb226ea1d3c7905c93 100644 (file)
@@ -52,11 +52,8 @@ class AxisView : public virtual Selectable
        virtual string name() const = 0;
 
        virtual bool marked_for_display() const { return _marked_for_display; }
-
        virtual void set_marked_for_display (bool yn) {
-               if (yn != _marked_for_display) {
-                       _marked_for_display = yn;
-               }
+               _marked_for_display = yn;
        }
        
        sigc::signal<void> Hiding;
index 4dacce782f2c27300e2967e59fb9d83420cc15e8..8486c5c30ff9306a734ca87c3afff561fab0ea4d 100644 (file)
@@ -61,7 +61,7 @@ BundleEditorMatrix::get_state (int r, std::string const & p) const
 uint32_t
 BundleEditorMatrix::n_rows () const
 {
-       return _bundle->nchannels ();
+       return _bundle->nchannels ().n_total();
 }
 
 uint32_t
index 44a710703b80dcd1bfabd80398c02d7b5a76cdcd..530d323961ac549628f707cc98e0215daa59825a 100644 (file)
@@ -24,7 +24,6 @@ CANVAS_VARIABLE(canvasvar_EnteredControlPointOutline, "entered control point out
 CANVAS_VARIABLE(canvasvar_EnteredControlPointSelected, "entered control point selected")
 CANVAS_VARIABLE(canvasvar_EnteredGainLine, "entered gain line")
 CANVAS_VARIABLE(canvasvar_EnteredMarker, "entered marker")
-CANVAS_VARIABLE(canvasvar_FrameBase, "region base")
 CANVAS_VARIABLE(canvasvar_FrameHandle, "frame handle")
 CANVAS_VARIABLE(canvasvar_GainLine, "gain line")
 CANVAS_VARIABLE(canvasvar_GainLineInactive, "gain line inactive")
@@ -82,6 +81,8 @@ CANVAS_VARIABLE(canvasvar_RangeDragBarRect, "range drag bar rect")
 CANVAS_VARIABLE(canvasvar_RangeDragRect, "range drag rect")
 CANVAS_VARIABLE(canvasvar_RangeMarkerBar, "range marker bar")
 CANVAS_VARIABLE(canvasvar_RecordingRect, "recording rect")
+CANVAS_VARIABLE(canvasvar_RecWaveFormFill, "recorded waveform fill")
+CANVAS_VARIABLE(canvasvar_RecWaveForm, "recorded waveform outline")
 CANVAS_VARIABLE(canvasvar_RubberBandRect, "rubber band rect")
 CANVAS_VARIABLE(canvasvar_SelectedCrossfadeEditorLine, "selected crossfade editor line")
 CANVAS_VARIABLE(canvasvar_SelectedCrossfadeEditorWave, "selected crossfade editor wave")
@@ -103,8 +104,9 @@ CANVAS_VARIABLE(canvasvar_TrimHandleLocked, "trim handle locked")
 CANVAS_VARIABLE(canvasvar_TrimHandle, "trim handle")
 CANVAS_VARIABLE(canvasvar_VerboseCanvasCursor, "verbose canvas cursor")
 CANVAS_VARIABLE(canvasvar_VestigialFrame, "vestigial frame")
+CANVAS_VARIABLE(canvasvar_FrameBase, "region base")
+CANVAS_VARIABLE(canvasvar_WaveForm, "waveform outline")
 CANVAS_VARIABLE(canvasvar_WaveFormClip, "clipped waveform")
 CANVAS_VARIABLE(canvasvar_WaveFormFill, "waveform fill")
-CANVAS_VARIABLE(canvasvar_WaveForm, "waveform outline")
 CANVAS_VARIABLE(canvasvar_ZeroLine, "zero line")
 CANVAS_VARIABLE(canvasvar_ZoomRect, "zoom rect")
index 22119721ffaf4fe7e3b7819c1809c24ba18167a2..1b5f4d886a516d80c0381be0b6c7698639f0b825 100644 (file)
@@ -52,7 +52,7 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
                              
 
        : TimeAxisViewItem ("xfade" /*xf.name()*/, *parent, tv, spu, basic_color, xf->position(), 
-                           xf->length(), TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
+                           xf->length(), false, TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
          crossfade (xf),
          left_view (lview),
          right_view (rview)
@@ -69,7 +69,7 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
        fade_out->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeLine.get();
        fade_out->property_width_pixels() = 1;
        
-       set_y_position_and_height (0, get_time_axis_view().height);
+       set_y_position_and_height (0, get_time_axis_view().current_height());
 
        /* no frame around the xfade or overlap rects */
 
@@ -109,15 +109,12 @@ CrossfadeView::reset_width_dependent_items (double pixel_width)
 void
 CrossfadeView::set_y_position_and_height (double y, double h)
 {
-       if (h == TimeAxisView::hSmaller || h == TimeAxisView::hSmall) {
-               TimeAxisViewItem::set_y_position_and_height (y, h - 3 );
+       if (h <= TimeAxisView::hSmaller) {
+               TimeAxisViewItem::set_y_position_and_height (y, h - 3);
        } else {
                TimeAxisViewItem::set_y_position_and_height (y, h - NAME_HIGHLIGHT_SIZE - 3 );
        }
 
-       _y_position = y;
-       _height = h;
-
        redraw_curves ();
 }
 
@@ -163,8 +160,10 @@ CrossfadeView::redraw_curves ()
         At "height - 3.0" the bottom of the crossfade touches the name highlight or the bottom of the track (if the
         track is either Small or Smaller.
         */
-       double const tav_height = get_time_axis_view().height;
-       if (tav_height == TimeAxisView::hSmaller || tav_height == TimeAxisView::hSmall) {
+
+       double tav_height = get_time_axis_view().current_height();
+       if (tav_height == TimeAxisView::hSmaller ||
+           tav_height == TimeAxisView::hSmall) {
                h = tav_height - 3.0;
        } else {
                h = tav_height - NAME_HIGHLIGHT_SIZE - 3.0;
index 2874e69308acc2504614d9a1fc073279646e8a3a..1e58fcddbc16bb44cc32ef52a3180c3e077fd5f5 100644 (file)
@@ -17,7 +17,7 @@
 
 */
 
-#include <string>
+#include <cstring>
 #include <cstring>
 
 #include "editing.h"
index 3d14d9617805ea72919ef7fd56afe90005158bb4..ab8940874ccd61f651bee76c0355924e5a180b55 100644 (file)
@@ -84,6 +84,7 @@
 #include "gui_thread.h"
 #include "simpleline.h"
 #include "rhythm_ferret.h"
+#include "actions.h"
 
 #ifdef FFT_ANALYSIS
 #include "analysis_window.h"
@@ -266,6 +267,7 @@ Editor::Editor ()
        clicked_control_point = 0;
        last_update_frame = 0;
        drag_info.item = 0;
+       drag_info.copied_location = 0;
        current_mixer_strip = 0;
        current_bbt_points = 0;
        
@@ -350,6 +352,13 @@ Editor::Editor ()
        select_new_marker = false;
        zoomed_to_region = false;
        rhythm_ferret = 0;
+       allow_vertical_scroll = false;
+       no_save_visual = false;
+       need_resize_line = false;
+       resize_line_y = 0;
+       old_resize_line_y = -1;
+       no_region_list_redisplay = false;
+       resize_idle_id = -1;
 
        _scrubbing = false;
        scrubbing_direction = 0;
@@ -370,8 +379,6 @@ Editor::Editor ()
        set_midi_edit_mode (MidiEditPencil, true);
        set_mouse_mode (MouseObject, true);
 
-       last_visual_state.frames_per_unit = 0;
-
        frames_per_unit = 2048; /* too early to use reset_zoom () */
        reset_hscrollbar_stepping ();
        
@@ -818,6 +825,7 @@ Editor::Editor ()
        ControlProtocol::ZoomIn.connect (bind (mem_fun (*this, &Editor::temporal_zoom_step), false));
        ControlProtocol::ZoomOut.connect (bind (mem_fun (*this, &Editor::temporal_zoom_step), true));
        ControlProtocol::ScrollTimeline.connect (mem_fun (*this, &Editor::control_scroll));
+       BasicUI::AccessAction.connect (mem_fun (*this, &Editor::access_action));
 
        Config->ParameterChanged.connect (mem_fun (*this, &Editor::parameter_changed));
        Route::SyncOrderKeys.connect (mem_fun (*this, &Editor::sync_order_keys));
@@ -850,6 +858,16 @@ Editor::~Editor()
                delete time_canvas;
                time_canvas = 0;
        }
+
+       if (track_canvas) {
+               delete track_canvas;
+               track_canvas = 0;
+       }
+
+       if (time_canvas) {
+               delete time_canvas;
+               time_canvas = 0;
+       }
 }
 
 void
@@ -971,10 +989,10 @@ Editor::zoom_adjustment_changed ()
 
        if (fpu < 1.0) {
                fpu = 1.0;
-               zoom_range_clock.set ((nframes_t) floor (fpu * canvas_width));
+               zoom_range_clock.set ((nframes64_t) floor (fpu * canvas_width));
        } else if (fpu > session->current_end_frame() / canvas_width) {
                fpu = session->current_end_frame() / canvas_width;
-               zoom_range_clock.set ((nframes_t) floor (fpu * canvas_width));
+               zoom_range_clock.set ((nframes64_t) floor (fpu * canvas_width));
        }
        
        temporal_zoom (fpu);
@@ -994,7 +1012,7 @@ Editor::control_scroll (float fraction)
        /*
                _control_scroll_target is an optional<T>
        
-               it acts like a pointer to an nframes_t, with
+               it acts like a pointer to an nframes64_t, with
                a operator conversion to boolean to check
                that it has a value could possibly use
                playhead_cursor->current_frame to store the
@@ -1007,12 +1025,12 @@ Editor::control_scroll (float fraction)
                _dragging_playhead = true;
        }
 
-       if ((fraction < 0.0f) && (*_control_scroll_target < (nframes_t) fabs(step))) {
+       if ((fraction < 0.0f) && (*_control_scroll_target < (nframes64_t) fabs(step))) {
                *_control_scroll_target = 0;
        } else if ((fraction > 0.0f) && (max_frames - *_control_scroll_target < step)) {
                *_control_scroll_target = max_frames - (current_page_frames()*2); // allow room for slop in where the PH is on the screen
        } else {
-               *_control_scroll_target += (nframes_t) floor (step);
+               *_control_scroll_target += (nframes64_t) floor (step);
        }
 
        /* move visuals, we'll catch up with it later */
@@ -1043,7 +1061,7 @@ Editor::control_scroll (float fraction)
 }
 
 bool
-Editor::deferred_control_scroll (nframes_t target)
+Editor::deferred_control_scroll (nframes64_t target)
 {
        session->request_locate (*_control_scroll_target, session->transport_rolling());
        // reset for next stream
@@ -1052,6 +1070,27 @@ Editor::deferred_control_scroll (nframes_t target)
        return false;
 }
 
+void
+Editor::access_action (std::string action_group, std::string action_item)
+{
+       if (!session) {
+               return;
+       }
+
+       ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::access_action), action_group, action_item));
+
+       cout<< "OSC: Recieved: "<< action_item << endl;
+
+       RefPtr<Action> act;
+       act = ActionManager::get_action( action_group.c_str(), action_item.c_str() );
+
+       if (act) {
+               act->activate();
+       }
+               
+
+}
+
 void
 Editor::on_realize ()
 {
@@ -1073,7 +1112,7 @@ Editor::stop_scrolling ()
 }
 
 void
-Editor::map_position_change (nframes_t frame)
+Editor::map_position_change (nframes64_t frame)
 {
        ENSURE_GUI_THREAD (bind (mem_fun(*this, &Editor::map_position_change), frame));
 
@@ -1086,7 +1125,7 @@ Editor::map_position_change (nframes_t frame)
 }      
 
 void
-Editor::center_screen (nframes_t frame)
+Editor::center_screen (nframes64_t frame)
 {
        double page = canvas_width * frames_per_unit;
 
@@ -1099,12 +1138,12 @@ Editor::center_screen (nframes_t frame)
 }
 
 void
-Editor::center_screen_internal (nframes_t frame, float page)
+Editor::center_screen_internal (nframes64_t frame, float page)
 {
        page /= 2;
                
        if (frame > page) {
-               frame -= (nframes_t) page;
+               frame -= (nframes64_t) page;
        } else {
                frame = 0;
        }
@@ -1117,7 +1156,7 @@ Editor::handle_new_duration ()
 {
        ENSURE_GUI_THREAD (mem_fun (*this, &Editor::handle_new_duration));
 
-       nframes_t new_end = session->get_maximum_extent() + (nframes_t) floorf (current_page_frames() * 0.10f);
+       nframes64_t new_end = session->get_maximum_extent() + (nframes64_t) floorf (current_page_frames() * 0.10f);
                                  
        if (new_end > last_canvas_frame) {
                last_canvas_frame = new_end;
@@ -1126,6 +1165,7 @@ Editor::handle_new_duration ()
        }
 
        horizontal_adjustment.set_value (leftmost_frame/frames_per_unit);
+       //cerr << "Editor::handle_new_duration () called ha v:l:u:ps:lcf = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << last_canvas_frame << endl;//DEBUG
 }
 
 void
@@ -1217,6 +1257,7 @@ Editor::connect_to_session (Session *t)
        zoom_range_clock.set_session (session);
        _playlist_selector->set_session (session);
        nudge_clock.set_session (session);
+       nudge_clock.set (session->frame_rate() * 5); // default of 5 seconds
 
        if (rhythm_ferret) {
                rhythm_ferret->set_session (session);
@@ -1471,10 +1512,10 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
 }
 
 void
-Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection, nframes_t frame)
+Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection, nframes64_t frame)
 {
        using namespace Menu_Helpers;
-       Menu* (Editor::*build_menu_function)(nframes_t);
+       Menu* (Editor::*build_menu_function)(nframes64_t);
        Menu *menu;
 
        switch (item_type) {
@@ -1590,7 +1631,7 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
 }
 
 Menu*
-Editor::build_track_context_menu (nframes_t ignored)
+Editor::build_track_context_menu (nframes64_t ignored)
 {
        using namespace Menu_Helpers;
 
@@ -1602,7 +1643,7 @@ Editor::build_track_context_menu (nframes_t ignored)
 }
 
 Menu*
-Editor::build_track_bus_context_menu (nframes_t ignored)
+Editor::build_track_bus_context_menu (nframes64_t ignored)
 {
        using namespace Menu_Helpers;
 
@@ -1614,7 +1655,7 @@ Editor::build_track_bus_context_menu (nframes_t ignored)
 }
 
 Menu*
-Editor::build_track_region_context_menu (nframes_t frame)
+Editor::build_track_region_context_menu (nframes64_t frame)
 {
        using namespace Menu_Helpers;
        MenuList& edit_items  = track_region_context_menu.items();
@@ -1627,10 +1668,20 @@ Editor::build_track_region_context_menu (nframes_t frame)
                boost::shared_ptr<Playlist> pl;
                
                if ((ds = rtv->get_diskstream()) && ((pl = ds->playlist()))) {
-                       Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)frame * ds->speed()));
-                       for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
-                               add_region_context_items (rtv->view(), (*i), edit_items);
+                       Playlist::RegionList* regions = pl->regions_at ((nframes64_t) floor ( (double)frame * ds->speed()));
+
+                       if (selection->regions.size() > 1) {
+                               // there's already a multiple selection: just add a 
+                               // single region context menu that will act on all 
+                               // selected regions
+                               boost::shared_ptr<Region> dummy_region; // = NULL               
+                               add_region_context_items (rtv->view(), dummy_region, edit_items);                       
+                       } else {
+                               for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+                                       add_region_context_items (rtv->view(), (*i), edit_items);
+                               }
                        }
+
                        delete regions;
                }
        }
@@ -1641,7 +1692,7 @@ Editor::build_track_region_context_menu (nframes_t frame)
 }
 
 Menu*
-Editor::build_track_crossfade_context_menu (nframes_t frame)
+Editor::build_track_crossfade_context_menu (nframes64_t frame)
 {
        using namespace Menu_Helpers;
        MenuList& edit_items  = track_crossfade_context_menu.items();
@@ -1667,10 +1718,17 @@ Editor::build_track_crossfade_context_menu (nframes_t frame)
                                add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
                        }
 
-                       for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
-                               add_region_context_items (atv->audio_view(), (*i), edit_items);
+                       if (selection->regions.size() > 1) {
+                               // there's already a multiple selection: just add a 
+                               // single region context menu that will act on all 
+                               // selected regions
+                               boost::shared_ptr<Region> dummy_region; // = NULL               
+                               add_region_context_items (atv->audio_view(), dummy_region, edit_items);                 
+                       } else {
+                               for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+                                       add_region_context_items (atv->audio_view(), (*i), edit_items);
+                               }
                        }
-
                        delete regions;
                }
        }
@@ -1719,7 +1777,7 @@ Editor::analyze_range_selection()
 #endif /* FFT_ANALYSIS */
 
 Menu*
-Editor::build_track_selection_context_menu (nframes_t ignored)
+Editor::build_track_selection_context_menu (nframes64_t ignored)
 {
        using namespace Menu_Helpers;
        MenuList& edit_items  = track_selection_context_menu.items();
@@ -1820,16 +1878,18 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
        if (region) {
                ar = boost::dynamic_pointer_cast<AudioRegion> (region);
                mr = boost::dynamic_pointer_cast<MidiRegion> (region);
-       }
 
-       /* when this particular menu pops up, make the relevant region 
-          become selected.
-       */
+               /* when this particular menu pops up, make the relevant region 
+                  become selected.
+               */
 
-       region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+               region_menu->signal_map_event().connect (
+                       bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+               
+               items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
+               items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
+       }
 
-       items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
-       items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
        items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
        items.push_back (MenuElem (_("Lower to bottom layer"), mem_fun  (*this, &Editor::lower_region_to_bottom)));
        items.push_back (SeparatorElem());
@@ -1851,49 +1911,61 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
 
        sigc::connection fooc;
 
-       items.push_back (CheckMenuElem (_("Lock")));
-       CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
-       if (region->locked()) {
-               region_lock_item->set_active();
-       }
-       region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
+       if (region) {
+               items.push_back (CheckMenuElem (_("Lock")));
+               CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
+               if (region->locked()) {
+                       region_lock_item->set_active();
+               }
+               region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
 
-       items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
-       CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
+               items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
+               CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
 
-       switch (region->positional_lock_style()) {
-       case Region::MusicTime:
-               bbt_glue_item->set_active (true);
-               break;
-       default:
-               bbt_glue_item->set_active (false);
-               break;
-       }
+               switch (region->positional_lock_style()) {
+               case Region::MusicTime:
+                       bbt_glue_item->set_active (true);
+                       break;
+               default:
+                       bbt_glue_item->set_active (false);
+                       break;
+               }
 
-       bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
+               bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
 
-       items.push_back (CheckMenuElem (_("Mute")));
-       CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
-       fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
-       if (region->muted()) {
-               fooc.block (true);
-               region_mute_item->set_active();
-               fooc.block (false);
-       }
-       
-       if (!Profile->get_sae()) {
-               items.push_back (CheckMenuElem (_("Opaque")));
-               CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
-               fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
-               if (region->opaque()) {
+               items.push_back (CheckMenuElem (_("Mute")));
+               CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
+               fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
+               if (region->muted()) {
                        fooc.block (true);
-                       region_opaque_item->set_active();
+                       region_mute_item->set_active();
                        fooc.block (false);
                }
+       
+               if (!Profile->get_sae()) {
+                       items.push_back (CheckMenuElem (_("Opaque")));
+                       CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
+                       fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
+                       if (region->opaque()) {
+                               fooc.block (true);
+                               region_opaque_item->set_active();
+                               fooc.block (false);
+                       }
+               }
+       } else {
+               // multiple regions selected
+               // how should these act? 
+               // here they toggle the property of all selected regions
+       
+               items.push_back (MenuElem (_("Lock"), mem_fun(*this, &Editor::toggle_region_lock)));
+               items.push_back (MenuElem (_("Mute"), mem_fun(*this, &Editor::toggle_region_mute)));
+               if (!Profile->get_sae()) {
+                       items.push_back (MenuElem (_("Opaque"), mem_fun(*this, &Editor::toggle_region_opaque)));
+               }
        }
 
        items.push_back (CheckMenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize)));
-       if (region->at_natural_position()) {
+       if (region && region->at_natural_position()) {
                items.back().set_sensitive (false);
        }
        
@@ -1985,7 +2057,7 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
        items.push_back (MenuElem (_("Multi-Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), true))));
        items.push_back (MenuElem (_("Fill Track"), (mem_fun(*this, &Editor::region_fill_track))));
        items.push_back (SeparatorElem());
-       items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_clicked_region)));
+       items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_selected_regions)));
 
        /* OK, stick the region submenu at the top of the list, and then add
           the standard items.
@@ -1996,7 +2068,7 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
        */
 
        string::size_type pos = 0;
-       string menu_item_name = region->name();
+       string menu_item_name = (region) ? region->name() : _("Selected regions");
 
        while ((pos = menu_item_name.find ("_", pos)) != string::npos) {
                menu_item_name.replace (pos, 1, "__");
@@ -2049,7 +2121,8 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items)
        items.push_back (MenuElem (_("Duplicate range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false)));
        items.push_back (MenuElem (_("Create chunk from range"), mem_fun(*this, &Editor::create_named_selection)));
        items.push_back (SeparatorElem());
-       items.push_back (MenuElem (_("Bounce range"), mem_fun(*this, &Editor::bounce_range_selection)));
+       items.push_back (MenuElem (_("Consolidate range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true)));
+       items.push_back (MenuElem (_("Bounce range to region list"), bind (mem_fun(*this, &Editor::bounce_range_selection), false)));
        items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_selection)));
 }
 
@@ -2199,8 +2272,9 @@ Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items)
 
 void
 Editor::set_snap_to (SnapType st)
-{      
+{
        unsigned int snap_ind = (unsigned int)st;
+
        snap_type = st;
        
        if (snap_ind > snap_type_strings.size() - 1) {
@@ -2355,7 +2429,7 @@ Editor::set_state (const XMLNode& node)
        move (x, y);
 
        if (session && (prop = node.property ("playhead"))) {
-               nframes_t pos = atol (prop->value().c_str());
+               nframes64_t pos = atol (prop->value().c_str());
                playhead_cursor->set_position (pos);
        } else {
                playhead_cursor->set_position (0);
@@ -2546,7 +2620,7 @@ Editor::get_state ()
 
        node->add_property ("edit-point", enum_2_string (_edit_point));
 
-       snprintf (buf, sizeof (buf), "%" PRIu32, playhead_cursor->current_frame);
+       snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame);
        node->add_property ("playhead", buf);
 
        node->add_property ("show-waveforms", _show_waveforms ? "yes" : "no");
@@ -2614,17 +2688,17 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
        switch (snap_type) {
        case SnapToCDFrame:
                if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
-                       start = (nframes_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
+                       start = (nframes64_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
                } else {
-                       start = (nframes_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
+                       start = (nframes64_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
                }
                break;
 
        case SnapToSMPTEFrame:
                if (((direction == 0) && (fmod((double)start, (double)session->frames_per_smpte_frame()) > (session->frames_per_smpte_frame() / 2))) || (direction > 0)) {
-                       start = (nframes_t) (ceil ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
+                       start = (nframes64_t) (ceil ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
                } else {
-                       start = (nframes_t) (floor ((double) start / session->frames_per_smpte_frame()) *  session->frames_per_smpte_frame());
+                       start = (nframes64_t) (floor ((double) start / session->frames_per_smpte_frame()) *  session->frames_per_smpte_frame());
                }
                break;
 
@@ -2636,9 +2710,9 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
                        start -= session->smpte_offset ();
                }    
                if (((direction == 0) && (start % one_smpte_second > one_smpte_second / 2)) || direction > 0) {
-                       start = (nframes_t) ceil ((double) start / one_smpte_second) * one_smpte_second;
+                       start = (nframes64_t) ceil ((double) start / one_smpte_second) * one_smpte_second;
                } else {
-                       start = (nframes_t) floor ((double) start / one_smpte_second) * one_smpte_second;
+                       start = (nframes64_t) floor ((double) start / one_smpte_second) * one_smpte_second;
                }
                
                if (session->smpte_offset_negative())
@@ -2657,9 +2731,9 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
                        start -= session->smpte_offset ();
                }
                if (((direction == 0) && (start % one_smpte_minute > one_smpte_minute / 2)) || direction > 0) {
-                       start = (nframes_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute;
+                       start = (nframes64_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute;
                } else {
-                       start = (nframes_t) floor ((double) start / one_smpte_minute) * one_smpte_minute;
+                       start = (nframes64_t) floor ((double) start / one_smpte_minute) * one_smpte_minute;
                }
                if (session->smpte_offset_negative())
                {
@@ -2671,17 +2745,17 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
                
        case SnapToSeconds:
                if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) {
-                       start = (nframes_t) ceil ((double) start / one_second) * one_second;
+                       start = (nframes64_t) ceil ((double) start / one_second) * one_second;
                } else {
-                       start = (nframes_t) floor ((double) start / one_second) * one_second;
+                       start = (nframes64_t) floor ((double) start / one_second) * one_second;
                }
                break;
                
        case SnapToMinutes:
                if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) {
-                       start = (nframes_t) ceil ((double) start / one_minute) * one_minute;
+                       start = (nframes64_t) ceil ((double) start / one_minute) * one_minute;
                } else {
-                       start = (nframes_t) floor ((double) start / one_minute) * one_minute;
+                       start = (nframes64_t) floor ((double) start / one_minute) * one_minute;
                }
                break;
 
@@ -2758,7 +2832,7 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
        case SnapToRegionSync:
        case SnapToRegionBoundary:
                if (!region_boundary_cache.empty()) {
-                       vector<nframes_t>::iterator i;
+                       vector<nframes64_t>::iterator i;
 
                        if (direction > 0) {
                                i = std::upper_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start);
@@ -2808,7 +2882,7 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
 }
 
 double
-Editor::snap_length_beats (nframes_t start)
+Editor::snap_length_beats (nframes64_t start)
 {
        if (!session) {
                return 1.0;
@@ -3685,6 +3759,8 @@ Editor::zoom_focus_selection_done ()
                focus_type = ZoomFocusEdit;
        } else if (choice == _("Active Mark")) {
                focus_type = ZoomFocusEdit;
+       } else if (choice == _("Active Mark")) {
+               focus_type = ZoomFocusEdit;
        } else {
                focus_type = ZoomFocusMouse;
        } 
@@ -3923,10 +3999,10 @@ Editor::playlist_selector () const
        return *_playlist_selector;
 }
 
-nframes_t
-Editor::get_nudge_distance (nframes_t pos, nframes_t& next)
+nframes64_t
+Editor::get_nudge_distance (nframes64_t pos, nframes64_t& next)
 {
-       nframes_t ret;
+       nframes64_t ret;
 
        ret = nudge_clock.current_duration (pos);
        next = ret + 1; /* XXXX fix me */
@@ -3978,7 +4054,7 @@ Editor::playlist_deletion_dialog (boost::shared_ptr<Playlist> pl)
 }
 
 bool
-Editor::audio_region_selection_covers (nframes_t where)
+Editor::audio_region_selection_covers (nframes64_t where)
 {
        for (RegionSelection::iterator a = selection->regions.begin(); a != selection->regions.end(); ++a) {
                if ((*a)->region()->covers (where)) {
@@ -3997,6 +4073,15 @@ Editor::prepare_for_cleanup ()
 
        selection->clear_regions ();
        selection->clear_playlists ();
+
+       no_region_list_redisplay = true;
+}
+
+void
+Editor::finish_cleanup ()
+{
+       no_region_list_redisplay = false;
+       redisplay_regions ();
 }
 
 Location*
@@ -4212,8 +4297,8 @@ Editor::maximise_editing_space ()
                post_maximal_pane_position = edit_pane.get_width();
        }
 
-
        fullscreen();
+
        if(post_maximal_editor_width) {
                edit_pane.set_position (post_maximal_pane_position - 
                        abs(post_maximal_editor_width - pre_maximal_editor_width));
@@ -4318,7 +4403,7 @@ Editor::on_key_release_event (GdkEventKey* ev)
 }
 
 void
-Editor::reset_x_origin (nframes_t frame)
+Editor::reset_x_origin (nframes64_t frame)
 {
        queue_visual_change (frame);
 }
@@ -4330,28 +4415,97 @@ Editor::reset_zoom (double fpu)
 }
 
 void
-Editor::reposition_and_zoom (nframes_t frame, double fpu)
+Editor::reposition_and_zoom (nframes64_t frame, double fpu)
 {
+       //cerr << "Editor::reposition_and_zoom () called ha v:l:u:ps:fpu = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << frames_per_unit << endl;//DEBUG
        reset_x_origin (frame);
        reset_zoom (fpu);
+
+       if (!no_save_visual) {
+               undo_visual_stack.push_back (current_visual_state(false));
+       }
+}
+
+Editor::VisualState*
+Editor::current_visual_state (bool with_tracks)
+{
+       VisualState* vs = new VisualState;
+       vs->y_position = vertical_adjustment.get_value();
+       vs->frames_per_unit = frames_per_unit;
+       vs->leftmost_frame = leftmost_frame;
+       vs->zoom_focus = zoom_focus;
+       vs->zoomed_to_region = zoomed_to_region;
+
+       if (with_tracks) {
+               for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                       vs->track_states.push_back (TAVState ((*i), &(*i)->get_state()));
+               }
+       }
+       
+       return vs;
 }
 
 void
-Editor::swap_visual_state ()
+Editor::undo_visual_state ()
 {
-       if (last_visual_state.frames_per_unit == 0) {
-               // never set
+       if (undo_visual_stack.empty()) {
                return;
        }
 
-       /* note: the correct functionality here is very dependent on the ordering of 
-          setting zoom focus, horizontal position and finally zoom. this is because
-          it is set_frames_per_unit() that overwrites last_visual_state.
-       */
+       VisualState* vs = undo_visual_stack.back();
+       undo_visual_stack.pop_back();
+       use_visual_state (*vs);
+       redo_visual_stack.push_back (vs);
+}
 
-       set_zoom_focus (last_visual_state.zoom_focus);
-       reposition_and_zoom (last_visual_state.leftmost_frame, last_visual_state.frames_per_unit);
-       zoomed_to_region = false;
+void
+Editor::redo_visual_state ()
+{
+       if (redo_visual_stack.empty()) {
+               return;
+       }
+
+       VisualState* vs = redo_visual_stack.back();
+       redo_visual_stack.pop_back();
+       use_visual_state (*vs);
+       undo_visual_stack.push_back (vs);
+}
+
+void
+Editor::swap_visual_state ()
+{
+       if (undo_visual_stack.empty()) {
+               redo_visual_state ();
+       } else {
+               undo_visual_state ();
+       }
+}
+
+void
+Editor::use_visual_state (VisualState& vs)
+{
+       no_save_visual = true;
+
+       vertical_adjustment.set_value (vs.y_position);
+
+       set_zoom_focus (vs.zoom_focus);
+       reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit);
+
+       for (list<TAVState>::iterator i = vs.track_states.begin(); i != vs.track_states.end(); ++i) {
+               TrackViewList::iterator t;
+
+               /* check if the track still exists - it could have been deleted */
+
+               if ((t = find (track_views.begin(), track_views.end(), i->first)) != track_views.end()) {
+                       (*t)->set_state (*(i->second));
+               }
+       }
+
+       if (!vs.track_states.empty()) {
+               update_route_visibility ();
+       } 
+       
+       no_save_visual = false;
 }
 
 void
@@ -4381,10 +4535,6 @@ Editor::set_frames_per_unit (double fpu)
        if (fpu == frames_per_unit) {
                return;
        }
-       
-       last_visual_state.frames_per_unit = frames_per_unit;
-       last_visual_state.leftmost_frame = leftmost_frame;
-       last_visual_state.zoom_focus = zoom_focus;
 
        frames_per_unit = fpu;
        post_zoom ();
@@ -4395,7 +4545,7 @@ Editor::post_zoom ()
 {
        // convert fpu to frame count
 
-       nframes_t frames = (nframes_t) floor (frames_per_unit * canvas_width);
+       nframes64_t frames = (nframes64_t) floor (frames_per_unit * canvas_width);
 
        if (frames_per_unit != zoom_range_clock.current_duration()) {
                zoom_range_clock.set (frames);
@@ -4424,11 +4574,11 @@ Editor::post_zoom ()
 }
 
 void
-Editor::queue_visual_change (nframes_t where)
+Editor::queue_visual_change (nframes64_t where)
 {
        pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
        pending_visual_change.time_origin = where;
-       
+
        if (pending_visual_change.idle_handler_id < 0) {
                pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this);
        }
@@ -4456,6 +4606,12 @@ int
 Editor::idle_visual_changer ()
 {
        VisualChange::Type p = pending_visual_change.pending;
+       nframes64_t csf, cef;
+
+       if (session) {
+               csf = session->current_start_frame();
+               cef = session->current_end_frame() + (current_page_frames() / 24);// Add a little extra so we can see the end marker
+       }
 
        pending_visual_change.pending = (VisualChange::Type) 0;
 
@@ -4469,17 +4625,26 @@ Editor::idle_visual_changer ()
        }
        if (p & VisualChange::TimeOrigin) {
                
-               nframes_t time_origin = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+               nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+
+               /* if we seek beyond the current end of the canvas, move the end */
 
                if (time_origin != pending_visual_change.time_origin) {
+                       
+                       if (horizontal_adjustment.get_upper() < pending_visual_change.time_origin) {
+                               last_canvas_frame = (cef > (pending_visual_change.time_origin + current_page_frames())) ? cef : pending_visual_change.time_origin + current_page_frames();
+                               horizontal_adjustment.set_upper ((cef - csf) / frames_per_unit);
+                               reset_scrolling_region ();
+                       }
+                       
                        horizontal_adjustment.set_value (pending_visual_change.time_origin/frames_per_unit);
                } else {
                        update_fixed_rulers();
                        redisplay_tempo (true);
                }
        }
-       pending_visual_change.idle_handler_id = -1;
 
+       pending_visual_change.idle_handler_id = -1;
        return 0; /* this is always a one-shot call */
 }
 
@@ -4550,7 +4715,7 @@ Editor::get_preferred_edit_position (bool ignore_playhead)
 }
 
 void
-Editor::set_loop_range (nframes_t start, nframes_t end, string cmd)
+Editor::set_loop_range (nframes64_t start, nframes64_t end, string cmd)
 {
        if (!session) return;
 
@@ -4577,7 +4742,7 @@ Editor::set_loop_range (nframes_t start, nframes_t end, string cmd)
 }
 
 void
-Editor::set_punch_range (nframes_t start, nframes_t end, string cmd)
+Editor::set_punch_range (nframes64_t start, nframes64_t end, string cmd)
 {
        if (!session) return;
 
@@ -4625,14 +4790,14 @@ Editor::get_regions_at (RegionSelection& rs, nframes64_t where, const TrackSelec
                        
                        if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
 
-                               Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)where * ds->speed()));
+                               Playlist::RegionList* regions = pl->regions_at ((nframes64_t) floor ( (double)where * ds->speed()));
 
                                for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
 
                                        RegionView* rv = atv->audio_view()->find_view (*i);
 
                                        if (rv) {
-                                               rs.push_back (rv);
+                                               rs.add (rv);
                                        }
                                }
 
@@ -4663,7 +4828,7 @@ Editor::get_regions_after (RegionSelection& rs, nframes64_t where, const TrackSe
                        
                        if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
 
-                               Playlist::RegionList* regions = pl->regions_touched ((nframes_t) floor ( (double)where * ds->speed()), max_frames);
+                               Playlist::RegionList* regions = pl->regions_touched ((nframes64_t) floor ( (double)where * ds->speed()), max_frames);
 
                                for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
 
@@ -4809,3 +4974,170 @@ Editor::first_idle ()
 
        _have_idled = true;
 }
+
+void
+Editor::start_resize_line_ops ()
+{
+#if 0
+       old_resize_line_y = -1;
+       resize_line_y = -1;
+       need_resize_line = true;
+#endif 
+}
+
+void
+Editor::end_resize_line_ops ()
+{
+#if 0
+       need_resize_line = false;
+
+       if (old_resize_line_y >= 0) {
+               Gdk::Rectangle r (0, old_resize_line_y, (int) canvas_width, 3);
+               Glib::RefPtr<Gdk::Window> win = get_window();
+               cerr << "Final invalidation at " << old_resize_line_y << endl;
+               win->invalidate_rect (r, false);
+       }
+#endif
+}
+
+void
+Editor::queue_draw_resize_line (int at)
+{
+#if 0  
+       Glib::RefPtr<Gdk::Window> win = get_window();
+
+       resize_line_y = at;
+
+       if (win && canvas_width) {
+
+               int controls_width = controls_layout.get_width();
+               int xroot, discard;
+               
+               controls_layout.get_window()->get_origin (xroot, discard);
+
+               if (old_resize_line_y >= 0) {
+                       
+                       /* redraw where it used to be */
+                       
+                       
+                       Gdk::Rectangle r (xroot, old_resize_line_y - 1, controls_width + (int) canvas_width, 3);
+                       win->invalidate_rect (r, true);
+                       cerr << "invalidate " << xroot << "," << old_resize_line_y - 1 << ' ' 
+                            << controls_width + canvas_width << " x 3\n";
+               }
+
+               /* draw where it is */
+
+               Gdk::Rectangle r (xroot, at - 1, controls_width + (int) canvas_width, 3);
+               win->invalidate_rect (r, true);
+       }
+#endif
+}
+
+bool
+Editor::on_expose_event (GdkEventExpose* ev)
+{
+       /* cerr << "+++ editor expose "
+            << ev->area.x << ',' << ev->area.y
+            << ' '
+            << ev->area.width << " x " << ev->area.height
+            << " need reize ? " << need_resize_line
+            << endl;
+       */
+       bool ret = Window::on_expose_event (ev);
+
+#if 0
+       if (need_resize_line) {
+               
+               int xroot, yroot, discard;
+               int controls_width;
+
+               /* Our root coordinates for drawing the line will be the left edge 
+                  of the track controls, and the upper left edge of our own window.
+               */
+
+               get_window()->get_origin (discard, yroot);
+               controls_layout.get_window()->get_origin (xroot, discard);
+               controls_width = controls_layout.get_width();
+               
+               GdkRectangle lr;
+               GdkRectangle intersection;
+
+               lr.x = xroot;
+               lr.y = resize_line_y;
+               lr.width = controls_width + (int) canvas_width;
+               lr.height = 3;
+
+               if (gdk_rectangle_intersect (&lr, &ev->area, &intersection)) {
+                       
+                       Glib::RefPtr<Gtk::Style> style (get_style());
+                       Glib::RefPtr<Gdk::GC> black_gc (style->get_black_gc ());
+                       Glib::RefPtr<Gdk::GC> gc = wrap (black_gc->gobj_copy(), false);
+
+                       /* draw on root window */
+
+                       GdkWindow* win = gdk_get_default_root_window();
+                       
+                       gc->set_subwindow (Gdk::INCLUDE_INFERIORS);
+                       gc->set_line_attributes (3, Gdk::LINE_SOLID, 
+                                                Gdk::CAP_NOT_LAST,
+                                                Gdk::JOIN_MITER);
+                       
+                       gdk_draw_line (win, gc->gobj(), 
+                                      xroot,
+                                      yroot + resize_line_y, 
+                                      xroot + (int) canvas_width + controls_width,
+                                      yroot + resize_line_y);
+                       cerr << "drew line @ " << xroot << ", " << yroot + resize_line_y 
+                            << " to " << xroot + (int) canvas_width + controls_width
+                            << ", " << yroot + resize_line_y
+                            << endl;
+                       old_resize_line_y = yroot + resize_line_y;
+                       cerr << "NEXT EXPOSE SHOULD BE AT " << old_resize_line_y << endl;
+               } else {
+                       cerr << "no intersect with "
+                            << lr.x << ',' << lr.y
+                            << ' '
+                            << lr.width << " x " << lr.height
+                            << endl;
+               }
+       }
+
+       //cerr << "--- editor expose\n";
+#endif
+
+       return ret;
+}
+
+static gboolean
+_idle_resizer (gpointer arg)
+{
+       return ((Editor*)arg)->idle_resize ();
+}
+
+void
+Editor::add_to_idle_resize (TimeAxisView* view, uint32_t h)
+{
+       if (resize_idle_id < 0) {
+               resize_idle_id = g_idle_add (_idle_resizer, this);
+       }
+
+       resize_idle_target = h;
+
+       pending_resizes.push_back (view);
+
+       if (selection->selected (view) && !selection->tracks.empty()) {
+               pending_resizes.insert (pending_resizes.end(), selection->tracks.begin(), selection->tracks.end());
+       }
+}
+
+bool
+Editor::idle_resize ()
+{
+       for (vector<TimeAxisView*>::iterator i = pending_resizes.begin(); i != pending_resizes.end(); ++i) {
+               (*i)->idle_resize (resize_idle_target);
+       }
+       pending_resizes.clear();
+       resize_idle_id = -1;
+       return false;
+}
index 2c7e32d19e24bd5323ec5cabaab50c03d6eb6014..e8af889ad12de63e8719a9685846baa4e21471bd 100644 (file)
@@ -136,9 +136,9 @@ class Editor : public PublicEditor
        void             first_idle ();
        virtual bool have_idled() const { return _have_idled; }
 
-       nframes_t leftmost_position() const { return leftmost_frame; }
-       nframes_t current_page_frames() const {
-               return (nframes_t) floor (canvas_width * frames_per_unit);
+       nframes64_t leftmost_position() const { return leftmost_frame; }
+       nframes64_t current_page_frames() const {
+               return (nframes64_t) floor (canvas_width * frames_per_unit);
        }
 
        void cycle_snap_mode ();
@@ -170,6 +170,7 @@ class Editor : public PublicEditor
 
        TimeAxisView* get_named_time_axis(const std::string & name) ;
        void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>);
+       void add_to_idle_resize (TimeAxisView*, uint32_t);
 
        RouteTimeAxisView* get_route_view_by_id (PBD::ID& id);
 
@@ -204,11 +205,11 @@ class Editor : public PublicEditor
 
        /* undo related */
 
-       nframes_t unit_to_frame (double unit) const {
-               return (nframes_t) rint (unit * frames_per_unit);
+       nframes64_t unit_to_frame (double unit) const {
+               return (nframes64_t) rint (unit * frames_per_unit);
        }
        
-       double frame_to_unit (nframes_t frame) const {
+       double frame_to_unit (nframes64_t frame) const {
                return rint ((double) frame / (double) frames_per_unit);
        }
 
@@ -232,7 +233,7 @@ class Editor : public PublicEditor
                */
 
                if (pixel >= 0) {
-                       return (nframes_t) rint (pixel * frames_per_unit * GNOME_CANVAS(track_canvas->gobj())->pixels_per_unit);
+                       return (nframes64_t) rint (pixel * frames_per_unit * GNOME_CANVAS(track_canvas->gobj())->pixels_per_unit);
                } else {
                        return 0;
                }
@@ -304,7 +305,7 @@ class Editor : public PublicEditor
        void show_editor_mixer (bool yn);
        void show_editor_list (bool yn);
        void set_selected_mixer_strip (TimeAxisView&);
-       void hide_track_in_display (TimeAxisView& tv);
+       void hide_track_in_display (TimeAxisView& tv, bool temporary = false);
        void show_track_in_display (TimeAxisView& tv);
 
        /* nudge is initiated by transport controls owned by ARDOUR_UI */
@@ -370,13 +371,14 @@ class Editor : public PublicEditor
 
        bool new_regionviews_display_gain () { return _new_regionviews_show_envelope; }
        void prepare_for_cleanup ();
+       void finish_cleanup ();
 
        void maximise_editing_space();
        void restore_editing_space();
 
-       void reset_x_origin (nframes_t);
+       void reset_x_origin (nframes64_t);
        void reset_zoom (double);
-       void reposition_and_zoom (nframes_t, double);
+       void reposition_and_zoom (nframes64_t, double);
 
        nframes64_t get_preferred_edit_position (bool ignore_playhead = false);
 
@@ -387,11 +389,19 @@ class Editor : public PublicEditor
 
        void show_rhythm_ferret();
 
+       void goto_visual_state (uint32_t);
+       void save_visual_state (uint32_t);
+
+       void queue_draw_resize_line (int at);
+       void start_resize_line_ops ();
+       void end_resize_line_ops ();
+
   protected:
        void map_transport_state ();
-       void map_position_change (nframes_t);
+       void map_position_change (nframes64_t);
 
        void on_realize();
+       bool on_expose_event (GdkEventExpose*);
 
   private:
 
@@ -401,25 +411,41 @@ class Editor : public PublicEditor
        bool                 constructed;
 
        // to keep track of the playhead position for control_scroll
-       boost::optional<nframes_t> _control_scroll_target;
+       boost::optional<nframes64_t> _control_scroll_target;
  
        PlaylistSelector* _playlist_selector;
 
+       typedef std::pair<TimeAxisView*,XMLNode*> TAVState;
+
        struct VisualState {
-           double    frames_per_unit;
-           nframes_t leftmost_frame;
-           Editing::ZoomFocus zoom_focus;
+           double              y_position;
+           double              frames_per_unit;
+           nframes64_t         leftmost_frame;
+           Editing::ZoomFocus  zoom_focus;
+           bool                zoomed_to_region;
+           std::list<TAVState> track_states;
        };
        
-       VisualState last_visual_state;
+       std::list<VisualState*> undo_visual_stack;
+       std::list<VisualState*> redo_visual_stack;
+       VisualState* current_visual_state (bool with_tracks = true);
+       void undo_visual_state ();
+       void redo_visual_state ();
+       void use_visual_state (VisualState&);
+       bool no_save_visual;
+       void swap_visual_state ();
+       
+       std::vector<VisualState*> visual_states;
+       sigc::connection visual_state_op_connection;
+       void start_visual_state_op (uint32_t n);
+       void cancel_visual_state_op (uint32_t n);
+       bool end_visual_state_op (uint32_t n);
 
-       nframes_t   leftmost_frame;
+       nframes64_t leftmost_frame;
        double      frames_per_unit;
        Editing::ZoomFocus zoom_focus;
 
-       void use_visual_state (const VisualState&);
        void set_frames_per_unit (double);
-       void swap_visual_state ();
        void post_zoom ();
 
        Editing::MouseMode mouse_mode;
@@ -469,7 +495,7 @@ class Editor : public PublicEditor
            void hide();
            void show ();
            void set_name (const string&);
-           void set_position (nframes_t start, nframes_t end = 0);
+           void set_position (nframes64_t start, nframes64_t end = 0);
            void set_color_rgba (uint32_t);
        };
 
@@ -482,7 +508,8 @@ class Editor : public PublicEditor
 
        void hide_marker (ArdourCanvas::Item*, GdkEvent*);
        void clear_marker_display ();
-       void mouse_add_new_marker (nframes_t where, bool is_cd=false, bool is_xrun=false);
+       void mouse_add_new_marker (nframes64_t where, bool is_cd=false, bool is_xrun=false);
+       bool choose_new_marker_name(string &name);
        void update_cd_marker_display ();
        void ensure_cd_marker_updated (LocationMarkers * lam, ARDOUR::Location * location);
 
@@ -542,12 +569,12 @@ class Editor : public PublicEditor
        Gtk::Menu * track_edit_playlist_submenu;
        Gtk::Menu * track_selection_edit_playlist_submenu;
 
-       void popup_track_context_menu (int, int, ItemType, bool, nframes_t);
-       Gtk::Menu* build_track_context_menu (nframes_t);
-       Gtk::Menu* build_track_bus_context_menu (nframes_t);
-       Gtk::Menu* build_track_region_context_menu (nframes_t frame);
-       Gtk::Menu* build_track_crossfade_context_menu (nframes_t);
-       Gtk::Menu* build_track_selection_context_menu (nframes_t);
+       void popup_track_context_menu (int, int, ItemType, bool, nframes64_t);
+       Gtk::Menu* build_track_context_menu (nframes64_t);
+       Gtk::Menu* build_track_bus_context_menu (nframes64_t);
+       Gtk::Menu* build_track_region_context_menu (nframes64_t frame);
+       Gtk::Menu* build_track_crossfade_context_menu (nframes64_t);
+       Gtk::Menu* build_track_selection_context_menu (nframes64_t);
        void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
        void add_bus_context_items (Gtk::Menu_Helpers::MenuList&);
        void add_region_context_items (StreamView*, boost::shared_ptr<ARDOUR::Region>, Gtk::Menu_Helpers::MenuList&);
@@ -564,6 +591,10 @@ class Editor : public PublicEditor
        Gtk::VBox           global_vpacker;
        Gtk::VBox           vpacker;
 
+       bool need_resize_line;
+       int  resize_line_y;
+       int  old_resize_line_y;
+
        Gdk::Cursor*          current_canvas_cursor;
        void set_canvas_cursor ();
        Gdk::Cursor* which_grabber_cursor ();
@@ -643,7 +674,7 @@ class Editor : public PublicEditor
        void compute_fixed_ruler_scale (); //calculates the RulerScale of the fixed rulers
        void update_fixed_rulers ();
        void update_tempo_based_rulers (); 
-       void popup_ruler_menu (nframes_t where = 0, ItemType type = RegionItem);
+       void popup_ruler_menu (nframes64_t where = 0, ItemType type = RegionItem);
        void update_ruler_visibility ();
        void set_ruler_visible (RulerType, bool);
        void toggle_ruler_visibility (RulerType rt);
@@ -704,7 +735,7 @@ class Editor : public PublicEditor
        gint bbt_nmarks;
        uint32_t bbt_bar_helper_on;
        uint32_t bbt_accent_modulo;
-       void compute_bbt_ruler_scale (nframes_t lower, nframes_t upper);
+       void compute_bbt_ruler_scale (nframes64_t lower, nframes64_t upper);
 
        gint metric_get_smpte (GtkCustomRulerMark **, gdouble, gdouble, gint);
        gint metric_get_bbt (GtkCustomRulerMark **, gdouble, gdouble, gint);
@@ -752,13 +783,13 @@ class Editor : public PublicEditor
            Editor&               editor;
            ArdourCanvas::Points  points;
            ArdourCanvas::Line    canvas_item;
-           nframes_t        current_frame;
+           nframes64_t           current_frame;
            double                length;
 
            Cursor (Editor&, bool (Editor::*)(GdkEvent*,ArdourCanvas::Item*));
            ~Cursor ();
 
-           void set_position (nframes_t);
+           void set_position (nframes64_t);
            void set_length (double units);
            void set_y_axis (double position);
        };
@@ -793,14 +824,12 @@ class Editor : public PublicEditor
        void    select_all_selectables_between (bool within);
        void    select_range_between ();
 
-       boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
+       boost::shared_ptr<ARDOUR::Region> find_next_region (nframes64_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
        nframes64_t find_next_region_boundary (nframes64_t, int32_t dir, const TrackViewList&);
 
-       vector<nframes_t> region_boundary_cache;
+       vector<nframes64_t> region_boundary_cache;
        void build_region_boundary_cache ();
 
-       Gtk::VBox           trackview_vpacker;
-
        Gtk::HBox           top_hbox;
        Gtk::HBox           bottom_hbox;
        
@@ -826,7 +855,7 @@ class Editor : public PublicEditor
        double canvas_width;
        double canvas_height;
        double full_canvas_height;
-       nframes_t last_canvas_frame;
+       nframes64_t last_canvas_frame;
 
        bool track_canvas_map_handler (GdkEventAny*);
        bool time_canvas_map_handler (GdkEventAny*);
@@ -841,7 +870,8 @@ class Editor : public PublicEditor
        Gtk::HBox           edit_controls_hbox;
 
        void control_scroll (float);
-       bool deferred_control_scroll (nframes_t);
+       void access_action (std::string,std::string);
+       bool deferred_control_scroll (nframes64_t);
        sigc::connection control_scroll_connection;
 
        void tie_vertical_scrolling ();
@@ -855,7 +885,7 @@ class Editor : public PublicEditor
            };
 
            Type pending;
-           nframes_t time_origin;
+           nframes64_t time_origin;
            double frames_per_unit;
 
            int idle_handler_id;
@@ -869,7 +899,7 @@ class Editor : public PublicEditor
        static int _idle_visual_changer (void *arg);
        int idle_visual_changer ();
 
-       void queue_visual_change (nframes_t);
+       void queue_visual_change (nframes64_t);
        void queue_visual_change (double);
 
        void end_location_changed (ARDOUR::Location*);
@@ -999,16 +1029,16 @@ class Editor : public PublicEditor
        static void build_cursors ();
 
        sigc::connection scroll_connection;
-       nframes_t last_update_frame;
-       void center_screen (nframes_t);
-       void center_screen_internal (nframes_t, float);
+       nframes64_t last_update_frame;
+       void center_screen (nframes64_t);
+       void center_screen_internal (nframes64_t, float);
        
        void update_current_screen ();
        
        void session_going_away ();
 
-       nframes_t cut_buffer_start;
-       nframes_t cut_buffer_length;
+       nframes64_t cut_buffer_start;
+       nframes64_t cut_buffer_length;
 
        bool typed_event (ArdourCanvas::Item*, GdkEvent*, ItemType);
        bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
@@ -1021,7 +1051,7 @@ class Editor : public PublicEditor
 
        void register_actions ();
 
-       int ensure_cursor (nframes_t* pos);
+       int ensure_cursor (nframes64_t* pos);
 
        void handle_new_region (boost::weak_ptr<ARDOUR::Region>);
        void handle_new_regions (vector<boost::weak_ptr<ARDOUR::Region> >& );
@@ -1030,6 +1060,7 @@ class Editor : public PublicEditor
        void add_regions_to_region_display (std::vector<boost::weak_ptr<ARDOUR::Region> > & );
        void region_hidden (boost::shared_ptr<ARDOUR::Region>);
        void redisplay_regions ();
+       bool no_region_list_redisplay;
        void insert_into_tmp_regionlist(boost::shared_ptr<ARDOUR::Region>);
 
        list<boost::shared_ptr<ARDOUR::Region> > tmp_region_list;
@@ -1041,7 +1072,7 @@ class Editor : public PublicEditor
        void cut_copy_ranges (Editing::CutCopyOp);
 
        void mouse_paste ();
-       void paste_internal (nframes_t position, float times);
+       void paste_internal (nframes64_t position, float times);
 
        /* EDITING OPERATIONS */
        
@@ -1055,19 +1086,19 @@ class Editor : public PublicEditor
        void lower_region ();
        void lower_region_to_bottom ();
        void split_region ();
-       void split_region_at (nframes_t);
-       void split_regions_at (nframes_t, RegionSelection&);
+       void split_region_at (nframes64_t);
+       void split_regions_at (nframes64_t, RegionSelection&);
        void split_region_at_transients ();
        void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret);
        void crop_region_to_selection ();
-       void crop_region_to (nframes_t start, nframes_t end);
+       void crop_region_to (nframes64_t start, nframes64_t end);
        void set_sync_point (nframes64_t, const RegionSelection&);
        void set_region_sync_from_edit_point ();
        void remove_region_sync();
-       void align_selection (ARDOUR::RegionPoint, nframes_t position, const RegionSelection&);
-       void align_selection_relative (ARDOUR::RegionPoint point, nframes_t position, const RegionSelection&);
-       void align_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes_t position);
-       void align_region_internal (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes_t position);
+       void align_selection (ARDOUR::RegionPoint, nframes64_t position, const RegionSelection&);
+       void align_selection_relative (ARDOUR::RegionPoint point, nframes64_t position, const RegionSelection&);
+       void align_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes64_t position);
+       void align_region_internal (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes64_t position);
        void remove_selected_regions ();
        void remove_clicked_region ();
        void edit_region ();
@@ -1087,7 +1118,7 @@ class Editor : public PublicEditor
        void quantize_region ();
 
        void do_insert_time ();
-       void insert_time (nframes64_t pos, nframes64_t distance, Editing::InsertTimeOption opt, bool ignore_music_glue);
+       void insert_time (nframes64_t pos, nframes64_t distance, Editing::InsertTimeOption opt, bool ignore_music_glue, bool markers_too);
 
        void tab_to_transient (bool forward);
 
@@ -1130,13 +1161,13 @@ class Editor : public PublicEditor
        void loop_location (ARDOUR::Location&);
 
        void temporal_zoom_selection ();
-       void temporal_zoom_region ();
-       void toggle_zoom_region ();
+       void temporal_zoom_region (bool both_axes);
+       void toggle_zoom_region (bool both_axes);
        bool zoomed_to_region;
        void temporal_zoom_session ();
        void temporal_zoom (gdouble scale);
-       void temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & op);
-       void temporal_zoom_to_frame (bool coarser, nframes_t frame);
+       void temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string & op);
+       void temporal_zoom_to_frame (bool coarser, nframes64_t frame);
 
        void amplitude_zoom (gdouble scale);
        void amplitude_zoom_step (bool in);
@@ -1259,8 +1290,8 @@ class Editor : public PublicEditor
        void set_loop_from_region (bool play);
        void set_punch_from_edit_range ();
 
-       void set_loop_range (nframes_t start, nframes_t end, std::string cmd);
-       void set_punch_range (nframes_t start, nframes_t end, std::string cmd);
+       void set_loop_range (nframes64_t start, nframes64_t end, std::string cmd);
+       void set_punch_range (nframes64_t start, nframes64_t end, std::string cmd);
 
        void add_location_from_playhead_cursor ();
        bool select_new_marker;
@@ -1281,7 +1312,7 @@ class Editor : public PublicEditor
        void keyboard_selection_begin ();
        void keyboard_selection_finish (bool add);
        bool have_pending_keyboard_selection;
-       nframes_t pending_keyboard_selection_start;
+       nframes64_t pending_keyboard_selection_start;
 
        boost::shared_ptr<ARDOUR::Region> select_region_for_operation (int dir, TimeAxisView **tv);
        void extend_selection_to_end_of_region (bool next);
@@ -1375,11 +1406,11 @@ class Editor : public PublicEditor
        void remove_gain_control_point (ArdourCanvas::Item*, GdkEvent*);
        void remove_control_point (ArdourCanvas::Item*, GdkEvent*);
 
-       void mouse_brush_insert_region (RegionView*, nframes_t pos);
-       void brush (nframes_t);
+       void mouse_brush_insert_region (RegionView*, nframes64_t pos);
+       void brush (nframes64_t);
 
-       void show_verbose_time_cursor (nframes_t frame, double offset = 0, double xpos=-1, double ypos=-1);
-       void show_verbose_duration_cursor (nframes_t start, nframes_t end, double offset = 0, double xpos=-1, double ypos=-1);
+       void show_verbose_time_cursor (nframes64_t frame, double offset = 0, double xpos=-1, double ypos=-1);
+       void show_verbose_duration_cursor (nframes64_t start, nframes64_t end, double offset = 0, double xpos=-1, double ypos=-1);
        double clamp_verbose_cursor_x (double);
        double clamp_verbose_cursor_y (double);
 
@@ -1486,8 +1517,8 @@ public:
 
        void new_tempo_section ();
 
-       void mouse_add_new_tempo_event (nframes_t where);
-       void mouse_add_new_meter_event (nframes_t where);
+       void mouse_add_new_tempo_event (nframes64_t where);
+       void mouse_add_new_meter_event (nframes64_t where);
 
        void remove_tempo_marker (ArdourCanvas::Item*);
        void remove_meter_marker (ArdourCanvas::Item*);
@@ -1513,6 +1544,8 @@ public:
        void marker_menu_set_playhead ();
        void marker_menu_set_from_playhead ();
        void marker_menu_set_from_selection ();
+       void marker_menu_range_to_next ();
+       void marker_menu_export_range ();
        void new_transport_marker_menu_set_loop ();
        void new_transport_marker_menu_set_punch ();
        void update_loop_range_view (bool visibility=false);
@@ -1548,14 +1581,8 @@ public:
        void redisplay_tempo (bool immediate_redraw);
        
        void snap_to (nframes64_t& first, int32_t direction = 0, bool for_mark = false);
-       void snap_to (nframes_t& first, int32_t direction = 0, bool for_mark = false) {
-               /* XXX remove this function when everything moves to 64 bit frame counts */
-               nframes64_t first64 = first;
-               snap_to (first64, direction, for_mark);
-               first = (nframes_t) first64;
-       }
        
-       double snap_length_beats (nframes_t start);
+       double snap_length_beats (nframes64_t start);
 
        uint32_t bbt_beat_subdivision;
 
@@ -1690,7 +1717,7 @@ public:
        void region_selection_op (void (ARDOUR::Region::*pmf)(void*), void*);
        void region_selection_op (void (ARDOUR::Region::*pmf)(bool), bool);
 
-       bool audio_region_selection_covers (nframes_t where);
+       bool audio_region_selection_covers (nframes64_t where);
 
        /* transport range select process */
        enum RangeMarkerOp {
@@ -1733,7 +1760,7 @@ public:
        void drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event);
        void end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event);
 
-       bool select_all_within (nframes_t start, nframes_t end, gdouble topy, gdouble boty, const TrackViewList&, Selection::Operation op);
+       bool select_all_within (nframes64_t start, nframes64_t end, gdouble topy, gdouble boty, const TrackViewList&, Selection::Operation op);
        
        ArdourCanvas::SimpleRect   *rubberband_rect;
        
@@ -1744,7 +1771,7 @@ public:
        void end_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event);
 
        ArdourCanvas::SimpleRect   *zoom_rect;
-       void reposition_zoom_rect (nframes_t start, nframes_t end);
+       void reposition_zoom_rect (nframes64_t start, nframes64_t end);
        
        /* diskstream/route display management */
 
@@ -1752,11 +1779,13 @@ public:
            RouteDisplayModelColumns() { 
                    add (text);
                    add (visible);
+                   add (temporary_visible);
                    add (tv);
                    add (route);
            }
            Gtk::TreeModelColumn<Glib::ustring>  text;
            Gtk::TreeModelColumn<bool>           visible;
+           Gtk::TreeModelColumn<bool>           temporary_visible;
            Gtk::TreeModelColumn<TimeAxisView*>  tv;
            Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Route> >  route;
        };
@@ -1769,6 +1798,8 @@ public:
        Gtk::ScrolledWindow                   route_list_scroller;
        Gtk::Menu*                            route_list_menu;
 
+       void update_route_visibility ();
+
        void sync_order_keys ();
        bool ignore_route_order_sync;
 
@@ -1854,7 +1885,7 @@ public:
        int last_autoscroll_x;
        int last_autoscroll_y;
        uint32_t autoscroll_cnt;
-       nframes_t autoscroll_x_distance;
+       nframes64_t autoscroll_x_distance;
        double autoscroll_y_distance;
      
        static gint _autoscroll_canvas (void *);
@@ -1862,6 +1893,7 @@ public:
        void start_canvas_autoscroll (int x, int y);
        void stop_canvas_autoscroll ();
        void maybe_autoscroll (GdkEventMotion*);
+       bool allow_vertical_scroll;
 
        /* trimming */
        enum TrimOp {
@@ -1873,9 +1905,9 @@ public:
        void start_trim (ArdourCanvas::Item*, GdkEvent*);
        void point_trim (GdkEvent*);
        void trim_motion_callback (ArdourCanvas::Item*, GdkEvent*);
-       void single_contents_trim (RegionView&, nframes_t, bool, bool, bool);
-       void single_start_trim (RegionView&, nframes_t, bool, bool);
-       void single_end_trim (RegionView&, nframes_t, bool, bool);
+       void single_contents_trim (RegionView&, nframes64_t, bool, bool, bool);
+       void single_start_trim (RegionView&, nframes64_t, bool, bool);
+       void single_end_trim (RegionView&, nframes64_t, bool, bool);
 
        void trim_finished_callback (ArdourCanvas::Item*, GdkEvent*);
        void thaw_region_after_trim (RegionView& rv);
@@ -1943,14 +1975,14 @@ public:
        ExportDialog *export_dialog;
        ExportDialog *export_range_markers_dialog;
        
-       void export_range (nframes_t start, nframes_t end);
+       void export_range (nframes64_t start, nframes64_t end);
        void export_range_markers ();
 
        int  write_region_selection(RegionSelection&);
        bool write_region (string path, boost::shared_ptr<ARDOUR::AudioRegion>);
        void export_region ();
        void bounce_region_selection ();
-       void bounce_range_selection ();
+       void bounce_range_selection (bool replace);
        void external_edit_region ();
 
        int write_audio_selection (TimeSelection&);
@@ -1967,12 +1999,6 @@ public:
        void begin_reversible_command (string cmd_name);
        void commit_reversible_command ();
 
-       /* visual history */
-
-       UndoHistory visual_history;
-       UndoTransaction current_visual_command;
-
-
        void update_title ();   
        void update_title_s (const string & snapshot_name);
 
@@ -2151,7 +2177,7 @@ public:
        Gtk::VBox        nudge_vbox;
        AudioClock       nudge_clock;
 
-       nframes_t get_nudge_distance (nframes_t pos, nframes_t& next);
+       nframes64_t get_nudge_distance (nframes64_t pos, nframes64_t& next);
 
        bool nudge_forward_release (GdkEventButton*);
        bool nudge_backward_release (GdkEventButton*);
@@ -2169,7 +2195,7 @@ public:
        /* tracking step changes of track height */
 
        TimeAxisView* current_stepping_trackview;
-       struct timeval last_track_height_step_timestamp;
+       ARDOUR::microseconds_t last_track_height_step_timestamp;
        gint track_height_step_timeout();
        sigc::connection step_timeout;
 
@@ -2240,7 +2266,8 @@ public:
 
        RhythmFerret* rhythm_ferret;
 
-       void set_track_height (TimeAxisView::TrackHeight h);
+       void fit_tracks ();
+       void set_track_height (uint32_t h);
        void set_track_height_largest ();
        void set_track_height_large ();
        void set_track_height_larger ();
@@ -2253,6 +2280,11 @@ public:
        void waveform_scale_chosen (Editing::WaveformScale);
 
        bool _have_idled;
+       int resize_idle_id;
+       int32_t resize_idle_target;
+       bool idle_resize();
+       friend gboolean _idle_resize (gpointer);
+       std::vector<TimeAxisView*> pending_resizes;
 };
 
 #endif /* __ardour_editor_h__ */
index 0d859985a296a91a6bc9c6605e26bd4eb0abb3e9..a1a7092eb0e1b630207d1d802f5d98534b9a4570 100644 (file)
@@ -73,6 +73,7 @@ Editor::register_actions ()
        ActionManager::register_action (editor_actions, X_("RegionEditOps"), _("Region operations"));
        ActionManager::register_action (editor_actions, X_("RegionGainMenu"), _("Gain"));
        ActionManager::register_action (editor_actions, X_("RulerMenu"), _("Rulers"));
+       ActionManager::register_action (editor_actions, X_("SavedViewMenu"), _("Views"));
        ActionManager::register_action (editor_actions, X_("ScrollMenu"), _("Scroll"));
        ActionManager::register_action (editor_actions, X_("SecondaryClockMenu"), _("Secondary Clock"));
        ActionManager::register_action (editor_actions, X_("Select"), _("Select"));
@@ -91,10 +92,8 @@ Editor::register_actions ()
        ActionManager::register_action (editor_actions, X_("TrimMenu"), _("Trim"));
        ActionManager::register_action (editor_actions, X_("View"), _("View"));
        ActionManager::register_action (editor_actions, X_("WaveformMenu"), _("Waveforms"));
-       ActionManager::register_action (editor_actions, X_("ZoomFocus"), _("Zoom"));
+       ActionManager::register_action (editor_actions, X_("ZoomFocus"), _("Zoom Focus"));
        ActionManager::register_action (editor_actions, X_("ZoomMenu"), _("Zoom"));
-       ActionManager::register_action (editor_actions, X_("ZoomFocusMenu"), _("Zoom Focus"));
-
 
        /* add named actions for the editor */
 
@@ -198,6 +197,56 @@ Editor::register_actions ()
        ActionManager::session_sensitive_actions.push_back (act);
        
 
+       act = ActionManager::register_action (editor_actions, "save-visual-state-1", _("Save View 1"), bind (mem_fun (*this, &Editor::start_visual_state_op), 0));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-1", _("Goto View 1"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 0));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-2", _("Save View 2"), bind (mem_fun (*this, &Editor::start_visual_state_op), 1));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-2", _("Goto View 2"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 1));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-3", _("Save View 3"), bind (mem_fun (*this, &Editor::start_visual_state_op), 2));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-3", _("Goto View 3"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 2));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-4", _("Save View 4"), bind (mem_fun (*this, &Editor::start_visual_state_op), 3));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-4", _("Goto View 4"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 3));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-5", _("Save View 5"), bind (mem_fun (*this, &Editor::start_visual_state_op), 4));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-5", _("Goto View 5"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 4));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-6", _("Save View 6"), bind (mem_fun (*this, &Editor::start_visual_state_op), 5));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-6", _("Goto View 6"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 5));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-7", _("Save View 7"), bind (mem_fun (*this, &Editor::start_visual_state_op), 6));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-7", _("Goto View 7"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 6));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-8", _("Save View 8"), bind (mem_fun (*this, &Editor::start_visual_state_op), 7));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-8", _("Goto View 8"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 7));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-9", _("Save View 9"), bind (mem_fun (*this, &Editor::start_visual_state_op), 8));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-9", _("Goto View 9"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 8));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-10", _("Save View 10"), bind (mem_fun (*this, &Editor::start_visual_state_op), 9));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-10", _("Goto View 10"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 9));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-11", _("Save View 11"), bind (mem_fun (*this, &Editor::start_visual_state_op), 10));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-11", _("Goto View 11"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 10));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "save-visual-state-12", _("Save View 12"), bind (mem_fun (*this, &Editor::start_visual_state_op), 11));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "goto-visual-state-12", _("Goto View 12"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 11));
+       ActionManager::session_sensitive_actions.push_back (act);
+
+
        act = ActionManager::register_action (editor_actions, "goto-mark-1", _("Locate to Mark 1"), bind (mem_fun (*this, &Editor::goto_nth_marker), 0));
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "goto-mark-2", _("Locate to Mark 2"), bind (mem_fun (*this, &Editor::goto_nth_marker), 1));
@@ -249,7 +298,9 @@ Editor::register_actions ()
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "zoom-to-session", _("Zoom to Session"), mem_fun(*this, &Editor::temporal_zoom_session));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "zoom-to-region", _("Zoom to Region"), mem_fun(*this, &Editor::toggle_zoom_region));
+       act = ActionManager::register_action (editor_actions, "zoom-to-region", _("Zoom to Region"), bind (mem_fun(*this, &Editor::toggle_zoom_region), false));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "zoom-to-region-both-axes", _("Zoom to Region (W&H)"), bind (mem_fun(*this, &Editor::toggle_zoom_region), true));
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "toggle-zoom", _("Toggle Zoom State"), mem_fun(*this, &Editor::swap_visual_state));
        ActionManager::session_sensitive_actions.push_back (act);
@@ -319,6 +370,9 @@ Editor::register_actions ()
        act = ActionManager::register_action (editor_actions, "pitch-shift-region", _("Transpose"), mem_fun(*this, &Editor::pitch_shift_regions));
        ActionManager::session_sensitive_actions.push_back (act);
        ActionManager::region_selection_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "toggle-opaque-region", _("Toggle Opaque"), mem_fun(*this, &Editor::toggle_region_opaque));
+       ActionManager::session_sensitive_actions.push_back (act);
+       ActionManager::region_selection_sensitive_actions.push_back (act);
        
        act = ActionManager::register_action (editor_actions, "set-fade-in-length", _("Set Fade In Length"), bind (mem_fun(*this, &Editor::set_fade_length), true));
        ActionManager::session_sensitive_actions.push_back (act);
@@ -467,7 +521,8 @@ Editor::register_actions ()
 
        act = ActionManager::register_action (editor_actions, "quantize-region", _("Quantize Region"), mem_fun(*this, &Editor::quantize_region));
        ActionManager::session_sensitive_actions.push_back (act);
-
+       ActionManager::region_selection_sensitive_actions.push_back (act);
+       
        act = ActionManager::register_action (editor_actions, "set-tempo-from-region", _("Set Tempo from Region=Bar"), mem_fun(*this, &Editor::use_region_as_bar));
        ActionManager::session_sensitive_actions.push_back (act);
        ActionManager::region_selection_sensitive_actions.push_back (act);
@@ -521,6 +576,8 @@ Editor::register_actions ()
        ActionManager::session_sensitive_actions.push_back (act);
        ActionManager::track_selection_sensitive_actions.push_back (act);
 
+       act = ActionManager::register_action (editor_actions, "fit-tracks", _("Fit Selected Tracks"), (mem_fun(*this, &Editor::fit_tracks)));
+       ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "track-height-largest", _("Largest"), (mem_fun(*this, &Editor::set_track_height_largest)));
        ActionManager::session_sensitive_actions.push_back (act);
        ActionManager::track_selection_sensitive_actions.push_back (act);
@@ -693,9 +750,10 @@ Editor::register_actions ()
 
        /* the next two are duplicate items with different names for use in two different contexts */
 
-
        act = ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Import"), mem_fun (*this, &Editor::external_audio_dialog));
        ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, X_("addExternalAudioToRegionList"), _("Import to Region List"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion));
+       ActionManager::session_sensitive_actions.push_back (act);
 
        act = ActionManager::register_toggle_action (editor_actions, X_("toggle-waveform-visible"), _("Show Waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility));
        ActionManager::track_selection_sensitive_actions.push_back (act);
index 61d0a2288295b95e53a0ce8221883b4d8e7e1035..b3b710f990b0e0ce988dbf8146331d716d4f82c2 100644 (file)
@@ -74,7 +74,7 @@ void
 Editor::add_external_audio_action (ImportMode mode_hint)
 {
        if (session == 0) {
-               MessageDialog msg (0, _("You can't import or embed a file until you have a session loaded."));
+               MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
                msg.run ();
                return;
        }
@@ -95,7 +95,7 @@ Editor::external_audio_dialog ()
        uint32_t track_cnt;
 
        if (session == 0) {
-               MessageDialog msg (0, _("You can't import or embed a file until you have a session loaded."));
+               MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
                msg.run ();
                return;
        }
index cfb8f0a5572d4ec8445573f438ade641ae88f9f5..7e821f0e5ee67fe8680c829a27d0448d9804ad4f 100644 (file)
@@ -111,6 +111,7 @@ Editor::toggle_meter_updating()
        } else {
                stop_updating ();
        }
+       track_canvas_allocate(track_canvas->get_allocation());
 }
 
 void
index 516443e01266c425886c571282af672d4803c59c..0be64cc80f20cf308be44fe9766e4a5d0ee1938d 100644 (file)
@@ -55,7 +55,7 @@ using namespace Glib;
 using namespace Gtkmm2ext;
 using namespace Editing;
 
-/* XXX this is a hack. it ought to be the maximum value of an nframes_t */
+/* XXX this is a hack. it ought to be the maximum value of an nframes64_t */
 
 const double max_canvas_coordinate = (double) JACK_MAX_FRAMES;
 
@@ -181,7 +181,6 @@ Editor::initialize_canvas ()
        
        marker_time_line_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0);
        marker_tempo_lines = new TempoLines(*time_canvas, marker_time_line_group);
-       
        meter_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0);
        tempo_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height);
        range_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 2.0);
@@ -190,23 +189,27 @@ Editor::initialize_canvas ()
        cd_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 5.0);
        
        tempo_bar = new ArdourCanvas::SimpleRect (*tempo_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
        tempo_bar->property_outline_what() = (0x1 | 0x8);
        tempo_bar->property_outline_pixels() = 1;
 
-       
        meter_bar = new ArdourCanvas::SimpleRect (*meter_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
        meter_bar->property_outline_what() = (0x1 | 0x8);
        meter_bar->property_outline_pixels() = 1;
        
        marker_bar = new ArdourCanvas::SimpleRect (*marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
        marker_bar->property_outline_what() = (0x1 | 0x8);
        marker_bar->property_outline_pixels() = 1;
 
        cd_marker_bar = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
        cd_marker_bar->property_outline_what() = (0x1 | 0x8);
        cd_marker_bar->property_outline_pixels() = 1;
        
        range_marker_bar = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
        range_marker_bar->property_outline_what() = (0x1 | 0x8);
        range_marker_bar->property_outline_pixels() = 1;
        
@@ -220,7 +223,7 @@ Editor::initialize_canvas ()
 
        range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
        range_bar_drag_rect->property_outline_pixels() = 0;
-       
+
        transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
        transport_bar_drag_rect->property_outline_pixels() = 0;
        transport_bar_drag_rect->hide ();
@@ -343,7 +346,7 @@ Editor::track_canvas_size_allocated ()
                full_canvas_height = height;
        }
 
-       zoom_range_clock.set ((nframes_t) floor ((canvas_width * frames_per_unit)));
+       zoom_range_clock.set ((nframes64_t) floor ((canvas_width * frames_per_unit)));
        playhead_cursor->set_position (playhead_cursor->current_frame);
 
        reset_hscrollbar_stepping ();
@@ -391,7 +394,7 @@ Editor::reset_scrolling_region (Gtk::Allocation* alloc)
        }
 
        double last_canvas_unit =  max ((last_canvas_frame / frames_per_unit), canvas_width);
-
+       //cerr << "Editor::reset_scrolling_region () lcf:fpu:cw:lcu " << last_canvas_frame << ":" << frames_per_unit << ":" << canvas_width << ":" << last_canvas_unit << endl;//DEBUG
        track_canvas->set_scroll_region (0.0, 0.0, last_canvas_unit, pos);
 
        // XXX what is the correct height value for the time canvas ? this overstates it
@@ -521,6 +524,8 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
 
                /* drop onto canvas background: create new tracks */
 
+               frame = 0;
+
                if (Profile->get_sae() || Config->get_only_copy_imported_files()) {
                        do_import (paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, SrcBest, frame); 
                } else {
@@ -587,8 +592,8 @@ Editor::drop_routes (const Glib::RefPtr<Gdk::DragContext>& context,
 void
 Editor::maybe_autoscroll (GdkEventMotion* event)
 {
-       nframes_t rightmost_frame = leftmost_frame + current_page_frames();
-       nframes_t frame = drag_info.current_pointer_frame;
+       nframes64_t rightmost_frame = leftmost_frame + current_page_frames();
+       nframes64_t frame = drag_info.current_pointer_frame;
        bool startit = false;
        double vertical_pos = vertical_adjustment.get_value();
 
@@ -621,6 +626,10 @@ Editor::maybe_autoscroll (GdkEventMotion* event)
 
        }
 
+       if (!allow_vertical_scroll) {
+               autoscroll_y = 0;
+       }
+
        if ((autoscroll_x != last_autoscroll_x) || (autoscroll_y != last_autoscroll_y) || (autoscroll_x == 0 && autoscroll_y == 0)) {
                stop_canvas_autoscroll ();
        }
@@ -642,10 +651,10 @@ Editor::_autoscroll_canvas (void *arg)
 bool
 Editor::autoscroll_canvas ()
 {
-       nframes_t new_frame;
-       nframes_t limit = max_frames - current_page_frames();
+       nframes64_t new_frame;
+       nframes64_t limit = max_frames - current_page_frames();
        GdkEventMotion ev;
-       nframes_t target_frame;
+       nframes64_t target_frame;
        double new_pixel;
        double target_pixel;
 
@@ -742,17 +751,17 @@ Editor::autoscroll_canvas ()
                        
                        /* after about a while, speed up a bit by changing the timeout interval */
                        
-                       autoscroll_x_distance = (nframes_t) floor (current_page_frames()/30.0f);
+                       autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/30.0f);
                        
                } else if (autoscroll_cnt == 150) { /* 1.0 seconds */
                        
-                       autoscroll_x_distance = (nframes_t) floor (current_page_frames()/20.0f);
+                       autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/20.0f);
                        
                } else if (autoscroll_cnt == 300) { /* 1.5 seconds */
                        
                        /* after about another while, speed up by increasing the shift per callback */
                        
-                       autoscroll_x_distance =  (nframes_t) floor (current_page_frames()/10.0f);
+                       autoscroll_x_distance =  (nframes64_t) floor (current_page_frames()/10.0f);
                        
                } 
        }
@@ -792,7 +801,7 @@ Editor::start_canvas_autoscroll (int dx, int dy)
        autoscroll_active = true;
        autoscroll_x = dx;
        autoscroll_y = dy;
-       autoscroll_x_distance = (nframes_t) floor (current_page_frames()/50.0);
+       autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/50.0);
        autoscroll_y_distance = fabs (dy * 5); /* pixels */
        autoscroll_cnt = 0;
        
@@ -864,7 +873,7 @@ Editor::tie_vertical_scrolling ()
 void 
 Editor::canvas_horizontally_scrolled ()
 {
-       nframes64_t time_origin = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+       nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
 
        if (time_origin != leftmost_frame) {
                canvas_scroll_to (time_origin);
@@ -874,8 +883,9 @@ Editor::canvas_horizontally_scrolled ()
 void
 Editor::canvas_scroll_to (nframes64_t time_origin)
 {
-       leftmost_frame = time_origin;
-       nframes_t rightmost_frame = leftmost_frame + current_page_frames ();
+       leftmost_frame = time_origin;
+
+       nframes64_t rightmost_frame = leftmost_frame + current_page_frames ();
 
        if (rightmost_frame > last_canvas_frame) {
                last_canvas_frame = rightmost_frame;
index 0da0bfc4878290e700c6f3a56531cf4413803917..dd107d8d0280a2c571a51bb06e5fb865c9af96e9 100644 (file)
@@ -56,7 +56,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
 {
        int x, y;
        double wx, wy;
-       nframes_t xdelta;
+       nframes64_t xdelta;
        int direction = ev->direction;
        CanvasNoteEvent *midi_event = dynamic_cast<CanvasNoteEvent *>(track_canvas->get_item_at(ev->x, ev->y));
 
@@ -80,7 +80,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                        event.button.x = wx;
                        event.button.y = wy;
                        
-                       nframes_t where = event_frame (&event, 0, 0);
+                       nframes64_t where = event_frame (&event, 0, 0);
                        temporal_zoom_to_frame (false, where);
                        return true;
                } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
@@ -93,7 +93,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                                        return false;
                                }
                        }
-                       gettimeofday (&last_track_height_step_timestamp, 0);
+                       last_track_height_step_timestamp = get_microseconds();
                        current_stepping_trackview->step_height (true);
                        return true;
                } else {
@@ -118,7 +118,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                        event.button.x = wx;
                        event.button.y = wy;
                        
-                       nframes_t where = event_frame (&event, 0, 0);
+                       nframes64_t where = event_frame (&event, 0, 0);
                        temporal_zoom_to_frame (true, where);
                        return true;
                } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
@@ -131,7 +131,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                                        return false;
                                }
                        }
-                       gettimeofday (&last_track_height_step_timestamp, 0);
+                       last_track_height_step_timestamp = get_microseconds();
                        current_stepping_trackview->step_height (false);
                        return true;
                } else {
@@ -180,7 +180,7 @@ Editor::track_canvas_scroll_event (GdkEventScroll *event)
 bool
 Editor::time_canvas_scroll (GdkEventScroll* ev)
 {
-       nframes_t xdelta;
+       nframes64_t xdelta;
        int direction = ev->direction;
 
        switch (direction) {
index 239d27d4f98dd413358e755f9100cc016c083117..54786bcebf8c480327421f016b2a4a4d6b8afca9 100644 (file)
@@ -61,7 +61,7 @@ Editor::Cursor::~Cursor ()
 }
 
 void
-Editor::Cursor::set_position (nframes_t frame)
+Editor::Cursor::set_position (nframes64_t frame)
 {
        double new_pos =  editor.frame_to_unit (frame);
 
index 157494b84617c1e9c23bad18bf90b1c5653b1b6d..c1d0c568331d8e0a08c27a9df00adac0e1674edb 100644 (file)
@@ -77,7 +77,7 @@ Editor::export_selection ()
 }
 
 void
-Editor::export_range (nframes_t start, nframes_t end)
+Editor::export_range (nframes64_t start, nframes64_t end)
 {
        if (session) {
                if (export_dialog == 0) {
@@ -157,7 +157,12 @@ Editor::bounce_region_selection ()
                itt.cancel = false;
                itt.progress = 0.0f;
 
-               track->bounce_range (region->position(), region->position() + region->length(), itt);
+               boost::shared_ptr<Region> r = track->bounce_range (region->position(), region->position() + region->length(), itt);
+               cerr << "Result of bounce of "
+                    << region->name() << " len = " << region->length()
+                    << " was "
+                    << r->name() << " len = " << r->length()
+                    << endl;
        }
 }
 
@@ -165,11 +170,11 @@ bool
 Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
 {
        boost::shared_ptr<AudioFileSource> fs;
-       const nframes_t chunk_size = 4096;
-       nframes_t to_read;
+       const nframes64_t chunk_size = 4096;
+       nframes64_t to_read;
        Sample buf[chunk_size];
        gain_t gain_buffer[chunk_size];
-       nframes_t pos;
+       nframes64_t pos;
        char s[PATH_MAX+1];
        uint32_t cnt;
        vector<boost::shared_ptr<AudioFileSource> > sources;
@@ -234,7 +239,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
        pos = region->position();
 
        while (to_read) {
-               nframes_t this_time;
+               nframes64_t this_time;
 
                this_time = min (to_read, chunk_size);
 
@@ -312,11 +317,11 @@ bool
 Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list<AudioRange>& range)
 {
        boost::shared_ptr<AudioFileSource> fs;
-       const nframes_t chunk_size = 4096;
-       nframes_t nframes;
+       const nframes64_t chunk_size = 4096;
+       nframes64_t nframes;
        Sample buf[chunk_size];
        gain_t gain_buffer[chunk_size];
-       nframes_t pos;
+       nframes64_t pos;
        char s[PATH_MAX+1];
        uint32_t cnt;
        string path;
@@ -369,7 +374,7 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list
                pos = (*i).start;
                
                while (nframes) {
-                       nframes_t this_time;
+                       nframes64_t this_time;
                        
                        this_time = min (nframes, chunk_size);
 
@@ -401,7 +406,7 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list
 
                        while (nframes) {
 
-                               nframes_t this_time = min (nframes, chunk_size);
+                               nframes64_t this_time = min (nframes, chunk_size);
                                memset (buf, 0, sizeof (Sample) * this_time);
 
                                for (uint32_t n=0; n < channels; ++n) {
index daba2496a04c8cbe62a522611595d0e76b85fab0..d4bf49759189eedb4cff90c505f392d2a2579922 100644 (file)
@@ -95,10 +95,10 @@ void
 Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
 {
        // GTK2FIX
-       //nframes_t offset = static_cast<nframes_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
-       nframes_t offset = 0;
+       //nframes64_t offset = static_cast<nframes64_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
+       nframes64_t offset = 0;
 
-       nframes_t x_pos = 0 ;
+       nframes64_t x_pos = 0 ;
 
        if (item->get_position() < offset) {
                x_pos = 0 ;
@@ -493,14 +493,14 @@ Editor::markerview_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
        double cx, cy ;
 
        MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
-       nframes_t pending_region_position ;
-       nframes_t pointer_frame ;
+       nframes64_t pending_region_position ;
+       nframes64_t pointer_frame ;
 
        pointer_frame = event_frame(event, &cx, &cy) ;
 
        snap_to(pointer_frame) ;
 
-       if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
+       if (pointer_frame > (nframes64_t) drag_info.pointer_frame_offset)
        {
                pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
                snap_to(pending_region_position) ;
@@ -541,14 +541,14 @@ Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
        
        ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
        
-       nframes_t pending_region_position;
-       nframes_t pointer_frame;
+       nframes64_t pending_region_position;
+       nframes64_t pointer_frame;
 
        pointer_frame = event_frame(event, &cx, &cy) ;
 
        snap_to(pointer_frame) ;
 
-       if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
+       if (pointer_frame > (nframes64_t) drag_info.pointer_frame_offset)
        {
                pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
                snap_to(pending_region_position) ;
@@ -576,7 +576,7 @@ Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
 void
 Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
 {
-       nframes_t where ;
+       nframes64_t where ;
        TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
 
        bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
@@ -674,9 +674,9 @@ Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent*
 {
        ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
        
-       nframes_t start = 0 ;
-       nframes_t end = 0 ;
-       nframes_t pointer_frame = event_frame(event) ;
+       nframes64_t start = 0 ;
+       nframes64_t end = 0 ;
+       nframes64_t pointer_frame = event_frame(event) ;
        
        // chekc th eposition of the item is not locked
        if(!ifv->get_position_locked()) {
@@ -693,7 +693,7 @@ Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent*
                        }
                        
                        // are we getting bigger or smaller?
-                       nframes_t new_dur_val = end - start ;
+                       nframes64_t new_dur_val = end - start ;
                        
                        // start handle, so a smaller pointer frame increases our component size
                        if(pointer_frame <= drag_info.grab_frame) 
@@ -751,10 +751,10 @@ Editor::imageframe_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* eve
        }
        else
        {
-               nframes_t temp = ifv->get_position() + ifv->get_duration() ;
+               nframes64_t temp = ifv->get_position() + ifv->get_duration() ;
                
-               ifv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
-               ifv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
+               ifv->set_position((nframes64_t) (temp - drag_info.cumulative_x_drag), this) ;
+               ifv->set_duration((nframes64_t) drag_info.cumulative_x_drag, this) ;
        }
 }
 
@@ -763,10 +763,10 @@ Editor::imageframe_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* ev
 {
        ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
        
-       nframes_t start = 0 ;
-       nframes_t end = 0 ;
-       nframes_t pointer_frame = event_frame(event) ;
-       nframes_t new_dur_val = 0 ;
+       nframes64_t start = 0 ;
+       nframes64_t end = 0 ;
+       nframes64_t pointer_frame = event_frame(event) ;
+       nframes64_t new_dur_val = 0 ;
 
        snap_to(pointer_frame) ;
        
@@ -828,7 +828,7 @@ Editor::imageframe_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* even
        }
        else
        {
-               nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
+               nframes64_t new_duration = (nframes64_t)drag_info.cumulative_x_drag ;
                if((new_duration <= ifv->get_max_duration()) && (new_duration >= ifv->get_min_duration()))
                {
                        ifv->set_duration(new_duration, this) ;
@@ -888,9 +888,9 @@ Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent*
 {
        MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
        
-       nframes_t start = 0 ;
-       nframes_t end = 0 ;
-       nframes_t pointer_frame = event_frame(event) ;
+       nframes64_t start = 0 ;
+       nframes64_t end = 0 ;
+       nframes64_t pointer_frame = event_frame(event) ;
        
        // chekc th eposition of the item is not locked
        if(!mv->get_position_locked())
@@ -911,7 +911,7 @@ Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent*
                        }
                        
                        // are we getting bigger or smaller?
-                       nframes_t new_dur_val = end - start ;
+                       nframes64_t new_dur_val = end - start ;
                        
                        if(pointer_frame <= drag_info.grab_frame)
                        {
@@ -968,10 +968,10 @@ Editor::markerview_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* eve
        }
        else
        {
-               nframes_t temp = mv->get_position() + mv->get_duration() ;
+               nframes64_t temp = mv->get_position() + mv->get_duration() ;
                
-               mv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
-               mv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
+               mv->set_position((nframes64_t) (temp - drag_info.cumulative_x_drag), this) ;
+               mv->set_duration((nframes64_t) drag_info.cumulative_x_drag, this) ;
        }
 }
 
@@ -980,10 +980,10 @@ Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* ev
 {
        MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
        
-       nframes_t start = 0 ;
-       nframes_t end = 0 ;
-       nframes_t pointer_frame = event_frame(event) ;
-       nframes_t new_dur_val = 0 ;
+       nframes64_t start = 0 ;
+       nframes64_t end = 0 ;
+       nframes64_t pointer_frame = event_frame(event) ;
+       nframes64_t new_dur_val = 0 ;
 
        snap_to(pointer_frame) ;
        
@@ -1008,7 +1008,7 @@ Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* ev
                {
                        // we cant extend beyond the item we are marking
                        ImageFrameView* marked_item = mv->get_marked_item() ;
-                       nframes_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
+                       nframes64_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
                        
                        if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
                        {
@@ -1062,7 +1062,7 @@ Editor::markerview_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* even
        }
        else
        {
-               nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
+               nframes64_t new_duration = (nframes64_t)drag_info.cumulative_x_drag ;
                mv->set_duration(new_duration, this) ;
        }
 }
index 60f838f06aba865bbcd1f80c9e6035176f555168..059855ccf5050cb58713e58a3d83b18b975ee142 100644 (file)
@@ -375,8 +375,8 @@ Editor::LocationMarkers::set_name (const string& str)
 }
 
 void
-Editor::LocationMarkers::set_position (nframes_t startf, 
-                                      nframes_t endf) 
+Editor::LocationMarkers::set_position (nframes64_t startf, 
+                                      nframes64_t endf) 
 {
        start->set_position (startf);
        if (end) { end->set_position (endf); }
@@ -390,7 +390,7 @@ Editor::LocationMarkers::set_color_rgba (uint32_t rgba)
 }
 
 void
-Editor::mouse_add_new_marker (nframes_t where, bool is_cd, bool is_xrun)
+Editor::mouse_add_new_marker (nframes64_t where, bool is_cd, bool is_xrun)
 {
        string markername, markerprefix;
        int flags = (is_cd ? Location::IsCDMarker|Location::IsMark : Location::IsMark);
@@ -404,6 +404,9 @@ Editor::mouse_add_new_marker (nframes_t where, bool is_cd, bool is_xrun)
 
        if (session) {
                session->locations()->next_available_name(markername, markerprefix);
+               if (!is_xrun && !choose_new_marker_name(markername)) {
+                       return;
+               }               
                Location *location = new Location (where, where, markername, (Location::Flags) flags);
                session->begin_reversible_command (_("add marker"));
                 XMLNode &before = session->locations()->get_state();
@@ -594,6 +597,8 @@ Editor::build_marker_menu (bool start_or_end)
 
        items.push_back (SeparatorElem());
 
+       items.push_back (MenuElem (_("Create range to next marker"), mem_fun(*this, &Editor::marker_menu_range_to_next)));
+
        items.push_back (MenuElem (_("Hide"), mem_fun(*this, &Editor::marker_menu_hide)));
        if (start_or_end) return;
        items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::marker_menu_rename)));
@@ -630,9 +635,11 @@ Editor::build_range_marker_menu (bool loop_or_punch)
                items.push_back (MenuElem (_("Set Range from Range Selection"), mem_fun(*this, &Editor::marker_menu_set_from_selection)));
        }
 
+       items.push_back (SeparatorElem());
+       items.push_back (MenuElem (_("Export Range"), mem_fun(*this, &Editor::marker_menu_export_range)));
        items.push_back (SeparatorElem());
 
-       if (! loop_or_punch) {
+       if (!loop_or_punch) {
                items.push_back (MenuElem (_("Hide Range"), mem_fun(*this, &Editor::marker_menu_hide)));
                items.push_back (MenuElem (_("Rename Range"), mem_fun(*this, &Editor::marker_menu_rename)));
                items.push_back (MenuElem (_("Remove Range"), mem_fun(*this, &Editor::marker_menu_remove)));
@@ -807,6 +814,57 @@ Editor::marker_menu_set_playhead ()
        }
 }
 
+void
+Editor::marker_menu_export_range ()
+{
+       Marker* marker;
+
+       if ((marker = reinterpret_cast<Marker *> (marker_menu_item->get_data ("marker"))) == 0) {
+               fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
+               /*NOTREACHED*/
+       }
+
+       Location* l;
+       bool is_start;
+
+       if ((l = find_location_from_marker (marker, is_start)) != 0) {
+               if (l->is_range_marker()) {
+                       export_range (l->start(), l->end());
+               }
+       }
+}
+
+void
+Editor::marker_menu_range_to_next ()
+{
+       Marker* marker;
+       if (!session) {
+               return;
+       }
+
+       if ((marker = reinterpret_cast<Marker *> (marker_menu_item->get_data ("marker"))) == 0) {
+               fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
+               /*NOTREACHED*/
+       }
+
+       Location* l;
+       bool is_start;
+
+       if ((l = find_location_from_marker (marker, is_start)) == 0) {
+               return;
+       }
+               
+       nframes_t end = session->locations()->first_mark_after (marker->position());
+
+       if (end != max_frames) {
+               string range_name = l->name();
+               range_name += "-range";
+
+               Location* newrange = new Location (marker->position(), end, range_name, Location::IsRangeMarker);
+               session->locations()->add (newrange);
+       }
+}
+
 void
 Editor::marker_menu_set_from_playhead ()
 {
index b7324877403e423a59a04b9efd8c66199c717b6f..5c9208fcfbd0f45a5d11265654f76be4eba33ade 100644 (file)
@@ -191,7 +191,7 @@ Editor::update_current_screen ()
 {
        if (session && session->engine().running()) {
 
-               nframes_t frame;
+               nframes64_t frame;
 
                frame = session->audible_frame();
 
@@ -253,11 +253,7 @@ Editor::update_current_screen ()
                } else {
                        
                        if (frame != last_update_frame) {
-                               if (frame < leftmost_frame || frame > leftmost_frame + current_page_frames()) {
-                                       playhead_cursor->canvas_item.hide();
-                               } else {
-                                       playhead_cursor->set_position (frame);
-                               }
+                               playhead_cursor->set_position (frame);
                        }
                }
 
index e1d320e386f05eb1b50e7cc71cd5c8ae36e79fe9..384f40fdf6bbc8313b202a445ffb450661371230 100644 (file)
@@ -598,6 +598,25 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
 bool
 Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
 {
+       Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas->get_window();
+       
+       if (canvas_window) {
+               Glib::RefPtr<const Gdk::Window> pointer_window;
+               int x, y;
+               double wx, wy;
+               Gdk::ModifierType mask;
+
+               pointer_window = canvas_window->get_pointer (x, y, mask);
+               
+               if (pointer_window == track_canvas->get_bin_window()) {
+                       
+                       track_canvas->window_to_world (x, y, wx, wy);
+                       allow_vertical_scroll = true;
+               } else {
+                       allow_vertical_scroll = false;
+               }
+       }
+
        track_canvas->grab_focus();
 
        if (session && session->actively_recording()) {
@@ -959,7 +978,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
 bool
 Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
 {
-       nframes_t where = event_frame (event, 0, 0);
+       nframes64_t where = event_frame (event, 0, 0);
        AutomationTimeAxisView* atv = 0;
 
        /* no action if we're recording */
@@ -1705,7 +1724,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
                
                track_canvas->get_pointer (x, y);
        } 
-       
+
        if (current_stepping_trackview) {
                /* don't keep the persistent stepped trackview if the mouse moves */
                current_stepping_trackview = 0;
@@ -1993,15 +2012,16 @@ Editor::start_fade_in_grab (ArdourCanvas::Item* item, GdkEvent* event)
 
        AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
 
-       drag_info.pointer_frame_offset = drag_info.grab_frame - ((nframes_t) arv->audio_region()->fade_in()->back()->when + arv->region()->position()); 
+
+       drag_info.pointer_frame_offset = drag_info.grab_frame - ((nframes64_t) arv->audio_region()->fade_in()->back()->when + arv->region()->position());       
 }
 
 void
 Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
        AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
-       nframes_t pos;
-       nframes_t fade_length;
+       nframes64_t pos;
+       nframes64_t fade_length;
 
        if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -2043,8 +2063,8 @@ void
 Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
        AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
-       nframes_t pos;
-       nframes_t fade_length;
+       nframes64_t pos;
+       nframes64_t fade_length;
 
        if (drag_info.first_move) return;
 
@@ -2101,15 +2121,15 @@ Editor::start_fade_out_grab (ArdourCanvas::Item* item, GdkEvent* event)
 
        AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
 
-       drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region()->length() - (nframes_t) arv->audio_region()->fade_out()->back()->when + arv->region()->position());      
+       drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region()->length() - (nframes64_t) arv->audio_region()->fade_out()->back()->when + arv->region()->position());    
 }
 
 void
 Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
        AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
-       nframes_t pos;
-       nframes_t fade_length;
+       nframes64_t pos;
+       nframes64_t fade_length;
 
        if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -2155,8 +2175,8 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve
        if (drag_info.first_move) return;
 
        AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
-       nframes_t pos;
-       nframes_t fade_length;
+       nframes64_t pos;
+       nframes64_t fade_length;
 
        if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -2239,7 +2259,7 @@ void
 Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
        Cursor* cursor = (Cursor *) drag_info.data;
-       nframes_t adjusted_frame;
+       nframes64_t adjusted_frame;
        
        if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -2362,21 +2382,21 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
 void
 Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
-       nframes_t f_delta;      
+       nframes64_t f_delta;    
        Marker* marker = (Marker *) drag_info.data;
        Location  *real_location;
        Location  *copy_location;
        bool is_start;
        bool move_both = false;
 
-       nframes_t newframe;
+       nframes64_t newframe;
        if (drag_info.pointer_frame_offset <= drag_info.current_pointer_frame) {
                newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
        } else {
                newframe = 0;
        }
 
-       nframes_t next = newframe;
+       nframes64_t next = newframe;
 
        if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
                snap_to (newframe, 0, true);
@@ -2562,7 +2582,7 @@ void
 Editor::meter_marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
        MeterMarker* marker = (MeterMarker *) drag_info.data;
-       nframes_t adjusted_frame;
+       nframes64_t adjusted_frame;
 
        if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -2694,7 +2714,7 @@ void
 Editor::tempo_marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
        TempoMarker* marker = (TempoMarker *) drag_info.data;
-       nframes_t adjusted_frame;
+       nframes64_t adjusted_frame;
        
        if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -2866,7 +2886,7 @@ Editor::control_point_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent*
        cy = min ((double) (cp->line().y_position() + cp->line().height()), cy);
 
        //translate cx to frames
-       nframes_t cx_frames = unit_to_frame (cx);
+       nframes64_t cx_frames = unit_to_frame (cx);
 
        if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && !drag_info.x_constrained) {
                snap_to (cx_frames);
@@ -2939,7 +2959,7 @@ Editor::start_line_grab (AutomationLine* line, GdkEvent* event)
 {
        double cx;
        double cy;
-       nframes_t frame_within_region;
+       nframes64_t frame_within_region;
 
        /* need to get x coordinate in terms of parent (TimeAxisItemView)
           origin.
@@ -2948,7 +2968,7 @@ Editor::start_line_grab (AutomationLine* line, GdkEvent* event)
        cx = event->button.x;
        cy = event->button.y;
        line->parent_group().w2i (cx, cy);
-       frame_within_region = (nframes_t) floor (cx * frames_per_unit);
+       frame_within_region = (nframes64_t) floor (cx * frames_per_unit);
 
        if (!line->control_points_adjacent (frame_within_region, current_line_drag_info.before, 
                                            current_line_drag_info.after)) {
@@ -3057,7 +3077,7 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
                speed = tv->get_diskstream()->speed();
        }
        
-       drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed);
+       drag_info.last_frame_position = (nframes64_t) (clicked_regionview->region()->position() / speed);
        drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
        drag_info.source_trackview = &clicked_regionview->get_time_axis_view();
        drag_info.dest_trackview = drag_info.source_trackview;
@@ -3106,7 +3126,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
        
        drag_info.source_trackview = &clicked_regionview->get_time_axis_view();
        drag_info.dest_trackview = drag_info.source_trackview;
-       drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed);
+       drag_info.last_frame_position = (nframes64_t) (clicked_regionview->region()->position() / speed);
        drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
        // we want a move threshold
        drag_info.want_move_threshold = true;
@@ -3138,7 +3158,7 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event)
                speed = tv->get_diskstream()->speed();
        }
        
-       drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed);
+       drag_info.last_frame_position = (nframes64_t) (clicked_regionview->region()->position() / speed);
        drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
        drag_info.source_trackview = &clicked_regionview->get_time_axis_view();
        drag_info.dest_trackview = drag_info.source_trackview;
@@ -3164,7 +3184,7 @@ Editor::possibly_copy_regions_during_grab (GdkEvent* event)
 
                        RegionView* rv;
                        RegionView* nrv;
-                       
+
                        rv = (*i);
 
                        AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv);
@@ -3309,7 +3329,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        double x_delta;
        double y_delta = 0;
        RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data); 
-       nframes_t pending_region_position = 0;
+       nframes64_t pending_region_position = 0;
        int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order;
        int32_t visible_y_high = 0, visible_y_low = 512;  //high meaning higher numbered.. not the height on the screen
        bool clamp_y_axis = false;
@@ -3363,12 +3383,13 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                                        tracks = tracks |= (0x01 << rtv2->order);
                                }
        
-                               height_list[rtv2->order] = (*i)->height;
+                               height_list[rtv2->order] = (*i)->current_height();
                                children = 1;
+
                                if ((children_list = rtv2->get_child_list()).size() > 0) {
                                        for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) { 
                                                tracks = tracks |= (0x01 << (rtv2->order + children));
-                                               height_list[rtv2->order + children] =  (*j)->height;                
+                                               height_list[rtv2->order + children] =  (*j)->current_height();
                                                numtracks++;
                                                children++;     
                                        }
@@ -3496,8 +3517,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
                if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
 
-                       nframes_t sync_frame;
-                       nframes_t sync_offset;
+                       nframes64_t sync_frame;
+                       nframes64_t sync_offset;
                        int32_t sync_dir;
 
                        pending_region_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -3685,7 +3706,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                  
                                                tvp2 = trackview_by_y_position (iy1 + y_delta);
                                                temp_rtv = dynamic_cast<RouteTimeAxisView*>(tvp2);
-                                               rv->set_y_position_and_height (0, temp_rtv->height);
+                                               rv->set_y_position_and_height (0, temp_rtv->current_height());
 
                                                /*   if you un-comment the following, the region colours will follow the track colours whilst dragging,
                                                     personally, i think this can confuse things, but never mind.
@@ -3837,7 +3858,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                double speed;
                bool changed_tracks;
                bool changed_position;
-               nframes_t where;
+               nframes64_t where;
 
                if (rv->region()->locked()) {
                        ++i;
@@ -3852,11 +3873,11 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                        speed = dest_rtv->get_diskstream()->speed();
                }
                
-               changed_position = (drag_info.last_frame_position != (nframes_t) (rv->region()->position()/speed));
+               changed_position = (drag_info.last_frame_position != (nframes64_t) (rv->region()->position()/speed));
                changed_tracks = (dest_tv != &rv->get_time_axis_view());
 
                if (changed_position && !drag_info.x_constrained) {
-                       where = (nframes_t) (unit_to_frame (ix1) * speed);
+                       where = (nframes64_t) (unit_to_frame (ix1) * speed);
                } else {
                        where = rv->region()->position();
                }
@@ -3869,6 +3890,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                
                boost::shared_ptr<Region> new_region;
 
+
                if (drag_info.copy) {
                        /* we already made a copy */
                        new_region = rv->region();
@@ -3918,7 +3940,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                        /* get the playlist where this drag started. we can't use rv->region()->playlist()
                           because we may have copied the region and it has not been attached to a playlist.
                        */
-                       
+
                        assert ((source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view())));
                        assert ((ds = source_tv->get_diskstream()));
                        assert ((from_playlist = ds->playlist()));
@@ -4036,7 +4058,7 @@ Editor::create_region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent
                begin_reversible_command (_("create region"));
                XMLNode &before = mtv->playlist()->get_state();
 
-               nframes_t start = drag_info.grab_frame;
+               nframes64_t start = drag_info.grab_frame;
                snap_to (start, -1);
                const Meter& m = session->tempo_map().meter_at(start);
                const Tempo& t = session->tempo_map().tempo_at(start);
@@ -4078,28 +4100,28 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event)
 
                        if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
                                
-                               align_region (rv.region(), SyncPoint, (nframes_t) (where * speed));
+                               align_region (rv.region(), SyncPoint, (nframes64_t) (where * speed));
                                
                        } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
                                
-                               align_region (rv.region(), End, (nframes_t) (where * speed));
+                               align_region (rv.region(), End, (nframes64_t) (where * speed));
                                
                        } else {
                                
-                               align_region (rv.region(), Start, (nframes_t) (where * speed));
+                               align_region (rv.region(), Start, (nframes64_t) (where * speed));
                        }
                }
        }
 }
 
 void
-Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, double ypos) 
+Editor::show_verbose_time_cursor (nframes64_t frame, double offset, double xpos, double ypos) 
 {
        char buf[128];
        SMPTE::Time smpte;
        BBT_Time bbt;
        int hours, mins;
-       nframes_t frame_rate;
+       nframes64_t frame_rate;
        float secs;
 
        if (session == 0) {
@@ -4137,7 +4159,7 @@ Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, d
                break;
 
        default:
-               snprintf (buf, sizeof(buf), "%u", frame);
+               snprintf (buf, sizeof(buf), "%" PRIi64, frame);
                break;
        }
 
@@ -4151,14 +4173,14 @@ Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, d
 }
 
 void
-Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double offset, double xpos, double ypos) 
+Editor::show_verbose_duration_cursor (nframes64_t start, nframes64_t end, double offset, double xpos, double ypos) 
 {
        char buf[128];
        SMPTE::Time smpte;
        BBT_Time sbbt;
        BBT_Time ebbt;
        int hours, mins;
-       nframes_t distance, frame_rate;
+       nframes64_t distance, frame_rate;
        float secs;
        Meter meter_at_start(session->tempo_map().meter_at(start));
 
@@ -4219,7 +4241,7 @@ Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double off
                break;
 
        default:
-               snprintf (buf, sizeof(buf), "%u", end - start);
+               snprintf (buf, sizeof(buf), "%" PRIi64, end - start);
                break;
        }
 
@@ -4331,8 +4353,8 @@ Editor::cancel_selection ()
 void
 Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, SelectionOp op)
 {
-       nframes_t start = 0;
-       nframes_t end = 0;
+       nframes64_t start = 0;
+       nframes64_t end = 0;
 
        if (session == 0) {
                return;
@@ -4389,10 +4411,10 @@ Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, Selection
 void
 Editor::drag_selection (ArdourCanvas::Item* item, GdkEvent* event)
 {
-       nframes_t start = 0;
-       nframes_t end = 0;
-       nframes_t length;
-       nframes_t pending_position;
+       nframes64_t start = 0;
+       nframes64_t end = 0;
+       nframes64_t length;
+       nframes64_t pending_position;
 
        if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pending_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -4550,9 +4572,9 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event)
                speed = tv->get_diskstream()->speed();
        }
        
-       nframes_t region_start = (nframes_t) (clicked_regionview->region()->position() / speed);
-       nframes_t region_end = (nframes_t) (clicked_regionview->region()->last_frame() / speed);
-       nframes_t region_length = (nframes_t) (clicked_regionview->region()->length() / speed);
+       nframes64_t region_start = (nframes64_t) (clicked_regionview->region()->position() / speed);
+       nframes64_t region_end = (nframes64_t) (clicked_regionview->region()->last_frame() / speed);
+       nframes64_t region_length = (nframes64_t) (clicked_regionview->region()->length() / speed);
 
        //drag_info.item = clicked_regionview->get_name_highlight();
        drag_info.item = item;
@@ -4591,7 +4613,7 @@ void
 Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
        RegionView* rv = clicked_regionview;
-       nframes_t frame_delta = 0;
+       nframes64_t frame_delta = 0;
        bool left_direction;
        bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier());
 
@@ -4676,7 +4698,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                }
                
        case EndTrim:
-               if ((left_direction == true) && (drag_info.current_pointer_frame > (nframes_t) (rv->region()->last_frame()/speed))) {
+               if ((left_direction == true) && (drag_info.current_pointer_frame > (nframes64_t) (rv->region()->last_frame()/speed))) {
                        break;
                } else {
                        for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
@@ -4704,10 +4726,10 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
        switch (trim_op) {
        case StartTrim:
-               show_verbose_time_cursor((nframes_t) (rv->region()->position()/speed), 10);     
+               show_verbose_time_cursor((nframes64_t) (rv->region()->position()/speed), 10);   
                break;
        case EndTrim:
-               show_verbose_time_cursor((nframes_t) (rv->region()->last_frame()/speed), 10);   
+               show_verbose_time_cursor((nframes64_t) (rv->region()->last_frame()/speed), 10); 
                break;
        case ContentsTrim:
                show_verbose_time_cursor(drag_info.current_pointer_frame, 10);  
@@ -4719,7 +4741,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 }
 
 void
-Editor::single_contents_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap)
+Editor::single_contents_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap)
 {
        boost::shared_ptr<Region> region (rv.region());
 
@@ -4727,7 +4749,7 @@ Editor::single_contents_trim (RegionView& rv, nframes_t frame_delta, bool left_d
                return;
        }
 
-       nframes_t new_bound;
+       nframes64_t new_bound;
 
        double speed = 1.0;
        TimeAxisView* tvp = clicked_axisview;
@@ -4739,27 +4761,27 @@ Editor::single_contents_trim (RegionView& rv, nframes_t frame_delta, bool left_d
        
        if (left_direction) {
                if (swap_direction) {
-                       new_bound = (nframes_t) (region->position()/speed) + frame_delta;
+                       new_bound = (nframes64_t) (region->position()/speed) + frame_delta;
                } else {
-                       new_bound = (nframes_t) (region->position()/speed) - frame_delta;
+                       new_bound = (nframes64_t) (region->position()/speed) - frame_delta;
                }
        } else {
                if (swap_direction) {
-                       new_bound = (nframes_t) (region->position()/speed) - frame_delta;
+                       new_bound = (nframes64_t) (region->position()/speed) - frame_delta;
                } else {
-                       new_bound = (nframes_t) (region->position()/speed) + frame_delta;
+                       new_bound = (nframes64_t) (region->position()/speed) + frame_delta;
                }
        }
 
        if (obey_snap) {
                snap_to (new_bound);
        }
-       region->trim_start ((nframes_t) (new_bound * speed), this);     
+       region->trim_start ((nframes64_t) (new_bound * speed), this);   
        rv.region_changed (StartChanged);
 }
 
 void
-Editor::single_start_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool obey_snap)
+Editor::single_start_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool obey_snap)
 {
        boost::shared_ptr<Region> region (rv.region()); 
 
@@ -4767,7 +4789,7 @@ Editor::single_start_trim (RegionView& rv, nframes_t frame_delta, bool left_dire
                return;
        }
 
-       nframes_t new_bound;
+       nframes64_t new_bound;
 
        double speed = 1.0;
        TimeAxisView* tvp = clicked_axisview;
@@ -4778,22 +4800,22 @@ Editor::single_start_trim (RegionView& rv, nframes_t frame_delta, bool left_dire
        }
        
        if (left_direction) {
-               new_bound = (nframes_t) (region->position()/speed) - frame_delta;
+               new_bound = (nframes64_t) (region->position()/speed) - frame_delta;
        } else {
-               new_bound = (nframes_t) (region->position()/speed) + frame_delta;
+               new_bound = (nframes64_t) (region->position()/speed) + frame_delta;
        }
 
        if (obey_snap) {
                snap_to (new_bound, (left_direction ? 0 : 1));  
        }
 
-       region->trim_front ((nframes_t) (new_bound * speed), this);
+       region->trim_front ((nframes64_t) (new_bound * speed), this);
 
        rv.region_changed (Change (LengthChanged|PositionChanged|StartChanged));
 }
 
 void
-Editor::single_end_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool obey_snap)
+Editor::single_end_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool obey_snap)
 {
        boost::shared_ptr<Region> region (rv.region());
 
@@ -4801,7 +4823,7 @@ Editor::single_end_trim (RegionView& rv, nframes_t frame_delta, bool left_direct
                return;
        }
 
-       nframes_t new_bound;
+       nframes64_t new_bound;
 
        double speed = 1.0;
        TimeAxisView* tvp = clicked_axisview;
@@ -4812,15 +4834,15 @@ Editor::single_end_trim (RegionView& rv, nframes_t frame_delta, bool left_direct
        }
        
        if (left_direction) {
-               new_bound = (nframes_t) ((region->last_frame() + 1)/speed) - frame_delta;
+               new_bound = (nframes64_t) ((region->last_frame() + 1)/speed) - frame_delta;
        } else {
-               new_bound = (nframes_t) ((region->last_frame() + 1)/speed) + frame_delta;
+               new_bound = (nframes64_t) ((region->last_frame() + 1)/speed) + frame_delta;
        }
 
        if (obey_snap) {
                snap_to (new_bound);
        }
-       region->trim_end ((nframes_t) (new_bound * speed), this);
+       region->trim_end ((nframes64_t) (new_bound * speed), this);
        rv.region_changed (LengthChanged);
 }
        
@@ -4860,7 +4882,7 @@ void
 Editor::point_trim (GdkEvent* event)
 {
        RegionView* rv = clicked_regionview;
-       nframes_t new_bound = drag_info.current_pointer_frame;
+       nframes64_t new_bound = drag_info.current_pointer_frame;
 
        if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
                snap_to (new_bound);
@@ -5008,8 +5030,8 @@ Editor::start_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event, Ran
 void
 Editor::drag_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
 {
-       nframes_t start = 0;
-       nframes_t end = 0;
+       nframes64_t start = 0;
+       nframes64_t end = 0;
        ArdourCanvas::SimpleRect *crect;
 
        switch (range_marker_op) {
@@ -5140,8 +5162,8 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
 
                if (Keyboard::no_modifier_keys_pressed (&event->button) && range_marker_op != CreateCDMarker) {
 
-                       nframes_t start;
-                       nframes_t end;
+                       nframes64_t start;
+                       nframes64_t end;
 
                        start = session->locations()->first_mark_before (drag_info.grab_frame);
                        end = session->locations()->first_mark_after (drag_info.grab_frame);
@@ -5191,8 +5213,8 @@ Editor::start_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event)
 void
 Editor::drag_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event)
 {
-       nframes_t start;
-       nframes_t end;
+       nframes64_t start;
+       nframes64_t end;
 
        if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
                snap_to (drag_info.current_pointer_frame);
@@ -5252,7 +5274,7 @@ Editor::end_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event)
 }
 
 void
-Editor::reposition_zoom_rect (nframes_t start, nframes_t end)
+Editor::reposition_zoom_rect (nframes64_t start, nframes64_t end)
 {
        double x1 = frame_to_pixel (start);
        double x2 = frame_to_pixel (end);
@@ -5279,8 +5301,8 @@ Editor::start_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
 void
 Editor::drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
 {
-       nframes_t start;
-       nframes_t end;
+       nframes64_t start;
+       nframes64_t end;
        double y1;
        double y2;
 
@@ -5453,7 +5475,7 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event)
                return;
        }
        
-       nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region()->position();
+       nframes64_t newlen = drag_info.last_pointer_frame - clicked_regionview->region()->position();
 
        float percentage = (double) newlen / (double) clicked_regionview->region()->length();
 
@@ -5477,7 +5499,7 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event)
 }
 
 void
-Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos)
+Editor::mouse_brush_insert_region (RegionView* rv, nframes64_t pos)
 {
        /* no brushing without a useful snap setting */
 
@@ -5516,7 +5538,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos)
        double speed = rtv->get_diskstream()->speed();
        
        XMLNode &before = playlist->get_state();
-       playlist->add_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (arv->audio_region())), (nframes_t) (pos * speed));
+       playlist->add_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (arv->audio_region())), (nframes64_t) (pos * speed));
        XMLNode &after = playlist->get_state();
        session->add_command(new MementoCommand<Playlist>(*playlist.get(), &before, &after));
        
@@ -5528,13 +5550,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos)
 gint
 Editor::track_height_step_timeout ()
 {
-       struct timeval now;
-       struct timeval delta;
-       
-       gettimeofday (&now, 0);
-       timersub (&now, &last_track_height_step_timestamp, &delta);
-       
-       if (delta.tv_sec * 1000000 + delta.tv_usec > 250000) { /* milliseconds */
+       if (get_microseconds() - last_track_height_step_timestamp < 250000) {
                current_stepping_trackview = 0;
                return false;
        }
index ffe7c1fe1697f37a2f899a3c10203b5e4c7a4487..fd482a9dd6390c4701e4dfa824152e02616fef11 100644 (file)
@@ -25,6 +25,7 @@
 #include <cmath>
 #include <string>
 #include <map>
+#include <set>
 
 #include <pbd/error.h>
 #include <pbd/basename.h>
@@ -35,6 +36,8 @@
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/choice.h>
 #include <gtkmm2ext/window_title.h>
+#include <gtkmm2ext/popup.h>
+
 
 #include <ardour/audioengine.h>
 #include <ardour/session.h>
@@ -109,7 +112,7 @@ Editor::split_region ()
 }
 
 void
-Editor::split_region_at (nframes_t where)
+Editor::split_region_at (nframes64_t where)
 {
        RegionSelection rs;
 
@@ -118,7 +121,7 @@ Editor::split_region_at (nframes_t where)
 }
 
 void
-Editor::split_regions_at (nframes_t where, RegionSelection& regions)
+Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
 {
        list <boost::shared_ptr<Playlist > > used_playlists;
 
@@ -144,6 +147,8 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
                snap_to (where);
        }
 
+       cerr << "Split " << regions.size() << " at " << where << endl;
+
        for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
 
                RegionSelection::iterator tmp;
@@ -219,21 +224,44 @@ Editor::remove_clicked_region ()
 void
 Editor::remove_selected_regions ()
 {
-       if (selection->regions.empty()) {
+       RegionSelection rs; 
+       get_regions_for_action (rs);
+       
+       if (!session) {
+               return;
+       }
+
+       if (rs.empty()) {
                return;
        }
 
-       /* XXX: should be called remove regions if we're removing more than one */
        begin_reversible_command (_("remove region"));
-       
 
-       while (!selection->regions.empty()) {
-               boost::shared_ptr<Region> region = selection->regions.front()->region ();
-               boost::shared_ptr<Playlist> playlist = region->playlist ();
+       list<boost::shared_ptr<Region> > regions_to_remove;
 
-               XMLNode &before = playlist->get_state();
-               playlist->remove_region (region);
-               XMLNode &after = playlist->get_state();
+       for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+               // we can't just remove the region(s) in this loop because
+               // this removes them from the RegionSelection, and they thus
+               // disappear from underneath the iterator, and the ++i above
+               // SEGVs in a puzzling fashion.
+
+               // so, first iterate over the regions to be removed from rs and
+               // add them to the regions_to_remove list, and then
+               // iterate over the list to actually remove them.
+               
+               regions_to_remove.push_back ((*i)->region());
+       }
+       
+       for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
+               boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
+               if (!playlist) {
+                       // is this check necessary?
+                       continue;
+               }
+
+               XMLNode &before = playlist->get_state();
+               playlist->remove_region (*rl);
+               XMLNode &after = playlist->get_state();
                session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
        }
 
@@ -245,7 +273,7 @@ Editor::select_region_for_operation (int dir, TimeAxisView **tv)
 {
        RegionView* rv;
        boost::shared_ptr<Region> region;
-       nframes_t start = 0;
+       nframes64_t start = 0;
 
        if (selection->time.start () == selection->time.end_frame ()) {
                
@@ -288,7 +316,7 @@ Editor::extend_selection_to_end_of_region (bool next)
 {
        TimeAxisView *tv;
        boost::shared_ptr<Region> region;
-       nframes_t start;
+       nframes64_t start;
 
        if ((region = select_region_for_operation (next ? 1 : 0, &tv)) == 0) {
                return;
@@ -316,7 +344,7 @@ Editor::extend_selection_to_start_of_region (bool previous)
 {
        TimeAxisView *tv;
        boost::shared_ptr<Region> region;
-       nframes_t end;
+       nframes64_t end;
 
        if ((region = select_region_for_operation (previous ? -1 : 0, &tv)) == 0) {
                return;
@@ -365,8 +393,8 @@ Editor::nudge_backward_release (GdkEventButton* ev)
 void
 Editor::nudge_forward (bool next, bool force_playhead)
 {
-       nframes_t distance;
-       nframes_t next_distance;
+       nframes64_t distance;
+       nframes64_t next_distance;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -441,8 +469,8 @@ Editor::nudge_forward (bool next, bool force_playhead)
 void
 Editor::nudge_backward (bool next, bool force_playhead)
 {
-       nframes_t distance;
-       nframes_t next_distance;
+       nframes64_t distance;
+       nframes64_t next_distance;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -528,7 +556,7 @@ Editor::nudge_backward (bool next, bool force_playhead)
 void
 Editor::nudge_forward_capture_offset ()
 {
-       nframes_t distance;
+       nframes64_t distance;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -558,7 +586,7 @@ Editor::nudge_forward_capture_offset ()
 void
 Editor::nudge_backward_capture_offset ()
 {
-       nframes_t distance;
+       nframes64_t distance;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -607,7 +635,7 @@ Editor::move_to_end ()
 void
 Editor::build_region_boundary_cache ()
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        vector<RegionPoint> interesting_points;
        boost::shared_ptr<Region> r;
        TrackViewList tracks;
@@ -650,8 +678,8 @@ Editor::build_region_boundary_cache ()
 
        while (pos < session->current_end_frame() && !at_end) {
 
-               nframes_t rpos;
-               nframes_t lpos = max_frames;
+               nframes64_t rpos;
+               nframes64_t lpos = max_frames;
 
                for (vector<RegionPoint>::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) {
 
@@ -699,7 +727,7 @@ Editor::build_region_boundary_cache ()
                           to sort later.
                        */
 
-                       vector<nframes_t>::iterator ri; 
+                       vector<nframes64_t>::iterator ri; 
                        
                        for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) {
                                if (*ri == rpos) {
@@ -721,20 +749,20 @@ Editor::build_region_boundary_cache ()
 }
 
 boost::shared_ptr<Region>
-Editor::find_next_region (nframes_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
+Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
 {
        TrackViewList::iterator i;
-       nframes_t closest = max_frames;
+       nframes64_t closest = max_frames;
        boost::shared_ptr<Region> ret;
-       nframes_t rpos = 0;
+       nframes64_t rpos = 0;
 
        float track_speed;
-       nframes_t track_frame;
+       nframes64_t track_frame;
        RouteTimeAxisView *rtav;
 
        for (i = tracks.begin(); i != tracks.end(); ++i) {
 
-               nframes_t distance;
+               nframes64_t distance;
                boost::shared_ptr<Region> r;
                
                track_speed = 1.0f;
@@ -866,7 +894,7 @@ void
 Editor::cursor_to_region_point (Cursor* cursor, RegionPoint point, int32_t dir)
 {
        boost::shared_ptr<Region> r;
-       nframes_t pos = cursor->current_frame;
+       nframes64_t pos = cursor->current_frame;
 
        if (!session) {
                return;
@@ -945,7 +973,7 @@ Editor::cursor_to_previous_region_point (Cursor* cursor, RegionPoint point)
 void
 Editor::cursor_to_selection_start (Cursor *cursor)
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -977,7 +1005,7 @@ Editor::cursor_to_selection_start (Cursor *cursor)
 void
 Editor::cursor_to_selection_end (Cursor *cursor)
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -1071,7 +1099,7 @@ void
 Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir)
 {
        boost::shared_ptr<Region> r;
-       nframes_t pos;
+       nframes64_t pos;
        Location* loc;
        bool ignored;
 
@@ -1147,7 +1175,7 @@ Editor::selected_marker_to_previous_region_point (RegionPoint point)
 void
 Editor::selected_marker_to_selection_start ()
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        Location* loc;
        bool ignored;
 
@@ -1186,7 +1214,7 @@ Editor::selected_marker_to_selection_start ()
 void
 Editor::selected_marker_to_selection_end ()
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        Location* loc;
        bool ignored;
 
@@ -1225,8 +1253,8 @@ Editor::selected_marker_to_selection_end ()
 void
 Editor::scroll_playhead (bool forward)
 {
-       nframes_t pos = playhead_cursor->current_frame;
-       nframes_t delta = (nframes_t) floor (current_page_frames() / 0.8);
+       nframes64_t pos = playhead_cursor->current_frame;
+       nframes64_t delta = (nframes64_t) floor (current_page_frames() / 0.8);
 
        if (forward) {
                if (pos == max_frames) {
@@ -1258,8 +1286,8 @@ Editor::scroll_playhead (bool forward)
 void
 Editor::playhead_backward ()
 {
-       nframes_t pos;
-       nframes_t cnt;
+       nframes64_t pos;
+       nframes64_t cnt;
        float prefix;
        bool was_floating;
 
@@ -1267,15 +1295,15 @@ Editor::playhead_backward ()
                cnt = 1;
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate ());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       cnt = (nframes_t) prefix;
+                       cnt = (nframes64_t) prefix;
                }
        }
 
        pos = playhead_cursor->current_frame;
 
-       if ((nframes_t) pos < cnt) {
+       if ((nframes64_t) pos < cnt) {
                pos = 0;
        } else {
                pos -= cnt;
@@ -1292,8 +1320,8 @@ Editor::playhead_backward ()
 void
 Editor::playhead_forward ()
 {
-       nframes_t pos;
-       nframes_t cnt;
+       nframes64_t pos;
+       nframes64_t cnt;
        bool was_floating;
        float prefix;
 
@@ -1301,9 +1329,9 @@ Editor::playhead_forward ()
                cnt = 1;
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate ());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       cnt = (nframes_t) floor (prefix);
+                       cnt = (nframes64_t) floor (prefix);
                }
        }
 
@@ -1362,9 +1390,9 @@ Editor::edit_cursor_backward ()
                cnt = 1;
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate ());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       cnt = (nframes_t) prefix;
+                       cnt = (nframes64_t) prefix;
                }
        }
 
@@ -1384,8 +1412,8 @@ Editor::edit_cursor_backward ()
 void
 Editor::edit_cursor_forward ()
 {
-       //nframes_t pos;
-       nframes_t cnt;
+       //nframes64_t pos;
+       nframes64_t cnt;
        bool was_floating;
        float prefix;
 
@@ -1393,9 +1421,9 @@ Editor::edit_cursor_forward ()
                cnt = 1;
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate ());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       cnt = (nframes_t) floor (prefix);
+                       cnt = (nframes64_t) floor (prefix);
                }
        }
 
@@ -1408,16 +1436,16 @@ Editor::goto_frame ()
 {
        float prefix;
        bool was_floating;
-       nframes_t frame;
+       nframes64_t frame;
 
        if (get_prefix (prefix, was_floating)) {
                return;
        }
 
        if (was_floating) {
-               frame = (nframes_t) floor (prefix * session->frame_rate());
+               frame = (nframes64_t) floor (prefix * session->frame_rate());
        } else {
-               frame = (nframes_t) floor (prefix);
+               frame = (nframes64_t) floor (prefix);
        }
 
        session->request_locate (frame);
@@ -1426,19 +1454,19 @@ Editor::goto_frame ()
 void
 Editor::scroll_backward (float pages)
 {
-       nframes_t frame;
-       nframes_t one_page = (nframes_t) rint (canvas_width * frames_per_unit);
+       nframes64_t frame;
+       nframes64_t one_page = (nframes64_t) rint (canvas_width * frames_per_unit);
        bool was_floating;
        float prefix;
-       nframes_t cnt;
+       nframes64_t cnt;
        
        if (get_prefix (prefix, was_floating)) {
-               cnt = (nframes_t) floor (pages * one_page);
+               cnt = (nframes64_t) floor (pages * one_page);
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate());
                } else {
-                       cnt = (nframes_t) floor (prefix * one_page);
+                       cnt = (nframes64_t) floor (prefix * one_page);
                }
        }
 
@@ -1454,19 +1482,19 @@ Editor::scroll_backward (float pages)
 void
 Editor::scroll_forward (float pages)
 {
-       nframes_t frame;
-       nframes_t one_page = (nframes_t) rint (canvas_width * frames_per_unit);
+       nframes64_t frame;
+       nframes64_t one_page = (nframes64_t) rint (canvas_width * frames_per_unit);
        bool was_floating;
        float prefix;
-       nframes_t cnt;
+       nframes64_t cnt;
        
        if (get_prefix (prefix, was_floating)) {
-               cnt = (nframes_t) floor (pages * one_page);
+               cnt = (nframes64_t) floor (pages * one_page);
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate());
                } else {
-                       cnt = (nframes_t) floor (prefix * one_page);
+                       cnt = (nframes64_t) floor (prefix * one_page);
                }
        }
 
@@ -1581,7 +1609,7 @@ Editor::temporal_zoom (gdouble fpu)
 
        nfpu = fpu;
        
-       new_page_size = (nframes_t) floor (canvas_width * nfpu);
+       new_page_size = (nframes64_t) floor (canvas_width * nfpu);
        half_page_size = new_page_size / 2;
 
        switch (zoom_focus) {
@@ -1681,12 +1709,14 @@ Editor::temporal_zoom (gdouble fpu)
 }      
 
 void
-Editor::temporal_zoom_region ()
+Editor::temporal_zoom_region (bool both_axes)
 {
 
        nframes64_t start = max_frames;
        nframes64_t end = 0;
        RegionSelection rs; 
+       set<TimeAxisView*> tracks;
+       double top_y_position = DBL_MAX;
 
        get_regions_for_action (rs);
 
@@ -1695,12 +1725,20 @@ Editor::temporal_zoom_region ()
        }
 
        for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+
                if ((*i)->region()->position() < start) {
                        start = (*i)->region()->position();
                }
+
                if ((*i)->region()->last_frame() + 1 > end) {
                        end = (*i)->region()->last_frame() + 1;
                }
+
+               tracks.insert (&((*i)->get_time_axis_view()));
+
+               if ((*i)->get_time_axis_view().y_position < top_y_position) {
+                       top_y_position = (*i)->get_time_axis_view().y_position;
+               }
        }
 
        /* now comes an "interesting" hack ... make sure we leave a little space
@@ -1713,8 +1751,15 @@ Editor::temporal_zoom_region ()
        gint mmwidth = gdk_screen_get_width_mm (screen);
        double pix_per_mm = (double) pixwidth/ (double) mmwidth;
        double one_centimeter_in_pixels = pix_per_mm * 10.0;
-       nframes_t extra_samples = unit_to_frame (one_centimeter_in_pixels);
-       
+
+       if ((start == 0 && end == 0) || end < start) {
+               return;
+       }
+
+       nframes64_t range = end - start;
+       double new_fpu = (double)range / (double)canvas_width;
+       nframes64_t extra_samples = (nframes64_t) floor (one_centimeter_in_pixels * new_fpu);
+
        if (start > extra_samples) {
                start -= extra_samples;
        } else {
@@ -1727,17 +1772,53 @@ Editor::temporal_zoom_region ()
                end = max_frames;
        }
 
+       if (both_axes) {
+               /* save visual state with track states included, and prevent
+                  set_frames_per_unit() from doing it again.
+               */
+               undo_visual_stack.push_back (current_visual_state(true));
+               no_save_visual = true;
+       }
+
        temporal_zoom_by_frame (start, end, "zoom to region");
+
+       if (both_axes) {
+               uint32_t per_track_height = (uint32_t) floor ((canvas_height - 10.0) / tracks.size());
+               
+               /* set visible track heights appropriately */
+               
+               for (set<TimeAxisView*>::iterator t = tracks.begin(); t != tracks.end(); ++t) {
+                       (*t)->set_height (per_track_height);
+               }
+               
+               /* hide irrelevant tracks */
+               
+               no_route_list_redisplay = true;
+
+               for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                       if (find (tracks.begin(), tracks.end(), (*i)) == tracks.end()) {
+                               hide_track_in_display (**i, true);
+                       }
+               }
+
+               no_route_list_redisplay = false;
+               redisplay_route_list ();
+
+               vertical_adjustment.set_value (std::max (top_y_position - 5.0, 0.0));
+               no_save_visual = false;
+       }
+
        zoomed_to_region = true;
+       redo_visual_stack.push_back (current_visual_state());
 }
 
 void
-Editor::toggle_zoom_region ()
+Editor::toggle_zoom_region (bool both_axes)
 {
        if (zoomed_to_region) {
                swap_visual_state ();
        } else {
-               temporal_zoom_region ();
+               temporal_zoom_region (both_axes);
        }
 }
 
@@ -1750,8 +1831,8 @@ Editor::temporal_zoom_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
        temporal_zoom_by_frame (start, end, "zoom to selection");
 }
@@ -1762,12 +1843,13 @@ Editor::temporal_zoom_session ()
        ENSURE_GUI_THREAD (mem_fun (*this, &Editor::temporal_zoom_session));
 
        if (session) {
+               last_canvas_frame = ((session->current_end_frame() - session->current_start_frame()) + (current_page_frames() / 24));
                temporal_zoom_by_frame (session->current_start_frame(), session->current_end_frame(), "zoom to session");
        }
 }
 
 void
-Editor::temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & op)
+Editor::temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string & op)
 {
        if (!session) return;
 
@@ -1775,32 +1857,23 @@ Editor::temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & o
                return;
        }
 
-       nframes_t range = end - start;
+       nframes64_t range = end - start;
 
        double new_fpu = (double)range / (double)canvas_width;
-//     double p2 = 1.0;
-
-//     while (p2 < new_fpu) {
-//             p2 *= 2.0;
-//     }
-//     new_fpu = p2;
        
-       nframes_t new_page = (nframes_t) floor (canvas_width * new_fpu);
-       nframes_t middle = (nframes_t) floor( (double)start + ((double)range / 2.0f ));
-       nframes_t new_leftmost = (nframes_t) floor( (double)middle - ((double)new_page/2.0f));
+       nframes64_t new_page = (nframes64_t) floor (canvas_width * new_fpu);
+       nframes64_t middle = (nframes64_t) floor( (double)start + ((double)range / 2.0f ));
+       nframes64_t new_leftmost = (nframes64_t) floor( (double)middle - ((double)new_page/2.0f));
 
-       if (new_leftmost > middle) new_leftmost = 0;
-
-//     begin_reversible_command (op);
-//     session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit));
-//     session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu));
-//     commit_reversible_command ();
+       if (new_leftmost > middle) {
+               new_leftmost = 0;
+       }
 
        reposition_and_zoom (new_leftmost, new_fpu);
 }
 
 void 
-Editor::temporal_zoom_to_frame (bool coarser, nframes_t frame)
+Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
 {
        if (!session) return;
        
@@ -1819,7 +1892,7 @@ Editor::temporal_zoom_to_frame (bool coarser, nframes_t frame)
 
        if (new_fpu == frames_per_unit) return;
 
-       nframes_t new_leftmost = frame - (nframes_t)range_before;
+       nframes64_t new_leftmost = frame - (nframes64_t)range_before;
 
        if (new_leftmost > frame) new_leftmost = 0;
 
@@ -1831,6 +1904,46 @@ Editor::temporal_zoom_to_frame (bool coarser, nframes_t frame)
        reposition_and_zoom (new_leftmost, new_fpu);
 }
 
+
+bool
+Editor::choose_new_marker_name(string &name) {
+
+       if (!Config->get_name_new_markers()) {
+               /* don't prompt user for a new name */
+               return true;
+       }
+
+       ArdourPrompter dialog (true);
+
+       dialog.set_prompt (_("New Name:"));
+
+       WindowTitle title(Glib::get_application_name());
+       title += _("Name New Location Marker");
+
+       dialog.set_title(title.get_string());
+
+       dialog.set_name ("MarkNameWindow");
+       dialog.set_size_request (250, -1);
+       dialog.set_position (Gtk::WIN_POS_MOUSE);
+
+       dialog.add_button (Stock::OK, RESPONSE_ACCEPT);
+       dialog.set_initial_text (name);
+
+       dialog.show ();
+
+       switch (dialog.run ()) {
+       case RESPONSE_ACCEPT:
+               break;
+       default:
+               return false;
+       }
+       
+       dialog.get_result(name);
+       return true;
+
+}
+
+
 void
 Editor::add_location_from_selection ()
 {
@@ -1844,8 +1957,8 @@ Editor::add_location_from_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
        session->locations()->next_available_name(rangename,"selection");
        Location *location = new Location (start, end, rangename, Location::IsRangeMarker);
@@ -1866,6 +1979,9 @@ Editor::add_location_mark (nframes64_t where)
        select_new_marker = true;
 
        session->locations()->next_available_name(markername,"mark");
+       if (!choose_new_marker_name(markername)) {
+               return;
+       }
        Location *location = new Location (where, where, markername, Location::IsMark);
        session->begin_reversible_command (_("add marker"));
         XMLNode &before = session->locations()->get_state();
@@ -1994,7 +2110,7 @@ Editor::jump_backward_to_mark ()
 void
 Editor::set_mark ()
 {
-       nframes_t pos;
+       nframes64_t pos;
        float prefix;
        bool was_floating;
        string markername;
@@ -2003,13 +2119,16 @@ Editor::set_mark ()
                pos = session->audible_frame ();
        } else {
                if (was_floating) {
-                       pos = (nframes_t) floor (prefix * session->frame_rate ());
+                       pos = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       pos = (nframes_t) floor (prefix);
+                       pos = (nframes64_t) floor (prefix);
                }
        }
 
        session->locations()->next_available_name(markername,"mark");
+       if (!choose_new_marker_name(markername)) {
+               return;
+       }
        session->locations()->add (new Location (pos, 0, markername, Location::IsMark), true);
 }
 
@@ -2089,7 +2208,7 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
        double wx, wy;
        double cx, cy;
        TimeAxisView *tv;
-       nframes_t where;
+       nframes64_t where;
        RouteTimeAxisView *rtv = 0;
        boost::shared_ptr<Playlist> playlist;
        
@@ -2545,6 +2664,11 @@ Editor::build_interthread_progress_window ()
 
        interthread_progress_bar.set_orientation (Gtk::PROGRESS_LEFT_TO_RIGHT);
        
+       interthread_progress_window->set_border_width (12);
+       interthread_progress_window->get_vbox()->set_spacing (6);
+
+       interthread_progress_label.set_alignment (0.5, 0.5);
+
        interthread_progress_window->get_vbox()->pack_start (interthread_progress_label, false, false);
        interthread_progress_window->get_vbox()->pack_start (interthread_progress_bar,false, false);
 
@@ -2577,17 +2701,17 @@ Editor::region_from_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
-       nframes_t selection_cnt = end - start + 1;
+       nframes64_t selection_cnt = end - start + 1;
        
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
                boost::shared_ptr<AudioRegion> current;
                boost::shared_ptr<Region> current_r;
                boost::shared_ptr<Playlist> pl;
 
-               nframes_t internal_start;
+               nframes64_t internal_start;
                string new_name;
 
                if ((pl = (*i)->playlist()) == 0) {
@@ -2615,8 +2739,8 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_re
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
        
        sort_track_selection ();
 
@@ -2625,7 +2749,7 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_re
                boost::shared_ptr<AudioRegion> current;
                boost::shared_ptr<Region> current_r;
                boost::shared_ptr<Playlist> playlist;
-               nframes_t internal_start;
+               nframes64_t internal_start;
                string new_name;
 
                if ((playlist = (*i)->playlist()) == 0) {
@@ -2762,7 +2886,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
                                                sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
                                                latest_regionviews.clear ();
 
-                                               playlist->partition ((nframes_t)((*t).start * speed), (nframes_t)((*t).end * speed), true);
+                                               playlist->partition ((nframes64_t)((*t).start * speed), (nframes64_t)((*t).end * speed), true);
 
                                                c.disconnect ();
 
@@ -2879,7 +3003,7 @@ Editor::crop_region_to_selection ()
 }              
 
 void
-Editor::crop_region_to (nframes_t start, nframes_t end)
+Editor::crop_region_to (nframes64_t start, nframes64_t end)
 {
        vector<boost::shared_ptr<Playlist> > playlists;
        boost::shared_ptr<Playlist> playlist;
@@ -2913,9 +3037,9 @@ Editor::crop_region_to (nframes_t start, nframes_t end)
                return;
        }
                
-       nframes_t the_start;
-       nframes_t the_end;
-       nframes_t cnt;
+       nframes64_t the_start;
+       nframes64_t the_end;
+       nframes64_t cnt;
        
        begin_reversible_command (_("trim to selection"));
        
@@ -2933,7 +3057,7 @@ Editor::crop_region_to (nframes_t start, nframes_t end)
                   if the selection extends beyond the region
                */
                
-               the_start = max (the_start, region->position());
+               the_start = max (the_start, (nframes64_t) region->position());
                if (max_frames - the_start < region->length()) {
                        the_end = the_start + region->length() - 1;
                } else {
@@ -2954,7 +3078,7 @@ Editor::crop_region_to (nframes_t start, nframes_t end)
 void
 Editor::region_fill_track ()
 {
-       nframes_t end;
+       nframes64_t end;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -3016,8 +3140,8 @@ Editor::region_fill_selection ()
        TreeModel::iterator i = region_list_display.get_selection()->get_selected();
        boost::shared_ptr<Region> region = (*i)[region_list_columns.region];
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
        boost::shared_ptr<Playlist> playlist; 
 
@@ -3025,7 +3149,7 @@ Editor::region_fill_selection ()
                return;
        }
 
-       nframes_t selection_length = end - start;
+       nframes64_t selection_length = end - start;
        float times = (float)selection_length / region->length();
        
        begin_reversible_command (_("fill selection"));
@@ -3086,16 +3210,22 @@ Editor::set_sync_point (nframes64_t where, const RegionSelection& rs)
 void
 Editor::remove_region_sync ()
 {
-       begin_reversible_command (_("remove sync"));
+       RegionSelection rs; 
 
-       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-               boost::shared_ptr<Region> r = (*i)->region();
-               XMLNode &before = r->playlist()->get_state();
-               r->clear_sync_position ();
-                XMLNode &after = r->playlist()->get_state();
-               session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
+       get_regions_for_action (rs);
+
+       if (rs.empty()) {
+               return;
        }
 
+       begin_reversible_command (_("remove sync"));
+       for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+
+                XMLNode &before = (*i)->region()->playlist()->get_state();
+               (*i)->region()->clear_sync_position ();
+                XMLNode &after = (*i)->region()->playlist()->get_state();
+               session->add_command(new MementoCommand<Playlist>(*((*i)->region()->playlist()), &before, &after));
+       }
        commit_reversible_command ();
 }
 
@@ -3158,18 +3288,19 @@ struct RegionSortByTime {
 };
 
 void
-Editor::align_selection_relative (RegionPoint point, nframes_t position, const RegionSelection& rs)
+Editor::align_selection_relative (RegionPoint point, nframes64_t position, const RegionSelection& rs)
 {
        if (rs.empty()) {
                return;
        }
 
-       nframes_t distance = 0;
-       nframes_t pos = 0;
+       nframes64_t distance;
+       nframes64_t pos = 0;
        int dir = 0;
 
        list<RegionView*> sorted;
        rs.by_position (sorted);
+
        boost::shared_ptr<Region> r ((*sorted.begin())->region());
 
        switch (point) {
@@ -3246,7 +3377,7 @@ Editor::align_selection_relative (RegionPoint point, nframes_t position, const R
 }
 
 void
-Editor::align_selection (RegionPoint point, nframes_t position, const RegionSelection& rs)
+Editor::align_selection (RegionPoint point, nframes64_t position, const RegionSelection& rs)
 {
        if (rs.empty()) {
                return;
@@ -3262,7 +3393,7 @@ Editor::align_selection (RegionPoint point, nframes_t position, const RegionSele
 }
 
 void
-Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nframes_t position)
+Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
 {
        begin_reversible_command (_("align region"));
        align_region_internal (region, point, position);
@@ -3270,7 +3401,7 @@ Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nfram
 }
 
 void
-Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, nframes_t position)
+Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
 {
        XMLNode &before = region->playlist()->get_state();
 
@@ -3346,8 +3477,8 @@ Editor::trim_region_to_location (const Location& loc, const char* str)
                }
 
                float speed = 1.0;
-               nframes_t start;
-               nframes_t end;
+               nframes64_t start;
+               nframes64_t end;
 
                if (atav->get_diskstream() != 0) {
                        speed = atav->get_diskstream()->speed();
@@ -3537,7 +3668,7 @@ Editor::freeze_route ()
 }
 
 void
-Editor::bounce_range_selection ()
+Editor::bounce_range_selection (bool replace)
 {
        if (selection->time.empty()) {
                return;
@@ -3545,9 +3676,9 @@ Editor::bounce_range_selection ()
 
        TrackSelection views = selection->tracks;
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
-       nframes_t cnt = end - start + 1;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
+       nframes64_t cnt = end - start + 1;
 
        begin_reversible_command (_("bounce range"));
 
@@ -3571,9 +3702,17 @@ Editor::bounce_range_selection ()
                itt.cancel = false;
                itt.progress = false;
 
-               XMLNode &before = playlist->get_state();
-               rtv->track()->bounce_range (start, cnt, itt);
-               XMLNode &after = playlist->get_state();
+                XMLNode &before = playlist->get_state();
+               boost::shared_ptr<Region> r = rtv->track()->bounce_range (start, start+cnt, itt);
+               
+               if (replace) {
+                       list<AudioRange> ranges;
+                       ranges.push_back (AudioRange (start, start+cnt, 0));
+                       playlist->cut (ranges); // discard result
+                       playlist->add_region (r, start);
+               }
+
+                XMLNode &after = playlist->get_state();
                session->add_command (new MementoCommand<Playlist> (*playlist, &before, &after));
        }
        
@@ -3642,6 +3781,19 @@ Editor::cut_copy (CutCopyOp op)
                opname = _("clear");
                break;
        }
+
+       /* if we're deleting something, and the mouse is still pressed,
+          the thing we started a drag for will be gone when we release
+          the mouse button(s). avoid this. see part 2 at the end of
+          this function.
+       */
+
+       if (op == Cut || op == Clear) {
+               if (drag_info.item) {
+                       drag_info.item->ungrab (0);
+                       drag_info.item = 0;
+               }
+       }
        
        cut_buffer->clear ();
 
@@ -3656,6 +3808,8 @@ Editor::cut_copy (CutCopyOp op)
                        Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::really_remove_marker), loc));
                }
 
+               break_drag ();
+
                return;
        }
 
@@ -3720,6 +3874,11 @@ Editor::cut_copy (CutCopyOp op)
        default:
                break;
        }
+
+
+       if (op == Cut || op == Clear) {
+               break_drag ();
+       }
 }
 
 /** Cut, copy or clear selected automation points.
@@ -3769,7 +3928,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
 
        vector<PlaylistMapping> pmap;
 
-       nframes_t first_position = max_frames;
+       nframes64_t first_position = max_frames;
        
        set<PlaylistState, lt_playlist> freezelist;
        pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
@@ -3780,7 +3939,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
 
        for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
 
-               first_position = min ((*x)->region()->position(), first_position);
+               first_position = min ((nframes64_t) (*x)->region()->position(), first_position);
 
                if (op == Cut || op == Clear) {
                        boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
@@ -3934,7 +4093,7 @@ Editor::mouse_paste ()
 }
 
 void
-Editor::paste_internal (nframes_t position, float times)
+Editor::paste_internal (nframes64_t position, float times)
 {
        bool commit = false;
 
@@ -4152,9 +4311,9 @@ void
 Editor::nudge_track (bool use_edit, bool forwards)
 {
        boost::shared_ptr<Playlist> playlist; 
-       nframes_t distance;
-       nframes_t next_distance;
-       nframes_t start;
+       nframes64_t distance;
+       nframes64_t next_distance;
+       nframes64_t start;
 
        if (use_edit) {
                start = get_preferred_edit_position();
@@ -4442,7 +4601,7 @@ Editor::external_edit_region ()
 }
 
 void
-Editor::brush (nframes_t pos)
+Editor::brush (nframes64_t pos)
 {
        RegionSelection sel;
        RegionSelection rs; 
@@ -4586,7 +4745,7 @@ Editor::set_fade_length (bool in)
        }
 
        nframes64_t pos = get_preferred_edit_position();
-       nframes_t len;
+       nframes64_t len;
        char* cmd;
        
        if (pos > rv->region()->last_frame() || pos < rv->region()->first_frame()) {
@@ -5029,8 +5188,8 @@ Editor::set_loop_from_selection (bool play)
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
        
        set_loop_range (start, end,  _("set loop range from selection"));
 
@@ -5100,8 +5259,8 @@ Editor::set_punch_from_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
        
        set_punch_range (start, end,  _("set punch range from selection"));
 }
@@ -5517,14 +5676,13 @@ Editor::tab_to_transient (bool forward)
                }
        }
 }
-
 void
 Editor::playhead_forward_to_grid ()
 {
        if (!session) return;
        nframes64_t pos = playhead_cursor->current_frame;
-       if (pos < max_frames) {
-               pos++;
+       if (pos < max_frames - 1) {
+               pos += 2;
                snap_to_internal (pos, 1, false);
                session->request_locate (pos);
        }
@@ -5536,15 +5694,15 @@ Editor::playhead_backward_to_grid ()
 {
        if (!session) return;
        nframes64_t pos = playhead_cursor->current_frame;
-       if (pos > 1) {
-               pos--;
+       if (pos > 2) {
+               pos -= 2;
                snap_to_internal (pos, -1, false);
                session->request_locate (pos);
        }
 }
 
 void
-Editor::set_track_height (TimeAxisView::TrackHeight h)
+Editor::set_track_height (uint32_t h)
 {
        TrackSelection& ts (selection->tracks);
 
@@ -5560,32 +5718,32 @@ Editor::set_track_height (TimeAxisView::TrackHeight h)
 void
 Editor::set_track_height_largest ()
 {
-       set_track_height (TimeAxisView::Largest);
+       set_track_height (TimeAxisView::hLargest);
 }
 void
 Editor::set_track_height_large ()
 {
-       set_track_height (TimeAxisView::Large);
+       set_track_height (TimeAxisView::hLarge);
 }
 void
 Editor::set_track_height_larger ()
 {
-       set_track_height (TimeAxisView::Larger);
+       set_track_height (TimeAxisView::hLarger);
 }
 void
 Editor::set_track_height_normal ()
 {
-       set_track_height (TimeAxisView::Normal);
+       set_track_height (TimeAxisView::hNormal);
 }
 void
 Editor::set_track_height_smaller ()
 {
-       set_track_height (TimeAxisView::Smaller);
+       set_track_height (TimeAxisView::hSmaller);
 }
 void
 Editor::set_track_height_small ()
 {
-       set_track_height (TimeAxisView::Small);
+       set_track_height (TimeAxisView::hSmall);
 }
 
 void
@@ -5725,7 +5883,8 @@ Editor::do_insert_time ()
        RadioButton move_button (group, _("Move"));
        RadioButton split_button (group, _("Split & Later Section Moves"));
        Label intersect_option_label (_("Intersected regions should:"));
-       ToggleButton glue_button (_("Move Glued Regions"));
+       CheckButton glue_button (_("Move Glued Regions"));
+       CheckButton marker_button (_("Move Markers"));
        AudioClock clock ("insertTimeClock", true, X_("InsertTimeClock"), true, true, true);
        HBox clock_box;
 
@@ -5739,6 +5898,7 @@ Editor::do_insert_time ()
        option_box.pack_start (intersect_option_label, false, false);
        option_box.pack_start (button_box, false, false);
        option_box.pack_start (glue_button, false, false);
+       option_box.pack_start (marker_button, false, false);
 
        button_box.pack_start (leave_button, false, false);
        button_box.pack_start (move_button, false, false);
@@ -5757,6 +5917,7 @@ Editor::do_insert_time ()
        glue_button.show ();
        clock.show_all();
        clock_box.show ();
+       marker_button.show ();
 
        d.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
        d.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
@@ -5768,7 +5929,7 @@ Editor::do_insert_time ()
                return;
        }
        
-       nframes_t distance = clock.current_duration (pos);
+       nframes64_t distance = clock.current_duration (pos);
 
        if (distance == 0) {
                return;
@@ -5784,11 +5945,12 @@ Editor::do_insert_time ()
                opt = SplitIntersected;
        }
 
-       insert_time (pos, distance, opt, glue_button.get_active());
+       insert_time (pos, distance, opt, glue_button.get_active(), marker_button.get_active());
 }
-                               
+
 void
-Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, bool ignore_music_glue)
+Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, 
+                    bool ignore_music_glue, bool markers_too)
 {
        bool commit = false;
 
@@ -5819,7 +5981,130 @@ Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
                commit = true;
        }
 
+       if (markers_too) {
+               bool moved = false;
+               XMLNode& before (session->locations()->get_state());
+               Locations::LocationList copy (session->locations()->list());
+
+               for (Locations::LocationList::iterator i = copy.begin(); i != copy.end(); ++i) {
+                       
+                       Locations::LocationList::const_iterator tmp;
+
+                       if ((*i)->start() >= pos) {
+                               (*i)->set_start ((*i)->start() + frames);
+                               if (!(*i)->is_mark()) {
+                                       (*i)->set_end ((*i)->end() + frames);
+                               }
+                               moved = true;
+                       }
+               }
+
+               if (moved) {
+                       XMLNode& after (session->locations()->get_state());
+                       session->add_command (new MementoCommand<Locations>(*session->locations(), &before, &after));
+               }
+       }
+
        if (commit) {
                commit_reversible_command ();
        }
 }
+
+void
+Editor::fit_tracks ()
+{
+       if (selection->tracks.empty()) {
+               return;
+       }
+
+       uint32_t child_heights = 0;
+
+       for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
+
+               if (!(*t)->marked_for_display()) {
+                       continue;
+               }
+
+               child_heights += ((*t)->effective_height - (*t)->current_height());
+       }
+
+       uint32_t h = (uint32_t) floor ((canvas_height - child_heights)/selection->tracks.size());
+       double first_y_pos = DBL_MAX;
+
+       undo_visual_stack.push_back (current_visual_state());
+       
+       for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
+               (*t)->set_height (h);
+               first_y_pos = std::min ((*t)->y_position, first_y_pos);
+       }
+
+
+       vertical_adjustment.set_value (first_y_pos);
+
+       redo_visual_stack.push_back (current_visual_state());
+}
+
+void
+Editor::save_visual_state (uint32_t n)
+{
+       while (visual_states.size() <= n) {
+               visual_states.push_back (0);
+       }
+
+       if (visual_states[n] != 0) {
+               delete visual_states[n];
+       }
+
+       visual_states[n] = current_visual_state (true);
+       gdk_beep ();
+}
+
+void
+Editor::goto_visual_state (uint32_t n)
+{
+       if (visual_states.size() <= n) {
+               return;
+       }
+
+       if (visual_states[n] == 0) {
+               return;
+       }
+
+       use_visual_state (*visual_states[n]);
+}
+
+void
+Editor::start_visual_state_op (uint32_t n)
+{
+       cerr << "Start\n";
+       if (visual_state_op_connection.empty()) {
+               cerr << "\tqueue\n";
+               visual_state_op_connection = Glib::signal_timeout().connect (bind (mem_fun (*this, &Editor::end_visual_state_op), n), 1000);
+       }
+}
+
+void
+Editor::cancel_visual_state_op (uint32_t n)
+{
+       cerr << "Cancel\n";
+       if (!visual_state_op_connection.empty()) {
+               cerr << "\tgoto\n";
+               visual_state_op_connection.disconnect();
+               goto_visual_state (n);
+       } 
+}
+
+bool
+Editor::end_visual_state_op (uint32_t n)
+{
+       visual_state_op_connection.disconnect();
+       save_visual_state (n);
+       
+       PopUp* pup = new PopUp (WIN_POS_MOUSE, 1000, true);
+       char buf[32];
+       snprintf (buf, sizeof (buf), _("Saved view %u"), n+1);
+       pup->set_text (buf);
+       pup->touch();
+
+       return false; // do not call again
+}
index c9067cacfe58d0d060fa08453bd234569fc9b1c1..54bc71e074792164c6a5ed00f35e638db16dfa20 100644 (file)
@@ -134,6 +134,18 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
 
        } else if (region->whole_file()) {
 
+               TreeModel::iterator i;
+               TreeModel::Children rows = region_list_model->children();
+
+               for (i = rows.begin(); i != rows.end(); ++i) {
+                       
+                       boost::shared_ptr<Region> rr = (*i)[region_list_columns.region];
+
+                       if (region->region_list_equivalent (rr)) {
+                               return;
+                       }
+               }
+
                row = *(region_list_model->append());
                if (missing_source) {
                        c.set_rgb(65535,0,0);     // FIXME: error color from style
@@ -203,6 +215,18 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
                                        break;
                                }
                        }
+
+                       TreeModel::iterator ii;
+                       TreeModel::Children subrows = (*i).children();
+
+                       for (ii = subrows.begin(); ii != subrows.end(); ++ii) {
+                               
+                               boost::shared_ptr<Region> rrr = (*ii)[region_list_columns.region];
+
+                               if (region->region_list_equivalent (rrr)) {
+                                       return;
+                               }
+                       }
                }
 
                if (!found_parent) {
@@ -307,6 +331,10 @@ Editor::insert_into_tmp_regionlist(boost::shared_ptr<Region> region)
 void
 Editor::redisplay_regions ()
 {
+       if (no_region_list_redisplay) {
+               return;
+       }
+               
        if (session) {
 
                region_list_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0));
index 65202cb0dbed2cc051bab3854a302fba0e5304de..c12a30ca73e6e8086be174c25f640f33fa41e4ea 100644 (file)
@@ -148,10 +148,17 @@ Editor::handle_gui_changes (const string & what, void *src)
        ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_gui_changes), what, src));
        
        if (what == "track_height") {
+               /* make tracks change height while it happens, instead 
+                  of on first-idle
+               */
+               track_canvas->update_now ();
                redisplay_route_list ();
        }
-}
 
+       if (what == "visible_tracks") {
+               redisplay_route_list ();
+       }
+}
 
 void
 Editor::remove_route (TimeAxisView *tv)
@@ -162,6 +169,10 @@ Editor::remove_route (TimeAxisView *tv)
        TreeModel::Children rows = route_display_model->children();
        TreeModel::Children::iterator ri;
 
+       if (tv == entered_track) {
+               entered_track = 0;
+       }
+
        /* Decrement old order keys for tracks `above' the one that is being removed */
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
                TimeAxisView* v = (*ri)[route_display_columns.tv];
@@ -209,11 +220,27 @@ Editor::route_name_changed (TimeAxisView *tv)
                        break;
                }
        } 
+}
+
+void
+Editor::update_route_visibility ()
+{
+       TreeModel::Children rows = route_display_model->children();
+       TreeModel::Children::iterator i;
+       
+       no_route_list_redisplay = true;
 
+       for (i = rows.begin(); i != rows.end(); ++i) {
+               TimeAxisView *tv = (*i)[route_display_columns.tv];
+               (*i)[route_display_columns.visible] = tv->marked_for_display ();
+       }
+
+       no_route_list_redisplay = false;
+       redisplay_route_list ();
 }
 
 void
-Editor::hide_track_in_display (TimeAxisView& tv)
+Editor::hide_track_in_display (TimeAxisView& tv, bool temponly)
 {
        TreeModel::Children rows = route_display_model->children();
        TreeModel::Children::iterator i;
@@ -221,6 +248,9 @@ Editor::hide_track_in_display (TimeAxisView& tv)
        for (i = rows.begin(); i != rows.end(); ++i) {
                if ((*i)[route_display_columns.tv] == &tv) { 
                        (*i)[route_display_columns.visible] = false;
+                       // if (temponly) {
+                       tv.set_marked_for_display (false);
+                       // }
                        break;
                }
        }
@@ -598,7 +628,6 @@ Editor::route_list_delete (const Gtk::TreeModel::Path& path)
        redisplay_route_list ();
 }
 
-
 void  
 Editor::route_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
                                                int x, int y, 
@@ -616,7 +645,6 @@ Editor::route_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& c
        context->drag_finish (true, false, time);
 }
 
-
 RouteTimeAxisView*
 Editor::get_route_view_by_id (PBD::ID& id)
 {
index 02e8f70727419a1b9c5fcdbe729688714b5eabd5..dc62f669f88a495476a4f8a8bdaaf1facf2b7243 100644 (file)
@@ -95,7 +95,7 @@ Editor::initialize_rulers ()
 bool
 Editor::ruler_scroll (GdkEventScroll* event)
 {
-       nframes_t xdelta;
+       nframes64_t xdelta;
        int direction = event->direction;
        bool handled = false;
 
@@ -168,7 +168,7 @@ Editor::ruler_button_press (GdkEventButton* ev)
        /* need to use the correct x,y, the event lies */
        time_canvas_event_box.get_window()->get_pointer (x, y, state);
 
-       nframes_t where = leftmost_frame + pixel_to_frame (x);
+       nframes64_t where = leftmost_frame + pixel_to_frame (x);
 
        switch (ev->button) {
        case 1:
@@ -212,7 +212,7 @@ Editor::ruler_button_release (GdkEventButton* ev)
 
        stop_canvas_autoscroll();
        
-       nframes_t where = leftmost_frame + pixel_to_frame (x);
+       nframes64_t where = leftmost_frame + pixel_to_frame (x);
 
        switch (ev->button) {
        case 1:
@@ -280,10 +280,10 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev)
        track_canvas->c2w (x, y, wcx, wcy);
        track_canvas->w2c (wcx, wcy, cx, cy);
        
-       nframes_t where = leftmost_frame + pixel_to_frame (x);
+       nframes64_t where = leftmost_frame + pixel_to_frame (x);
 
        /// ripped from maybe_autoscroll, and adapted to work here
-       nframes_t rightmost_frame = leftmost_frame + current_page_frames ();
+       nframes64_t rightmost_frame = leftmost_frame + current_page_frames ();
 
        jack_nframes_t frame = pixel_to_frame (cx);
 
@@ -336,7 +336,7 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev)
 
 
 void
-Editor::popup_ruler_menu (nframes_t where, ItemType t)
+Editor::popup_ruler_menu (nframes64_t where, ItemType t)
 {
        using namespace Menu_Helpers;
 
@@ -750,8 +750,8 @@ Editor::update_ruler_visibility ()
        time_canvas_event_box.show_all();
        time_button_frame.show_all();
 
-       compute_current_bbt_points (leftmost_frame, leftmost_frame + (nframes_t)(edit_packer.get_width() * frames_per_unit));
-       compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + (nframes_t)(edit_packer.get_width() * frames_per_unit));
+       compute_current_bbt_points (leftmost_frame, leftmost_frame + (nframes64_t)(edit_packer.get_width() * frames_per_unit));
+       compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + (nframes64_t)(edit_packer.get_width() * frames_per_unit));
 
        redisplay_tempo (false);
 }
@@ -765,7 +765,7 @@ Editor::update_just_smpte ()
                return;
        }
 
-       nframes_t rightmost_frame = leftmost_frame + current_page_frames();
+       nframes64_t rightmost_frame = leftmost_frame + current_page_frames();
 
        if (ruler_timecode_action->get_active()) {
                gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_smpte_ruler), leftmost_frame, rightmost_frame,
@@ -792,7 +792,7 @@ Editor::compute_fixed_ruler_scale ()
 void
 Editor::update_fixed_rulers ()
 {
-       nframes_t rightmost_frame;
+       nframes64_t rightmost_frame;
 
        if (session == 0) {
                return;
@@ -868,9 +868,9 @@ Editor::_metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble u
 void
 Editor::set_smpte_ruler_scale (gdouble lower, gdouble upper)
 {
-       nframes_t range;
-       nframes_t spacer;
-       nframes_t fr;
+       nframes64_t range;
+       nframes64_t spacer;
+       nframes64_t fr;
 
        if (session == 0) {
                return;
@@ -878,13 +878,13 @@ Editor::set_smpte_ruler_scale (gdouble lower, gdouble upper)
 
        fr = session->frame_rate();
 
-       if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+       if (lower > (spacer = (nframes64_t)(128 * Editor::get_current_zoom ()))) {
                lower = lower - spacer;
        } else {
                lower = 0;
        }
        upper = upper + spacer;
-       range = (nframes_t) floor (upper - lower);
+       range = (nframes64_t) floor (upper - lower);
 
        if (range < (2 * session->frames_per_smpte_frame())) { /* 0 - 2 frames */
                smpte_ruler_scale = smpte_show_bits;
@@ -893,19 +893,19 @@ Editor::set_smpte_ruler_scale (gdouble lower, gdouble upper)
        } else if (range <= (fr / 4)) { /* 2 frames - 0.250 second */
                smpte_ruler_scale = smpte_show_frames;
                smpte_mark_modulo = 1;
-               smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
+               smpte_nmarks = 2 + (range / (nframes64_t)session->frames_per_smpte_frame());
        } else if (range <= (fr / 2)) { /* 0.25-0.5 second */
                smpte_ruler_scale = smpte_show_frames;
                smpte_mark_modulo = 2;
-               smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
+               smpte_nmarks = 2 + (range / (nframes64_t)session->frames_per_smpte_frame());
        } else if (range <= fr) { /* 0.5-1 second */
                smpte_ruler_scale = smpte_show_frames;
                smpte_mark_modulo = 5;
-               smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
+               smpte_nmarks = 2 + (range / (nframes64_t)session->frames_per_smpte_frame());
        } else if (range <= 2 * fr) { /* 1-2 seconds */
                smpte_ruler_scale = smpte_show_frames;
                smpte_mark_modulo = 10;
-               smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
+               smpte_nmarks = 2 + (range / (nframes64_t)session->frames_per_smpte_frame());
        } else if (range <= 8 * fr) { /* 2-8 seconds */
                smpte_ruler_scale = smpte_show_seconds;
                smpte_mark_modulo = 1;
@@ -956,7 +956,7 @@ Editor::set_smpte_ruler_scale (gdouble lower, gdouble upper)
                smpte_nmarks = 2 + 24;
        } else {
     
-               /* not possible if nframes_t is a 32 bit quantity */
+               /* not possible if nframes64_t is a 32 bit quantity */
     
                smpte_ruler_scale = smpte_show_hours;
                smpte_mark_modulo = 4;
@@ -969,7 +969,7 @@ gint
 Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
 {
        nframes_t pos;
-       nframes_t spacer;
+       nframes64_t spacer;
        SMPTE::Time smpte;
        gchar buf[16];
        gint n;
@@ -978,7 +978,7 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
                return 0;
        }
 
-       if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+       if (lower > (spacer = (nframes64_t)(128 * Editor::get_current_zoom ()))) {
                lower = lower - spacer;
        } else {
                lower = 0;
@@ -1124,7 +1124,7 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
 
 
 void
-Editor::compute_bbt_ruler_scale (nframes_t lower, nframes_t upper)
+Editor::compute_bbt_ruler_scale (nframes64_t lower, nframes64_t upper)
 {
         if (session == 0) {
                 return;
@@ -1219,15 +1219,15 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
 
         char buf[64];
         gint  n = 0;
-       nframes_t pos;
+       nframes64_t pos;
        BBT_Time next_beat;
-       nframes_t next_beat_pos;
+       nframes64_t next_beat_pos;
         uint32_t beats = 0;
 
        uint32_t tick = 0;
        uint32_t skip;
        uint32_t t;
-       nframes_t frame_skip;
+       nframes64_t frame_skip;
        double frame_skip_error;
        double bbt_position_of_helper;
        double accumulated_error;
@@ -1330,7 +1330,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                                
                        next_beat_pos = session->tempo_map().frame_time(next_beat);
                        
-                       frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() *  60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+                       frame_skip = (nframes64_t) floor (frame_skip_error = (session->frame_rate() *  60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
                        frame_skip_error -= frame_skip;
                        skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
 
@@ -1348,7 +1348,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                                snprintf (buf, sizeof(buf), " ");
                                (*marks)[n].label = g_strdup (buf);
 
-                               /* Error compensation for float to nframes_t*/
+                               /* Error compensation for float to nframes64_t*/
                                accumulated_error += frame_skip_error;
                                if (accumulated_error > 1) {
                                        pos += 1;
@@ -1422,7 +1422,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                                
                        next_beat_pos = session->tempo_map().frame_time(next_beat);
                        
-                       frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() *  60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+                       frame_skip = (nframes64_t) floor (frame_skip_error = (session->frame_rate() *  60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
                        frame_skip_error -= frame_skip;
                        skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
 
@@ -1445,7 +1445,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
 
                                (*marks)[n].label = g_strdup (buf);
 
-                               /* Error compensation for float to nframes_t*/
+                               /* Error compensation for float to nframes64_t*/
                                accumulated_error += frame_skip_error;
                                if (accumulated_error > 1) {
                                        pos += 1;
@@ -1519,7 +1519,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                                
                        next_beat_pos = session->tempo_map().frame_time(next_beat);
                        
-                       frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() *  60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+                       frame_skip = (nframes64_t) floor (frame_skip_error = (session->frame_rate() *  60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
                        frame_skip_error -= frame_skip;
                        skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
 
@@ -1542,7 +1542,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
 
                                  (*marks)[n].label = g_strdup (buf);
 
-                                 /* Error compensation for float to nframes_t*/
+                                 /* Error compensation for float to nframes64_t*/
                                  accumulated_error += frame_skip_error;
                                  if (accumulated_error > 1) {
                                          pos += 1;
@@ -1683,10 +1683,10 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
 gint
 Editor::metric_get_frames (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
 {
-       nframes_t mark_interval;
-       nframes_t pos;
-       nframes_t ilower = (nframes_t) floor (lower);
-       nframes_t iupper = (nframes_t) floor (upper);
+       nframes64_t mark_interval;
+       nframes64_t pos;
+       nframes64_t ilower = (nframes64_t) floor (lower);
+       nframes64_t iupper = (nframes64_t) floor (upper);
        gchar buf[16];
        gint nmarks;
        gint n;
@@ -1714,15 +1714,15 @@ Editor::metric_get_frames (GtkCustomRulerMark **marks, gdouble lower, gdouble up
 }
 
 static void
-sample_to_clock_parts ( nframes_t sample,
-                       nframes_t sample_rate, 
+sample_to_clock_parts ( nframes64_t sample,
+                       nframes64_t sample_rate, 
                        long *hrs_p,
                        long *mins_p,
                        long *secs_p,
                        long *millisecs_p)
 
 {
-       nframes_t left;
+       nframes64_t left;
        long hrs;
        long mins;
        long secs;
@@ -1748,9 +1748,9 @@ sample_to_clock_parts ( nframes_t sample,
 void
 Editor::set_minsec_ruler_scale (gdouble lower, gdouble upper)
 {
-       nframes_t range;
-       nframes_t fr;
-       nframes_t spacer;
+       nframes64_t range;
+       nframes64_t fr;
+       nframes64_t spacer;
 
        if (session == 0) {
                return;
@@ -1759,13 +1759,13 @@ Editor::set_minsec_ruler_scale (gdouble lower, gdouble upper)
        fr = session->frame_rate();
 
        /* to prevent 'flashing' */
-       if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+       if (lower > (spacer = (nframes64_t)(128 * Editor::get_current_zoom ()))) {
                lower -= spacer;
        } else {
                lower = 0;
        }
        upper += spacer;
-       range = (nframes_t) (upper - lower);
+       range = (nframes64_t) (upper - lower);
 
        if (range <  (fr / 50)) {
                minsec_mark_interval =  fr / 1000; /* show 1/1000 seconds */
@@ -1837,7 +1837,7 @@ Editor::set_minsec_ruler_scale (gdouble lower, gdouble upper)
                minsec_mark_modulo = 2;
         } else {
                                                                                                                    
-                /* not possible if nframes_t is a 32 bit quantity */
+                /* not possible if nframes64_t is a 32 bit quantity */
                                                                                                                    
                 minsec_mark_interval = 4 * 60 * 60 * fr; /* show 4 hrs */
         }
@@ -1847,8 +1847,8 @@ Editor::set_minsec_ruler_scale (gdouble lower, gdouble upper)
 gint
 Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
 {
-       nframes_t pos;
-       nframes_t spacer;
+       nframes64_t pos;
+       nframes64_t spacer;
        long hrs, mins, secs, millisecs;
        gchar buf[16];
        gint n;
@@ -1858,14 +1858,14 @@ Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble up
        }
 
        /* to prevent 'flashing' */
-       if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+       if (lower > (spacer = (nframes64_t)(128 * Editor::get_current_zoom ()))) {
                lower = lower - spacer;
        } else {
                lower = 0;
        }
 
        *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * minsec_nmarks);
-       pos = ((((nframes_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
+       pos = ((((nframes64_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
        switch (minsec_ruler_scale) {
        case minsec_show_seconds:
                for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
index 9d0347e0e2c222533958eafcf63a00bdb4280ca6..f35391cff5dd8b4d0738c685c267bcca2a3a1852 100644 (file)
@@ -18,7 +18,7 @@
 */
 
 #include <algorithm>
-#include <stdlib.h>
+#include <cstdlib>
 
 #include <pbd/stacktrace.h>
 
@@ -235,7 +235,7 @@ Editor::set_selected_control_point_from_click (Selection::Operation op, bool no_
        /* select this point and any others that it represents */
 
        double y1, y2;
-       nframes_t x1, x2;
+       nframes64_t x1, x2;
 
        x1 = pixel_to_frame (clicked_control_point->get_x() - 10);
        x2 = pixel_to_frame (clicked_control_point->get_x() + 10);
@@ -449,8 +449,8 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
        } else if (op == Selection::Extend) {
 
                list<Selectable*> results;
-               nframes_t last_frame;
-               nframes_t first_frame;
+               nframes64_t last_frame;
+               nframes64_t first_frame;
                bool same_track = false;
 
                /* 1. find the last selected regionview in the track that was clicked in */
@@ -909,7 +909,7 @@ Editor::invert_selection ()
 }
 
 bool
-Editor::select_all_within (nframes_t start, nframes_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op)
+Editor::select_all_within (nframes64_t start, nframes64_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op)
 {
        list<Selectable*> touched;
        list<Selectable*>::size_type n = 0;
@@ -1029,8 +1029,8 @@ Editor::select_all_selectables_using_time_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
        if (end - start < 1)  {
                return;
@@ -1122,8 +1122,8 @@ Editor::select_all_selectables_using_loop()
 void
 Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
 {
-        nframes_t start;
-       nframes_t end;
+        nframes64_t start;
+       nframes64_t end;
        list<Selectable *> touched;
 
        if (after) {
@@ -1162,8 +1162,8 @@ Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
 void
 Editor::select_all_selectables_using_edit (bool after)
 {
-        nframes_t start;
-       nframes_t end;
+        nframes64_t start;
+       nframes64_t end;
        list<Selectable *> touched;
 
        if (after) {
index c9bd50607b8289be03490cd50188331497353d83..1e5c02f5d8bcf2d2ca1106f1c14485a9892cb82e 100644 (file)
@@ -210,7 +210,7 @@ Editor::draw_measures ()
 }
 
 void
-Editor::mouse_add_new_tempo_event (nframes_t frame)
+Editor::mouse_add_new_tempo_event (nframes64_t frame)
 {
        if (session == 0) {
                return;
@@ -252,7 +252,7 @@ Editor::mouse_add_new_tempo_event (nframes_t frame)
 }
 
 void
-Editor::mouse_add_new_meter_event (nframes_t frame)
+Editor::mouse_add_new_meter_event (nframes64_t frame)
 {
        if (session == 0) {
                return;
index 652973ca2698f05e5b432154e706b943bfaa00fa..6628be711615b5c9d492c7e2b4ec8773a6787516 100644 (file)
@@ -279,7 +279,6 @@ Editor::time_fx (RegionSelection& regions, float val, bool pitching)
        bool realtime = false;
        bool precise = false;
        bool peaklock = true;
-       bool softening = true;
        bool longwin = false;
        bool shortwin = false;
        string txt;
@@ -314,7 +313,6 @@ Editor::time_fx (RegionSelection& regions, float val, bool pitching)
        if (realtime)    options |= RubberBandStretcher::OptionProcessRealTime;
        if (precise)     options |= RubberBandStretcher::OptionStretchPrecise;
        if (!peaklock)   options |= RubberBandStretcher::OptionPhaseIndependent;
-       if (!softening)  options |= RubberBandStretcher::OptionPhasePeakLocked;
        if (longwin)     options |= RubberBandStretcher::OptionWindowLong;
        if (shortwin)    options |= RubberBandStretcher::OptionWindowShort;
                
index ab02a051c251cb3cae2e0b72617406ec88e890bd..7d8f29cce46c3c5f2a11b27e2033c03fa4b97884 100644 (file)
@@ -452,11 +452,19 @@ EngineControl::build_command_line (vector<string>& cmd)
                        
                } else if (str == _("Playback/Recording on 2 Devices")) {
                        
+                       string input_device = get_device_name (driver, input_device_combo.get_active_text());
+                       string output_device = get_device_name (driver, output_device_combo.get_active_text());
+
+                       if (input_device.empty() || output_device.empty()) {
+                               cmd.clear ();
+                               return;
+                       }
+
                        cmd.push_back ("-C");
-                       cmd.push_back (get_device_name (driver, input_device_combo.get_active_text()));
+                       cmd.push_back (input_device);
                        cmd.push_back ("-P");
-                       cmd.push_back (get_device_name (driver, output_device_combo.get_active_text()));
-                       
+                       cmd.push_back (output_device);
+
                } else if (str == _("Playback only")) {
                        cmd.push_back ("-P");
                } else if (str == _("Recording only")) {
@@ -478,8 +486,15 @@ EngineControl::build_command_line (vector<string>& cmd)
        if (using_alsa) {
                
                if (audio_mode_combo.get_active_text() != _("Playback/Recording on 2 Devices")) {
+
+                       string device = get_device_name (driver, interface_combo.get_active_text());
+                       if (device.empty()) {
+                               cmd.clear ();
+                               return;
+                       }
+
                        cmd.push_back ("-d");
-                       cmd.push_back (get_device_name (driver, interface_combo.get_active_text()));
+                       cmd.push_back (device);
                } 
 
                if (hw_meter_button.get_active()) {
@@ -513,8 +528,15 @@ EngineControl::build_command_line (vector<string>& cmd)
 
 #ifdef __APPLE__
                // note: older versions of the CoreAudio JACK backend use -n instead of -d here
+               
+               string device = get_device_name (driver, interface_combo.get_active_text());
+               if (device.empty()) {
+                       cmd.clear ();
+                       return;
+               }
+
                cmd.push_back ("-d");
-               cmd.push_back (get_device_name (driver, interface_combo.get_active_text()));
+               cmd.push_back (device);
 #endif
 
        } else if (using_oss) {
@@ -544,6 +566,10 @@ EngineControl::setup_engine ()
        std::string cwd = "/tmp";
 
        build_command_line (args);
+       
+       if (args.empty()) {
+               return 1; // try again
+       }
 
        Glib::ustring jackdrc_path = Glib::get_home_dir();
        jackdrc_path += "/.jackdrc";
@@ -990,6 +1016,15 @@ EngineControl::get_device_name (const string& driver, const string& human_readab
        vector<string>::iterator n;
        vector<string>::iterator i;
 
+       if (human_readable.empty()) {
+               /* this can happen if the user's .ardourrc file has a device name from
+                  another computer system in it
+               */
+               MessageDialog msg (_("You need to choose an audio device first."));
+               msg.run ();
+               return string();
+       }
+
        if (backend_devs.empty()) {
                return human_readable;
        }
@@ -1001,12 +1036,9 @@ EngineControl::get_device_name (const string& driver, const string& human_readab
        }
        
        if (i == devices[driver].end()) {
-               fatal << string_compose (_("programming error: %1"), "true hardware name for ID missing") << endmsg;
-               /*NOTREACHED*/
+               warning << string_compose (_("Audio device \"%1\" not known on this computer."), human_readable) << endmsg;
        }
 
-       /* keep gcc happy */
-
        return string();
 }
 
index db741d66ed58bffbc7b4655f991dbb1cf1dd7838..ef99bf43bf8059330c507686e5c70ac5c3274c9b 100644 (file)
@@ -975,8 +975,9 @@ ExportDialog::do_export ()
        progress_connection = Glib::signal_timeout().connect (mem_fun(*this, &ExportDialog::progress_timeout), 100);
        cancel_label.set_text (_("Stop Export"));
 
+       session->pre_export ();
        export_data();
-       
+
        progress_connection.disconnect ();
        end_dialog ();
 }
@@ -996,7 +997,7 @@ ExportDialog::end_dialog ()
                }
        }
 
-       session->finalize_audio_export ();
+       session->finalize_export ();
 
        hide_all ();
 
@@ -1017,6 +1018,7 @@ ExportDialog::start_export ()
        */
        
        if (file_entry.get_text().length() == 0) {
+
                sys::path export_file_path = session->session_directory().export_path();
 
                if (!wants_dir()) {
@@ -1229,7 +1231,7 @@ ExportDialog::initSpec(string &filepath)
 {
        spec.path = filepath;
        spec.progress = 0;
-       spec.running = true;
+       spec.running = false;
        spec.stop = false;
        spec.port_map.clear();
        
index 8bb93eb4aa0214e8d19880be37f9e9e60fbad0ac..bf2f0e3989aba2f44ca00dfbb45895a1badfcc67 100644 (file)
@@ -81,8 +81,6 @@ ExportRangeMarkersDialog::process_range_markers_export(Locations::LocationList&
                        spec.start_frame = currentLocation->start();
                        spec.end_frame = currentLocation->end();
 
-                       getSession().request_locate(spec.start_frame, false);
-
                        if (getSession().start_export(spec)){
                                // if export fails                      
                                return;
@@ -100,6 +98,8 @@ ExportRangeMarkersDialog::process_range_markers_export(Locations::LocationList&
                        }
                        
                        current_range_marker_index++;
+                       
+                       getSession().stop_export (spec);
                }
        }
        
index 0e51b7a68c6fda06fad42245897dd24670a029b6..107b0eedfc9bf67dea492b42db0bc7c4daec87f2 100644 (file)
@@ -57,42 +57,49 @@ using namespace Gtk;
 using namespace sigc;
 using namespace std;
 
-sigc::signal<void> GainMeter::ResetAllPeakDisplays;
-sigc::signal<void,RouteGroup*> GainMeter::ResetGroupPeakDisplays;
-Glib::RefPtr<Gdk::Pixbuf> GainMeter::slider;
-Glib::RefPtr<Gdk::Pixbuf> GainMeter::rail;
+sigc::signal<void> GainMeterBase::ResetAllPeakDisplays;
+sigc::signal<void,RouteGroup*> GainMeterBase::ResetGroupPeakDisplays;
+
 map<string,Glib::RefPtr<Gdk::Pixmap> > GainMeter::metric_pixmaps;
+Glib::RefPtr<Gdk::Pixbuf> GainMeter::slider;
 
-int
+
+void
 GainMeter::setup_slider_pix ()
 {
-       slider = ::get_icon ("fader_belt");
-       return 0;
+       if ((slider = ::get_icon ("fader_belt")) == 0) {
+               throw failed_constructor();
+       }
 }
 
-GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
+GainMeterBase::GainMeterBase (boost::shared_ptr<IO> io, Session& s, 
+                             const Glib::RefPtr<Gdk::Pixbuf>& pix,
+                             bool horizontal)
        : _io (io),
          _session (s),
-         gain_slider (0),
          // 0.781787 is the value needed for gain to be set to 0.
          gain_adjustment (0.781787, 0.0, 1.0, 0.01, 0.1),
          gain_automation_style_button (""),
          gain_automation_state_button ("")
        
 {
-       if (slider == 0) {
-               setup_slider_pix ();
-       }
-
        ignore_toggle = false;
        meter_menu = 0;
        next_release_selects = false;
        style_changed = true;
+       _width = Wide;
 
-       gain_slider = manage (new VSliderController (slider,
-                                                    &gain_adjustment,
-                                                    *_io->gain_control().get(),
-                                                    false));
+       if (horizontal) {
+               gain_slider = manage (new HSliderController (pix,
+                                                            &gain_adjustment,
+                                                            _io->gain_control(),
+                                                            false));
+       } else {
+               gain_slider = manage (new VSliderController (pix,
+                                                            &gain_adjustment,
+                                                            _io->gain_control(),
+                                                            false));
+       }
 
        level_meter = new LevelMeter(_io, _session);
 
@@ -107,11 +114,6 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
        gain_display.signal_focus_in_event().connect (mem_fun (*this, &GainMeter::gain_focused), false);
        gain_display.signal_focus_out_event().connect (mem_fun (*this, &GainMeter::gain_focused), false);
 
-       gain_display_box.set_name ("MeterMetricsStrip");
-       gain_display_box.set_homogeneous (true);
-       gain_display_box.set_spacing (2);
-       gain_display_box.pack_start (gain_display, true, true);
-
        peak_display.set_name ("MixerStripPeakDisplay");
 //     peak_display.set_has_frame (false);
 //     peak_display.set_editable (false);
@@ -120,9 +122,6 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
        peak_display.set_label (_("-inf"));
        peak_display.unset_flags (Gtk::CAN_FOCUS);
 
-       meter_metric_area.set_name ("MeterMetricsStrip");
-       set_size_request_to_display_given_text (meter_metric_area, "-50", 0, 0);
-
        gain_automation_style_button.set_name ("MixerAutomationModeButton");
        gain_automation_state_button.set_name ("MixerAutomationPlaybackButton");
 
@@ -135,193 +134,67 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
        gain_automation_state_button.set_size_request(15, 15);
        gain_automation_style_button.set_size_request(15, 15);
 
-       HBox* fader_centering_box = manage (new HBox);
-       fader_centering_box->pack_start (*gain_slider, true, false);
-
-       fader_vbox = manage (new Gtk::VBox());
-       fader_vbox->set_spacing (0);
-       fader_vbox->pack_start (*fader_centering_box, false, false, 0);
 
-       hbox.set_spacing (2);
 
-       if (_io->default_type() == ARDOUR::DataType::AUDIO) {
-               hbox.pack_start (*fader_vbox, true, true);
-       }
-       
-       set_width (Narrow);
 
-       Route* r;
 
-       if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+       boost::shared_ptr<Route> r;
 
-               /* 
-                  if we have a non-hidden route (ie. we're not the click or the auditioner), 
-                  pack some route-dependent stuff.
-               */
+       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
 
-               gain_display_box.pack_end (peak_display, true, true);
-               hbox.pack_end (*level_meter, true, true);
+               if (!r->is_hidden()) {
 
-               using namespace Menu_Helpers;
-       
-               gain_astate_menu.items().push_back (MenuElem (_("Manual"), 
-                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
-                                                                 Parameter(GainAutomation), (AutoState) Off)));
-               gain_astate_menu.items().push_back (MenuElem (_("Play"),
-                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
-                                                                 Parameter(GainAutomation), (AutoState) Play)));
-               gain_astate_menu.items().push_back (MenuElem (_("Write"),
-                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
-                                                                 Parameter(GainAutomation), (AutoState) Write)));
-               gain_astate_menu.items().push_back (MenuElem (_("Touch"),
-                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
-                                                                 Parameter(GainAutomation), (AutoState) Touch)));
-       
-               gain_astyle_menu.items().push_back (MenuElem (_("Trim")));
-               gain_astyle_menu.items().push_back (MenuElem (_("Abs")));
+                       using namespace Menu_Helpers;
        
-               gain_astate_menu.set_name ("ArdourContextMenu");
-               gain_astyle_menu.set_name ("ArdourContextMenu");
-
-               gain_automation_style_button.signal_button_press_event().connect (mem_fun(*this, &GainMeter::gain_automation_style_button_event), false);
-               gain_automation_state_button.signal_button_press_event().connect (mem_fun(*this, &GainMeter::gain_automation_state_button_event), false);
-               
-               r->gain_control()->list()->automation_state_changed.connect (mem_fun(*this, &GainMeter::gain_automation_state_changed));
-               r->gain_control()->list()->automation_style_changed.connect (mem_fun(*this, &GainMeter::gain_automation_style_changed));
-               fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
+                       gain_astate_menu.items().push_back (MenuElem (_("Manual"), 
+                                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+                                                                           Parameter(GainAutomation), (AutoState) Off)));
+                       gain_astate_menu.items().push_back (MenuElem (_("Play"),
+                                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+                                                                           Parameter(GainAutomation), (AutoState) Play)));
+                       gain_astate_menu.items().push_back (MenuElem (_("Write"),
+                                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+                                                                           Parameter(GainAutomation), (AutoState) Write)));
+                       gain_astate_menu.items().push_back (MenuElem (_("Touch"),
+                                                                     bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+                                                                           Parameter(GainAutomation), (AutoState) Touch)));
+                       
+                       gain_astyle_menu.items().push_back (MenuElem (_("Trim")));
+                       gain_astyle_menu.items().push_back (MenuElem (_("Abs")));
+                       
+                       gain_astate_menu.set_name ("ArdourContextMenu");
+                       gain_astyle_menu.set_name ("ArdourContextMenu");
+                       
+                       gain_automation_style_button.signal_button_press_event().connect (mem_fun(*this, &GainMeterBase::gain_automation_style_button_event), false);
+                       gain_automation_state_button.signal_button_press_event().connect (mem_fun(*this, &GainMeterBase::gain_automation_state_button_event), false);
+                       
+                       r->gain_control()->list()->automation_state_changed.connect (mem_fun(*this, &GainMeter::gain_automation_state_changed));
+                       r->gain_control()->list()->automation_style_changed.connect (mem_fun(*this, &GainMeter::gain_automation_style_changed));
 
-               gain_automation_state_changed ();
+                       gain_automation_state_changed ();
+               }
        }
 
-       set_spacing (2);
-
-       pack_start (gain_display_box, Gtk::PACK_SHRINK);
-       pack_start (hbox, Gtk::PACK_SHRINK);
-
-       _io->gain_control()->Changed.connect (mem_fun(*this, &GainMeter::gain_changed));
+       _io->gain_control()->Changed.connect (mem_fun(*this, &GainMeterBase::gain_changed));
 
-       meter_metric_area.signal_expose_event().connect (mem_fun(*this, &GainMeter::meter_metrics_expose));
-       gain_adjustment.signal_value_changed().connect (mem_fun(*this, &GainMeter::gain_adjusted));
-       peak_display.signal_button_release_event().connect (mem_fun(*this, &GainMeter::peak_button_release), false);
-       gain_display.signal_key_press_event().connect (mem_fun(*this, &GainMeter::gain_key_press), false);
+       gain_adjustment.signal_value_changed().connect (mem_fun(*this, &GainMeterBase::gain_adjusted));
+       peak_display.signal_button_release_event().connect (mem_fun(*this, &GainMeterBase::peak_button_release), false);
+       gain_display.signal_key_press_event().connect (mem_fun(*this, &GainMeterBase::gain_key_press), false);
 
        gain_changed ();
        show_gain ();
 
        update_gain_sensitive ();
        
-       ResetAllPeakDisplays.connect (mem_fun(*this, &GainMeter::reset_peak_display));
-       ResetGroupPeakDisplays.connect (mem_fun(*this, &GainMeter::reset_group_peak_display));
-
-       UI::instance()->theme_changed.connect (mem_fun(*this, &GainMeter::on_theme_changed));
-
-       ColorsChanged.connect (bind (mem_fun (*this, &GainMeter::color_handler), false));
-       DPIReset.connect (bind (mem_fun (*this, &GainMeter::color_handler), true));
+       ResetAllPeakDisplays.connect (mem_fun(*this, &GainMeterBase::reset_peak_display));
+       ResetGroupPeakDisplays.connect (mem_fun(*this, &GainMeterBase::reset_group_peak_display));
 
-       //hide_all();
+       UI::instance()->theme_changed.connect (mem_fun(*this, &GainMeterBase::on_theme_changed));
+       ColorsChanged.connect (bind(mem_fun (*this, &GainMeterBase::color_handler), false));
+       DPIReset.connect (bind(mem_fun (*this, &GainMeterBase::color_handler), true));
 }
 
-void
-GainMeter::set_width (Width w, int len)
-{
-       _width = w;
-       level_meter->setup_meters (len);
-}
-
-Glib::RefPtr<Gdk::Pixmap>
-GainMeter::render_metrics (Gtk::Widget& w)
-{
-       //cerr << "GainMeter::render_metrics() called, red = " << w.get_style()->get_bg(Gtk::STATE_NORMAL).get_red() << endl;//DEBUG
-       Glib::RefPtr<Gdk::Window> win (w.get_window());
-       Glib::RefPtr<Gdk::GC> fg_gc (w.get_style()->get_fg_gc (Gtk::STATE_NORMAL));
-       Glib::RefPtr<Gdk::GC> bg_gc (w.get_style()->get_bg_gc (Gtk::STATE_NORMAL));
-       gint width, height;
-       int  db_points[] = { -50, -40, -20, -30, -10, -3, 0, 4 };
-       char buf[32];
-
-       win->get_size (width, height);
-       
-       Glib::RefPtr<Gdk::Pixmap> pixmap = Gdk::Pixmap::create (win, width, height);
-
-       metric_pixmaps[w.get_name()] = pixmap;
-
-       pixmap->draw_rectangle (bg_gc, true, 0, 0, width, height);
-
-       Glib::RefPtr<Pango::Layout> layout = w.create_pango_layout("");
-
-       for (uint32_t i = 0; i < sizeof (db_points)/sizeof (db_points[0]); ++i) {
-
-               float fraction = log_meter (db_points[i]);
-               gint pos = height - (gint) floor (height * fraction);
-
-               snprintf (buf, sizeof (buf), "%d", abs (db_points[i]));
-
-               layout->set_text (buf);
-
-               /* we want logical extents, not ink extents here */
-
-               int width, height;
-               layout->get_pixel_size (width, height);
-
-               pixmap->draw_line (fg_gc, 0, pos, 4, pos);
-               pixmap->draw_layout (fg_gc, 6, pos - (height/2), layout);
-       }
-
-       return pixmap;
-}
-
-gint
-GainMeter::meter_metrics_expose (GdkEventExpose *ev)
-{
-       /* Only draw dB scale if we're metering audio */
-       if (_io->n_inputs().n_audio() + _io->n_outputs().n_audio() == 0)
-               return true;
-
-       static Glib::RefPtr<Gtk::Style> meter_style;
-       
-       if (style_changed) {
-               meter_style = meter_metric_area.get_style();
-       }
-               
-       Glib::RefPtr<Gdk::Window> win (meter_metric_area.get_window());
-       Glib::RefPtr<Gdk::GC> fg_gc (meter_style->get_fg_gc (Gtk::STATE_NORMAL));
-       Glib::RefPtr<Gdk::GC> bg_gc (meter_style->get_bg_gc (Gtk::STATE_NORMAL));
-
-       GdkRectangle base_rect;
-       GdkRectangle draw_rect;
-       gint width, height;
-
-       win->get_size (width, height);
-       
-       base_rect.width = width;
-       base_rect.height = height;
-       base_rect.x = 0;
-       base_rect.y = 0;
-
-       Glib::RefPtr<Gdk::Pixmap> pixmap;
-       std::map<string,Glib::RefPtr<Gdk::Pixmap> >::iterator i = metric_pixmaps.find (meter_metric_area.get_name());
-
-       if (i == metric_pixmaps.end() || style_changed || dpi_changed) {
-               pixmap = render_metrics (meter_metric_area);
-       } else {
-               pixmap = i->second;
-       }
-
-       gdk_rectangle_intersect (&ev->area, &base_rect, &draw_rect);
-       win->draw_rectangle (bg_gc, false, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height);
-       win->draw_drawable (fg_gc, pixmap, draw_rect.x, draw_rect.y, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height);
-       
-       style_changed = false;
-       return true;
-}
-
-void
-GainMeter::on_theme_changed()
-{
-       style_changed = true;
-}
-
-GainMeter::~GainMeter ()
+GainMeterBase::~GainMeterBase ()
 {
        if (meter_menu) {
                delete meter_menu;
@@ -332,12 +205,18 @@ GainMeter::~GainMeter ()
        }
 }
 
+void
+GainMeterBase::hide_all_meters ()
+{
+       level_meter->hide_meters();
+}
+
 void
 GainMeter::hide_all_meters ()
 {
        bool remove_metric_area = false;
 
-       level_meter->hide_meters();
+       GainMeterBase::hide_all_meters ();
 
        if (remove_metric_area) {
                if (meter_metric_area.get_parent()) {
@@ -347,24 +226,23 @@ GainMeter::hide_all_meters ()
 }
 
 void
+GainMeterBase::setup_meters (int len)
+{
+       level_meter->setup_meters(len, 5);
+}
+
+void 
 GainMeter::setup_meters (int len)
 {
        if (!meter_metric_area.get_parent()) {
                level_meter->pack_end (meter_metric_area, false, false);
                meter_metric_area.show_all ();
        }
-       level_meter->setup_meters(len, 5);
-}
-
-int
-GainMeter::get_gm_width ()
-{
-       Gtk::Requisition sz = hbox.size_request ();
-       return sz.width;
+       GainMeterBase::setup_meters (len);
 }
 
 bool
-GainMeter::gain_key_press (GdkEventKey* ev)
+GainMeterBase::gain_key_press (GdkEventKey* ev)
 {
        if (key_is_legal_for_numeric_entry (ev->keyval)) {
                /* drop through to normal handling */
@@ -375,15 +253,16 @@ GainMeter::gain_key_press (GdkEventKey* ev)
 }
 
 bool
-GainMeter::peak_button_release (GdkEventButton* ev)
+GainMeterBase::peak_button_release (GdkEventButton* ev)
 {
        /* reset peak label */
 
        if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) {
                ResetAllPeakDisplays ();
        } else if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
-               Route* r;
-               if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+               boost::shared_ptr<Route> r;
+
+               if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
                        ResetGroupPeakDisplays (r->mix_group());
                }
        } else {
@@ -394,10 +273,11 @@ GainMeter::peak_button_release (GdkEventButton* ev)
 }
 
 void
-GainMeter::reset_peak_display ()
+GainMeterBase::reset_peak_display ()
 {
-       Route * r;
-       if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+       boost::shared_ptr<Route> r;
+
+       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
                r->peak_meter().reset_max();
        }
 
@@ -408,10 +288,11 @@ GainMeter::reset_peak_display ()
 }
 
 void
-GainMeter::reset_group_peak_display (RouteGroup* group)
+GainMeterBase::reset_group_peak_display (RouteGroup* group)
 {
-       Route* r;
-       if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+       boost::shared_ptr<Route> r;
+       
+       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
                if (group == r->mix_group()) {
                        reset_peak_display ();
                }
@@ -419,7 +300,7 @@ GainMeter::reset_group_peak_display (RouteGroup* group)
 }
 
 void
-GainMeter::popup_meter_menu (GdkEventButton *ev)
+GainMeterBase::popup_meter_menu (GdkEventButton *ev)
 {
        using namespace Menu_Helpers;
 
@@ -440,7 +321,7 @@ GainMeter::popup_meter_menu (GdkEventButton *ev)
 }
 
 bool
-GainMeter::gain_focused (GdkEventFocus* ev)
+GainMeterBase::gain_focused (GdkEventFocus* ev)
 {
        if (ev->in) {
                gain_display.select_region (0, -1);
@@ -451,7 +332,7 @@ GainMeter::gain_focused (GdkEventFocus* ev)
 }
 
 void
-GainMeter::gain_activated ()
+GainMeterBase::gain_activated ()
 {
        float f;
 
@@ -470,7 +351,7 @@ GainMeter::gain_activated ()
 }
 
 void
-GainMeter::show_gain ()
+GainMeterBase::show_gain ()
 {
        char buf[32];
 
@@ -486,7 +367,7 @@ GainMeter::show_gain ()
 }
 
 void
-GainMeter::gain_adjusted ()
+GainMeterBase::gain_adjusted ()
 {
        if (!ignore_toggle) {
                _io->gain_control()->set_value (slider_position_to_gain (gain_adjustment.get_value()));
@@ -495,7 +376,7 @@ GainMeter::gain_adjusted ()
 }
 
 void
-GainMeter::effective_gain_display ()
+GainMeterBase::effective_gain_display ()
 {
        gfloat value = gain_to_slider_position (_io->effective_gain());
        
@@ -507,25 +388,25 @@ GainMeter::effective_gain_display ()
 }
 
 void
-GainMeter::gain_changed ()
+GainMeterBase::gain_changed ()
 {
-       Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &GainMeter::effective_gain_display));
+       Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &GainMeterBase::effective_gain_display));
 }
 
 void
-GainMeter::set_meter_strip_name (const char * name)
+GainMeterBase::set_meter_strip_name (const char * name)
 {
        meter_metric_area.set_name (name);
 }
 
 void
-GainMeter::set_fader_name (const char * name)
+GainMeterBase::set_fader_name (const char * name)
 {
        gain_slider->set_name (name);
 }
 
 void
-GainMeter::update_gain_sensitive ()
+GainMeterBase::update_gain_sensitive ()
 {
        static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (!(_io->gain_control()->list()->automation_state() & Play));
 }
@@ -552,13 +433,13 @@ next_meter_point (MeterPoint mp)
 }
 
 gint
-GainMeter::meter_press(GdkEventButton* ev)
+GainMeterBase::meter_press(GdkEventButton* ev)
 {
-       Route* _route;
+       boost::shared_ptr<Route> _route;
 
        wait_for_release = false;
-
-       if ((_route = dynamic_cast<Route*>(_io.get())) == 0) {
+       
+       if ((_route = boost::dynamic_pointer_cast<Route>(_io)) == 0) {
                return FALSE;
        }
 
@@ -589,7 +470,7 @@ GainMeter::meter_press(GdkEventButton* ev)
 
                                        _session.begin_reversible_command (_("meter point change"));
                                         Session::GlobalMeteringStateCommand *cmd = new Session::GlobalMeteringStateCommand (_session, this);
-                                       _session.foreach_route (this, &GainMeter::set_meter_point, next_meter_point (_route->meter_point()));
+                                       _session.foreach_route (this, &GainMeterBase::set_meter_point, next_meter_point (_route->meter_point()));
                                         cmd->mark();
                                        _session.add_command (cmd);
                                        _session.commit_reversible_command ();
@@ -627,26 +508,31 @@ GainMeter::meter_press(GdkEventButton* ev)
 }
 
 gint
-GainMeter::meter_release(GdkEventButton* ev)
+GainMeterBase::meter_release(GdkEventButton* ev)
 {
-
        if(!ignore_toggle){
                if (wait_for_release){
                        wait_for_release = false;
-                       set_meter_point (*(dynamic_cast<Route*>(_io.get())), old_meter_point);
+                       
+                       boost::shared_ptr<Route> r;
+                       
+                       if ((r = boost::dynamic_pointer_cast<Route>(_io)) != 0) {
+                               set_meter_point (*r, old_meter_point);
+                       }
                }
        }
+
        return true;
 }
 
 void
-GainMeter::set_meter_point (Route& route, MeterPoint mp)
+GainMeterBase::set_meter_point (Route& route, MeterPoint mp)
 {
        route.set_meter_point (mp, this);
 }
 
 void
-GainMeter::set_mix_group_meter_point (Route& route, MeterPoint mp)
+GainMeterBase::set_mix_group_meter_point (Route& route, MeterPoint mp)
 {
        RouteGroup* mix_group;
 
@@ -658,31 +544,31 @@ GainMeter::set_mix_group_meter_point (Route& route, MeterPoint mp)
 }
 
 void
-GainMeter::meter_point_clicked ()
+GainMeterBase::meter_point_clicked ()
 {
-       Route* r;
-
-       if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+       boost::shared_ptr<Route> r;
 
+       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
+               /* WHAT? */
        }
 }
 
 gint
-GainMeter::start_gain_touch (GdkEventButton* ev)
+GainMeterBase::start_gain_touch (GdkEventButton* ev)
 {
        _io->gain_control()->list()->start_touch ();
        return FALSE;
 }
 
 gint
-GainMeter::end_gain_touch (GdkEventButton* ev)
+GainMeterBase::end_gain_touch (GdkEventButton* ev)
 {
        _io->gain_control()->list()->stop_touch ();
        return FALSE;
 }
 
 gint
-GainMeter::gain_automation_state_button_event (GdkEventButton *ev)
+GainMeterBase::gain_automation_state_button_event (GdkEventButton *ev)
 {
        if (ev->type == GDK_BUTTON_RELEASE) {
                return TRUE;
@@ -700,7 +586,7 @@ GainMeter::gain_automation_state_button_event (GdkEventButton *ev)
 }
 
 gint
-GainMeter::gain_automation_style_button_event (GdkEventButton *ev)
+GainMeterBase::gain_automation_style_button_event (GdkEventButton *ev)
 {
        if (ev->type == GDK_BUTTON_RELEASE) {
                return TRUE;
@@ -717,19 +603,19 @@ GainMeter::gain_automation_style_button_event (GdkEventButton *ev)
 }
 
 string
-GainMeter::astate_string (AutoState state)
+GainMeterBase::astate_string (AutoState state)
 {
        return _astate_string (state, false);
 }
 
 string
-GainMeter::short_astate_string (AutoState state)
+GainMeterBase::short_astate_string (AutoState state)
 {
        return _astate_string (state, true);
 }
 
 string
-GainMeter::_astate_string (AutoState state, bool shrt)
+GainMeterBase::_astate_string (AutoState state, bool shrt)
 {
        string sstr;
 
@@ -752,19 +638,19 @@ GainMeter::_astate_string (AutoState state, bool shrt)
 }
 
 string
-GainMeter::astyle_string (AutoStyle style)
+GainMeterBase::astyle_string (AutoStyle style)
 {
        return _astyle_string (style, false);
 }
 
 string
-GainMeter::short_astyle_string (AutoStyle style)
+GainMeterBase::short_astyle_string (AutoStyle style)
 {
        return _astyle_string (style, true);
 }
 
 string
-GainMeter::_astyle_string (AutoStyle style, bool shrt)
+GainMeterBase::_astyle_string (AutoStyle style, bool shrt)
 {
        if (style & Trim) {
                return _("Trim");
@@ -776,9 +662,8 @@ GainMeter::_astyle_string (AutoStyle style, bool shrt)
 }
 
 void
-GainMeter::gain_automation_style_changed ()
+GainMeterBase::gain_automation_style_changed ()
 {
-  // Route* _route = dynamic_cast<Route*>(&_io);
        switch (_width) {
        case Wide:
                gain_automation_style_button.set_label (astyle_string(_io->gain_control()->list()->automation_style()));
@@ -790,10 +675,9 @@ GainMeter::gain_automation_style_changed ()
 }
 
 void
-GainMeter::gain_automation_state_changed ()
+GainMeterBase::gain_automation_state_changed ()
 {
-       ENSURE_GUI_THREAD(mem_fun(*this, &GainMeter::gain_automation_state_changed));
-       //Route* _route = dynamic_cast<Route*>(&_io);
+       ENSURE_GUI_THREAD(mem_fun(*this, &GainMeterBase::gain_automation_state_changed));
        
        bool x;
 
@@ -821,12 +705,12 @@ GainMeter::gain_automation_state_changed ()
        gain_watching.disconnect();
 
        if (x) {
-               gain_watching = ARDOUR_UI::RapidScreenUpdate.connect (mem_fun (*this, &GainMeter::effective_gain_display));
+               gain_watching = ARDOUR_UI::RapidScreenUpdate.connect (mem_fun (*this, &GainMeterBase::effective_gain_display));
        }
 }
 
 void
-GainMeter::update_meters()
+GainMeterBase::update_meters()
 {
        char buf[32];
        float mpeak = level_meter->update_meters();
@@ -846,9 +730,167 @@ GainMeter::update_meters()
        }
 }
 
-void GainMeter::color_handler (bool dpi)
+void GainMeterBase::color_handler(bool dpi)
 {
        color_changed = true;
        dpi_changed = (dpi) ? true : false;
        setup_meters();
 }
+
+void
+GainMeterBase::set_width (Width w, int len)
+{
+       _width = w;
+       level_meter->setup_meters (len);
+}
+
+
+void
+GainMeterBase::on_theme_changed()
+{
+       style_changed = true;
+}
+
+GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
+       : GainMeterBase (io, s, slider, false)
+{
+
+       gain_display_box.set_homogeneous (true);
+       gain_display_box.set_spacing (2);
+       gain_display_box.pack_start (gain_display, true, true);
+
+       meter_metric_area.set_name ("AudioTrackMetrics");
+       set_size_request_to_display_given_text (meter_metric_area, "-50", 0, 0);
+
+       gain_automation_style_button.set_name ("MixerAutomationModeButton");
+       gain_automation_state_button.set_name ("MixerAutomationPlaybackButton");
+
+       ARDOUR_UI::instance()->tooltips().set_tip (gain_automation_state_button, _("Fader automation mode"));
+       ARDOUR_UI::instance()->tooltips().set_tip (gain_automation_style_button, _("Fader automation type"));
+
+       gain_automation_style_button.unset_flags (Gtk::CAN_FOCUS);
+       gain_automation_state_button.unset_flags (Gtk::CAN_FOCUS);
+
+       gain_automation_state_button.set_size_request(15, 15);
+       gain_automation_style_button.set_size_request(15, 15);
+
+       HBox* fader_centering_box = manage (new HBox);
+       fader_centering_box->pack_start (*gain_slider, true, false);
+
+       fader_vbox = manage (new Gtk::VBox());
+       fader_vbox->set_spacing (0);
+       fader_vbox->pack_start (*fader_centering_box, false, false, 0);
+
+       hbox.set_spacing (2);
+       hbox.pack_start (*fader_vbox, true, true);
+
+       boost::shared_ptr<Route> r;
+
+       if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
+               
+               /* 
+                  if we have a non-hidden route (ie. we're not the click or the auditioner), 
+                  pack some route-dependent stuff.
+               */
+
+               gain_display_box.pack_end (peak_display, true, true);
+               hbox.pack_end (*level_meter, true, true);
+
+               if (!r->is_hidden()) {
+                       fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
+               }
+       }
+
+       set_spacing (2);
+
+       pack_start (gain_display_box, Gtk::PACK_SHRINK);
+       pack_start (hbox, Gtk::PACK_SHRINK);
+
+       meter_metric_area.signal_expose_event().connect (mem_fun(*this, &GainMeter::meter_metrics_expose));
+}
+
+
+int
+GainMeter::get_gm_width ()
+{
+       Gtk::Requisition sz;
+       hbox.size_request (sz);
+       return sz.width;
+}
+
+Glib::RefPtr<Gdk::Pixmap>
+GainMeter::render_metrics (Gtk::Widget& w)
+{
+       Glib::RefPtr<Gdk::Window> win (w.get_window());
+       Glib::RefPtr<Gdk::GC> fg_gc (w.get_style()->get_fg_gc (Gtk::STATE_NORMAL));
+       Glib::RefPtr<Gdk::GC> bg_gc (w.get_style()->get_bg_gc (Gtk::STATE_NORMAL));
+       gint width, height;
+       int  db_points[] = { -50, -40, -20, -30, -10, -3, 0, 4 };
+       char buf[32];
+
+       win->get_size (width, height);
+       
+       Glib::RefPtr<Gdk::Pixmap> pixmap = Gdk::Pixmap::create (win, width, height);
+
+       metric_pixmaps[w.get_name()] = pixmap;
+
+       pixmap->draw_rectangle (bg_gc, true, 0, 0, width, height);
+
+       Glib::RefPtr<Pango::Layout> layout = w.create_pango_layout("");
+
+       for (uint32_t i = 0; i < sizeof (db_points)/sizeof (db_points[0]); ++i) {
+
+               float fraction = log_meter (db_points[i]);
+               gint pos = height - (gint) floor (height * fraction);
+
+               snprintf (buf, sizeof (buf), "%d", abs (db_points[i]));
+
+               layout->set_text (buf);
+
+               /* we want logical extents, not ink extents here */
+
+               int width, height;
+               layout->get_pixel_size (width, height);
+
+               pixmap->draw_line (fg_gc, 0, pos, 4, pos);
+               pixmap->draw_layout (fg_gc, 6, pos - (height/2), layout);
+       }
+
+       return pixmap;
+}
+
+gint
+GainMeter::meter_metrics_expose (GdkEventExpose *ev)
+{
+       static Glib::RefPtr<Gtk::Style> meter_style;
+       if (style_changed) {
+               meter_style = meter_metric_area.get_style();
+       }
+       Glib::RefPtr<Gdk::Window> win (meter_metric_area.get_window());
+       Glib::RefPtr<Gdk::GC> bg_gc (meter_style->get_bg_gc (Gtk::STATE_INSENSITIVE));
+       GdkRectangle base_rect;
+       GdkRectangle draw_rect;
+       gint width, height;
+
+       win->get_size (width, height);
+       
+       base_rect.width = width;
+       base_rect.height = height;
+       base_rect.x = 0;
+       base_rect.y = 0;
+
+       Glib::RefPtr<Gdk::Pixmap> pixmap;
+       std::map<string,Glib::RefPtr<Gdk::Pixmap> >::iterator i = metric_pixmaps.find (meter_metric_area.get_name());
+
+       if (i == metric_pixmaps.end() || style_changed || dpi_changed) {
+               pixmap = render_metrics (meter_metric_area);
+       } else {
+               pixmap = i->second;
+       }
+
+       gdk_rectangle_intersect (&ev->area, &base_rect, &draw_rect);
+       win->draw_drawable (bg_gc, pixmap, draw_rect.x, draw_rect.y, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height);
+       style_changed = false;
+       return true;
+}
+
index cd8e74d59d8335bc1bfbd57eaef646ded9f44ab5..d493edf0fb3f059e3ca89ece9d9ce1cfc22309f9 100644 (file)
@@ -55,33 +55,29 @@ namespace Gtk {
        class Menu;
 }
 
-class GainMeter : public Gtk::VBox
+class GainMeterBase : virtual public sigc::trackable
 {
   public:
-       GainMeter (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&);
-       ~GainMeter ();
+       GainMeterBase (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&, const Glib::RefPtr<Gdk::Pixbuf>& pix,
+                      bool horizontal);
+       virtual ~GainMeterBase ();
 
        void update_gain_sensitive ();
-
        void update_meters ();
 
        void effective_gain_display ();
-
        void set_width (Width, int len=0);
-       void setup_meters (int len=0);
-
-       int get_gm_width ();
-
        void set_meter_strip_name (const char * name);
        void set_fader_name (const char * name);
 
-       /* should probably switch to using the shared_ptr that underlies
-          all this stuff
-       */
+       virtual void setup_meters (int len=0);
 
-       PBD::Controllable* get_controllable() { return _io->gain_control().get(); }
+       boost::shared_ptr<PBD::Controllable> get_controllable() { return _io->gain_control(); }
 
-  private:
+       LevelMeter& get_level_meter() const { return *level_meter; }
+       Gtkmm2ext::SliderController& get_gain_slider() const { return *gain_slider; }
+
+  protected:
 
        friend class MixerStrip;
        boost::shared_ptr<ARDOUR::IO> _io;
@@ -90,14 +86,12 @@ class GainMeter : public Gtk::VBox
        bool ignore_toggle;
        bool next_release_selects;
 
-       Gtkmm2ext::VSliderController *gain_slider;
+       Gtkmm2ext::SliderController *gain_slider;
        Gtk::Adjustment              gain_adjustment;
        Gtkmm2ext::FocusEntry        gain_display;
        Gtk::Button                  peak_display;
-       Gtk::HBox                    gain_display_box;
-       Gtk::HBox                    fader_box;
        Gtk::DrawingArea             meter_metric_area;
-       LevelMeter                                       *level_meter;
+       LevelMeter                  *level_meter;
 
        sigc::connection gain_watching;
 
@@ -125,27 +119,19 @@ class GainMeter : public Gtk::VBox
 
        Width _width;
 
-       static std::map<std::string,Glib::RefPtr<Gdk::Pixmap> > metric_pixmaps;
-       static Glib::RefPtr<Gdk::Pixmap> render_metrics (Gtk::Widget&);
-
-       gint meter_metrics_expose (GdkEventExpose *);
-
        void show_gain ();
        void gain_activated ();
        bool gain_focused (GdkEventFocus*);
 
        float       max_peak;
        
-       Gtk::VBox*   fader_vbox;
-       Gtk::HBox   hbox;
-
        void gain_adjusted ();
        void gain_changed ();
        
        void meter_point_clicked ();
        void gain_unit_changed ();
        
-       void hide_all_meters ();
+       virtual void hide_all_meters ();
 
        gint meter_button_press (GdkEventButton*, uint32_t);
 
@@ -173,10 +159,6 @@ class GainMeter : public Gtk::VBox
        static sigc::signal<void> ResetAllPeakDisplays;
        static sigc::signal<void,ARDOUR::RouteGroup*> ResetGroupPeakDisplays;
 
-       static Glib::RefPtr<Gdk::Pixbuf> slider;
-       static Glib::RefPtr<Gdk::Pixbuf> rail;
-       static int setup_slider_pix ();
-
        void on_theme_changed ();
        bool style_changed;
        bool dpi_changed;
@@ -184,5 +166,33 @@ class GainMeter : public Gtk::VBox
        void color_handler(bool);
 };
 
+class GainMeter : public GainMeterBase, public Gtk::VBox
+{
+  public:
+       GainMeter (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&);
+       ~GainMeter () {}
+
+       int get_gm_width ();
+       void setup_meters (int len=0);
+
+       static void setup_slider_pix ();
+
+  protected:
+       void hide_all_meters ();
+
+       gint meter_metrics_expose (GdkEventExpose *);
+
+       static std::map<std::string,Glib::RefPtr<Gdk::Pixmap> > metric_pixmaps;
+       static Glib::RefPtr<Gdk::Pixmap> render_metrics (Gtk::Widget&);
+
+  private:
+       Gtk::HBox  gain_display_box;
+       Gtk::HBox  fader_box;
+       Gtk::VBox* fader_vbox;
+       Gtk::HBox  hbox;
+
+       static Glib::RefPtr<Gdk::Pixbuf> slider;
+};
+
 #endif /* __ardour_gtk_gain_meter_h__ */
 
index 4e06ece82fe7e1caa3a147aeefb331662bb96a52..9da7ceb370ddc37387fb702b957e1ee3ed9affc6 100644 (file)
@@ -43,7 +43,7 @@ GhostRegion::GhostRegion (ArdourCanvas::Group* parent, TimeAxisView& tv, TimeAxi
        base_rect = new ArdourCanvas::SimpleRect (*group);
        base_rect->property_x1() = (double) 0.0;
        base_rect->property_y1() = (double) 0.0;
-       base_rect->property_y2() = (double) trackview.height;
+       base_rect->property_y2() = (double) trackview.current_height();
        base_rect->property_outline_what() = (guint32) 0;
 
        if (!is_automation_ghost()) {
@@ -73,7 +73,7 @@ GhostRegion::set_duration (double units)
 void
 GhostRegion::set_height ()
 {
-       base_rect->property_y2() = (double) trackview.height;
+       base_rect->property_y2() = (double) trackview.current_height();
 }
 
 void
@@ -121,7 +121,7 @@ AudioGhostRegion::set_height ()
 
        GhostRegion::set_height();
 
-       ht = ((trackview.height) / (double) waves.size());
+       ht = ((trackview.current_height()) / (double) waves.size());
        
        for (n = 0, i = waves.begin(); i != waves.end(); ++i, ++n) {
                gdouble yoff = n * ht;
index 018fae68959e169c849bd65171cd050d64cfaa09..f3630e715262830ff877b0fc2e8a1cee2a0164c0 100644 (file)
@@ -81,7 +81,7 @@ ImageFrameTimeAxis::ImageFrameTimeAxis(const string & track_id, PublicEditor& ed
        label_view() ;
                
        // set the initial height of this time axis
-       set_height(Normal) ;
+       set_height(hNormal) ;
 }
 
 /**
@@ -133,10 +133,10 @@ ImageFrameTimeAxis::~ImageFrameTimeAxis ()
 /**
  * Sets the height of this TrackView to one of ths TrackHeghts
  *
- * @param h the TrackHeight value to set
+ * @param h 
  */
 void
-ImageFrameTimeAxis::set_height (TrackHeight h)
+ImageFrameTimeAxis::set_height (uint32_t h)
 {
        VisualTimeAxis::set_height(h) ;
        
index 4b3bf0c857faaff59dd80cf61a77907601bdecec..7cbed6a394242734053242c7de0a2ccacdc4d17f 100644 (file)
@@ -76,9 +76,9 @@ class ImageFrameTimeAxis : public VisualTimeAxis
                /**
                 * Sets the height of this TrackView to one of ths TrackHeghts
                 *
-                * @param h the TrackHeight value to set
+                * @param h the number of pixels to set the height too
                 */     
-               virtual void set_height(TimeAxisView::TrackHeight) ;
+               virtual void set_height(uint32_t h) ;
                
                /**
                 * Sets the number of samples per unit that are used.
index 69205cd5119961f1fa2cdec980334c4e4bd4ffd5..a57db60a38212e137fc980bed155b391ade00b9a 100644 (file)
@@ -50,7 +50,7 @@ using namespace Editing;
 ImageFrameTimeAxisView::ImageFrameTimeAxisView (ImageFrameTimeAxis& tv)
        : _trackview (tv),
          canvas_group (*_trackview.canvas_display),
-         canvas_rect (canvas_group, 0.0, 0.0, 1000000.0, tv.height)
+         canvas_rect (canvas_group, 0.0, 0.0, 1000000.0, tv.current_height())
 {
        region_color = _trackview.color() ;
        stream_base_color = ARDOUR_UI::config()->canvasvar_ImageTrack.get() ;
index f8bba3aa842cc576d9b68be327cde5400878e165..f35381301e238d4bf43228ff5fd935581b285fcd 100644 (file)
@@ -91,9 +91,9 @@ ImageFrameView::ImageFrameView(const string & item_id,
        
        //calculate our image width based on the track height
        double im_ratio = (double)width/(double)height ;
-       double im_width = ((double)(trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE) * im_ratio) ;
+       double im_width = ((double)(trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE) * im_ratio) ;
        
-       imageframe = new ImageFrame (*group, pbuf, 1.0, 1.0, ANCHOR_NW, im_width, (trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE));
+       imageframe = new ImageFrame (*group, pbuf, 1.0, 1.0, ANCHOR_NW, im_width, (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE));
 
        frame_handle_start->signal_event().connect (bind (mem_fun (trackview.editor, &PublicEditor::canvas_imageframe_start_handle_event), frame_handle_start, this));
        frame_handle_end->signal_event().connect (bind (mem_fun (trackview.editor, &PublicEditor::canvas_imageframe_end_handle_event), frame_handle_end, this));
index b0b1a5f9b7674496e87b2e0995a8902fc6bfc8e4..16576a0b8ff358a8bdffe0b04e4a0aa4f622d050 100644 (file)
 
 */
 
+#include <gtkmm/messagedialog.h>
 #include <glibmm/objectbase.h>
+
 #include <gtkmm2ext/doi.h>
+
 #include <ardour/port_insert.h>
 #include "ardour/session.h"
 #include "ardour/io.h"
 #include "ardour/audio_track.h"
 #include "ardour/midi_track.h"
 #include "ardour/data_type.h"
+
 #include "io_selector.h"
 #include "utils.h"
 #include "gui_thread.h"
 #include "i18n.h"
 
+using namespace ARDOUR;
+using namespace Gtk;
+
 IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool offer_inputs)
        : PortMatrix (
                session, io->default_type(), !offer_inputs,
@@ -46,14 +53,12 @@ IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO>
                _io->output_changed.connect (mem_fun(*this, &IOSelector::ports_changed));
        }
 
-#ifdef FIXME
-       /* these got lost in a merge from 2.0 */
-       set_button_sensitivity ();
-       io->name_changed.connect (mem_fun(*this, &IOSelector::name_changed));
-#endif
+       /* this got lost in a merge from 2.0 */
 
-}
+       // set_button_sensitivity ();
+       // io->name_changed.connect (mem_fun(*this, &IOSelector::name_changed));
 
+}
 
 void
 IOSelector::ports_changed (ARDOUR::IOChange change, void *src)
@@ -161,8 +166,8 @@ IOSelector::add_row ()
                        _io->add_input_port ("", this);
                }
 
-               catch (ARDOUR::AudioEngine::PortRegistrationFailure& err) {
-                       Gtk::MessageDialog msg (0,  _("There are no more JACK ports available."));
+               catch (AudioEngine::PortRegistrationFailure& err) {
+                       MessageDialog msg (_("There are no more JACK ports available."));
                        msg.run ();
                }
 
@@ -172,14 +177,13 @@ IOSelector::add_row ()
                        _io->add_output_port ("", this);
                }
 
-               catch (ARDOUR::AudioEngine::PortRegistrationFailure& err) {
-                       Gtk::MessageDialog msg (0, _("There are no more JACK ports available."));
+               catch (AudioEngine::PortRegistrationFailure& err) {
+                       MessageDialog msg (_("There are no more JACK ports available."));
                        msg.run ();
                }
        }
 }
 
-
 void
 IOSelector::remove_row (int r)
 {
@@ -199,7 +203,54 @@ IOSelector::row_descriptor () const
        return _("port");
 }
 
+#if 0
+void 
+IOSelector::set_button_sensitivity ()
+{
+       if (for_input) {
+
+               if (io->input_maximum() < 0 || io->input_maximum() > (int) io->n_inputs()) {
+                       add_port_button.set_sensitive (true);
+               } else {
+                       add_port_button.set_sensitive (false);
+               }
+
+       } else {
+
+               if (io->output_maximum() < 0 || io->output_maximum() > (int) io->n_outputs()) {
+                       add_port_button.set_sensitive (true);
+               } else {
+                       add_port_button.set_sensitive (false);
+               }
+                       
+       }
+
+       if (for_input) {
+               if (io->n_inputs() && (io->input_minimum() < 0 || io->input_minimum() < (int) io->n_inputs())) {
+                       remove_port_button.set_sensitive (true);
+               } else {
+                       remove_port_button.set_sensitive (false);
+               }
+                       
+       } else {
+               if (io->n_outputs() && (io->output_minimum() < 0 || io->output_minimum() < (int) io->n_outputs())) {
+                       remove_port_button.set_sensitive (true);
+               } else {
+                       remove_port_button.set_sensitive (false);
+               }
+       }
+}
+#endif
 
+#if 0
+void
+IOSelector::name_changed (void* src)
+{
+       ENSURE_GUI_THREAD(bind (mem_fun(*this, &IOSelector::name_changed), src));
+       
+       display_ports ();
+}
+#endif
 
 IOSelectorWindow::IOSelectorWindow (
        ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool for_input, bool can_cancel
index 22dd27430698e430efe388053ca4e19f78641aed..ef8cc3438938be21d28d3b991a243b9927c1a813 100644 (file)
@@ -17,6 +17,7 @@
 
 */
 
+#include <vector>
 #include <ardour/ardour.h>
 
 #include "ardour_ui.h"
 #include "keyboard.h"
 #include "gui_thread.h"
 #include "opts.h"
+#include "actions.h"
 
 #include "i18n.h"
 
 using namespace PBD;
 using namespace ARDOUR;
+using namespace Gtk;
+using namespace std;
 
 #define KBD_DEBUG 1
 bool debug_keyboard = false;
@@ -75,8 +79,10 @@ bool         Keyboard::_some_magic_widget_has_focus = false;
 
 std::string Keyboard::user_keybindings_path;
 bool Keyboard::can_save_keybindings = false;
+bool Keyboard::bindings_changed_after_save_became_legal = false;
 map<string,string> Keyboard::binding_files;
-std::string Keyboard::_current_binding_name = _("Unknown");
+string Keyboard::_current_binding_name = _("Unknown");
+map<AccelKey,pair<string,string>,Keyboard::AccelKeyLess> Keyboard::release_keys;
 
 /* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */
 
@@ -186,6 +192,7 @@ gint
 Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
 {
        uint32_t keyval;
+       bool ret = false;
 
 #if 0
        cerr << "snoop widget " << widget << " key " << event->keyval << " type: " << event->type 
@@ -215,7 +222,23 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
                if (find (state.begin(), state.end(), keyval) == state.end()) {
                        state.push_back (keyval);
                        sort (state.begin(), state.end());
-               } 
+
+               } else {
+
+                       /* key is already down. if its also used for release,
+                          prevent auto-repeat events.
+                       */
+
+                       for (map<AccelKey,two_strings,AccelKeyLess>::iterator k = release_keys.begin(); k != release_keys.end(); ++k) {
+
+                               const AccelKey& ak (k->first);
+                               
+                               if (keyval == ak.get_key() && (Gdk::ModifierType)(event->state | Gdk::RELEASE_MASK) == ak.get_mod()) {
+                                       ret = true;
+                                       break;
+                               }
+                       }
+               }
 
        } else if (event->type == GDK_KEY_RELEASE) {
 
@@ -226,6 +249,20 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
                        sort (state.begin(), state.end());
                } 
 
+               for (map<AccelKey,two_strings,AccelKeyLess>::iterator k = release_keys.begin(); k != release_keys.end(); ++k) {
+
+                       const AccelKey& ak (k->first);
+                       two_strings ts (k->second);
+
+                       if (keyval == ak.get_key() && (Gdk::ModifierType)(event->state | Gdk::RELEASE_MASK) == ak.get_mod()) {
+                               Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (ts.first.c_str(), ts.second.c_str());
+                               if (act) {
+                                       act->activate();
+                                       ret = true;
+                               }
+                               break;
+                       }
+               }
        }
 
        if (event->type == GDK_KEY_RELEASE && event->keyval == GDK_w && modifier_state_equals (event->state, PrimaryModifier)) {
@@ -235,7 +272,7 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
                }
        }
 
-       return false;
+       return ret;
 }
 
 bool
@@ -388,6 +425,16 @@ accel_map_changed (GtkAccelMap* map,
                   GdkModifierType mod,
                   gpointer arg)
 {
+       Keyboard::keybindings_changed ();
+}
+
+void
+Keyboard::keybindings_changed ()
+{
+       if (Keyboard::can_save_keybindings) {
+               Keyboard::bindings_changed_after_save_became_legal = true;
+       }
+
        Keyboard::save_keybindings ();
 }
 
@@ -400,7 +447,7 @@ Keyboard::set_can_save_keybindings (bool yn)
 void
 Keyboard::save_keybindings ()
 {
-       if (can_save_keybindings) {
+       if (can_save_keybindings && bindings_changed_after_save_became_legal) {
                Gtk::AccelMap::save (user_keybindings_path);
        } 
 }
@@ -555,13 +602,34 @@ Keyboard::load_keybindings (string path)
                        }
                }
 
-               return true;
 
        } catch (...) {
                error << string_compose (_("Ardour key bindings file not found at \"%1\" or contains errors."), path)
                      << endmsg;
                return false;
        }
+
+       /* now find all release-driven bindings */
+
+       vector<string> groups;
+       vector<string> names;
+       vector<AccelKey> bindings;
+       
+       ActionManager::get_all_actions (groups, names, bindings);
+       
+       vector<string>::iterator g;
+       vector<AccelKey>::iterator b;
+       vector<string>::iterator n;
+
+       release_keys.clear ();
+
+       for (n = names.begin(), b = bindings.begin(), g = groups.begin(); n != names.end(); ++n, ++b, ++g) {
+               if ((*b).get_mod() & Gdk::RELEASE_MASK) {
+                       release_keys.insert (pair<AccelKey,two_strings> (*b, two_strings (*g, *n)));
+               }
+       }
+
+       return true;
 }
 
 
index de2a0929ed4c50dcb74600cdcde7b526fed9d37c..e6d5065e86e758a5744cdb9938720f22c951fa95 100644 (file)
 #ifndef __ardour_keyboard_h__
 #define __ardour_keyboard_h__
 
+#include <map>
 #include <vector>
 #include <string>
 
 #include <sigc++/signal.h>
 #include <gtk/gtk.h>
+#include <gtkmm/accelkey.h>
 
 #include <ardour/types.h>
 #include <pbd/stateful.h>
 
 #include "selection.h"
 
-using std::vector;
 using std::string;
 
 class Keyboard : public sigc::trackable, PBD::Stateful
@@ -43,7 +44,7 @@ class Keyboard : public sigc::trackable, PBD::Stateful
        XMLNode& get_state (void);
        int set_state (const XMLNode&);
 
-       typedef vector<uint32_t> State;
+       typedef std::vector<uint32_t> State;
        typedef uint32_t ModifierMask;
 
        static uint32_t PrimaryModifier;
@@ -114,12 +115,23 @@ class Keyboard : public sigc::trackable, PBD::Stateful
        static void magic_widget_drop_focus ();
 
        static void setup_keybindings ();
+       static void keybindings_changed ();
        static void save_keybindings ();
        static bool load_keybindings (std::string path);
        static void set_can_save_keybindings (bool yn);
        static std::string current_binding_name () { return _current_binding_name; }
        static std::map<std::string,std::string> binding_files;
 
+       struct AccelKeyLess {
+           bool operator() (const Gtk::AccelKey a, const Gtk::AccelKey b) const {
+                   if (a.get_key() != b.get_key()) {
+                           return a.get_key() < b.get_key();
+                   } else {
+                           return a.get_mod() < b.get_mod();
+                   }
+           }
+       };
+
   private:
        static Keyboard* _the_keyboard;
 
@@ -134,8 +146,13 @@ class Keyboard : public sigc::trackable, PBD::Stateful
        static Gtk::Window* current_window;
        static std::string user_keybindings_path;
        static bool can_save_keybindings;
+       static bool bindings_changed_after_save_became_legal;
        static std::string _current_binding_name;
 
+       typedef std::pair<std::string,std::string> two_strings;
+
+       static std::map<Gtk::AccelKey,two_strings,AccelKeyLess> release_keys;
+
        static gint _snooper (GtkWidget*, GdkEventKey*, gpointer);
        gint snooper (GtkWidget*, GdkEventKey*);
 
index cdac398a30db958bcadf5d58e8fd111064152662..e44d92943f15aa3b76765d529465da200811ef9b 100644 (file)
@@ -16,6 +16,7 @@
 #include "actions.h"
 #include "keyboard.h"
 #include "keyeditor.h"
+#include "utils.h"
 
 #include "i18n.h"
 
@@ -167,6 +168,8 @@ KeyEditor::on_key_release_event (GdkEventKey* ev)
                        goto out;
                } 
 
+               possibly_translate_keyval_to_make_legal_accelerator (ev->keyval);
+
                bool result = AccelMap::change_entry (path,
                                                      ev->keyval,
                                                      (ModifierType) ev->state,
index d03ad5b9f9bcb842ce84fcc90b5b3a9234234e09..e7c42fd78005651fc20b6c1107d855065316dbb4 100644 (file)
@@ -41,6 +41,7 @@ LatencyGUI::LatencyGUI (Latent& l, nframes64_t sr, nframes64_t psz)
          initial_value (_latent.signal_latency()),
          sample_rate (sr),
          period_size (psz),
+         ignored (new PBD::IgnorableControllable()),
          /* max 1 second, step by frames, page by msecs */
          adjustment (initial_value, 0.0, sample_rate, 1.0, sample_rate / 1000.0f),
          bc (adjustment, ignored, sigc::mem_fun (*this, &LatencyGUI::latency_printer)),
index 0be7fdbf4c422283c114944f0e2fba1fbd6de108..f352f698d7b6961406538f613b52248f110513ce 100644 (file)
@@ -35,7 +35,7 @@ class LatencyGUI : public Gtk::VBox
        nframes64_t initial_value;
        nframes64_t sample_rate;
        nframes64_t period_size;
-       PBD::IgnorableControllable ignored;
+       boost::shared_ptr<PBD::IgnorableControllable> ignored;
 
        Gtk::Adjustment adjustment;
        Gtkmm2ext::BarController bc;
index 8a05d8da5629c925cf69f2055241e84bd5d93696..f6e3731aac1130546759fcf9a59ce038cd1c13db 100644 (file)
@@ -100,6 +100,9 @@ LevelMeter::update_meters ()
                        if (mpeak > max_peak) {
                                max_peak = mpeak;
                        }
+                       if (mpeak > max_peak) {
+                               max_peak = mpeak;
+                       }
                }
        }
        return max_peak;
@@ -143,6 +146,7 @@ LevelMeter::setup_meters (int len, int initial_width)
 {
        uint32_t nmeters = _io->n_outputs().n_total();
        regular_meter_width = initial_width;
+
        guint16 width;
 
        hide_all_meters ();
index 2079d0dc7a722de5c966964a2cb0607272768987..451a85efd7e0bedfa1ab3c311426f1e337b421ea 100644 (file)
@@ -46,10 +46,10 @@ using namespace Gtkmm2ext;
 LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
        : location(0), session(0),
          item_table (1, 7, false),
-         start_set_button (_("Set")),
+         start_set_button (_("Use PH")),
          start_go_button (_("Go")),
          start_clock (X_("locationstart"), true, X_("LocationEditRowClock"), true),
-         end_set_button (_("Set")),
+         end_set_button (_("Use PH")),
          end_go_button (_("Go")),
          end_clock (X_("locationend"), true, X_("LocationEditRowClock"), true),
          length_clock (X_("locationlength"), true, X_("LocationEditRowClock"), true, true),
@@ -82,7 +82,9 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
        composer_label.set_name ("LocationEditNumberLabel");
        composer_entry.set_name ("LocationEditNameEntry");
 
-
+       ARDOUR_UI::instance()->tooltips().set_tip(start_set_button, _("Set value to Playhead"));
+       ARDOUR_UI::instance()->tooltips().set_tip(end_set_button, _("Set value to Playhead"));
        isrc_label.set_text ("ISRC: ");
        isrc_label.set_size_request (30, -1);
        performer_label.set_text ("Performer: ");
@@ -131,6 +133,7 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
        start_set_button.signal_clicked().connect(bind (mem_fun (*this, &LocationEditRow::set_button_pressed), LocStart));
        start_go_button.signal_clicked().connect(bind (mem_fun (*this, &LocationEditRow::go_button_pressed), LocStart));
        start_clock.ValueChanged.connect (bind (mem_fun (*this, &LocationEditRow::clock_changed), LocStart));
+       start_clock.ChangeAborted.connect (bind (mem_fun (*this, &LocationEditRow::change_aborted), LocStart));
 
        
        end_hbox.pack_start (end_go_button, false, false);
@@ -142,9 +145,11 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
        end_set_button.signal_clicked().connect(bind (mem_fun (*this, &LocationEditRow::set_button_pressed), LocEnd));
        end_go_button.signal_clicked().connect(bind (mem_fun (*this, &LocationEditRow::go_button_pressed), LocEnd));
        end_clock.ValueChanged.connect (bind (mem_fun (*this, &LocationEditRow::clock_changed), LocEnd));
+       end_clock.ChangeAborted.connect (bind (mem_fun (*this, &LocationEditRow::change_aborted), LocEnd));
        
 //     item_table.attach (length_clock, 3, 4, 0, 1, 0, 0, 4, 0);
        length_clock.ValueChanged.connect (bind ( mem_fun(*this, &LocationEditRow::clock_changed), LocLength));
+       length_clock.ChangeAborted.connect (bind (mem_fun (*this, &LocationEditRow::change_aborted), LocLength));
 
 //     item_table.attach (cd_check_button, 4, 5, 0, 1, 0, Gtk::FILL, 4, 0);
 //     item_table.attach (hide_check_button, 5, 6, 0, 1, 0, Gtk::FILL, 4, 0);
@@ -414,6 +419,14 @@ LocationEditRow::clock_changed (LocationPart part)
 
 }
 
+void
+LocationEditRow::change_aborted (LocationPart part)
+{
+       if (i_am_the_modifier || !location) return;
+       
+       set_location(location);
+}
+
 void
 LocationEditRow::cd_toggled ()
 {
@@ -600,6 +613,12 @@ LocationEditRow::flags_changed (ARDOUR::Location *loc, void *src)
        i_am_the_modifier--;
 }
 
+void
+LocationEditRow::focus_name() {
+       name_entry.grab_focus();
+}
+
+
 LocationUI::LocationUI ()
        : ArdourDialog ("locations dialog"),
          add_location_button (_("Add New Location")),
@@ -628,6 +647,8 @@ LocationUI::LocationUI ()
        location_rows_scroller.set_name ("LocationLocRowsScroller");
        location_rows_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
        location_rows_scroller.set_size_request (-1, 130);
+       
+       newest_location = 0;
 
        loc_frame_box.set_spacing (5);
        loc_frame_box.set_border_width (5);
@@ -789,6 +810,10 @@ LocationUI::map_locations (Locations::LocationList& locations)
                        erow->remove_requested.connect (mem_fun(*this, &LocationUI::location_remove_requested));
                        erow->redraw_ranges.connect (mem_fun(*this, &LocationUI::location_redraw_ranges));
                        loc_children.push_back(Box_Helpers::Element(*erow, PACK_SHRINK, 1, PACK_START));
+                       if (location == newest_location) {
+                               newest_location = 0;
+                               erow->focus_name();
+                       }
                }
                else if (location->is_auto_punch()) {
                        punch_edit_row.set_session (session);
@@ -820,6 +845,9 @@ LocationUI::add_new_location()
                nframes_t where = session->audible_frame();
                session->locations()->next_available_name(markername,"mark");
                Location *location = new Location (where, where, markername, Location::IsMark);
+               if (Config->get_name_new_markers()) {
+                       newest_location = location;                     
+               }
                session->begin_reversible_command (_("add marker"));
                XMLNode &before = session->locations()->get_state();
                session->locations()->add (location, true);
index de435b999fc8fbe9e25b693fd0df20e4ecca41ee..3c32f02025fffa08b60fff8591beefa24b4be771 100644 (file)
@@ -50,6 +50,7 @@ class LocationEditRow  : public Gtk::HBox
        void set_session (ARDOUR::Session *);
 
        void set_number (int);
+       void focus_name();
        
        sigc::signal<void,ARDOUR::Location*> remove_requested;  
        sigc::signal<void> redraw_ranges;  
@@ -114,6 +115,7 @@ class LocationEditRow  : public Gtk::HBox
        void go_button_pressed (LocationPart part);
 
        void clock_changed (LocationPart part);
+       void change_aborted (LocationPart part);
 
        void cd_toggled ();
        void hide_toggled ();
@@ -149,6 +151,7 @@ class LocationUI : public ArdourDialog
 
   private:
        ARDOUR::LocationStack* locations;
+       ARDOUR::Location *newest_location;
         
        void session_gone();
 
index dd4bcab9195d94c03259f87d7b5dd15d22ad5578..abbf216eea9f06f95c86c38ad6d9a91c72b5e423 100644 (file)
@@ -205,6 +205,13 @@ fixup_bundle_environment ()
           actually exists ...
        */
 
+       try {
+               sys::create_directories (user_config_directory ());
+       }
+       catch (const sys::filesystem_error& ex) {
+               error << _("Could not create user configuration directory") << endmsg;
+       }
+       
        sys::path pangopath = user_config_directory();
        pangopath /= "pango.rc";
        path = pangopath.to_string();
@@ -212,6 +219,7 @@ fixup_bundle_environment ()
        std::ofstream pangorc (path.c_str());
        if (!pangorc) {
                error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
+               return;
        } else {
                pangorc << "[Pango]\nModuleFiles=";
 
@@ -221,6 +229,7 @@ fixup_bundle_environment ()
                pangopath /= "pango.modules";
                        
                pangorc << pangopath.to_string() << endl;
+
                pangorc.close ();
 
                setenv ("PANGO_RC_FILE", path.c_str(), 1);
index dd5a70bb7d07e9087f7ec37717db53293605ab02..edfec8a600b466c8fb15454fa0fffbe8ea602cfb 100644 (file)
@@ -247,8 +247,8 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con
        Pango::FontDescription* font = get_font_for_style (N_("MarkerText"));
 
        text = new Text (*group);
-       text->property_text() = annotation.c_str();
        text->property_font_desc() = *font;
+       text->property_text() = annotation.c_str();
 
        delete font;
        
index e10967d01a61778ed58f64695061afddc87ddaca..df041f8f765373e4af48f9057c486f160859a503 100644 (file)
@@ -82,7 +82,7 @@ MarkerTimeAxis::MarkerTimeAxis (PublicEditor& ed, ARDOUR::Session& sess, Canvas&
        label_view() ;
                
        // set the initial height of this time axis
-       set_height(Small) ;
+       set_height(hSmall) ;
 }
 
 /**
@@ -106,13 +106,8 @@ MarkerTimeAxis::~MarkerTimeAxis()
 //---------------------------------------------------------------------------------------//
 // ui methods & data
        
-/**
- * Sets the height of this TrackView to one of the defined TrackHeights
- *
- * @param h the TrackHeight value to set
- */    
 void
-MarkerTimeAxis::set_height (TrackHeight h)
+MarkerTimeAxis::set_height (uint32_t h)
 {
        VisualTimeAxis::set_height(h) ;
        
index 13288ce66f661f64d41591ea88f2f93a2782c9b1..56856d3bd30bf4a43bce59c77c707ca621afe667 100644 (file)
@@ -80,9 +80,9 @@ class MarkerTimeAxis : public VisualTimeAxis
                /**
                 * Sets the height of this TrackView to one of the defined TrackHeights
                 *
-                * @param h the TrackHeight value to set
+                * @param h the number of pixels to set the height to
                 */
-               virtual void set_height(TimeAxisView::TrackHeight h) ;
+               virtual void set_height(uint32_t h) ;
                
                /**
                 * Sets the number of samples per unit that are used.
index b38067bfbfeeb26c98d96f8038b056c6338fe8ae..2f414405a068b6629a850169a5ecec473587c198 100644 (file)
@@ -78,7 +78,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
 }
 
 MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
-       : RegionView (parent, tv, r, spu, basic_color, visibility)
+       : RegionView (parent, tv, r, spu, basic_color, false, visibility)
        , _force_channel(-1)
        , _last_channel_selection(0xFFFF)
        , _default_note_length(0.0)
@@ -112,7 +112,7 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd)
 
        reset_width_dependent_items ((double) _region->length() / samples_per_unit);
 
-       set_y_position_and_height (0, trackview.height);
+       set_y_position_and_height (0, trackview.current_height());
 
        region_muted ();
        region_resized (BoundsChanged);
@@ -148,7 +148,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
        static double drag_start_x, drag_start_y;
        static double last_x, last_y;
        double event_x, event_y;
-       nframes_t event_frame = 0;
+       nframes64_t event_frame = 0;
 
        static ArdourCanvas::SimpleRect* drag_rect = NULL;
 
@@ -381,7 +381,7 @@ MidiRegionView::create_note_at(double x, double y, double duration)
        assert(note >= 0.0);
        assert(note <= 127.0);
 
-       nframes_t new_note_time = trackview.editor.pixel_to_frame (x);
+       nframes64_t new_note_time = trackview.editor.pixel_to_frame (x);
        assert(new_note_time >= 0);
        new_note_time += _region->start();
 
@@ -391,14 +391,14 @@ MidiRegionView::create_note_at(double x, double y, double duration)
        double duration = m.frames_per_bar(t, trackview.session().frame_rate()) / m.beats_per_bar();
        */
        
-       // we need to snap here again in nframes_t in order to be sample accurate 
+       // we need to snap here again in nframes64_t in order to be sample accurate 
        // since note time is region-absolute but snap_to_frame expects position-relative
        // time we have to coordinate transform back and forth here.
-       nframes_t new_note_time_position_relative = new_note_time      - _region->start(); 
+       nframes64_t new_note_time_position_relative = new_note_time      - _region->start(); 
        new_note_time = snap_to_frame(new_note_time_position_relative) + _region->start();
        
        // we need to snap the duration too to be sample accurate
-       nframes_t new_note_duration = nframes_t(duration);
+       nframes64_t new_note_duration = nframes_t(duration);
        new_note_duration = snap_to_frame(new_note_time_position_relative + new_note_duration) + _region->start() 
                            - new_note_time;
 
@@ -648,7 +648,7 @@ MidiRegionView::set_y_position_and_height (double y, double h)
                                                note->property_y2() = y2;
                                        }
                                        if (CanvasHit* hit = dynamic_cast<CanvasHit*>(event)) {
-                                               double x = trackview.editor.frame_to_pixel((nframes_t)
+                                               double x = trackview.editor.frame_to_pixel((nframes64_t)
                                                                event->note()->time() - _region->start());
                                                const double diamond_size = midi_stream_view()->note_height() / 2.0;
                                                double y = midi_stream_view()->note_to_y(event->note()->note()) 
@@ -744,7 +744,7 @@ MidiRegionView::resolve_note(uint8_t note, double end_time)
                return;
 
        if (_active_notes && _active_notes[note]) {
-               _active_notes[note]->property_x2() = trackview.editor.frame_to_pixel((nframes_t)end_time);
+               _active_notes[note]->property_x2() = trackview.editor.frame_to_pixel((nframes64_t)end_time);
                _active_notes[note]->property_outline_what() = (guint32) 0xF; // all edges
                _active_notes[note] = NULL;
        }
@@ -792,13 +792,13 @@ MidiRegionView::add_note(const boost::shared_ptr<Note> note)
 
        CanvasNoteEvent* event = 0;
        
-       const double x = trackview.editor.frame_to_pixel((nframes_t)note->time() - _region->start());
+       const double x = trackview.editor.frame_to_pixel((nframes64_t)note->time() - _region->start());
        
        if (midi_view()->note_mode() == Sustained) {
 
                const double y1 = midi_stream_view()->note_to_y(note->note());
                const double note_endpixel = 
-                       trackview.editor.frame_to_pixel((nframes_t)note->end_time() - _region->start());
+                       trackview.editor.frame_to_pixel((nframes64_t)note->end_time() - _region->start());
                
                CanvasNote* ev_rect = new CanvasNote(*this, *group, note);
                ev_rect->property_x1() = x;
@@ -880,7 +880,7 @@ MidiRegionView::add_pgm_change(boost::shared_ptr<MIDI::Event> event)
                return;
        
        ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
-       const double x = trackview.editor.frame_to_pixel((nframes_t)event->time() - _region->start());
+       const double x = trackview.editor.frame_to_pixel((nframes64_t)event->time() - _region->start());
        
        double height = midi_stream_view()->contents_height();
        _pgm_changes.push_back(
@@ -1064,7 +1064,7 @@ MidiRegionView::note_dropped(CanvasNoteEvent* ev, double dt, uint8_t dnote)
 
                        const boost::shared_ptr<Note> copy(new Note(*(*i)->note().get()));
 
-                       // we need to snap here again in nframes_t in order to be sample accurate 
+                       // we need to snap here again in nframes64_t in order to be sample accurate 
                        double new_note_time = (*i)->note()->time();
                        new_note_time +=  dt;
 
@@ -1075,7 +1075,7 @@ MidiRegionView::note_dropped(CanvasNoteEvent* ev, double dt, uint8_t dnote)
                        
                        // since note time is region-absolute but snap_to_frame expects position-relative
                        // time we have to coordinate transform back and forth here.
-                       new_note_time = snap_to_frame(nframes_t(new_note_time) - _region->start()) + _region->start();
+                       new_note_time = snap_to_frame(nframes64_t(new_note_time) - _region->start()) + _region->start();
                        
                        copy->set_time(new_note_time);
 
@@ -1111,26 +1111,26 @@ MidiRegionView::note_dropped(CanvasNoteEvent* ev, double dt, uint8_t dnote)
        }
 }
 
-nframes_t
+nframes64_t
 MidiRegionView::snap_to_frame(double x)
 {
        PublicEditor &editor = trackview.editor;
        // x is region relative
        // convert x to global frame
-       nframes_t frame = editor.pixel_to_frame(x) + _region->position();
+       nframes64_t frame = editor.pixel_to_frame(x) + _region->position();
        editor.snap_to(frame);
        // convert event_frame back to local coordinates relative to position
        frame -= _region->position();
        return frame;
 }
 
-nframes_t
-MidiRegionView::snap_to_frame(nframes_t x)
+nframes64_t
+MidiRegionView::snap_to_frame(nframes64_t x)
 {
        PublicEditor &editor = trackview.editor;
        // x is region relative
        // convert x to global frame
-       nframes_t frame = x + _region->position();
+       nframes64_t frame = x + _region->position();
        editor.snap_to(frame);
        // convert event_frame back to local coordinates relative to position
        frame -= _region->position();
@@ -1146,7 +1146,7 @@ MidiRegionView::snap_to_pixel(double x)
 double
 MidiRegionView::get_position_pixels(void)
 {
-       nframes_t  region_frame  = get_position();
+       nframes64_t  region_frame  = get_position();
        return trackview.editor.frame_to_pixel(region_frame);
 }
 
@@ -1250,7 +1250,7 @@ MidiRegionView::commit_resizing(CanvasNote::NoteEnd note_end, double event_x, bo
 
                // because snapping works on world coordinates we have to transform current_x
                // to world coordinates before snapping and transform it back afterwards
-               nframes_t current_frame = snap_to_frame(current_x);
+               nframes64_t current_frame = snap_to_frame(current_x);
                // transform to region start relative
                current_frame += _region->start();
                
index c2475f00faabdf5b816414623c7ba4445ff3757c..50cac66d778552a1801d02bf51b277af2b387ff2 100644 (file)
@@ -164,7 +164,7 @@ class MidiRegionView : public RegionView
        
        /**
         * This function provides the snap function for region position relative coordinates
-        * for pixel units (double) instead of nframes_t
+        * for pixel units (double) instead of nframes64_t
         * @param x a pixel coordinate relative to region start
         * @return the snapped pixel coordinate relative to region start
         */
@@ -172,18 +172,18 @@ class MidiRegionView : public RegionView
 
        /**
         * This function provides the snap function for region position relative coordinates
-        * for pixel units (double) instead of nframes_t
+        * for pixel units (double) instead of nframes64_t
         * @param x a pixel coordinate relative to region start
-        * @return the snapped nframes_t coordinate relative to region start
+        * @return the snapped nframes64_t coordinate relative to region start
         */
-       nframes_t snap_to_frame(double x);
+       nframes64_t snap_to_frame(double x);
 
        /**
         * This function provides the snap function for region position relative coordinates
         * @param x a pixel coordinate relative to region start
-        * @return the snapped nframes_t coordinate relative to region start
+        * @return the snapped nframes64_t coordinate relative to region start
         */
-       nframes_t snap_to_frame(nframes_t x);
+       nframes64_t snap_to_frame(nframes64_t x);
        
   protected:
 
index de14f302e57fd73594cd9c6b388fd9e749df002e..5b162dc510c5a4e309659376a4e18b7762b07716 100644 (file)
@@ -93,7 +93,7 @@ MidiStreamView::~MidiStreamView ()
 
 
 RegionView*
-MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd)
+MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd, bool recording)
 {
        boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion> (r);
 
@@ -384,7 +384,7 @@ MidiStreamView::setup_rec_box ()
                        rec_rect->property_x1() = xstart;
                        rec_rect->property_y1() = 1.0;
                        rec_rect->property_x2() = xend;
-                       rec_rect->property_y2() = (double) _trackview.height - 1;
+                       rec_rect->property_y2() = (double) _trackview.current_height() - 1;
                        rec_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_RecordingRect.get();
                        rec_rect->property_fill_color_rgba() = fill_color;
                        rec_rect->lower_to_bottom();
index 60dde8cc8505a9b8ed6aa1675aa55e48fdf12dae..1caad3481999a6d416d5ebb12bf8d5704c9411e2 100644 (file)
@@ -81,7 +81,7 @@ class MidiStreamView : public StreamView
        void redisplay_diskstream ();
        
        inline double contents_height() const
-               { return (_trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2); }
+       { return (_trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2); }
        
        inline double note_to_y(uint8_t note) const
                { return contents_height()
@@ -105,7 +105,7 @@ class MidiStreamView : public StreamView
        void rec_data_range_ready (jack_nframes_t start, jack_nframes_t dur, boost::weak_ptr<ARDOUR::Source> src); 
        void update_rec_regions (boost::shared_ptr<ARDOUR::MidiModel> data, jack_nframes_t start, jack_nframes_t dur);
        
-       RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
+       RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves, bool recording = false);
        void        display_region(MidiRegionView* region_view, bool load_model);
        void        display_diskstream (boost::shared_ptr<ARDOUR::Diskstream> ds);
        
index f6d2993cfed12213fa465da66c5663083cbb438a..5802cc7e20a76a73b5dc77a86d7ae57b1757a4e3 100644 (file)
@@ -396,15 +396,19 @@ MidiTimeAxisView::route_active_changed ()
 void 
 MidiTimeAxisView::channel_selector_toggled()
 {
-       static TimeAxisView::TrackHeight previous_height;
+       static uint32_t previous_height;
        
        if(_midi_expander.property_expanded()) {
-               previous_height = height_style;
-               if(previous_height != TimeAxisView::Largest) {
-                       set_height(TimeAxisView::Large);
+
+               previous_height = current_height();
+
+               if (previous_height < TimeAxisView::hLargest) {
+                       set_height (TimeAxisView::hLarge);
                }
+
        } else {
-               set_height(previous_height);
+
+               set_height (previous_height);
        }
 }
 
index dff81bc5b6d85f3ea3c24a43da394b02e76b420f..c98f4c5a0f59167e1542ee7aa900526d7c44b183 100644 (file)
@@ -682,7 +682,7 @@ MixerStrip::add_bundle_to_input_menu (boost::shared_ptr<Bundle> b, std::vector<b
 
        MenuList& citems = input_menu.items();
        
-       if (b->nchannels() == _route->n_inputs().n_total()) {
+       if (b->nchannels() == _route->n_inputs()) {
 
                citems.push_back (CheckMenuElem (b->name(), bind (mem_fun(*this, &MixerStrip::bundle_input_chosen), b)));
 
@@ -705,7 +705,7 @@ MixerStrip::add_bundle_to_output_menu (boost::shared_ptr<Bundle> b, std::vector<
                return;
        }
 
-       if (b->nchannels() == _route->n_outputs().n_total()) {
+       if (b->nchannels() == _route->n_outputs()) {
 
                MenuList& citems = output_menu.items();
                citems.push_back (CheckMenuElem (b->name(), bind (mem_fun(*this, &MixerStrip::bundle_output_chosen), b)));
@@ -1208,7 +1208,6 @@ MixerStrip::map_frozen ()
                        break;
                }
        }
-
        
        hide_redirect_editors ();
 }
@@ -1303,6 +1302,8 @@ MixerStrip::meter_changed (void *src)
        }
 
        gpm.setup_meters ();
+               // reset peak when meter point changes
+               gpm.reset_peak_display();
                set_width(_width, this);
 }
 
index 6754581b436f84c8cc95f0ff8ed87d36ee6eee6e..b2f8ece64ee1a3bc0aedc82681262a4697eb1caf 100644 (file)
@@ -221,7 +221,7 @@ Mixer_UI::Mixer_UI ()
        signal_configure_event().connect (mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
 
        _selection.RoutesChanged.connect (mem_fun(*this, &Mixer_UI::follow_strip_selection));
-       
+
        mix_group_display_button_box->show();
        mix_group_add_button->show();
        mix_group_remove_button->show();
@@ -797,34 +797,33 @@ Mixer_UI::auto_rebind_midi_controls ()
                                pos++;
                        }
 
-                       PBD::Controllable::CreateBinding ( strip->solo_button->get_controllable(), controlValue, 0);
-                       PBD::Controllable::CreateBinding ( strip->mute_button->get_controllable(), controlValue, 1);
+                       PBD::Controllable::CreateBinding ( strip->solo_button->get_controllable().get(), controlValue, 0);
+                       PBD::Controllable::CreateBinding ( strip->mute_button->get_controllable().get(), controlValue, 1);
 
                        if( strip->is_audio_track() ) {
-                               PBD::Controllable::CreateBinding ( strip->rec_enable_button->get_controllable(), controlValue, 2);
+                               PBD::Controllable::CreateBinding ( strip->rec_enable_button->get_controllable().get(), controlValue, 2);
                        }
 
-                       PBD::Controllable::CreateBinding ( strip->gpm.get_controllable(), controlValue, 3);
-                       PBD::Controllable::CreateBinding ( strip->panners.get_controllable(), controlValue, 4);
+                       PBD::Controllable::CreateBinding ( strip->gpm.get_controllable().get(), controlValue, 3);
+                       PBD::Controllable::CreateBinding ( strip->panners.get_controllable().get(), controlValue, 4);
 
                }
                else {  // Remove any existing binding
-                       PBD::Controllable::DeleteBinding ( strip->solo_button->get_controllable() );
-                       PBD::Controllable::DeleteBinding ( strip->mute_button->get_controllable() );
+                       PBD::Controllable::DeleteBinding ( strip->solo_button->get_controllable().get() );
+                       PBD::Controllable::DeleteBinding ( strip->mute_button->get_controllable().get() );
 
                        if( strip->is_audio_track() ) {
-                               PBD::Controllable::DeleteBinding ( strip->rec_enable_button->get_controllable() );
+                               PBD::Controllable::DeleteBinding ( strip->rec_enable_button->get_controllable().get() );
                        }
 
-                       PBD::Controllable::DeleteBinding ( strip->gpm.get_controllable() );
-                       PBD::Controllable::DeleteBinding ( strip->panners.get_controllable() ); // This only takes the first panner if there are multiples...
+                       PBD::Controllable::DeleteBinding ( strip->gpm.get_controllable().get() );
+                       PBD::Controllable::DeleteBinding ( strip->panners.get_controllable().get() ); // This only takes the first panner if there are multiples...
                }
 
        } // for
   
 }
 
-
 struct SignalOrderRouteSorter {
     bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
            /* use of ">" forces the correct sort order */
index 2eafa6e0ad53afa400fe5f65db83b2c7d7f6b4d4..6326c868f992acd25f18ab45f653957e9e17a479 100644 (file)
@@ -79,7 +79,8 @@
 (gtk_accel_path "<Actions>/Common/Save" "<%PRIMARY%>s")
 (gtk_accel_path "<Actions>/Editor/duplicate-region" "d")
 (gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<%PRIMARY%>d")
-(gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "f")
+(gtk_accel_path "<Actions>/Editor/fit-tracks" "f")
+(gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "<%PRIMARY%>f")
 (gtk_accel_path "<Actions>/Editor/toggle-rhythm-ferret" "<%WINDOW%>f")
 (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-gain" "g")
 (gtk_accel_path "<Actions>/Editor/play-selected-regions" "h")
 
 ;; HOME ROW
 
+<<<<<<< .working
 (gtk_accel_path "<Actions>/Editor/zoom-to-region" "<%SECONDARY%>z")
+=======
+(gtk_accel_path "<Actions>/Editor/zoom-to-region" "<%PRIMARY%><%SECONDARY%>z")
+(gtk_accel_path "<Actions>/Editor/zoom-to-region-both-axes" "<%SECONDARY%>z")
+>>>>>>> .merge-right.r3622
 (gtk_accel_path "<Actions>/Editor/undo" "<%PRIMARY%>z")
 (gtk_accel_path "<Actions>/Editor/toggle-zoom" "<%TERTIARY%>z")
+<<<<<<< .working
 (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "z")
 (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-note" "n")
+=======
+(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "z")
+>>>>>>> .merge-right.r3622
 (gtk_accel_path "<Actions>/Editor/editor-cut" "<%PRIMARY%>x")
 (gtk_accel_path "<Actions>/Editor/editor-copy" "<%PRIMARY%>c")
 (gtk_accel_path "<Actions>/Common/ToggleColorManager" "<%WINDOW%>c")
 (gtk_accel_path "<Actions>/Editor/select-range-between-cursors" "F6")
 (gtk_accel_path "<Actions>/Common/ToggleMaximalEditor" "F11")
 
+(gtk_accel_path "<Actions>/Editor/save-visual-state-1" "<%PRIMARY%>F1")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-2" "<%PRIMARY%>F2")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-3" "<%PRIMARY%>F3")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-4" "<%PRIMARY%>F4")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-5" "<%PRIMARY%>F5")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-6" "<%PRIMARY%>F6")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-7" "<%PRIMARY%>F7")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-8" "<%PRIMARY%>F8")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-9" "<%PRIMARY%>F9")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-10" "<%PRIMARY%>F10")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-11" "<%PRIMARY%>F11")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-12" "<%PRIMARY%>F12")
+
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-1" "<release><%PRIMARY%>F1")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-2" "<release><%PRIMARY%>F2")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-3" "<release><%PRIMARY%>F3")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-4" "<release><%PRIMARY%>F4")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-5" "<release><%PRIMARY%>F5")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-6" "<release><%PRIMARY%>F6")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-7" "<release><%PRIMARY%>F7")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-8" "<release><%PRIMARY%>F8")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-9" "<release><%PRIMARY%>F9")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-10" "<release><%PRIMARY%>F10")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-11" "<release><%PRIMARY%>F11")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-12" "<release><%PRIMARY%>F12")
+
+
 ;; numbers
 
 (gtk_accel_path "<Actions>/Editor/toggle-edit-mode" "1")
index 2dfa63080d0b614c69c83ae8b1c7d8ffab2b6cbb..9ddf9999b9ef88ac1c1628ab2939b718b5eb27a3 100644 (file)
@@ -113,6 +113,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
 {
        using namespace Notebook_Helpers;
 
+       first_click_setup = true;
        click_io_selector = 0;
        auditioner_io_selector = 0;
        session = 0;
@@ -1036,8 +1037,8 @@ void
 OptionEditor::clear_click_editor ()
 {
        if (click_io_selector) {
-               click_packer.remove (*click_io_selector);
-               click_packer.remove (*click_gpm);
+               click_hpacker.remove (*click_io_selector);
+               click_hpacker.remove (*click_gpm);
                delete click_io_selector;
                delete click_gpm;
                click_io_selector = 0;
@@ -1049,31 +1050,59 @@ void
 OptionEditor::setup_click_editor ()
 {
        Label* label;
-       HBox* hpacker = manage (new HBox);
+
+       if (first_click_setup) {
+               
+               click_path_entry.set_name ("OptionsEntry");
+               click_emphasis_path_entry.set_name ("OptionsEntry");
+               
+               click_path_entry.signal_activate().connect (mem_fun(*this, &OptionEditor::click_sound_changed));
+               click_emphasis_path_entry.signal_activate().connect (mem_fun(*this, &OptionEditor::click_emphasis_sound_changed));
+               
+               click_path_entry.signal_focus_out_event().connect (bind (mem_fun(*this, &OptionEditor::focus_out_event_handler), &OptionEditor::click_sound_changed));
+               click_emphasis_path_entry.signal_focus_out_event().connect (bind (mem_fun(*this, &OptionEditor::focus_out_event_handler), &OptionEditor::click_emphasis_sound_changed));
+               
+               click_browse_button.set_name ("EditorGTKButton");
+               click_emphasis_browse_button.set_name ("EditorGTKButton");
+
+               click_browse_button.signal_clicked().connect (mem_fun(*this, &OptionEditor::click_browse_clicked));
+               click_emphasis_browse_button.signal_clicked().connect (mem_fun(*this, &OptionEditor::click_emphasis_browse_clicked));
+
+               click_packer.set_border_width (12);
+               click_packer.set_spacing (5);
+
+               click_table.set_col_spacings (10);
+               
+               label = manage(new Label(_("Click audio file")));
+               label->set_name ("OptionsLabel");
+               click_table.attach (*label, 0, 1, 0, 1, FILL|EXPAND, FILL);
+               click_table.attach (click_path_entry, 1, 2, 0, 1, Gtk::FILL|Gtk::EXPAND, FILL);
+               click_table.attach (click_browse_button, 2, 3, 0, 1, FILL|EXPAND, FILL);
+               
+               label = manage(new Label(_("Click emphasis audiofile")));
+               label->set_name ("OptionsLabel");
+               click_table.attach (*label, 0, 1, 1, 2, FILL|EXPAND, FILL);
+               click_table.attach (click_emphasis_path_entry, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, FILL);
+               click_table.attach (click_emphasis_browse_button, 2, 3, 1, 2, FILL|EXPAND, FILL);
+
+               click_packer.pack_start (click_table, false, false);
+               click_packer.pack_start (click_hpacker, false, false);
+
+
+               click_hpacker.set_spacing (10);
+
+               first_click_setup = false;
+       }
 
        click_path_entry.set_sensitive (true);
        click_emphasis_path_entry.set_sensitive (true);
 
-       click_path_entry.set_name ("OptionsEntry");
-       click_emphasis_path_entry.set_name ("OptionsEntry");
-
-       click_path_entry.signal_activate().connect (mem_fun(*this, &OptionEditor::click_sound_changed));
-       click_emphasis_path_entry.signal_activate().connect (mem_fun(*this, &OptionEditor::click_emphasis_sound_changed));
-
-       click_path_entry.signal_focus_out_event().connect (bind (mem_fun(*this, &OptionEditor::focus_out_event_handler), &OptionEditor::click_sound_changed));
-       click_emphasis_path_entry.signal_focus_out_event().connect (bind (mem_fun(*this, &OptionEditor::focus_out_event_handler), &OptionEditor::click_emphasis_sound_changed));
-
-       click_browse_button.set_name ("EditorGTKButton");
-       click_emphasis_browse_button.set_name ("EditorGTKButton");
-       click_browse_button.signal_clicked().connect (mem_fun(*this, &OptionEditor::click_browse_clicked));
-       click_emphasis_browse_button.signal_clicked().connect (mem_fun(*this, &OptionEditor::click_emphasis_browse_clicked));
-
-       click_packer.set_border_width (12);
-       click_packer.set_spacing (5);
-
        click_io_selector = new IOSelector (*session, session->click_io(), false);
        click_gpm = new GainMeter (session->click_io(), *session);
 
+       click_hpacker.pack_start (*click_io_selector, false, false);
+       click_hpacker.pack_start (*click_gpm, false, false);
+
        click_table.set_col_spacings (10);
 
        label = manage(new Label(_("Click audio file")));
@@ -1088,13 +1117,6 @@ OptionEditor::setup_click_editor ()
        click_table.attach (click_emphasis_path_entry, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, FILL);
        click_table.attach (click_emphasis_browse_button, 2, 3, 1, 2, FILL|EXPAND, FILL);
 
-       hpacker->set_spacing (10);
-       hpacker->pack_start (*click_io_selector, false, false);
-       hpacker->pack_start (*click_gpm, false, false);
-
-       click_packer.pack_start (click_table, false, false);
-       click_packer.pack_start (*hpacker, false, false);
-
        click_packer.show_all ();
 }
 
index c6f13049b0adae59ce81463f82d5424531861bba..bb126980415d429a4ce68b9a70a31b7ebf81eac6 100644 (file)
@@ -173,6 +173,8 @@ class OptionEditor : public ArdourDialog
        IOSelector*   click_io_selector;
        GainMeter* click_gpm;
        PannerUI*     click_panner;
+       bool          first_click_setup;
+       Gtk::HBox     click_hpacker;
        Gtk::VBox     click_packer;
        Gtk::Table    click_table;
        Gtk::Entry    click_path_entry;
index 2607cdf2b85e3ac3f346acd05aead4f04fd0594e..975f1e6b3b66d17fefc36be3dd919af37542a689 100644 (file)
@@ -35,7 +35,7 @@ null_label_callback (char* buf, unsigned int bufsize)
 
 
 PannerBar::PannerBar (Gtk::Adjustment& adj, boost::shared_ptr<PBD::Controllable> c)
-       : BarController (adj, *c.get(), sigc::ptr_fun (null_label_callback))
+       : BarController (adj, c, sigc::ptr_fun (null_label_callback))
 {
        set_style (BarController::Line);
 }
index a1f99c40d46c95995734d739e84a111904254277..6fa64be8e60e5d6a71869ad6a72683ba62c1cbdc 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <cmath>
 #include <climits>
-#include <string.h>
+#include <cstring>
 
 #include <gtkmm/menu.h>
 #include <gtkmm/checkmenuitem.h>
index d4f0d9eeca47aae6f9ecc56174503c8862af9f7e..3fe43850a353ee09ffda8d66f697e435ef9c5542 100644 (file)
@@ -166,7 +166,7 @@ PannerUI::PannerUI (boost::shared_ptr<IO> io, Session& s)
        show();
 }
 
-PBD::Controllable* 
+boost::shared_ptr<PBD::Controllable>
 PannerUI::get_controllable() 
 { 
        return pan_bars[0]->get_controllable();
index 093800387dfb1a447253ea268a16d1f1d621969d..e10080a3176c313a84b46edbec5e44e796b6b2c7 100644 (file)
@@ -68,7 +68,7 @@ class PannerUI : public Gtk::HBox
        void effective_pan_display ();
 
        void set_meter_strip_name (string name);
-       PBD::Controllable* get_controllable();
+       boost::shared_ptr<PBD::Controllable> get_controllable();
 
   private:
        friend class MixerStrip;
diff --git a/gtk2_ardour/plugin_interest.h b/gtk2_ardour/plugin_interest.h
new file mode 100644 (file)
index 0000000..1b7d3c0
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+    Copyright (C) 2008 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.
+
+*/
+
+#ifndef __gtkardour_plugin_interest_h__
+#define __gtkardour_plugin_interest_h__
+
+#include <vector>
+#include <ardour/plugin.h>
+
+typedef std::vector<ARDOUR::PluginPtr> SelectedPlugins;
+
+class PluginInterestedObject {
+  public:
+       PluginInterestedObject() {}
+       virtual ~PluginInterestedObject() {}
+
+       virtual void use_plugins (const SelectedPlugins&) = 0;
+};
+
+#endif /* __gtkardour_plugin_interest_h__ */
index aa269be5775c05b476760a411eb88dfea7001c43..87d5532d34575e52170fd4f9afe526fb8a04791f 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <cstdio>
 #include <lrdf.h>
+#include <map>
 
 #include <algorithm>
 
@@ -51,6 +52,7 @@ static const char* _filter_mode_strings[] = {
        N_("Type contains"),
        N_("Author contains"),
        N_("Library contains"),
+       N_("Favorites only"),
        0
 };
 
@@ -64,9 +66,15 @@ PluginSelector::PluginSelector (PluginManager *mgr)
 
        manager = mgr;
        session = 0;
-       
+       _menu = 0;
+       in_row_change = false;
+
        plugin_model = Gtk::ListStore::create (plugin_columns);
        plugin_display.set_model (plugin_model);
+       /* XXX translators: try to convert "Fav" into a short term
+          related to "favorite"
+       */
+       plugin_display.append_column (_("Fav"), plugin_columns.favorite);
        plugin_display.append_column (_("Available Plugins"), plugin_columns.name);
        plugin_display.append_column (_("Type"), plugin_columns.type_name);
        plugin_display.append_column (_("Category"), plugin_columns.category);
@@ -78,6 +86,13 @@ PluginSelector::PluginSelector (PluginManager *mgr)
        plugin_display.set_headers_visible (true);
        plugin_display.set_headers_clickable (true);
        plugin_display.set_reorderable (false);
+       plugin_display.set_rules_hint (true);
+
+       CellRendererToggle* fav_cell = dynamic_cast<CellRendererToggle*>(plugin_display.get_column_cell_renderer (0));
+       fav_cell->property_activatable() = true;
+       fav_cell->property_radio() = false;
+       fav_cell->signal_toggled().connect (mem_fun (*this, &PluginSelector::favorite_changed));
+
        scroller.set_border_width(10);
        scroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
        scroller.add(plugin_display);
@@ -187,6 +202,10 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string&
        std::string compstr;
        std::string mode = filter_mode.get_active_text ();
 
+       if (mode == _("Favorites only")) {
+               return manager->is_a_favorite_plugin (info);
+       }
+
        if (!filterstr.empty()) {
                
                if (mode == _("Name contains")) {
@@ -197,8 +216,8 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string&
                        compstr = info->creator;
                } else if (mode == _("Library contains")) {
                        compstr = info->path;
-               }
-               
+               } 
+
                transform (compstr.begin(), compstr.end(), compstr.begin(), ::toupper);
 
                if (compstr.find (filterstr) != string::npos) {
@@ -206,7 +225,6 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string&
                } else {
                        return false;
                }
-               
        }
 
        return true;
@@ -224,6 +242,8 @@ PluginSelector::refill ()
 {
        std::string filterstr;
 
+       in_row_change = true;
+
        plugin_model->clear ();
 
        setup_filter_string (filterstr);
@@ -232,6 +252,8 @@ PluginSelector::refill ()
        lv2_refiller (filterstr);
        vst_refiller (filterstr);
        au_refiller (filterstr);
+
+       in_row_change = false;
 }
 
 void
@@ -244,11 +266,11 @@ PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& filte
                if (show_this_plugin (*i, filterstr)) {
 
                        TreeModel::Row newrow = *(plugin_model->append());
+                       newrow[plugin_columns.favorite] = manager->is_a_favorite_plugin (*i);
                        newrow[plugin_columns.name] = (*i)->name;
                        newrow[plugin_columns.type_name] = type;
                        newrow[plugin_columns.category] = (*i)->category;
 
-
                        string creator = (*i)->creator;
                        string::size_type pos = 0;
 
@@ -313,18 +335,14 @@ PluginSelector::au_refiller (const std::string& filterstr)
 #endif
 }
 
-void
-PluginSelector::use_plugin (PluginInfoPtr pi)
+PluginPtr
+PluginSelector::load_plugin (PluginInfoPtr pi)
 {
        if (session == 0) {
-               return;
+               return PluginPtr();
        }
 
-       PluginPtr plugin = pi->load (*session);
-
-       if (plugin) {
-               PluginCreated (plugin);
-       }
+       return pi->load (*session);
 }
 
 void
@@ -390,6 +408,7 @@ PluginSelector::run ()
 {
        ResponseType r;
        TreeModel::Children::iterator i;
+       SelectedPlugins plugins;
 
        r = (ResponseType) Dialog::run ();
 
@@ -397,24 +416,26 @@ PluginSelector::run ()
        case RESPONSE_APPLY:
                for (i = amodel->children().begin(); i != amodel->children().end(); ++i) {
                        PluginInfoPtr pp = (*i)[acols.plugin];
-                       use_plugin (pp);
+                       PluginPtr p = load_plugin (pp);
+                       if (p) {
+                               plugins.push_back (p);
+                       }
+               }
+               if (interested_object && !plugins.empty()) {
+                       interested_object->use_plugins (plugins);
                }
+               
                break;
 
        default:
                break;
        }
 
-       cleanup ();
-
-       return (int) r;
-}
-
-void
-PluginSelector::cleanup ()
-{
        hide();
        amodel->clear();
+       interested_object = 0;
+
+       return (int) r;
 }
 
 void
@@ -432,6 +453,14 @@ PluginSelector::filter_entry_changed ()
 void 
 PluginSelector::filter_mode_changed ()
 {
+       std::string mode = filter_mode.get_active_text ();
+
+       if (mode == _("Favorites only")) {
+               filter_entry.set_sensitive (false);
+       } else {
+               filter_entry.set_sensitive (true);
+       }
+
        refill ();
 }
 
@@ -441,3 +470,153 @@ PluginSelector::on_show ()
        ArdourDialog::on_show ();
        filter_entry.grab_focus ();
 }
+
+struct PluginMenuCompare {
+    bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
+           int cmp;
+
+           cmp = strcasecmp (a->creator.c_str(), b->creator.c_str());
+
+           if (cmp < 0) {
+                   return true;
+           } else if (cmp == 0) {
+                   /* same creator ... compare names */
+                   if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
+                           return true;
+                   } 
+           }
+           return false;
+    }
+};
+
+Gtk::Menu&
+PluginSelector::plugin_menu()
+{
+       using namespace Menu_Helpers;
+
+       typedef std::map<Glib::ustring,Gtk::Menu*> SubmenuMap;
+       SubmenuMap submenu_map;
+
+       if (!_menu) {
+               _menu = new Menu();
+               _menu->set_name("ArdourContextMenu");
+       } 
+
+       MenuList& items = _menu->items();
+       Menu* favs = new Menu();
+       favs->set_name("ArdourContextMenu");
+
+       items.clear ();
+       items.push_back (MenuElem (_("Favorites"), *favs));
+       items.push_back (MenuElem (_("Plugin Manager"), mem_fun (*this, &PluginSelector::show_manager)));
+       items.push_back (SeparatorElem ());
+
+       PluginInfoList all_plugs;
+
+       all_plugs.insert (all_plugs.end(), manager->ladspa_plugin_info().begin(), manager->ladspa_plugin_info().end());
+#ifdef VST_SUPPORT
+       all_plugs.insert (all_plugs.end(), manager->vst_plugin_info().begin(), manager->vst_plugin_info().end());
+#endif
+#ifdef HAVE_AUDIOUNITS
+       all_plugs.insert (all_plugs.end(), manager->au_plugin_info().begin(), manager->au_plugin_info().end());
+#endif
+#ifdef HAVE_SLV2
+       all_plugs.insert (all_plugs.end(), manager->lv2_plugin_info().begin(), manager->lv2_plugin_info().end());
+#endif
+
+       PluginMenuCompare cmp;
+       all_plugs.sort (cmp);
+
+       for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
+               SubmenuMap::iterator x;
+               Gtk::Menu* submenu;
+
+               string creator = (*i)->creator;
+               string::size_type pos = 0;
+
+               if (manager->is_a_favorite_plugin (*i)) {
+                       favs->items().push_back (MenuElem ((*i)->name, (bind (mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i))));
+               }
+               
+               /* stupid LADSPA creator strings */
+               
+               while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos;
+               creator = creator.substr (0, pos);
+
+               if ((x = submenu_map.find (creator)) != submenu_map.end()) {
+                       submenu = x->second;
+               } else {
+                       submenu = new Gtk::Menu;
+                       items.push_back (MenuElem (creator, *submenu));
+                       submenu_map.insert (pair<Glib::ustring,Menu*> (creator, submenu));
+                       submenu->set_name("ArdourContextMenu");
+               }
+               
+               submenu->items().push_back (MenuElem ((*i)->name, (bind (mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i))));
+       }
+       
+       return *_menu;
+}
+
+void
+PluginSelector::plugin_chosen_from_menu (const PluginInfoPtr& pi)
+{
+       PluginPtr p = load_plugin (pi);
+
+       if (p && interested_object) {
+               SelectedPlugins plugins;
+               plugins.push_back (p);
+               interested_object->use_plugins (plugins);
+       }
+
+       interested_object = 0;
+}
+
+void 
+PluginSelector::favorite_changed (const Glib::ustring& path)
+{
+       PluginInfoPtr pi;
+
+       if (in_row_change) {
+               return;
+       }
+
+       in_row_change = true;
+       
+       TreeModel::iterator iter = plugin_model->get_iter (path);
+       
+       if (iter) {
+
+               bool favorite = !(*iter)[plugin_columns.favorite];
+
+               /* change state */
+
+               (*iter)[plugin_columns.favorite] = favorite;
+
+               /* save new favorites list */
+
+               pi = (*iter)[plugin_columns.plugin];
+               
+               if (favorite) {
+                       manager->add_favorite (pi->type, pi->unique_id);
+               } else {
+                       manager->remove_favorite (pi->type, pi->unique_id);
+               }
+               
+               manager->save_favorites ();
+       }
+       in_row_change = false;
+}
+
+void
+PluginSelector::show_manager ()
+{
+       show_all();
+       run ();
+}
+
+void
+PluginSelector::set_interested_object (PluginInterestedObject& obj)
+{
+       interested_object = &obj;
+}
index fe797588dee2dfeb1a2f32c3005a0aadc9c195c9..c4b613647d20781df194aeff47fd9d3901946cf8 100644 (file)
@@ -26,6 +26,7 @@
 #include <gtkmm2ext/selector.h>
 
 #include <ardour/plugin.h>
+#include "plugin_interest.h"
 
 namespace ARDOUR {
        class Session;
@@ -36,16 +37,21 @@ class PluginSelector : public ArdourDialog
 {
   public:
        PluginSelector (ARDOUR::PluginManager *);
-       sigc::signal<void,boost::shared_ptr<ARDOUR::Plugin> > PluginCreated;
 
+       void set_interested_object (PluginInterestedObject&);
+       
        int run (); // XXX should we try not to overload the non-virtual Gtk::Dialog::run() ?
 
        void set_session (ARDOUR::Session*);
        void on_show ();
 
+       Gtk::Menu& plugin_menu ();
+
   private:
+       PluginInterestedObject* interested_object;
+
        ARDOUR::Session* session;
-       Gtk::ScrolledWindow scroller;  // Available plugins
+       Gtk::ScrolledWindow scroller;   // Available plugins
        Gtk::ScrolledWindow ascroller;  // Added plugins
 
        Gtk::ComboBoxText filter_mode;
@@ -58,6 +64,7 @@ class PluginSelector : public ArdourDialog
        
        struct PluginColumns : public Gtk::TreeModel::ColumnRecord {
                PluginColumns () {
+                       add (favorite);
                        add (name);
                        add (type_name);
                        add (category);
@@ -68,6 +75,7 @@ class PluginSelector : public ArdourDialog
                        add (midi_outs);
                        add (plugin);
                }
+               Gtk::TreeModelColumn<bool> favorite;
                Gtk::TreeModelColumn<std::string> name;
                Gtk::TreeModelColumn<std::string> type_name;
                Gtk::TreeModelColumn<std::string> category;
@@ -112,10 +120,16 @@ class PluginSelector : public ArdourDialog
        void added_list_selection_changed();
        void display_selection_changed();
        void btn_apply_clicked();
-       void use_plugin (ARDOUR::PluginInfoPtr);
-       void cleanup ();
+       ARDOUR::PluginPtr load_plugin (ARDOUR::PluginInfoPtr);
        bool show_this_plugin (const ARDOUR::PluginInfoPtr&, const std::string&);
        void setup_filter_string (std::string&);
+
+       void favorite_changed (const Glib::ustring& path);
+       bool in_row_change;
+
+       void plugin_chosen_from_menu (const ARDOUR::PluginInfoPtr&);
+       Gtk::Menu* _menu;
+       void show_manager ();
 };
 
 #endif // __ardour_plugin_selector_h__
index 014638e9cd3f056a868839d0b1f966c09afb8423..d3c9effaa24b4efdee534045b9970a90dfe45d2b 100644 (file)
@@ -51,6 +51,7 @@
 #include "utils.h"
 #include "gui_thread.h"
 #include "public_editor.h"
+#include "keyboard.h"
 
 #include "i18n.h"
 
@@ -150,6 +151,20 @@ PluginUIWindow::on_map ()
        set_keep_above (true);
 }
 
+bool
+PluginUIWindow::on_enter_notify_event (GdkEventCrossing *ev)
+{
+       Keyboard::the_keyboard().enter_window (ev, this);
+       return false;
+}
+
+bool
+PluginUIWindow::on_leave_notify_event (GdkEventCrossing *ev)
+{
+       Keyboard::the_keyboard().leave_window (ev, this);
+       return false;
+}
+
 void
 PluginUIWindow::on_show ()
 {
index 65b7b0d7fb1f01fed60780ed57806bab14b86ebc..acc1e4d53a6a40586ba98145cd6cdd2c75b07bcf 100644 (file)
@@ -214,11 +214,14 @@ class PluginUIWindow : public Gtk::Window
        void resize_preferred();
        void set_parent (Gtk::Window*);
 
+       bool on_enter_notify_event (GdkEventCrossing*);
+       bool on_leave_notify_event (GdkEventCrossing*);
        bool on_key_press_event (GdkEventKey*);
        bool on_key_release_event (GdkEventKey*);
        void on_show ();
        void on_hide ();
        void on_map ();
+
   private:
        PlugUIBase* _pluginui;
        Gtk::Window* parent;
index d870c203fe7d54f6981e21935a835fe9ceade86a..158b1c4cecf70b6b86c643e87d8cfded77f0684a 100644 (file)
@@ -1966,15 +1966,6 @@ msgstr "Tona Ut"
 msgid "Audition"
 msgstr "Avlyssna"
 
-
-#: gtk2_ardour/editor.cc:105 gtk2_ardour/editor.cc:3517
-msgid "Slide Edit"
-msgstr "Glidred."
-
-#: gtk2_ardour/editor.cc:106 gtk2_ardour/editor.cc:3515
-msgid "Splice Edit"
-msgstr "Fogred."
-
 #: gtk2_ardour/editor.cc:111 gtk2_ardour/editor.cc:3572
 #: gtk2_ardour/export_dialog.cc:78 gtk2_ardour/export_dialog.cc:92
 #: gtk2_ardour/export_dialog.cc:893 gtk2_ardour/export_dialog.cc:1225
@@ -7102,6 +7093,7 @@ msgstr "EJ tonhöjdsändrat soloslagverk"
 #: gtk2_ardour/editor_timefx.cc:73
 msgid "Contents:"
 msgstr "InnehÃ¥ll"
+<<<<<<< .working
 
 
 #: gtk2_ardour/editor_actions.cc:359
@@ -7442,3 +7434,558 @@ msgstr "FFT-analysfönster"
 #: gtk2_ardour/analysis_window.cc:135
 msgid "Re-analyze data"
 msgstr "Ã…teranalysera data"
+=======
+
+#: gtk2_ardour/editor_actions.cc:359
+msgid "Playhead to Mouse"
+msgstr "Startmarkören till mus"
+
+#: gtk2_ardour/editor_actions.cc:277
+msgid "Playhead To Active Mark"
+msgstr "Startmarkören till aktiv markör"
+
+#: gtk2_ardour/editor_actions.cc:231
+msgid "Nudge Playhead Forward"
+msgstr "Knuffa startmarkören framÃ¥t"
+
+#: gtk2_ardour/editor_actions.cc:233
+msgid "Nudge Playhead Backward"
+msgstr "Knuffa startmarkören bakÃ¥t"
+
+#: gtk2_ardour/editor_actions.cc:475
+msgid "Move Forward to Transient"
+msgstr "GÃ¥ framÃ¥t till transient"
+
+#: gtk2_ardour/editor_actions.cc:477
+msgid "Move Backwards to Transient"
+msgstr "GÃ¥ bakÃ¥t till transient"
+
+#: gtk2_ardour/editor_actions.cc:235
+msgid "Forward To Grid"
+msgstr "FramÃ¥t till rutnät"
+
+#: gtk2_ardour/editor_actions.cc:237
+msgid "Backward To Grid"
+msgstr "BakÃ¥t till rutnät"
+
+#: gtk2_ardour/editor_actions.cc:66 gtk2_ardour/editor.cc:151
+#: gtk2_ardour/editor.cc:3446
+msgid "Active Mark"
+msgstr "Aktiv markör"
+
+#: gtk2_ardour/editor_actions.cc:137
+msgid "to Next Region Boundary"
+msgstr "till nästa regionsgränsen"
+
+#: gtk2_ardour/editor_actions.cc:139
+msgid "to Previous Region Boundary"
+msgstr "till förra regionsgränsen"
+
+#: gtk2_ardour/editor_actions.cc:279
+msgid "Active Mark To Playhead"
+msgstr "Aktiv markör till startmarkören"
+
+#: gtk2_ardour/editor_actions.cc:361
+msgid "Active Marker to Mouse"
+msgstr "Aktiv markör till musen"
+
+#: gtk2_ardour/editor_actions.cc:61 gtk2_ardour/editor_actions.cc:613
+msgid "Markers"
+msgstr "Markörer"
+
+#: gtk2_ardour/ardour_ui_ed.cc:333
+msgid "Punch In/Out"
+msgstr "Inslag/utslag"
+
+#: gtk2_ardour/editor_actions.cc:177
+msgid "Select All Overlapping Edit Range"
+msgstr "Välj allt som Ã¶verlappar redigeringsomfÃ¥nget"
+
+#: gtk2_ardour/editor_actions.cc:179
+msgid "Select All Inside Edit Range"
+msgstr "Välj allt inom redigeringsomfÃ¥nget"
+
+#: gtk2_ardour/editor_actions.cc:182
+msgid "Select Edit Range"
+msgstr "Välj redigeringsomfÃ¥ng"
+
+
+#: gtk2_ardour/editor_actions.cc:444
+msgid "Separate Using Punch Range"
+msgstr "Separera utifrÃ¥n in-/utslagsomfÃ¥nget"
+
+#: gtk2_ardour/editor_actions.cc:447
+msgid "Separate Using Loop Range"
+msgstr "Separera utifrÃ¥n loopomfÃ¥nget"
+
+#: gtk2_ardour/editor_actions.cc:469
+msgid "Split Regions At Percussion Onsets"
+msgstr "Dela regioner vid perkussiva anslag"
+
+#: gtk2_ardour/editor_actions.cc:282
+msgid "Trim Start At Edit Point"
+msgstr "Beskär början vid redigeringspunkten"
+
+#: gtk2_ardour/editor_actions.cc:285
+msgid "Trim End At Edit Point"
+msgstr "Beskär slutet vid redigeringspunkten"
+
+#: gtk2_ardour/ardour_ui_ed.cc:95
+msgid "Misc. Shortcuts"
+msgstr "Diverse kortkommandon"
+
+#: gtk2_ardour/editor_actions.cc:385
+msgid "Boost Region Gain"
+msgstr "Öka regionens volym"
+
+#: gtk2_ardour/editor_actions.cc:388
+msgid "Cut Region Gain"
+msgstr "Sänk regionens volym"
+
+#: gtk2_ardour/editor_actions.cc:99
+msgid "Break drag"
+msgstr "Avbryt dragning"
+
+
+#: gtk2_ardour/editor_actions.cc:400
+msgid "Raise Region"
+msgstr "Höj regionen"
+
+#: gtk2_ardour/editor_actions.cc:403
+msgid "Lower Region"
+msgstr "Sänk regionen"
+
+#: gtk2_ardour/editor_actions.cc:415
+msgid "Move To Original Position"
+msgstr "Flytta till ursprunglig position"
+
+#: gtk2_ardour/editor_actions.cc:409
+msgid "Lock Region"
+msgstr "LÃ¥s region"
+
+#: gtk2_ardour/editor_actions.cc:397
+msgid "Remove Region Sync"
+msgstr "Ta bort regionsynk.-punkt"
+
+#: gtk2_ardour/editor_actions.cc:505 gtk2_ardour/editor_ops.cc:5651
+msgid "Insert Time"
+msgstr "Infoga tid"
+
+#: gtk2_ardour/editor_actions.cc:93
+msgid "Waveforms"
+msgstr "VÃ¥gformer"
+
+#: gtk2_ardour/editor_actions.cc:509
+msgid "Toggle Active"
+msgstr "Växla aktiv"
+
+#: gtk2_ardour/editor_actions.cc:547
+msgid "Zoom Focus Mouse"
+msgstr "Zoomfokus: mus"
+
+#: gtk2_ardour/editor_actions.cc:582
+msgid "Next Snap Mode"
+msgstr "Nästa fästläge"
+
+#: gtk2_ardour/editor_actions.cc:583
+msgid "Next Snap Choice"
+msgstr "Nästa fästlägealternativ"
+
+#: gtk2_ardour/editor_actions.cc:70
+msgid "Primary Clock"
+msgstr "Primär klocka"
+
+#: gtk2_ardour/editor_actions.cc:77
+msgid "Secondary Clock"
+msgstr "Sekundär klocka"
+
+#: gtk2_ardour/ardour_ui_ed.cc:309 gtk2_ardour/ardour_ui_ed.cc:318
+#: gtk2_ardour/editor_actions.cc:616
+msgid "Bars & Beats"
+msgstr "Takter & slag"
+
+#: gtk2_ardour/ardour_ui_ed.cc:311 gtk2_ardour/ardour_ui_ed.cc:320
+msgid "Minutes & Seconds"
+msgstr "Minuter & sekunder"
+
+#: gtk2_ardour/editor_actions.cc:75
+msgid "Rulers"
+msgstr "Tidslinjevisning"
+
+#: gtk2_ardour/editor_actions.cc:619
+msgid "Min:Sec"
+msgstr "Min:sek"
+
+#: gtk2_ardour/editor_actions.cc:615
+msgid "Loop/Punch"
+msgstr "Loop-/inslagsmarkörer"
+
+#: gtk2_ardour/editor_actions.cc:76
+msgid "Scroll"
+msgstr "Skrollning"
+
+#: gtk2_ardour/rhythm_ferret.cc:40
+msgid "Analysis"
+msgstr "Analys"
+
+#: gtk2_ardour/rhythm_ferret.cc:30
+msgid "Percussive Onset"
+msgstr "Perkussivt anslag"
+
+#: gtk2_ardour/rhythm_ferret.cc:31
+msgid "Note Onset"
+msgstr "Notanslag"
+
+#: gtk2_ardour/rhythm_ferret.cc:48
+msgid "Threshold"
+msgstr "Tröskel"
+
+#: gtk2_ardour/rhythm_ferret.cc:51
+msgid "Sensitivity"
+msgstr "Känslighet"
+
+#: gtk2_ardour/rhythm_ferret.cc:52
+msgid "Analyze"
+msgstr "Analysera"
+
+#: gtk2_ardour/rhythm_ferret.cc:55
+msgid "Trigger gap (msecs)"
+msgstr "Utlösningsmellanrum (msek)"
+
+#: gtk2_ardour/rhythm_ferret.cc:43
+msgid "Set Tempo Map"
+msgstr "Sätt tempokarta"
+
+#: gtk2_ardour/rhythm_ferret.cc:44
+msgid "Conform Region"
+msgstr "Anpassa region"
+
+#: gtk2_ardour/rhythm_ferret.cc:39
+msgid "Selection"
+msgstr "Markering"
+
+
+#: gtk2_ardour/editor_actions.cc:463
+msgid "Set Tempo from Region=Bar"
+msgstr "Sätt tempo frÃ¥n region=takt"
+
+#: gtk2_ardour/editor_actions.cc:466
+msgid "Set Tempo from Edit Range=Bar"
+msgstr "Sätt tempo frÃ¥n redigeringsomfÃ¥ng=takt"
+
+
+#: gtk2_ardour/ardour_ui_ed.cc:548
+msgid "JACK does monitoring"
+msgstr "JACK sköter medhörning"
+
+#: gtk2_ardour/ardour_ui_ed.cc:552
+msgid "Ardour does monitoring"
+msgstr "Ardour sköter medhörning"
+
+#: gtk2_ardour/ardour_ui_ed.cc:553
+msgid "Audio Hardware does monitoring"
+msgstr "LjudhÃ¥rdvaran sköter medhörning"
+
+#: gtk2_ardour/ardour_ui_ed.cc:438
+msgid "Tape Machine mode"
+msgstr "Bandmaskinläge"
+
+#: gtk2_ardour/editor_actions.cc:64
+msgid "Misc Options"
+msgstr "Diverse inställningar"
+
+#: gtk2_ardour/ardour_ui_ed.cc:446
+msgid "Create marker at xrun location"
+msgstr "Skapa markör vid xrun-förekomst"
+
+#: gtk2_ardour/ardour_ui_ed.cc:455
+msgid "Rubberbanding Snaps to Grid"
+msgstr "Gummibandning fäster mot rutnätet"
+
+#: gtk2_ardour/ardour_ui_ed.cc:456
+msgid "Auto-analyse new audio"
+msgstr "Autoanalysera nya ljud"
+
+#: gtk2_ardour/editor_actions.cc:689
+msgid "Import to Region List"
+msgstr "Importera till regionslistan"
+
+#: gtk2_ardour/mixer_strip.cc:984
+msgid "Protect against denormals"
+msgstr "Skydda mot denormals"
+
+#: gtk2_ardour/option_editor.cc:1242
+msgid "Keyboard layout"
+msgstr "Tangentbordslayout"
+
+#: gtk2_ardour/option_editor.cc:275
+msgid "Font Scaling"
+msgstr "Typsnittsskalning"
+
+#: gtk2_ardour/option_editor.cc:97
+msgid "Add new MIDI port"
+msgstr "Lägg till ny MIDI-port"
+
+
+#: gtk2_ardour/editor.cc:1779 gtk2_ardour/editor.cc:1948
+msgid "Spectral Analysis"
+msgstr "Spektralanalys"
+
+#: gtk2_ardour/editor.cc:1793
+msgid "Glue to Bars&Beats"
+msgstr "Klistra mot takt&slag"
+
+#: gtk2_ardour/analysis_window.cc:46
+msgid "Signal source"
+msgstr "Signalkälla"
+
+#: gtk2_ardour/analysis_window.cc:47
+msgid "Selected ranges"
+msgstr "Valda omfÃ¥ng"
+
+#: gtk2_ardour/analysis_window.cc:48
+msgid "Selected regions"
+msgstr "Valda regioner"
+
+#: gtk2_ardour/analysis_window.cc:50
+msgid "Display model"
+msgstr "Visningsmodell"
+
+#: gtk2_ardour/analysis_window.cc:51
+msgid "Composite graphs for each track"
+msgstr "Sammansatt graf för varje spÃ¥r"
+
+#: gtk2_ardour/analysis_window.cc:52
+msgid "Composite graph of all tracks"
+msgstr "Sammansatt graf för alla spÃ¥r"
+
+#: gtk2_ardour/analysis_window.cc:54
+msgid "Show frequency power range"
+msgstr "Visa frekvenskraftsomfÃ¥ng"
+
+#: gtk2_ardour/analysis_window.cc:55
+msgid "Normalize values"
+msgstr "Normalisera värden"
+
+#: gtk2_ardour/analysis_window.cc:59 gtk2_ardour/analysis_window.cc:60
+msgid "FFT analysis window"
+msgstr "FFT-analysfönster"
+
+#: gtk2_ardour/analysis_window.cc:135
+msgid "Re-analyze data"
+msgstr "Ã…teranalysera data"
+
+#: gtk2_ardour/ardour_ui_ed.cc:195
+msgid "Window"
+msgstr "Fönster"
+
+#: gtk2_ardour/ardour_ui_dependents.cc:74
+msgid "Setup Editor"
+msgstr "Förbereder redigeraren..."
+
+#: gtk2_ardour/ardour_ui_dependents.cc:76
+msgid "Setup Mixer"
+msgstr "Förbereder mixern..."
+
+#: gtk2_ardour/ardour_ui_dependents.cc:81
+msgid "Reload Session History"
+msgstr "Laddar sessionshistoriken..."
+
+#: gtk2_ardour/editor.cc:4571
+msgid "Please wait while Ardour loads visual data"
+msgstr "Vänta medan Ardour laddar visuell data..."
+
+#: gtk2_ardour/editor_actions.cc:368
+msgid "Toggle Opaque"
+msgstr "Växla genomskinligt"
+
+#: gtk2_ardour/editor_actions.cc:570
+msgid "Fit Selected Tracks"
+msgstr "Rym valda spÃ¥r"
+
+#: gtk2_ardour/editor_actions.cc:299
+msgid "Zoom to Region (W&H)"
+msgstr "Zooma till region (bredd & höjd)"
+
+#: gtk2_ardour/editor_actions.cc:76
+msgid "Views"
+msgstr "Visningslägen"
+
+
+#: gtk2_ardour/editor_actions.cc:196
+msgid "Save View 1"
+msgstr "Spara läge 1"
+
+#: gtk2_ardour/editor_actions.cc:198
+msgid "Goto View 1"
+msgstr "Använd läge 1"
+
+#: gtk2_ardour/editor_actions.cc:200
+msgid "Save View 2"
+msgstr "Spara läge 2"
+
+#: gtk2_ardour/editor_actions.cc:202
+msgid "Goto View 2"
+msgstr "Använd läge 2 "
+
+#: gtk2_ardour/editor_actions.cc:204
+msgid "Save View 3"
+msgstr "Spara läge 3"
+
+#: gtk2_ardour/editor_actions.cc:206
+msgid "Goto View 3"
+msgstr "Använd läge 3"
+
+#: gtk2_ardour/editor_actions.cc:208
+msgid "Save View 4"
+msgstr "Spara läge 4"
+
+#: gtk2_ardour/editor_actions.cc:210
+msgid "Goto View 4"
+msgstr "Använd läge 4"
+
+#: gtk2_ardour/editor_actions.cc:212
+msgid "Save View 5"
+msgstr "Spara läge 5"
+
+#: gtk2_ardour/editor_actions.cc:214
+msgid "Goto View 5"
+msgstr "Använd läge 5"
+
+#: gtk2_ardour/editor_actions.cc:216
+msgid "Save View 6"
+msgstr "Spara läge 6"
+
+#: gtk2_ardour/editor_actions.cc:218
+msgid "Goto View 6"
+msgstr "Använd läge 6"
+
+#: gtk2_ardour/editor_actions.cc:220
+msgid "Save View 7"
+msgstr "Spara läge 7"
+
+#: gtk2_ardour/editor_actions.cc:222
+msgid "Goto View 7"
+msgstr "Använd läge 7"
+
+#: gtk2_ardour/editor_actions.cc:224
+msgid "Save View 8"
+msgstr "Spara läge 8"
+
+#: gtk2_ardour/editor_actions.cc:226
+msgid "Goto View 8"
+msgstr "Använd läge 8"
+
+#: gtk2_ardour/editor_actions.cc:228
+msgid "Save View 9"
+msgstr "Spara läge 9"
+
+#: gtk2_ardour/editor_actions.cc:230
+msgid "Goto View 9"
+msgstr "Använd läge 9"
+
+#: gtk2_ardour/editor_actions.cc:232
+msgid "Save View 10"
+msgstr "Spara läge 10"
+
+#: gtk2_ardour/editor_actions.cc:234
+msgid "Goto View 10"
+msgstr "Använd läge 10"
+
+#: gtk2_ardour/editor_actions.cc:236
+msgid "Save View 11"
+msgstr "Spara läge 11"
+
+#: gtk2_ardour/editor_actions.cc:238
+msgid "Goto View 11"
+msgstr "Använd läge 11"
+
+#: gtk2_ardour/editor_actions.cc:240
+msgid "Save View 12"
+msgstr "Spara läge 12"
+
+#: gtk2_ardour/editor_actions.cc:242
+msgid "Goto View 12"
+msgstr "Använd läge 12"
+
+#: gtk2_ardour/ardour_ui_ed.cc:462
+msgid "Name New Markers"
+msgstr "Namnge nya markörer"
+
+#: gtk2_ardour/editor_ops.cc:1900
+msgid "Name New Location Marker"
+msgstr "Namnge ny platsmarkör"
+
+#: gtk2_ardour/sfdb_ui.cc:513
+msgid "Search Freesound"
+msgstr "Sök i Freesound"
+
+#: gtk2_ardour/sfdb_ui.cc:480
+msgid "User:"
+msgstr "Användarnamn:"
+
+#: gtk2_ardour/sfdb_ui.cc:484
+msgid "Password:"
+msgstr "Lösenord:"
+
+#: gtk2_ardour/sfdb_ui.cc:400 gtk2_ardour/sfdb_ui.cc:789
+msgid "Start Downloading"
+msgstr "Ladda ner"
+
+#: gtk2_ardour/redirect_box.cc:1190
+msgid "New Plugin"
+msgstr "Nytt insticksprogram"
+
+#: gtk2_ardour/plugin_selector.cc:100
+msgid "Plugins to be connected"
+msgstr "Insticksprogram att ansluta"
+
+#: gtk2_ardour/plugin_selector.cc:156
+msgid "Insert Plugin(s)"
+msgstr "Infoga"
+
+#: gtk2_ardour/plugin_selector.cc:501
+msgid "Favorites"
+msgstr "Favoriter"
+
+#: gtk2_ardour/plugin_selector.cc:502
+msgid "Plugin Manager"
+msgstr "Insticksprogram"
+
+#: gtk2_ardour/plugin_selector.cc:77
+msgid "Fav"
+msgstr ""
+
+#: gtk2_ardour/plugin_selector.cc:78
+msgid "Available Plugins"
+msgstr "Tillgängliga insticksprogram"
+
+#: gtk2_ardour/plugin_selector.cc:80
+msgid "Category"
+msgstr "Kategori"
+
+#: gtk2_ardour/plugin_selector.cc:81
+msgid "Creator"
+msgstr "Upphovsperson"
+
+#: gtk2_ardour/plugin_selector.cc:51 gtk2_ardour/plugin_selector.cc:209
+msgid "Name contains"
+msgstr "Namn innehÃ¥ller"
+
+#: gtk2_ardour/plugin_selector.cc:52 gtk2_ardour/plugin_selector.cc:211
+msgid "Type contains"
+msgstr "Typ innehÃ¥ller"
+
+#: gtk2_ardour/plugin_selector.cc:53 gtk2_ardour/plugin_selector.cc:213
+msgid "Author contains"
+msgstr "Upphovsperson innehÃ¥ller"
+
+#: gtk2_ardour/plugin_selector.cc:54 gtk2_ardour/plugin_selector.cc:215
+msgid "Library contains"
+msgstr "Bibliotek innehÃ¥ller"
+
+#: gtk2_ardour/plugin_selector.cc:55 gtk2_ardour/plugin_selector.cc:203
+#: gtk2_ardour/plugin_selector.cc:451
+msgid "Favorites only"
+msgstr "Endast favoriter"
+>>>>>>> .merge-right.r3622
index 9ce28d0aa608d60a35ccbaa005459cda4f3954bf..370bb7548be683e6145293bc23cc84c54d4adf8a 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <cmath>
 #include <iostream>
+#include <set>
 
 #include <sigc++/bind.h>
 
@@ -46,6 +47,7 @@
 #include <ardour/plugin_insert.h>
 #include <ardour/port_insert.h>
 #include <ardour/ladspa_plugin.h>
+#include <ardour/profile.h>
 
 #include "ardour_ui.h"
 #include "ardour_dialog.h"
 #include "mixer_ui.h"
 #include "actions.h"
 #include "plugin_ui.h"
-#include "send_ui.h"
 #include "io_selector.h"
 #include "utils.h"
 #include "gui_thread.h"
 
 #include "i18n.h"
 
-#ifdef HAVE_AUDIOUNIT
-#include "au_pluginui.h"
+#ifdef HAVE_AUDIOUNITS
+class AUPluginUI;
 #endif
 
 using namespace sigc;
@@ -93,8 +94,8 @@ ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, boost::shared_ptr<Ro
        if (get_colors) {
                active_processor_color = new Gdk::Color;
                inactive_processor_color = new Gdk::Color;
-               set_color (*active_processor_color, rgba_from_style ("RedirectSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_ACTIVE, false ));
-               set_color (*inactive_processor_color, rgba_from_style ("RedirectSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
+               set_color (*active_processor_color, rgba_from_style ("ProcessorSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_ACTIVE, false ));
+               set_color (*inactive_processor_color, rgba_from_style ("ProcessorSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
                get_colors = false;
        }
 
@@ -113,14 +114,13 @@ ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, boost::shared_ptr<Ro
 
        processor_display.set_model (model);
        processor_display.append_column (X_("notshown"), columns.text);
-       processor_display.set_name ("RedirectSelector");
+       processor_display.set_name ("ProcessorSelector");
        processor_display.set_headers_visible (false);
        processor_display.set_reorderable (true);
        processor_display.set_size_request (-1, 40);
        processor_display.get_column(0)->set_sizing(TREE_VIEW_COLUMN_FIXED);
        processor_display.get_column(0)->set_fixed_width(48);
-       processor_display.set_enable_search (false);
-       processor_display.add_object_drag (columns.processor.index(), "redirects");
+       processor_display.add_object_drag (columns.processor.index(), "processors");
        processor_display.signal_object_drop.connect (mem_fun (*this, &ProcessorBox::object_drop));
 
        TreeViewColumn* name_col = processor_display.get_column(0);
@@ -153,10 +153,6 @@ ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, boost::shared_ptr<Ro
        /* now force an update of all the various elements */
 
        redisplay_processors ();
-       processor_eventbox.show();
-       processor_scroller.show();
-       processor_display.show();
-       show();
 }
 
 ProcessorBox::~ProcessorBox ()
@@ -173,7 +169,7 @@ ProcessorBox::route_going_away ()
 void
 ProcessorBox::object_drop (string type, uint32_t cnt, const boost::shared_ptr<Processor>* ptr)
 {
-       if (type != "redirects" || cnt == 0 || !ptr) {
+       if (type != "processors" || cnt == 0 || !ptr) {
                return;
        }
 
@@ -210,12 +206,14 @@ void
 ProcessorBox::remove_processor_gui (boost::shared_ptr<Processor> processor)
 {
        boost::shared_ptr<Send> send;
-       boost::shared_ptr<PortInsert> port_processor;
+       boost::shared_ptr<PortInsert> port_insert;
+
+       if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
+
+               PortInsertUI *io_selector = reinterpret_cast<PortInsertUI *> (port_insert->get_gui());
+               port_insert->set_gui (0);
+               delete io_selector;
 
-       if ((port_processor = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
-                       PortInsertUI *io_selector = reinterpret_cast<PortInsertUI *> (port_processor->get_gui());
-                       port_processor->set_gui (0);
-                       delete io_selector;
        } else if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
                SendUIWindow *sui = reinterpret_cast<SendUIWindow*> (send->get_gui());
                send->set_gui (0);
@@ -256,6 +254,12 @@ ProcessorBox::show_processor_menu (gint arg)
                processor_menu = build_processor_menu ();
        }
 
+       Gtk::MenuItem* plugin_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/processormenu/newplugin"));
+
+       if (plugin_menu_item) {
+               plugin_menu_item->set_submenu (_plugin_selector.plugin_menu());
+       }
+
        paste_action->set_sensitive (!_rr_selection.processors.empty());
 
        processor_menu->popup (1, arg);
@@ -304,7 +308,7 @@ ProcessorBox::processor_button_press_event (GdkEventButton *ev)
        } else if (processor && ev->button == 1 && selected) {
 
                // this is purely informational but necessary
-               InsertSelected (processor); // emit
+               ProcessorSelected (processor); // emit
        }
        
        return ret;
@@ -340,6 +344,8 @@ ProcessorBox::processor_button_release_event (GdkEventButton *ev)
 
        } else if (processor && (ev->button == 2) && (Keyboard::no_modifier_keys_pressed (ev) && ((ev->state & Gdk::BUTTON2_MASK) == Gdk::BUTTON2_MASK))) {
                
+               /* button2-click with no modifiers */
+
                processor->set_active (!processor->active());
                ret = true;
 
@@ -352,7 +358,6 @@ Menu *
 ProcessorBox::build_processor_menu ()
 {
        processor_menu = dynamic_cast<Gtk::Menu*>(ActionManager::get_widget("/processormenu") );
-       assert(processor_menu != 0);
        processor_menu->set_name ("ArdourContextMenu");
 
        show_all_children();
@@ -382,26 +387,26 @@ ProcessorBox::deselect_all_processors ()
 void
 ProcessorBox::choose_plugin ()
 {
-       sigc::connection newplug_connection = _plugin_selector.PluginCreated.connect (mem_fun(*this,&ProcessorBox::processor_plugin_chosen));
-       _plugin_selector.show_all();
-       _plugin_selector.run ();
-       newplug_connection.disconnect();
+       _plugin_selector.set_interested_object (*this);
 }
 
 void
-ProcessorBox::processor_plugin_chosen (boost::shared_ptr<Plugin> plugin)
+ProcessorBox::use_plugins (const SelectedPlugins& plugins)
 {
-       if (plugin) {
+       for (SelectedPlugins::const_iterator p = plugins.begin(); p != plugins.end(); ++p) {
 
-               boost::shared_ptr<Processor> processor (new PluginInsert (_session, plugin, _placement));
-               
-               Route::ProcessorStreams err;
+               boost::shared_ptr<Processor> processor (new PluginInsert (_session, *p, _placement));
 
-               if (_route->add_processor (processor, &err)) {
-                       weird_plugin_dialog (*plugin, err, _route);
+               Route::ProcessorStreams err_streams;
+               
+               if (_route->add_processor (processor, &err_streams)) {
+                       weird_plugin_dialog (**p, err_streams, _route);
                        // XXX SHAREDPTR delete plugin here .. do we even need to care? 
                } else {
-                       processor->set_active(true);
+                       
+                       if (Profile->get_sae()) {
+                               processor->set_active (true);
+                       }
                        processor->ActiveChanged.connect (bind (mem_fun (*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor)));
                }
        }
@@ -471,7 +476,7 @@ ProcessorBox::weird_plugin_dialog (Plugin& p, Route::ProcessorStreams streams, b
 }
 
 void
-ProcessorBox::choose_processor ()
+ProcessorBox::choose_insert ()
 {
        boost::shared_ptr<Processor> processor (new PortInsert (_session, _placement));
        processor->ActiveChanged.connect (bind (mem_fun(*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor)));
@@ -494,35 +499,54 @@ ProcessorBox::choose_send ()
                outs = _route->n_outputs();
        }
 
-       send->io()->ensure_io (ChanCount::ZERO, outs, false, this);
+       /* XXX need processor lock on route */
 
-       SendUIWindow* gui = new SendUIWindow (send, _session);
+       try {
+               send->io()->ensure_io (ChanCount::ZERO, outs, false, this);
+       } catch (AudioEngine::PortRegistrationFailure& err) {
+               error << string_compose (_("Cannot set up new send: %1"), err.what()) << endmsg;
+               return;
+       }
        
        /* let the user adjust the output setup (number and connections) before passing
           it along to the Route
        */
        
-       gui->show_all ();
-       gui->present ();
+       IOSelectorWindow *ios = new IOSelectorWindow (_session, send->io(), false, true);
 
-       /* pass shared_ptr, it will go out of scope when the GUI is deleted */
-       /* also, connect it *before* existing handlers so that its definitely executed */
+       ios->show_all ();
 
-       gui->signal_delete_event().connect (bind (mem_fun(*this, &ProcessorBox::send_io_finished), send, gui), false);
+       boost::shared_ptr<Processor> r = boost::static_pointer_cast<Processor>(send);
+       
+       ios->selector().Finished.connect (bind (mem_fun(*this, &ProcessorBox::send_io_finished), boost::weak_ptr<Processor>(r), ios));
 }
 
-bool
-ProcessorBox::send_io_finished (GdkEventAny* ev, boost::shared_ptr<Send> send, SendUIWindow* sui)
+void
+ProcessorBox::send_io_finished (IOSelector::Result r, boost::weak_ptr<Processor> weak_processor, IOSelectorWindow* ios)
 {
-       _route->add_processor (send);
-       delete sui;
-       return false;
+       boost::shared_ptr<Processor> processor (weak_processor.lock());
+
+       if (!processor) {
+               return;
+       }
+
+       switch (r) {
+       case IOSelector::Cancelled:
+               // processor will go away when all shared_ptrs to it vanish
+               break;
+
+       case IOSelector::Accepted:
+               _route->add_processor (processor);
+               break;
+       }
+
+       delete_when_idle (ios);
 }
 
 void
 ProcessorBox::redisplay_processors ()
 {
-       ENSURE_GUI_THREAD(mem_fun(*this, &ProcessorBox::redisplay_processors));
+       ENSURE_GUI_THREAD (mem_fun(*this, &ProcessorBox::redisplay_processors));
 
        if (no_processor_redisplay) {
                return;
@@ -535,15 +559,15 @@ ProcessorBox::redisplay_processors ()
        processor_active_connections.clear ();
        processor_name_connections.clear ();
 
-       void (ProcessorBox::*pmf)(boost::shared_ptr<Processor>) = &ProcessorBox::add_processor_to_display;
-       _route->foreach_processor (this, pmf);
+       void (ProcessorBox::*method)(boost::shared_ptr<Processor>) = &ProcessorBox::add_processor_to_display;
+       _route->foreach_processor (this, method);
 
        switch (_placement) {
        case PreFader:
-               build_processor_tooltip(processor_eventbox, _("Pre-fader processors, sends & plugins:"));
+               build_processor_tooltip(processor_eventbox, _("Pre-fader inserts, sends & plugins:"));
                break;
        case PostFader:
-               build_processor_tooltip(processor_eventbox, _("Post-fader processors, sends & plugins:"));
+               build_processor_tooltip(processor_eventbox, _("Post-fader inserts, sends & plugins:"));
                break;
        }
 }
@@ -629,11 +653,7 @@ ProcessorBox::build_processor_tooltip (EventBox& box, string start)
        for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
                Gtk::TreeModel::Row row = *iter;
                tip += '\n';
-
-               /* don't use the column text, since it may be narrowed */
-
-               boost::shared_ptr<Processor> i = row[columns.processor];
-               tip += i->name();
+               tip += row[columns.text];
        }
        ARDOUR_UI::instance()->tooltips().set_tip (box, tip);
 }
@@ -648,14 +668,14 @@ ProcessorBox::show_processor_name (boost::weak_ptr<Processor> processor)
 void
 ProcessorBox::show_processor_active (boost::weak_ptr<Processor> weak_processor)
 {
-       ENSURE_GUI_THREAD(bind (mem_fun(*this, &ProcessorBox::show_processor_active), weak_processor));
-       
        boost::shared_ptr<Processor> processor (weak_processor.lock());
        
        if (!processor) {
                return;
        }
 
+       ENSURE_GUI_THREAD(bind (mem_fun(*this, &ProcessorBox::show_processor_active), weak_processor));
+       
        Gtk::TreeModel::Children children = model->children();
        Gtk::TreeModel::Children::iterator iter = children.begin();
 
@@ -693,8 +713,8 @@ ProcessorBox::compute_processor_sort_keys ()
        Gtk::TreeModel::Children children = model->children();
 
        for (Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
-               boost::shared_ptr<Processor> i = (*iter)[columns.processor];
-               i->set_sort_key (sort_key);
+               boost::shared_ptr<Processor> r = (*iter)[columns.processor];
+               r->set_sort_key (sort_key);
                sort_key++;
        }
 
@@ -966,13 +986,13 @@ ProcessorBox::get_selected_processors (vector<boost::shared_ptr<Processor> >& pr
 }
 
 void
-ProcessorBox::for_selected_processors (void (ProcessorBox::*pmf)(boost::shared_ptr<Processor>))
+ProcessorBox::for_selected_processors (void (ProcessorBox::*method)(boost::shared_ptr<Processor>))
 {
     vector<Gtk::TreeModel::Path> pathlist = processor_display.get_selection()->get_selected_rows();
 
        for (vector<Gtk::TreeModel::Path>::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) {
                boost::shared_ptr<Processor> processor = (*(model->get_iter(*iter)))[columns.processor];
-               (this->*pmf)(processor);
+               (this->*method)(processor);
        }
 }
 
@@ -999,16 +1019,6 @@ ProcessorBox::all_processors_active (bool state)
        _route->all_processors_active (_placement, state);
 }
 
-void
-ProcessorBox::all_plugins_active (bool state)
-{
-       if (state) {
-               // XXX not implemented
-       } else {
-               _route->disable_plugins (_placement);
-       }
-}
-
 void
 ProcessorBox::ab_plugins ()
 {
@@ -1016,6 +1026,7 @@ ProcessorBox::ab_plugins ()
        ab_direction = !ab_direction;
 }
 
+
 void
 ProcessorBox::clear_processors ()
 {
@@ -1054,8 +1065,9 @@ void
 ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
 {
        boost::shared_ptr<Send> send;
-       boost::shared_ptr<PluginInsert> plugin_processor;
-       boost::shared_ptr<PortInsert> port_processor;
+       boost::shared_ptr<PluginInsert> plugin_insert;
+       boost::shared_ptr<PortInsert> port_insert;
+       Window* gidget = 0;
 
        if (boost::dynamic_pointer_cast<AudioTrack>(_route) != 0) {
 
@@ -1070,6 +1082,8 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
                        return;
                }
 
+               boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
+               
                SendUIWindow *send_ui;
                
                if (send->get_gui() == 0) {
@@ -1086,100 +1100,64 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
                        send_ui = reinterpret_cast<SendUIWindow *> (send->get_gui());
                }
                
-               if (send_ui->is_visible()) {
-                       send_ui->get_window()->raise ();
-               } else {
-                       send_ui->show_all ();
-                       send_ui->present ();
-               }
+               gidget = send_ui;
+               
+       } else if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (processor)) != 0) {
+               
+               PluginUIWindow *plugin_ui;
                
-       } else if ((plugin_processor = boost::dynamic_pointer_cast<PluginInsert> (processor)) != 0) {
+               /* these are both allowed to be null */
+               
+               Container* toplevel = get_toplevel();
+               Window* win = dynamic_cast<Gtk::Window*>(toplevel);
+               
+               if (plugin_insert->get_gui() == 0) {
                        
-                       ARDOUR::PluginType type = plugin_processor->type();
-
-                       if (type == ARDOUR::LADSPA || type == ARDOUR::VST) {
-
-                               PluginUIWindow *plugin_ui;
+                       plugin_ui = new PluginUIWindow (win, plugin_insert);
                        
-                               /* these are both allowed to be null */
-                               
-                               Container* toplevel = get_toplevel();
-                               Window* win = dynamic_cast<Gtk::Window*>(toplevel);
-                               
-                               if (plugin_processor->get_gui() == 0) {
-                                                               
-                                       plugin_ui = new PluginUIWindow (win, plugin_processor);
-
-                                       WindowTitle title(Glib::get_application_name());
-                                       title += generate_processor_title (plugin_processor);
-                                       plugin_ui->set_title (title.get_string());
-
-                                       plugin_processor->set_gui (plugin_ui);
-                                       
-                                       // change window title when route name is changed
-                                       _route->NameChanged.connect (bind (mem_fun(*this, &ProcessorBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_processor)));
-                               
-                               } else {
-                                       plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_processor->get_gui());
-                               }
+                       WindowTitle title(Glib::get_application_name());
+                       title += generate_processor_title (plugin_insert);
+                       plugin_ui->set_title (title.get_string());
                        
-                               if (plugin_ui->is_visible()) {
-                                       plugin_ui->get_window()->raise ();
-                               } else {
-                                       plugin_ui->show_all ();
-                                       plugin_ui->present ();
-                               }
-#ifdef HAVE_AUDIOUNIT
-                       } else if (type == ARDOUR::AudioUnit) {
-                               AUPluginUI* plugin_ui;
-                               if (plugin_processor->get_gui() == 0) {
-                                       plugin_ui = new AUPluginUI (plugin_processor);
-                               } else {
-                                       plugin_ui = reinterpret_cast<AUPluginUI*> (plugin_processor->get_gui());
-                               }
-                               
-                               plugin_ui = new PluginUIWindow (plugin_insert);
-                               
-                               // plugin_ui->set_keep_above (true);
-
-                               WindowTitle title(Glib::get_application_name());
-                               title += generate_redirect_title (plugin_insert);
-                               plugin_ui->set_title (title.get_string());
-                               
-                               plugin_insert->set_gui (plugin_ui);
-                               
-                               // change window title when route name is changed
-                               _route->name_changed.connect (bind (mem_fun(*this, &RedirectBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_insert)));
-#endif
-                               
-                       } else {
-                               warning << "Unsupported plugin sent to ProcessorBox::edit_processor()" << endmsg;
-                               return;
-                       }
-
-       } else if ((port_processor = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
-
+                       plugin_insert->set_gui (plugin_ui);
+                       
+                       // change window title when route name is changed
+                       _route->NameChanged.connect (bind (mem_fun(*this, &ProcessorBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_insert)));
+                       
+               } else {
+                       plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_insert->get_gui());
+                       plugin_ui->set_parent (win);
+               }
+               
+               gidget = plugin_ui;
+               
+       } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
+               
                if (!_session.engine().connected()) {
                        MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible"));
                        msg.run ();
                        return;
                }
-
+               
                PortInsertWindow *io_selector;
-
-               if (port_processor->get_gui() == 0) {
-                       io_selector = new PortInsertWindow (_session, port_processor);
-                       port_processor->set_gui (io_selector);
-
+               
+               if (port_insert->get_gui() == 0) {
+                       io_selector = new PortInsertWindow (_session, port_insert);
+                       port_insert->set_gui (io_selector);
+                       
                } else {
-                       io_selector = reinterpret_cast<PortInsertWindow *> (port_processor->get_gui());
+                       io_selector = reinterpret_cast<PortInsertWindow *> (port_insert->get_gui());
                }
+               
+               gidget = io_selector;
+       }
 
-               if (io_selector->is_visible()) {
-                       io_selector->get_window()->raise ();
+       if (gidget) {
+               if (gidget->is_visible()) {
+                       gidget->get_window()->raise ();
                } else {
-                       io_selector->show_all ();
-                       io_selector->present ();
+                       gidget->show_all ();
+                       gidget->present ();
                }
        }
 }
@@ -1208,9 +1186,9 @@ ProcessorBox::register_actions ()
        Glib::RefPtr<Action> act;
 
        /* new stuff */
-       ActionManager::register_action (popup_act_grp, X_("newplugin"), _("New Plugin ..."),  sigc::ptr_fun (ProcessorBox::rb_choose_plugin));
+       ActionManager::register_action (popup_act_grp, X_("newplugin"), _("New Plugin"),  sigc::ptr_fun (ProcessorBox::rb_choose_plugin));
 
-       act = ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"),  sigc::ptr_fun (ProcessorBox::rb_choose_processor));
+       act = ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"),  sigc::ptr_fun (ProcessorBox::rb_choose_insert));
        ActionManager::jack_sensitive_actions.push_back (act);
        act = ActionManager::register_action (popup_act_grp, X_("newsend"), _("New Send ..."),  sigc::ptr_fun (ProcessorBox::rb_choose_send));
        ActionManager::jack_sensitive_actions.push_back (act);
@@ -1240,9 +1218,6 @@ ProcessorBox::register_actions ()
        ActionManager::register_action (popup_act_grp, X_("activate_all"), _("Activate all"),  sigc::ptr_fun (ProcessorBox::rb_activate_all));
        ActionManager::register_action (popup_act_grp, X_("deactivate_all"), _("Deactivate all"),  sigc::ptr_fun (ProcessorBox::rb_deactivate_all));
 
-       ActionManager::register_action (popup_act_grp, X_("a_b_plugins"), _("A/B plugins"),  sigc::ptr_fun (ProcessorBox::rb_ab_plugins));
-       ActionManager::register_action (popup_act_grp, X_("deactivate_plugins"), _("Deactivate plugins"),  sigc::ptr_fun (ProcessorBox::rb_deactivate_plugins));
-
        /* show editors */
        act = ActionManager::register_action (popup_act_grp, X_("edit"), _("Edit"),  sigc::ptr_fun (ProcessorBox::rb_edit));
        ActionManager::plugin_selection_sensitive_actions.push_back(act);
@@ -1262,12 +1237,12 @@ ProcessorBox::rb_choose_plugin ()
 }
 
 void
-ProcessorBox::rb_choose_processor ()
+ProcessorBox::rb_choose_insert ()
 {
        if (_current_processor_box == 0) {
                return;
        }
-       _current_processor_box->choose_processor ();
+       _current_processor_box->choose_insert ();
 }
 
 void
@@ -1395,27 +1370,6 @@ ProcessorBox::rb_deactivate_all ()
        _current_processor_box->all_processors_active (false);
 }
 
-void
-ProcessorBox::rb_deactivate_plugins ()
-{
-       if (_current_processor_box == 0) {
-               return;
-       }
-       _current_processor_box->all_plugins_active (false);
-}
-
-
-void
-ProcessorBox::rb_ab_plugins ()
-{
-       if (_current_processor_box == 0) {
-               return;
-       }
-
-       _current_processor_box->ab_plugins ();
-}
-
-
 void
 ProcessorBox::rb_edit ()
 {
@@ -1430,8 +1384,8 @@ void
 ProcessorBox::route_name_changed (PluginUIWindow* plugin_ui, boost::weak_ptr<PluginInsert> wpi)
 {
        ENSURE_GUI_THREAD(bind (mem_fun (*this, &ProcessorBox::route_name_changed), plugin_ui, wpi));
+
        boost::shared_ptr<PluginInsert> pi (wpi.lock());
-       
 
        if (pi) {
                WindowTitle title(Glib::get_application_name());
index b6bb3ae3d781bd856b72b0005fd9bf23be1a494a..5d3eb731cafdbd4183cade3939adcd478512a065 100644 (file)
 #include <ardour/types.h>
 #include <ardour/ardour.h>
 #include <ardour/io.h>
+#include <ardour/plugin_insert.h>
+#include <ardour/port_insert.h>
 #include <ardour/processor.h>
-#include <ardour/io_processor.h>
 
 #include <pbd/fastlog.h>
 
+#include "plugin_interest.h"
 #include "route_ui.h"
 #include "io_selector.h"
+#include "send_ui.h"
 #include "enums.h"
 
 class MotionController;
 class PluginSelector;
 class PluginUIWindow;
 class RouteRedirectSelection;
-class SendUIWindow;
 
 namespace ARDOUR {
-       class Bundle;
-       class Processor;
+       class Connection;
+       class Insert;
        class Plugin;
        class PluginInsert;
        class PortInsert;
@@ -63,8 +65,7 @@ namespace ARDOUR {
        class Session;
 }
 
-
-class ProcessorBox : public Gtk::HBox
+class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
 {
   public:
        ProcessorBox (ARDOUR::Placement, ARDOUR::Session&, 
@@ -78,10 +79,11 @@ class ProcessorBox : public Gtk::HBox
        void select_all_processors ();
        void deselect_all_processors ();
        void select_all_plugins ();
+       void select_all_inserts ();
        void select_all_sends ();
        
-       sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > InsertSelected;
-       sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > InsertUnselected;
+       sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > ProcessorSelected;
+       sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > ProcessorUnselected;
        
        static void register_actions();
 
@@ -107,9 +109,9 @@ class ProcessorBox : public Gtk::HBox
                    add (processor);
                    add (color);
            }
-           Gtk::TreeModelColumn<std::string>                           text;
+           Gtk::TreeModelColumn<std::string>       text;
            Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Processor> > processor;
-           Gtk::TreeModelColumn<Gdk::Color>                            color;
+           Gtk::TreeModelColumn<Gdk::Color>        color;
        };
 
        ModelColumns columns;
@@ -122,7 +124,7 @@ class ProcessorBox : public Gtk::HBox
        static Gdk::Color* inactive_processor_color;
        
        Gtk::EventBox          processor_eventbox;
-       //Gtk::HBox              processor_hpacker;
+       Gtk::HBox              processor_hpacker;
        Gtkmm2ext::DnDTreeView<boost::shared_ptr<ARDOUR::Processor> > processor_display;
        Gtk::ScrolledWindow    processor_scroller;
 
@@ -143,10 +145,10 @@ class ProcessorBox : public Gtk::HBox
        void show_processor_menu (gint arg);
 
        void choose_send ();
-       bool send_io_finished (GdkEventAny*,boost::shared_ptr<ARDOUR::Send>, SendUIWindow*);
-       void choose_processor ();
+       void send_io_finished (IOSelector::Result, boost::weak_ptr<ARDOUR::Processor>, IOSelectorWindow*);
+       void choose_insert ();
        void choose_plugin ();
-       void processor_plugin_chosen (boost::shared_ptr<ARDOUR::Plugin>);
+       void use_plugins (const SelectedPlugins&);
 
        bool no_processor_redisplay;
        bool ignore_delete;
@@ -164,8 +166,8 @@ class ProcessorBox : public Gtk::HBox
 
        void processors_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*);
        void compute_processor_sort_keys ();
-       vector<sigc::connection> processor_active_connections;
-       vector<sigc::connection> processor_name_connections;
+       std::vector<sigc::connection> processor_active_connections;
+       std::vector<sigc::connection> processor_name_connections;
        
        bool processor_drag_in_progress;
        void processor_drag_begin (GdkDragContext*);
@@ -204,7 +206,7 @@ class ProcessorBox : public Gtk::HBox
        static bool leave_box (GdkEventCrossing*, ProcessorBox*);
 
        static void rb_choose_plugin ();
-       static void rb_choose_processor ();
+       static void rb_choose_insert ();
        static void rb_choose_send ();
        static void rb_clear ();
        static void rb_cut ();
@@ -218,9 +220,8 @@ class ProcessorBox : public Gtk::HBox
        static void rb_deactivate ();
        static void rb_activate_all ();
        static void rb_deactivate_all ();
-       static void rb_edit ();
        static void rb_ab_plugins ();
-       static void rb_deactivate_plugins ();
+       static void rb_edit ();
        
        void route_name_changed (PluginUIWindow* plugin_ui, boost::weak_ptr<ARDOUR::PluginInsert> pi);
        std::string generate_processor_title (boost::shared_ptr<ARDOUR::PluginInsert> pi);
index 6797119a1f2e0eafa416a8258baf7c8212566aac..399c71caa9e0b256044eacc1f34c0ffcee1b446d 100644 (file)
 
 PublicEditor* PublicEditor::_instance = 0;
 
-/** PublicEditor constructor */
+const int PublicEditor::window_border_width = 12;
+const int PublicEditor::container_border_width = 12;
+const int PublicEditor::vertical_spacing = 6;
+const int PublicEditor::horizontal_spacing = 6;
+
 PublicEditor::PublicEditor ()
        : Window (Gtk::WINDOW_TOPLEVEL)
 {
 }
 
-/** PublicEditor destructor */
 PublicEditor::~PublicEditor()
 {
 }
index e6f576352a53fb040d20696b2b8984c3fd21d5f4..9994f422d4cab2543a564c178736f01347cbb860 100644 (file)
@@ -117,14 +117,15 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual void set_snap_threshold (double t) = 0;
        
        /** Snap a value according to the current snap setting. */
-       virtual void snap_to (nframes_t& first, int32_t direction = 0, bool for_mark = false) = 0;
+       virtual void snap_to (nframes64_t& first, int32_t direction = 0, bool for_mark = false) = 0;
        
        /** Get the current snap value in beats */
-       virtual double snap_length_beats (nframes_t start) = 0;
+       virtual double snap_length_beats (nframes64_t start) = 0;
 
        /** Undo some transactions.
         * @param n Number of transactions to undo.
         */
+
        virtual void undo (uint32_t n = 1) = 0;
 
        /** Redo some transactions.
@@ -188,8 +189,12 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
 
        virtual void toggle_playback (bool with_abort) = 0;
        virtual void transition_to_rolling (bool fwd) = 0;
-       virtual nframes_t unit_to_frame (double unit) const = 0;
-       virtual double frame_to_unit (nframes_t frame) const = 0;
+       virtual nframes64_t unit_to_frame (double unit) const = 0;
+       // XXX remove me when libardour goes nframes64_t
+       double frame_to_unit (nframes_t frame) const { 
+               return frame_to_unit ((nframes64_t) frame);
+       }
+       virtual double frame_to_unit (nframes64_t frame) const = 0;
        virtual double frame_to_unit (double frame) const = 0;
        virtual nframes64_t pixel_to_frame (double pixel) const = 0;
        virtual gulong frame_to_pixel (nframes64_t frame) const = 0;
@@ -225,7 +230,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual void select_all_tracks () = 0;
        virtual void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove = false) = 0;
        virtual void set_selected_mixer_strip (TimeAxisView&) = 0;
-       virtual void hide_track_in_display (TimeAxisView& tv) = 0;
+       virtual void hide_track_in_display (TimeAxisView& tv, bool temporary = false) = 0;
        virtual void show_track_in_display (TimeAxisView& tv) = 0;
 
        /** Set whether the editor should follow the playhead.
@@ -244,22 +249,24 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual void ensure_float (Gtk::Window&) = 0;
        virtual void show_window () = 0;
        virtual TrackViewList* get_valid_views (TimeAxisView*, ARDOUR::RouteGroup* grp = 0) = 0;
-       virtual nframes_t leftmost_position () const = 0;
-       virtual nframes_t current_page_frames () const = 0;
+       virtual nframes64_t leftmost_position() const = 0;
+       virtual nframes64_t current_page_frames() const = 0;
        virtual void temporal_zoom_step (bool coarser) = 0;
        virtual void scroll_tracks_down_line () = 0;
        virtual void scroll_tracks_up_line () = 0;
        virtual bool new_regionviews_display_gain () = 0;
        virtual void prepare_for_cleanup () = 0;
-       virtual void reset_x_origin (nframes_t frame) = 0;
+       virtual void finish_cleanup () = 0;
+       virtual void reset_x_origin (nframes64_t frame) = 0;
        virtual void remove_last_capture () = 0;
        virtual void maximise_editing_space () = 0;
        virtual void restore_editing_space () = 0;
        virtual nframes64_t get_preferred_edit_position (bool ignore_playhead = false) = 0;
        virtual void toggle_meter_updating() = 0;
        virtual void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret) = 0;
-       virtual void mouse_add_new_marker (nframes_t where, bool is_cd=false, bool is_xrun=false) = 0;
+       virtual void mouse_add_new_marker (nframes64_t where, bool is_cd=false, bool is_xrun=false) = 0;
        virtual void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>) = 0;
+       virtual void add_to_idle_resize (TimeAxisView*,uint32_t) = 0;
 
 #ifdef WITH_CMT
        virtual void add_imageframe_time_axis(const std::string & track_name, void*)  = 0;
@@ -277,7 +284,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        sigc::signal<void> ZoomChanged;
        sigc::signal<void> Resized;
        sigc::signal<void> Realized;
-       sigc::signal<void,nframes_t> UpdateAllTransportClocks;
+       sigc::signal<void,nframes64_t> UpdateAllTransportClocks;
 
        Glib::RefPtr<Gtk::ActionGroup> editor_actions;
 
@@ -320,6 +327,15 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual bool canvas_markerview_end_handle_event(GdkEvent* event, ArdourCanvas::Item*,MarkerView*) = 0;
 #endif
 
+       virtual void queue_draw_resize_line (int at) = 0;
+       virtual void start_resize_line_ops () = 0;
+       virtual void end_resize_line_ops () = 0;
+
+       static const int window_border_width;
+       static const int container_border_width;
+       static const int vertical_spacing;
+       static const int horizontal_spacing;
+
        /// Singleton instance, set up by Editor::Editor()
        static PublicEditor* _instance;
 
index fff7243f5346ec74efde9dd7e2be8da12521e302..27f9c878193e63f15aad1ca00cceb9b215d6eb34 100644 (file)
@@ -64,7 +64,8 @@ RegionView::RegionView (ArdourCanvas::Group*              parent,
                         boost::shared_ptr<ARDOUR::Region> r,
                         double                            spu,
                         Gdk::Color&                       basic_color)
-       : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(),
+       : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), false,
+
                            TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText|
                                                          TimeAxisViewItem::ShowNameHighlight|
                                                          TimeAxisViewItem::ShowFrame))
@@ -87,11 +88,10 @@ RegionView::RegionView (const RegionView& other)
        /* derived concrete type will call init () */
 
        _region = other._region;
-       editor = 0;
        current_visible_sync_position = other.current_visible_sync_position;
        valid = false;
-       _enable_display = false;
        _pixel_width = other._pixel_width;
+       _height = other._height;
 }
 
 RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other_region)
@@ -104,7 +104,6 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other
        /* derived concrete type will call init () */
 
        _region = other_region;
-       editor = other.editor;
        current_visible_sync_position = other.current_visible_sync_position;
        valid = false;
        _pixel_width = other._pixel_width;
@@ -116,8 +115,9 @@ RegionView::RegionView (ArdourCanvas::Group*         parent,
                         boost::shared_ptr<ARDOUR::Region> r,
                         double                       spu,
                         Gdk::Color&                  basic_color,
+                                               bool recording,
                         TimeAxisViewItem::Visibility visibility)
-       : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), visibility)
+       : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), recording, visibility)
        , _region (r)
        , sync_mark(0)
        , sync_line(0)
@@ -134,10 +134,11 @@ RegionView::RegionView (ArdourCanvas::Group*         parent,
 void
 RegionView::init (Gdk::Color& basic_color, bool wfd)
 {
-       valid           = true;
-       _enable_display = false;
-       in_destructor   = false;
-       wait_for_data   = wfd;
+       editor        = 0;
+       valid         = true;
+       in_destructor = false;
+       _height       = 0;
+       wait_for_data = wfd;
        sync_mark     = 0;
        sync_line     = 0;
        sync_mark     = 0;
@@ -145,7 +146,10 @@ RegionView::init (Gdk::Color& basic_color, bool wfd)
 
        compute_colors (basic_color);
 
-       name_highlight->set_data ("regionview", this);
+       if (name_highlight) {
+               name_highlight->set_data ("regionview", this);
+               name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this));
+       }
 
        if (name_text) {
                name_text->set_data ("regionview", this);
@@ -154,17 +158,16 @@ RegionView::init (Gdk::Color& basic_color, bool wfd)
        if (wfd)
                _enable_display = true;
 
-       set_y_position_and_height (0, trackview.height - 2);
+       set_height (trackview.current_height());
 
        _region->StateChanged.connect (mem_fun(*this, &RegionView::region_changed));
 
        group->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this));
-       name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this));
 
        set_colors ();
 
        ColorsChanged.connect (mem_fun (*this, &RegionView::color_handler));
-       // set_pango_fontsize();
+
        /* XXX sync mark drag? */
 }
 
@@ -517,7 +520,7 @@ RegionView::region_sync_changed ()
 
                        points.clear ();
                        points.push_back (Gnome::Art::Point (offset, 0));
-                       points.push_back (Gnome::Art::Point (offset, trackview.height - NAME_HIGHLIGHT_SIZE));
+                       points.push_back (Gnome::Art::Point (offset, trackview.current_height() - NAME_HIGHLIGHT_SIZE));
 
                        sync_line->property_points().set_value (points);
                        sync_line->show ();
index 19d13ccf0360727a73377ad33b1a2676bbd94271..579b6e55940678bb5a1409981dfdeb92dd4c5050 100644 (file)
@@ -101,6 +101,7 @@ class RegionView : public TimeAxisViewItem
                boost::shared_ptr<ARDOUR::Region>,
                double      samples_per_unit,
                Gdk::Color& basic_color,
+               bool recording,
                TimeAxisViewItem::Visibility);
     
     virtual void region_resized (ARDOUR::Change);
index 63440e7ab1b8022a51aca01311cd55e7b3d431e7..4a4f3d4ec477a367cdf2497c40c53c73c7856485 100644 (file)
@@ -4,6 +4,7 @@
 #include <pbd/memento_command.h>
 
 #include <ardour/transient_detector.h>
+#include <ardour/onset_detector.h>
 #include <ardour/audiosource.h>
 #include <ardour/audioregion.h>
 #include <ardour/playlist.h>
@@ -32,6 +33,17 @@ static const gchar * _analysis_mode_strings[] = {
        0
 };
 
+static const gchar * _onset_function_strings[] = {
+       N_("Energy Based"),
+       N_("Spectral Difference"),
+       N_("High-Frequency Content"),
+       N_("Complex Domain"),
+       N_("Phase Deviation"),
+       N_("Kullback-Liebler"),
+       N_("Modified Kullback-Liebler"),
+       0
+};
+
 RhythmFerret::RhythmFerret (PublicEditor& e)
        : ArdourDialog (_("Rhythm Ferret"))
        , editor (e)
@@ -50,6 +62,13 @@ RhythmFerret::RhythmFerret (PublicEditor& e)
        , sensitivity_scale (sensitivity_adjustment)
        , sensitivity_label (_("Sensitivity"))
        , analyze_button (_("Analyze"))
+       , onset_function_label (_("Detection function"))
+       , peak_picker_threshold_adjustment (0.3, 0.0, 1.0, 0.01, 0.1)
+       , peak_picker_threshold_scale (peak_picker_threshold_adjustment)
+       , peak_picker_label (_("Peak Threshold"))
+       , silence_threshold_adjustment (-90.0, -120.0, 0.0, 1, 10)
+       , silence_threshold_scale (silence_threshold_adjustment)
+       , silence_label (_("Silent Threshold (dB)"))
        , trigger_gap_adjustment (3, 0, 100, 1, 10)
        , trigger_gap_spinner (trigger_gap_adjustment)
        , trigger_gap_label (_("Trigger gap (msecs)"))
@@ -78,6 +97,14 @@ RhythmFerret::RhythmFerret (PublicEditor& e)
        analysis_mode_strings = I18N (_analysis_mode_strings);
        Gtkmm2ext::set_popdown_strings (analysis_mode_selector, analysis_mode_strings);
        analysis_mode_selector.set_active_text (analysis_mode_strings.front());
+       analysis_mode_selector.signal_changed().connect (mem_fun (*this, &RhythmFerret::analysis_mode_changed));
+
+       onset_function_strings = I18N (_onset_function_strings);
+       Gtkmm2ext::set_popdown_strings (onset_detection_function_selector, onset_function_strings);
+       /* Onset plugin uses complex domain as default function 
+          XXX there should be a non-hacky way to set this
+        */
+       onset_detection_function_selector.set_active_text (onset_function_strings[3]);
 
        box = manage (new HBox);
        box->set_spacing (6);
@@ -85,28 +112,50 @@ RhythmFerret::RhythmFerret (PublicEditor& e)
        box->pack_start (analysis_mode_selector, true, true);
        ferret_packer.pack_start (*box, false, false);
 
+       ferret_packer.pack_start (analysis_packer, false, false);
+
        box = manage (new HBox);
        box->set_spacing (6);
-       box->pack_start (detection_threshold_label, false, false);
-       box->pack_start (detection_threshold_scale, true, true);
+       box->pack_start (trigger_gap_label, false, false);
+       box->pack_start (trigger_gap_spinner, false, false);
        ferret_packer.pack_start (*box, false, false);
 
+       ferret_packer.pack_start (analyze_button, false, false);
+
+       analyze_button.signal_clicked().connect (mem_fun (*this, &RhythmFerret::run_analysis));
+       
+       box = manage (new HBox);
+       box->set_spacing (6);
+       box->pack_start (detection_threshold_label, false, false);
+       box->pack_start (detection_threshold_scale, true, true);
+       perc_onset_packer.pack_start (*box, false, false);
+               
        box = manage (new HBox);
        box->set_spacing (6);
        box->pack_start (sensitivity_label, false, false);
        box->pack_start (sensitivity_scale, true, true);
-       ferret_packer.pack_start (*box, false, false);
+       perc_onset_packer.pack_start (*box, false, false);
 
        box = manage (new HBox);
        box->set_spacing (6);
-       box->pack_start (trigger_gap_label, false, false);
-       box->pack_start (trigger_gap_spinner, false, false);
-       ferret_packer.pack_start (*box, false, false);
+       box->pack_start (onset_function_label, false, false);
+       box->pack_start (onset_detection_function_selector, true, true);
+       note_onset_packer.pack_start (*box, false, false);
+               
+       box = manage (new HBox);
+       box->set_spacing (6);
+       box->pack_start (peak_picker_label, false, false);
+       box->pack_start (peak_picker_threshold_scale, true, true);
+       note_onset_packer.pack_start (*box, false, false);
+       
+       box = manage (new HBox);
+       box->set_spacing (6);
+       box->pack_start (silence_label, false, false);
+       box->pack_start (silence_threshold_scale, true, true);
+       note_onset_packer.pack_start (*box, false, false);
 
-       ferret_packer.pack_start (analyze_button, false, false);
+       analysis_mode_changed ();
 
-       analyze_button.signal_clicked().connect (mem_fun (*this, &RhythmFerret::run_analysis));
-       
        ferret_frame.add (ferret_packer);
        
        logo = manage (new Gtk::Image (::get_icon (X_("ferret_02"))));
@@ -137,12 +186,30 @@ RhythmFerret::~RhythmFerret()
        }
 }
 
+void
+RhythmFerret::analysis_mode_changed ()
+{
+       analysis_packer.children().clear ();
+
+       switch (get_analysis_mode()) {
+       case PercussionOnset:
+               analysis_packer.pack_start (perc_onset_packer);
+               break;
+
+       case NoteOnset:
+               analysis_packer.pack_start (note_onset_packer);
+               break;
+       }
+
+       analysis_packer.show_all ();
+}
+
 RhythmFerret::AnalysisMode
 RhythmFerret::get_analysis_mode () const
 {
        string str = analysis_mode_selector.get_active_text ();
 
-       if (str == _(_analysis_mode_strings[(int) NoteOnset])) {
+       if (str == analysis_mode_strings[(int) NoteOnset]) {
                return NoteOnset;
        } 
 
@@ -184,6 +251,9 @@ RhythmFerret::run_analysis ()
                case PercussionOnset:
                        run_percussion_onset_analysis (rd, (*i)->region()->position(), current_results);
                        break;
+               case NoteOnset:
+                       run_note_onset_analysis (rd, (*i)->region()->position(), current_results);
+                       break;
                default:
                        break;
                }
@@ -232,6 +302,67 @@ RhythmFerret::run_percussion_onset_analysis (boost::shared_ptr<Readable> readabl
        return 0;
 }
 
+int
+RhythmFerret::get_note_onset_function ()
+{
+       string txt = onset_detection_function_selector.get_active_text();
+
+       for (int n = 0; _onset_function_strings[n]; ++n) {
+               /* compare translated versions */
+               if (txt == onset_function_strings[n]) {
+                       return n;
+               }
+       }
+       fatal << string_compose (_("programming error: %1 (%2)"), X_("illegal note onset function string"), txt)
+             << endmsg;
+       /*NOTREACHED*/
+       return -1;
+}
+
+int
+RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, nframes64_t offset, AnalysisFeatureList& results)
+{
+       try {
+               OnsetDetector t (session->frame_rate());
+               
+               for (uint32_t i = 0; i < readable->n_channels(); ++i) {
+                       
+                       AnalysisFeatureList these_results;
+                       
+                       t.reset ();
+                       
+                       t.set_function (get_note_onset_function());
+                       t.set_silence_threshold (silence_threshold_adjustment.get_value());
+                       t.set_peak_threshold (peak_picker_threshold_adjustment.get_value());
+                       
+                       if (t.run ("", readable.get(), i, these_results)) {
+                               continue;
+                       }
+                       
+                       /* translate all transients to give absolute position */
+                       
+                       for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
+                               (*x) += offset;
+                       }
+                       
+                       /* merge */
+                       
+                       results.insert (results.end(), these_results.begin(), these_results.end());
+                       these_results.clear ();
+               }
+
+       } catch (failed_constructor& err) {
+               error << "Could not load note onset detection plugin" << endmsg;
+               return -1;
+       }
+
+       if (!results.empty()) {
+               OnsetDetector::cleanup_onsets (results, session->frame_rate(), trigger_gap_adjustment.get_value());
+       }
+
+       return 0;
+}
+
 void
 RhythmFerret::do_action ()
 {
@@ -277,6 +408,7 @@ RhythmFerret::do_split_action ()
 
                i = tmp;
        }
+       session->commit_reversible_command ();
 
 }
 
index 2ddb2a4ffde2679856f1d50ea77130c047594665..91c10695ad38b1dd3ad4664771c2cc36a5a13067 100644 (file)
@@ -71,6 +71,9 @@ class RhythmFerret : public ArdourDialog {
        Gtk::VBox ferret_packer;
        Gtk::ComboBoxText analysis_mode_selector;
        Gtk::Label analysis_mode_label;
+
+       /* transient detection widgets */
+
        Gtk::Adjustment detection_threshold_adjustment;
        Gtk::HScale detection_threshold_scale;
        Gtk::Label detection_threshold_label;
@@ -78,22 +81,44 @@ class RhythmFerret : public ArdourDialog {
        Gtk::HScale sensitivity_scale;
        Gtk::Label sensitivity_label;
        Gtk::Button analyze_button;
+       Gtk::VBox perc_onset_packer;
+
+       /* onset detection widgets */
+
+       Gtk::ComboBoxText onset_detection_function_selector;
+       Gtk::Label onset_function_label;
+       Gtk::Adjustment peak_picker_threshold_adjustment;
+       Gtk::HScale peak_picker_threshold_scale;
+       Gtk::Label peak_picker_label;
+       Gtk::Adjustment silence_threshold_adjustment;
+       Gtk::HScale silence_threshold_scale;
+       Gtk::Label silence_label;
+       Gtk::VBox note_onset_packer;
+
+       /* generic stuff */
+
        Gtk::Adjustment trigger_gap_adjustment;
        Gtk::SpinButton trigger_gap_spinner;
        Gtk::Label trigger_gap_label;
 
+       Gtk::VBox analysis_packer;
+
        Gtk::Label operation_clarification_label;
        Gtk::Button action_button;
 
        std::vector<std::string> analysis_mode_strings;
+       std::vector<std::string> onset_function_strings;
 
        ARDOUR::AnalysisFeatureList current_results;
 
        AnalysisMode get_analysis_mode () const;
        Action get_action() const;
+       void analysis_mode_changed ();
+       int get_note_onset_function ();
 
        void run_analysis ();
        int run_percussion_onset_analysis (boost::shared_ptr<ARDOUR::Readable> region, nframes64_t offset, ARDOUR::AnalysisFeatureList& results);
+       int run_note_onset_analysis (boost::shared_ptr<ARDOUR::Readable> region, nframes64_t offset, ARDOUR::AnalysisFeatureList& results);
 
        void do_action ();
        void do_split_action ();
index 497e99ba61058ea75030a8c05175f76f4dcf44d4..f39d41def5a3be7826419089769035c9b2666286 100644 (file)
@@ -235,10 +235,10 @@ RouteParams_UI::setup_processor_boxes()
                pre_redir_hpane.pack1 (*pre_insert_box);
                post_redir_hpane.pack1 (*post_insert_box);
 
-               pre_insert_box->InsertSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
-               pre_insert_box->InsertUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
-               post_insert_box->InsertSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
-               post_insert_box->InsertUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
+               pre_insert_box->ProcessorSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
+               pre_insert_box->ProcessorUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
+               post_insert_box->ProcessorSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
+               post_insert_box->ProcessorUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
 
                pre_redir_hpane.show_all();
                post_redir_hpane.show_all();
index a5619b8ae9bc613a2f8a0bed84b8255ac5000a5b..82777944f415aac3133d302f697b9410e7b9d59d 100644 (file)
@@ -87,11 +87,12 @@ using namespace std;
 
 Glib::RefPtr<Gdk::Pixbuf> RouteTimeAxisView::slider;
 
-int
+void
 RouteTimeAxisView::setup_slider_pix ()
 {
-       slider = ::get_icon ("fader_belt_h");
-       return 0;
+       if ((slider = ::get_icon ("fader_belt_h")) == 0) {
+               throw failed_constructor ();
+       }
 }
 
 RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas)
@@ -105,18 +106,12 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
          size_button (_("h")), // height
          automation_button (_("a")),
          visual_button (_("v")),
-         lm (rt, sess),
-         underlay_xml_node (0),
-         gain_slider (0),
-         gain_adjustment (0.781787, 0.0, 1.0, 0.01, 0.1)
+         gm (rt, sess, slider, true)
 
 {
-       if (slider == 0) {
-               setup_slider_pix ();
-       }
+       gm.get_level_meter().set_no_show_all();
+       gm.get_level_meter().setup_meters(50);
 
-       lm.set_no_show_all();
-       lm.setup_meters(50);
        _has_state = true;
        playlist_menu = 0;
        playlist_action_menu = 0;
@@ -127,8 +122,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
        destructive_track_mode_item = 0;
        normal_track_mode_item = 0;
 
-       gain_slider = manage (new HSliderController (slider, &gain_adjustment, *_route->gain_control().get(), false));
-
        ignore_toggle = false;
 
        edit_group_button.set_name ("TrackGroupButton");
@@ -175,7 +168,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
 
        }
 
-       controls_hbox.pack_start(lm, false, false);
+       controls_hbox.pack_start(gm.get_level_meter(), false, false);
        _route->meter_change.connect (mem_fun(*this, &RouteTimeAxisView::meter_changed));
        _route->input_changed.connect (mem_fun(*this, &RouteTimeAxisView::io_changed));
        _route->output_changed.connect (mem_fun(*this, &RouteTimeAxisView::io_changed));
@@ -184,7 +177,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
        controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
 
        controls_table.attach (edit_group_button, 7, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
-       controls_table.attach (*gain_slider, 0, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       controls_table.attach (gm.get_gain_slider(), 0, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
 
        ARDOUR_UI::instance()->tooltips().set_tip(*solo_button,_("Solo"));
        ARDOUR_UI::instance()->tooltips().set_tip(*mute_button,_("Mute"));
@@ -239,14 +232,8 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
        editor.ZoomChanged.connect (mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit));
        ColorsChanged.connect (mem_fun (*this, &RouteTimeAxisView::color_handler));
 
-       gain_slider->signal_button_press_event().connect (mem_fun(*this, &RouteTimeAxisView::start_gain_touch));
-       gain_slider->signal_button_release_event().connect (mem_fun(*this, &RouteTimeAxisView::end_gain_touch));
-       gain_slider->set_name ("TrackGainFader");
-
-       gain_adjustment.signal_value_changed().connect (mem_fun(*this, &RouteTimeAxisView::gain_adjusted));
-       _route->gain_control()->Changed.connect (mem_fun(*this, &RouteTimeAxisView::gain_changed));
-
-       gain_slider->show_all();
+       gm.get_gain_slider().signal_scroll_event().connect(mem_fun(*this, &RouteTimeAxisView::controls_ebox_scroll), false);
+       gm.get_gain_slider().set_name ("TrackGainFader");
 }
 
 RouteTimeAxisView::~RouteTimeAxisView ()
@@ -285,6 +272,7 @@ RouteTimeAxisView::post_construct ()
        /* map current state of the route */
 
        update_diskstream_display ();
+
        subplugin_menu.items().clear ();
        _route->foreach_processor (this, &RouteTimeAxisView::add_processor_to_subplugin_menu);
        _route->foreach_processor (this, &RouteTimeAxisView::add_existing_processor_automation_curves);
@@ -306,69 +294,6 @@ RouteTimeAxisView::playlist_modified ()
 {
 }
 
-void
-RouteTimeAxisView::set_state (const XMLNode& node)
-{
-       const XMLProperty *prop;
-       
-       TimeAxisView::set_state (node);
-       
-       if ((prop = node.property ("shown_editor")) != 0) {
-               if (prop->value() == "no") {
-                       _marked_for_display = false;
-               } else {
-                       _marked_for_display = true;
-               }
-       } else {
-               _marked_for_display = true;
-       }
-       
-       XMLNodeList nlist = node.children();
-       XMLNodeConstIterator niter;
-       XMLNode *child_node;
-       
-       _show_automation.clear();
-       
-       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-               child_node = *niter;
-
-               if (child_node->name() == AutomationTimeAxisView::state_node_name) {
-                       XMLProperty* prop = child_node->property ("automation-id");
-                       if (!prop)
-                               continue;
-                       
-                       Parameter param(prop->value());
-                       if (!param)
-                               continue;
-                       
-                       bool show = false;
-                       
-                       prop = child_node->property ("shown");
-                       
-                       if (prop && prop->value() == "yes") {
-                               show = true;
-                               _show_automation.insert(param);
-                       }
-                       
-                       if (_automation_tracks.find(param) == _automation_tracks.end()) {
-                               create_automation_child(param, show);
-                       }
-               }
-               else if (child_node->name() == "Underlays") {
-                       underlay_xml_node = child_node;
-                       
-                       /* Wait for all gui tracks to be loaded as underlays are cross referencing tracks*/
-                       Glib::signal_idle().connect(mem_fun(*this, &RouteTimeAxisView::set_underlay_state));
-               }
-       }
-}
-
-XMLNode* 
-RouteTimeAxisView::get_automation_child_xml_node (Parameter param)
-{
-       return RouteUI::get_automation_child_xml_node (param);
-}
-
 gint
 RouteTimeAxisView::edit_click (GdkEventButton *ev)
 {
@@ -632,6 +557,7 @@ RouteTimeAxisView::build_display_menu ()
        route_active_menu_item->set_active (_route->active());
 
        items.push_back (SeparatorElem());
+       items.push_back (MenuElem (_("Hide"), mem_fun(*this, &RouteTimeAxisView::hide_click)));
        items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route)));
 }
 
@@ -768,7 +694,7 @@ RouteTimeAxisView::show_timestretch (nframes_t start, nframes_t end)
 
        x1 = start / editor.get_current_zoom();
        x2 = (end - 1) / editor.get_current_zoom();
-       y2 = height - 2;
+       y2 = current_height() - 2;
        
        timestretch_rect->property_x1() = x1;
        timestretch_rect->property_y1() = 1.0;
@@ -807,55 +733,30 @@ RouteTimeAxisView::show_selection (TimeSelection& ts)
 }
 
 void
-RouteTimeAxisView::set_height (TrackHeight h)
+RouteTimeAxisView::set_height (uint32_t h)
 {
-       int gmlen = (height_to_pixels (h)) - 5;
-       bool height_changed = (height == 0) || (h != height_style);
-       lm.setup_meters (gmlen);
+       int gmlen = h - 5;
+       bool height_changed = (height == 0) || (h != height);
+       gm.get_level_meter().setup_meters (gmlen);
+
        TimeAxisView::set_height (h);
 
        ensure_xml_node ();
 
        if (_view) {
-               _view->set_height ((double) height);
+               _view->set_height ((double) current_height());
        }
 
-       switch (height_style) {
-       case Largest:
-               xml_node->add_property ("track_height", "largest");
-               break;
-
-       case Large:
-               xml_node->add_property ("track_height", "large");
-               break;
-
-       case Larger:
-               xml_node->add_property ("track_height", "larger");
-               break;
+       char buf[32];
+       snprintf (buf, sizeof (buf), "%u", height);
+       xml_node->add_property ("height", buf);
 
-       case Normal:
-               xml_node->add_property ("track_height", "normal");
-               break;
-
-       case Smaller:
-               xml_node->add_property ("track_height", "smaller");
-               break;
-
-       case Small:
-               xml_node->add_property ("track_height", "small");
-               break;
-       }
-
-       switch (height_style) {
-       case Largest:
-       case Large:
-       case Larger:
-       case Normal:
+       if (height >= hNormal) {
                reset_meter();
                show_name_entry ();
                hide_name_label ();
 
-               gain_slider->show();
+               gm.get_gain_slider().show();
                mute_button->show();
                solo_button->show();
                if (rec_enable_button)
@@ -870,14 +771,14 @@ RouteTimeAxisView::set_height (TrackHeight h)
                if (is_track() && track()->mode() == ARDOUR::Normal) {
                        playlist_button.show();
                }
-               break;
 
-       case Smaller:
+       } else if (height >= hSmaller) {
+
                reset_meter();
                show_name_entry ();
                hide_name_label ();
 
-               gain_slider->hide();
+               gm.get_gain_slider().hide();
                mute_button->show();
                solo_button->show();
                if (rec_enable_button)
@@ -892,13 +793,13 @@ RouteTimeAxisView::set_height (TrackHeight h)
                if (is_track() && track()->mode() == ARDOUR::Normal) {
                        playlist_button.hide ();
                }
-               break;
 
-       case Small:
+       } else {
+
                hide_name_entry ();
                show_name_label ();
-
-               gain_slider->hide();
+               
+               gm.get_gain_slider().hide();
                mute_button->hide();
                solo_button->hide();
                if (rec_enable_button)
@@ -911,7 +812,6 @@ RouteTimeAxisView::set_height (TrackHeight h)
                automation_button.hide ();
                playlist_button.hide ();
                name_label.set_text (_route->name());
-               break;
        }
 
        if (height_changed) {
@@ -1630,7 +1530,7 @@ RouteTimeAxisView::automation_track_hidden (Parameter param)
                ran->menu_item->set_active (false);
        }
 
-        _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+        _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
 }
 
 
@@ -1664,10 +1564,9 @@ RouteTimeAxisView::show_all_automation ()
 
        no_redraw = false;
 
-
        /* Redraw */
 
-        _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+        _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
 }
 
 void
@@ -1699,8 +1598,8 @@ RouteTimeAxisView::show_existing_automation ()
        }
 
        no_redraw = false;
-
-        _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+       
+       _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
 }
 
 void
@@ -1728,7 +1627,7 @@ RouteTimeAxisView::hide_all_automation ()
        _show_automation.clear();
 
        no_redraw = false;
-        _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+        _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
 }
 
 
@@ -1869,7 +1768,7 @@ RouteTimeAxisView::processor_automation_track_hidden (RouteTimeAxisView::Process
 
        i->mark_automation_visible (pan->what, false);
 
-        _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+        _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
 }
 
 void
@@ -1902,7 +1801,7 @@ RouteTimeAxisView::add_automation_child(Parameter param, boost::shared_ptr<Autom
        track->Hiding.connect (bind (mem_fun (*this, &RouteTimeAxisView::automation_track_hidden), param));
 
        bool hideit = (!show);
-       
+
        XMLNode* node;
 
        if ((node = track->get_state_node()) != 0) {
@@ -1918,8 +1817,11 @@ RouteTimeAxisView::add_automation_child(Parameter param, boost::shared_ptr<Autom
        if (hideit) {
                track->hide ();
        } else {
-               _show_automation.insert(param);
-               _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+               _show_automation.insert (param);
+
+               if (!no_redraw) {
+                       _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
+               }
        }
 
        build_display_menu();
@@ -2041,7 +1943,7 @@ RouteTimeAxisView::processor_menu_item_toggled (RouteTimeAxisView::ProcessorAuto
 
                /* now trigger a redisplay */
                
-                _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+                _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
 
        }
 }
@@ -2079,7 +1981,7 @@ RouteTimeAxisView::processors_changed ()
 
        /* change in visibility was possible */
 
-       _route->gui_changed ("track_height", this);
+       _route->gui_changed ("visible_tracks", this);
 }
 
 boost::shared_ptr<AutomationLine>
@@ -2131,14 +2033,14 @@ RouteTimeAxisView::automation_child(ARDOUR::Parameter param)
 void
 RouteTimeAxisView::fast_update ()
 {
-       lm.update_meters ();
+       gm.get_level_meter().update_meters ();
 }
 
 void
 RouteTimeAxisView::hide_meter ()
 {
        clear_meter ();
-       lm.hide_meters ();
+       gm.get_level_meter().hide_meters ();
 }
 
 void
@@ -2151,7 +2053,7 @@ void
 RouteTimeAxisView::reset_meter ()
 {
        if (Config->get_show_track_meters()) {
-               lm.setup_meters (height-5);
+               gm.get_level_meter().setup_meters (height-5);
        } else {
                hide_meter ();
        }
@@ -2160,7 +2062,7 @@ RouteTimeAxisView::reset_meter ()
 void
 RouteTimeAxisView::clear_meter ()
 {
-       lm.clear_meters ();
+       gm.get_level_meter().clear_meters ();
 }
 
 void
@@ -2290,36 +2192,3 @@ RouteTimeAxisView::remove_underlay(StreamView* v)
        }
 }
 
-gint
-RouteTimeAxisView::start_gain_touch (GdkEventButton* ev)
-{
-       _route->gain_control()->list()->start_touch ();
-       return FALSE;
-}
-
-gint
-RouteTimeAxisView::end_gain_touch (GdkEventButton* ev)
-{
-       _route->gain_control()->list()->stop_touch ();
-       return FALSE;
-}
-
-void
-RouteTimeAxisView::gain_adjusted ()
-{
-       _route->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this);
-}
-
-void
-RouteTimeAxisView::gain_changed ()
-{
-       Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &RouteTimeAxisView::effective_gain_display));
-}
-
-void
-RouteTimeAxisView::effective_gain_display ()
-{
-       gfloat value = gain_to_slider_position (_route->effective_gain());
-       gain_adjustment.set_value (value);
-}
-
index e318451832c58483ea6d2c8cddb6ed2b32b4474f..230ea45b8676c3fdbfdf09423bd0bd1dcc901048 100644 (file)
@@ -40,7 +40,7 @@
 #include "enums.h"
 #include "time_axis_view.h"
 #include "canvas.h"
-#include "level_meter.h"
+#include "gain_meter.h"
 
 
 namespace ARDOUR {
@@ -74,7 +74,7 @@ public:
        void show_selection (TimeSelection&);
 
        void set_samples_per_unit (double);
-       void set_height (TimeAxisView::TrackHeight);
+       void set_height (uint32_t h);
        void show_timestretch (nframes_t start, nframes_t end);
        void hide_timestretch ();
        void selection_click (GdkEventButton*);
@@ -117,6 +117,10 @@ public:
 
        virtual void create_automation_child (ARDOUR::Parameter param, bool show) = 0;
        
+       /* make sure we get the right version of this */
+
+       XMLNode* get_automation_child_xml_node (ARDOUR::Parameter param) { return RouteUI::get_automation_child_xml_node (param); }
+       
        typedef map<ARDOUR::Parameter, RouteAutomationNode*> AutomationTracks;
        AutomationTracks automation_tracks() { return _automation_tracks; }
 
@@ -134,7 +138,9 @@ public:
        void clear_meter ();
        void io_changed (ARDOUR::IOChange, void *);
        void meter_changed (void *);
-       void effective_gain_display ();
+       void effective_gain_display () { gm.effective_gain_display(); }
+
+       static void setup_slider_pix ();
 
 protected:
        friend class StreamView;
@@ -297,11 +303,9 @@ protected:
 
        void post_construct ();
        
-       void set_state (const XMLNode&);
-       
-       XMLNode* get_automation_child_xml_node (ARDOUR::Parameter param);
+       GainMeterBase gm;
 
-       LevelMeter      lm;
+       static Glib::RefPtr<Gdk::Pixbuf> slider;
 
        XMLNode* underlay_xml_node;
        bool set_underlay_state();
@@ -310,16 +314,6 @@ protected:
        UnderlayList _underlay_streams;
        typedef list<RouteTimeAxisView*> UnderlayMirrorList;
        UnderlayMirrorList _underlay_mirrors;
-
-       Gtkmm2ext::HSliderController *gain_slider;
-       Gtk::Adjustment              gain_adjustment;
-       static Glib::RefPtr<Gdk::Pixbuf> slider;
-       static int setup_slider_pix ();
-       void gain_adjusted();
-
-       gint start_gain_touch (GdkEventButton*);
-       gint end_gain_touch (GdkEventButton*);
-       void gain_changed ();
 };
 
 #endif /* __ardour_route_time_axis_h__ */
index 9c88bec37ccd58654a3ccd9d151f16386cfe43e0..4d1d92ac5a3ff0eb8d55098b6cb63ddff0c2776f 100644 (file)
@@ -81,10 +81,10 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
 
        _route->active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed));
 
-       mute_button = manage (new BindableToggleButton (*_route->mute_control().get(), m_name ));
+       mute_button = manage (new BindableToggleButton (_route->mute_control(), m_name ));
        mute_button->set_self_managed (true);
 
-       solo_button = manage (new BindableToggleButton (*_route->solo_control().get(), s_name ));
+       solo_button = manage (new BindableToggleButton (_route->solo_control(), s_name ));
        solo_button->set_self_managed (true);
 
        mute_button->set_name ("MuteButton");
@@ -105,7 +105,7 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
 
                _session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed));
 
-               rec_enable_button = manage (new BindableToggleButton (*t->rec_enable_control().get(), r_name ));
+               rec_enable_button = manage (new BindableToggleButton (t->rec_enable_control(), r_name ));
                rec_enable_button->set_name ("RecordEnableButton");
                rec_enable_button->set_self_managed (true);
                
index 20ac152f83b7f82f1d7fea2c7eec6e2a71267de2..aecf351f3a2db05be49d9e394e0a014b594c0009 100644 (file)
@@ -124,10 +124,6 @@ class RouteUI : public virtual AxisView
 
        int  set_color_from_route ();
 
-       sigc::connection blink_connection;
-
-       void rec_enable_button_blink (bool onoff, ARDOUR::AudioDiskstream *, Gtk::Widget *w);
-       
        void remove_this_route ();
        static gint idle_remove_this_route (RouteUI *);
 
index c91068f97c27bf37d4b6aae839d411ba9301a687..90ff3de717637378aa6e3260020c05a7158aa2e1 100644 (file)
@@ -44,7 +44,7 @@ SendUI::SendUI (boost::shared_ptr<Send> s, Session& se)
        vbox.pack_start (hbox, false, false, false);
        vbox.pack_start (panners, false,false);
 
-       io = new IOSelector (se, s->io(), false);
+       io = manage (new IOSelector (se, s->io(), false));
        
        pack_start (vbox, false, false);
 
@@ -70,7 +70,7 @@ SendUI::SendUI (boost::shared_ptr<Send> s, Session& se)
 SendUI::~SendUI ()
 {
        _send->set_metering (false);
-       
+
        /* XXX not clear that we need to do this */
 
        screen_update_connection.disconnect();
@@ -121,8 +121,8 @@ SendUIWindow::SendUIWindow (boost::shared_ptr<Send> s, Session& ss)
 
        add (vpacker);
        set_name ("SendUIWindow");
-
-       s->GoingAway.connect (mem_fun (*this, &SendUIWindow::send_going_away));
+       
+       going_away_connection = s->GoingAway.connect (mem_fun (*this, &SendUIWindow::send_going_away));
 
        signal_delete_event().connect (bind (ptr_fun (just_hide_it), reinterpret_cast<Window *> (this)));
 
@@ -138,5 +138,6 @@ SendUIWindow::send_going_away ()
 {
        ENSURE_GUI_THREAD (mem_fun (*this, &SendUIWindow::send_going_away));
        delete_when_idle (this);
+       going_away_connection.disconnect ();
 }
 
index 0cd4b1a26513ed1f72841ffa5e50e196d5d5b2c2..5a7298c51584222b84195b8bc64152e2ad994ae3 100644 (file)
@@ -42,6 +42,8 @@ class SendUI : public Gtk::HBox
 
        IOSelector* io;
 
+       boost::shared_ptr<ARDOUR::Send>& send() { return _send; }
+
   private:
        boost::shared_ptr<ARDOUR::Send> _send;
        ARDOUR::Session& _session;
@@ -70,6 +72,7 @@ class SendUIWindow : public Gtk::Window
        Gtk::HBox hpacker;
 
        void send_going_away ();
+       sigc::connection going_away_connection;
 };
 
 #endif /* __ardour_gtk_send_ui_h__ */
index b7b853ebec359b03d9dc4b31431a8ac53037fefa..77c7f59afc4e9da86e353dbdceccbae46b7fd0f7 100644 (file)
@@ -404,16 +404,19 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
          found_list_view (found_list),
          freesound_search_btn (_("Start Downloading")),
          freesound_list_view (freesound_list)
-
 {
        resetting_ourselves = false;
        gm = 0;
 
+       resetting_ourselves = false;
+       gm = 0;
+
        if (ARDOUR::Profile->get_sae()) {
                chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
                chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
        }
        
+
        //add the file chooser
        {
                chooser.set_border_width (12);
@@ -426,14 +429,14 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
                
                matchall_filter.add_pattern ("*.*");
                matchall_filter.set_name (_("All files"));
-               
+
                chooser.add_filter (audio_filter);
                chooser.add_filter (midi_filter);
                chooser.add_filter (matchall_filter);
                chooser.set_select_multiple (true);
                chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
                chooser.signal_file_activated().connect (mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
-               
+
                if (!persistent_folder.empty()) {
                        chooser.set_current_folder (persistent_folder);
                }
@@ -445,11 +448,6 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
                VBox* vbox;
                HBox* hbox;
 
-               hpacker.set_spacing (6);
-               hpacker.pack_start (notebook, true, true);
-               hpacker.pack_start (preview, false, false);
-
-               get_vbox()->pack_start (hpacker, true, true);
 
                hbox = manage(new HBox);
                hbox->pack_start (found_entry);
@@ -474,7 +472,6 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
 
                notebook.append_page (*vbox, _("Search Tags"));
        }
-       
 
        //add freesound search
 #ifdef FREESOUND
@@ -483,12 +480,6 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
                HBox* passbox;
                Label* label;
 
-               hpacker.set_spacing (6);
-               hpacker.pack_start (notebook, true, true);
-               hpacker.pack_start (preview, false, false);
-
-               get_vbox()->pack_start (hpacker, true, true);
-
                passbox = manage(new HBox);
                passbox->set_border_width (12);
                passbox->set_spacing (6);
@@ -522,10 +513,8 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
                
                //freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
                freesound_list_view.signal_row_activated().connect (mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
-
                freesound_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
                freesound_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
-
                notebook.append_page (*vbox, _("Search Freesound"));
        }
 #endif
@@ -1083,11 +1072,9 @@ SoundFileOmega::check_info (const vector<ustring>& paths, bool& same_size, bool&
        for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
 
                if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
-               
                        if (info.channels > 1) {
                                multichannel = true;
                        }
-                       
                        if (sz == 0) {
                                sz = info.length;
                        } else {
index a0be66493c5e919df1c7236dd8927cf6f3716b59..24cb08cc1b1602f8a681f10191df0555c3a2f3d1 100644 (file)
@@ -150,6 +150,7 @@ class SoundFileBrowser : public ArdourDialog
        
        Gtk::FileFilter audio_filter;
        Gtk::FileFilter midi_filter;
+       Gtk::FileFilter custom_filter;
        Gtk::FileFilter matchall_filter;
        Gtk::HBox hpacker;
 
index 46cb078c63cbb2641ff043c3a807e8551ffdea77..0f52f07939af82a9fa0621c30edd006a8bf93d1d 100644 (file)
@@ -66,7 +66,7 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* group)
        canvas_rect->property_x1() = 0.0;
        canvas_rect->property_y1() = 0.0;
        canvas_rect->property_x2() = _trackview.editor.frame_to_pixel (max_frames);
-       canvas_rect->property_y2() = (double) tv.height;
+       canvas_rect->property_y2() = (double) tv.current_height();
        canvas_rect->property_outline_what() = (guint32) (0x2|0x8);  // outline RHS and bottom 
        // (Fill/Outline colours set in derived classes)
 
index cb7a3332cd82bbda7a2e673415542c60d3d3699a..7cb5830dcbd5b053dde6abf9f457de08d0f03c39 100644 (file)
@@ -112,7 +112,7 @@ protected:
        void         update_rec_box ();
        //virtual void update_rec_regions () = 0;
        
-       virtual RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_data) = 0;
+       virtual RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves, bool recording = false) = 0;
        virtual void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
        //void         remove_rec_region (boost::shared_ptr<ARDOUR::Region>); (unused)
 
index 9791d0a7aa8b694ec322cf82be0b4414488d12c4..21bc41800e107babcf88aa162c2c417610935792 100644 (file)
@@ -53,7 +53,7 @@ TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTime
                                          double spu, 
                                          Gdk::Color& basic_color)
 
-       : AudioRegionView (parent, tv, r, spu, basic_color, 
+       : AudioRegionView (parent, tv, r, spu, basic_color, false,
                           TimeAxisViewItem::Visibility ((r->position() != 0) ? default_tape_visibility : 
                                                         TimeAxisViewItem::Visibility (default_tape_visibility|TimeAxisViewItem::HideFrameLeft)))
 {
index 3259ac8a286753389efb30903bb730e29696ac22..0973fb9c93e5b9016ad0f84e0b5ba08531d98f00 100644 (file)
@@ -74,7 +74,6 @@ bool TimeAxisView::need_size_info = true;
 TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisView* rent, Canvas& canvas) 
        : AxisView (sess), 
          editor (ed),
-         height_style(Small),
          y_position(0),
          order(0),
          controls_table (2, 8)
@@ -105,6 +104,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie
        _has_state = false;
        last_name_entry_key_press_event = 0;
        name_packing = NamePackingBits (0);
+       resize_drag_start = -1;
 
        /*
          Create the standard LHS Controls
@@ -140,7 +140,23 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie
        controls_table.show_all ();
        controls_table.set_no_show_all ();
 
+       resizer.set_size_request (10, 10);
+       resizer.set_name ("ResizeHandle");
+       resizer.signal_expose_event().connect (mem_fun (*this, &TimeAxisView::resizer_expose));
+       resizer.signal_button_press_event().connect (mem_fun (*this, &TimeAxisView::resizer_button_press));
+       resizer.signal_button_release_event().connect (mem_fun (*this, &TimeAxisView::resizer_button_release));
+       resizer.signal_motion_notify_event().connect (mem_fun (*this, &TimeAxisView::resizer_motion));
+       resizer.set_events (Gdk::BUTTON_PRESS_MASK|
+                           Gdk::BUTTON_RELEASE_MASK|
+                           Gdk::POINTER_MOTION_MASK|
+                           Gdk::SCROLL_MASK);
+
+       resizer_box.pack_start (resizer, false, false);
+       resizer.show ();
+       resizer_box.show();
+
        controls_vbox.pack_start (controls_table, false, false);
+       controls_vbox.pack_end (resizer_box, false, true);
        controls_vbox.show ();
        
        //controls_ebox.set_name ("TimeAxisViewControlsBaseUnselected");
@@ -238,9 +254,9 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
        _hidden = false;
        
        /* height in pixels depends on _order, so update it now we've changed _order */
-       set_height (height_style);
+       set_height (height);
        
-       effective_height = height;
+       effective_height = current_height();
 
        /* now show children */
        
@@ -267,6 +283,9 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
                if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
                        step_height (true);
                        return true;
+               } else if (Keyboard::no_modifiers_active (ev->state)) {
+                       editor.scroll_tracks_up_line();
+                       return true;
                }
                break;
                
@@ -274,6 +293,9 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
                if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
                        step_height (false);
                        return true;
+               } else if (Keyboard::no_modifiers_active (ev->state)) {
+                       editor.scroll_tracks_down_line();
+                       return true;
                }
                break;
 
@@ -338,39 +360,21 @@ TimeAxisView::hide ()
 void
 TimeAxisView::step_height (bool bigger)
 {
-  
-       if (height == hLargest) {
-               if (!bigger) set_height (Large);
-               return;
-       }
-       if (height == hLarge) {
-               if (bigger) set_height (Largest);
-                else set_height (Larger);
-               return;
-       }
-       if (height == hLarger) {
-                if (bigger) set_height (Large);
-                else set_height (Normal);
-               return;
-       }
-       if (height == hNormal) {
-                if (bigger) set_height (Larger);
-                else set_height (Smaller);
-               return;
-       }
-       if (height == hSmaller) {
-                if (bigger) set_height (Normal);
-                else set_height (Small);
-               return;
-       }
-       if (height == hSmall) {
-                if (bigger) set_height (Smaller);
-               return;
-       }
+       static const uint32_t step = 20;
+
+       if (bigger) {
+               set_height (height + step);
+       } else {
+               if (height > step) {
+                       set_height (std::max (height - step, hSmall));
+               } else if (height != hSmall) {
+                       set_height (hSmall);
+               }
+       }
 }
 
 void
-TimeAxisView::set_heights (TrackHeight h)
+TimeAxisView::set_heights (uint32_t h)
 {
        TrackSelection& ts (editor.get_selection().tracks);
 
@@ -380,27 +384,20 @@ TimeAxisView::set_heights (TrackHeight h)
 }
 
 void
-TimeAxisView::set_height (TrackHeight h)
+TimeAxisView::set_height(uint32_t h)
 {
-       height_style = h;
-       set_height_pixels (height_to_pixels (h));
+       height = h;
 
        for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
                (*i)->set_height ();
        }
-}
 
-void
-TimeAxisView::set_height_pixels (uint32_t h)
-{
-       height = h;
-       controls_hbox.set_size_request (-1, height + ((order == 0) ? 1 : 0));
-       //cerr << "TimeAxisView::set_height_pixels() called h = " << h << endl;//DEBUG
        if (canvas_item_visible (selection_group)) {
                /* resize the selection rect */
                show_selection (editor.get_selection().time);
        }
-       
+
+       reshow_feature_lines ();
 }
 
 bool
@@ -440,8 +437,11 @@ TimeAxisView::name_entry_key_release (GdkEventKey* ev)
                                }
                        }
 
-                       if ((*i)->height_style == Small) {
-                               (*i)->set_height(Smaller);
+
+                       /* resize to show editable name display */
+                       
+                       if ((*i)->current_height() >= hSmall && (*i)->current_height() < hNormal) {
+                               (*i)->set_height (hSmaller);
                        }
                        
                        (*i)->name_entry.grab_focus();
@@ -549,7 +549,6 @@ TimeAxisView::conditionally_add_to_selection ()
        Selection& s (editor.get_selection());
 
        if (!s.selected (this)) {
-               cerr << "set selected track\n";
                editor.set_selected_track (*this, Selection::Set);
        }
 }
@@ -617,6 +616,8 @@ TimeAxisView::set_selected (bool yn)
                        (*i)->set_selected (false);
                }
        }
+
+       resizer.queue_draw ();
 }
 
 void
@@ -628,12 +629,12 @@ TimeAxisView::build_size_menu ()
        size_menu->set_name ("ArdourContextMenu");
        MenuList& items = size_menu->items();
        
-       items.push_back (MenuElem (_("Largest"), bind (mem_fun (*this, &TimeAxisView::set_heights), Largest)));
-       items.push_back (MenuElem (_("Large"), bind (mem_fun (*this, &TimeAxisView::set_heights), Large)));
-       items.push_back (MenuElem (_("Larger"), bind (mem_fun (*this, &TimeAxisView::set_heights), Larger)));
-       items.push_back (MenuElem (_("Normal"), bind (mem_fun (*this, &TimeAxisView::set_heights), Normal)));
-       items.push_back (MenuElem (_("Smaller"), bind (mem_fun (*this, &TimeAxisView::set_heights),Smaller)));
-       items.push_back (MenuElem (_("Small"), bind (mem_fun (*this, &TimeAxisView::set_heights), Small)));
+       items.push_back (MenuElem (_("Largest"), bind (mem_fun (*this, &TimeAxisView::set_heights), hLargest)));
+       items.push_back (MenuElem (_("Large"), bind (mem_fun (*this, &TimeAxisView::set_heights), hLarge)));
+       items.push_back (MenuElem (_("Larger"), bind (mem_fun (*this, &TimeAxisView::set_heights), hLarger)));
+       items.push_back (MenuElem (_("Normal"), bind (mem_fun (*this, &TimeAxisView::set_heights), hNormal)));
+       items.push_back (MenuElem (_("Smaller"), bind (mem_fun (*this, &TimeAxisView::set_heights),hSmaller)));
+       items.push_back (MenuElem (_("Small"), bind (mem_fun (*this, &TimeAxisView::set_heights), hSmall)));
 }
 
 void
@@ -716,7 +717,7 @@ TimeAxisView::show_selection (TimeSelection& ts)
                
                x1 = editor.frame_to_unit (start);
                x2 = editor.frame_to_unit (start + cnt - 1);
-               y2 = height;
+               y2 = current_height();
 
                rect->rect->property_x1() = x1;
                rect->rect->property_y1() = 1.0;
@@ -936,7 +937,7 @@ TimeAxisView::touched (double top, double bot)
           y_position is the "origin" or "top" of the track.
         */
 
-       double mybot = y_position + height;
+       double mybot = y_position + current_height();
        
        return ((y_position <= bot && y_position >= top) || 
                ((mybot <= bot) && (top < mybot)) || 
@@ -969,68 +970,69 @@ TimeAxisView::get_parent_with_state ()
        return parent->get_parent_with_state ();
 }              
 
-void
+
+XMLNode&
+TimeAxisView::get_state ()
+{
+       XMLNode* node = new XMLNode ("TAV-" + name());
+       char buf[32];
+
+       snprintf (buf, sizeof(buf), "%u", height);
+       node->add_property ("height", buf);
+       node->add_property ("marked_for_display", (_marked_for_display ? "1" : "0"));
+       return *node;
+}
+
+int
 TimeAxisView::set_state (const XMLNode& node)
 {
        const XMLProperty *prop;
 
+       if ((prop = node.property ("marked_for_display")) != 0) {
+               _marked_for_display = (prop->value() == "1");
+       }
+
        if ((prop = node.property ("track_height")) != 0) {
 
                if (prop->value() == "largest") {
-                       set_height (Largest);
+                       set_height (hLargest);
                } else if (prop->value() == "large") {
-                       set_height (Large);
+                       set_height (hLarge);
                } else if (prop->value() == "larger") {
-                       set_height (Larger);
+                       set_height (hLarger);
                } else if (prop->value() == "normal") {
-                       set_height (Normal);
+                       set_height (hNormal);
                } else if (prop->value() == "smaller") {
-                       set_height (Smaller);
+                       set_height (hSmaller);
                } else if (prop->value() == "small") {
-                       set_height (Small);
+                       set_height (hSmall);
                } else {
                        error << string_compose(_("unknown track height name \"%1\" in XML GUI information"), prop->value()) << endmsg;
                        set_height (Normal);
                }
 
+       } else if ((prop = node.property ("height")) != 0) {
+
+               set_height (atoi (prop->value()));
+               
        } else {
-               set_height (Normal);
+
+               set_height (hNormal);
        }
+
+       return 0;
 }
 
 void
 TimeAxisView::reset_height()
 {
-       set_height_pixels (height);
+       set_height (height);
 
        for (Children::iterator i = children.begin(); i != children.end(); ++i) {
-               (*i)->set_height_pixels ((TrackHeight)(*i)->height);
+               (*i)->set_height ((*i)->height);
        }
 }
        
-uint32_t
-TimeAxisView::height_to_pixels (TrackHeight h)
-{
-       switch (h) {
-       case Largest:
-               return hLargest;
-       case Large:
-               return hLarge;
-       case Larger:
-               return hLarger;
-       case Normal:
-               return hNormal;
-       case Smaller:
-               return hSmaller;
-       case Small:
-               return hSmall;
-       }
-       
-       // what is wrong with gcc ?
-       
-       return hNormal;
-}
-                       
 void
 TimeAxisView::compute_controls_size_info ()
 {
@@ -1039,7 +1041,8 @@ TimeAxisView::compute_controls_size_info ()
        Gtk::Table one_row_table (1, 8);
        Button* buttons[5];
        const int border_width = 2;
-       const int extra_height = (2 * border_width) + 2; // 2 pixels for the controls frame
+       const int extra_height = (2 * border_width) + 2 // 2 pixels for the controls frame
+               + 10; // resizer button
 
        window.add (one_row_table);
 
@@ -1213,8 +1216,6 @@ TimeAxisView::reshow_feature_lines ()
        while (feature_lines.size()< analysis_features.size()) {
                ArdourCanvas::SimpleLine* l = new ArdourCanvas::SimpleLine (*canvas_display);
                l->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();
-               l->property_y1() = 0;
-               l->property_y2() = height;
                feature_lines.push_back (l);
        }
 
@@ -1230,7 +1231,90 @@ TimeAxisView::reshow_feature_lines ()
        for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
                (*l)->property_x1() = editor.frame_to_pixel (*i);
                (*l)->property_x2() = editor.frame_to_pixel (*i);
+               (*l)->property_y1() = 0;
+               (*l)->property_y2() = current_height();
                (*l)->show ();
        }
 }
 
+bool
+TimeAxisView::resizer_button_press (GdkEventButton* event)
+{
+       resize_drag_start = event->y_root;
+       resize_idle_target = current_height();
+       editor.start_resize_line_ops ();
+       return true;
+}
+
+bool
+TimeAxisView::resizer_button_release (GdkEventButton* ev)
+{
+       resize_drag_start = -1;
+       editor.end_resize_line_ops ();
+       return true;
+}
+
+void
+TimeAxisView::idle_resize (uint32_t h)
+{
+       set_height (h);
+}
+
+bool
+TimeAxisView::resizer_motion (GdkEventMotion* ev)
+{
+       if (resize_drag_start < 0) {
+               return true;
+       }
+
+       int32_t delta = (int32_t) floor (resize_drag_start - ev->y_root);
+
+       resize_idle_target = std::max (resize_idle_target - delta, (int) hSmall);
+       editor.add_to_idle_resize (this, resize_idle_target);
+       
+       resize_drag_start = ev->y_root;
+
+       return true;
+}
+
+bool
+TimeAxisView::resizer_expose (GdkEventExpose* event)
+{
+       int w, h, x, y, d;
+       Glib::RefPtr<Gdk::Window> win (resizer.get_window());
+       Glib::RefPtr<Gdk::GC> dark (resizer.get_style()->get_fg_gc (STATE_NORMAL));
+       Glib::RefPtr<Gdk::GC> light (resizer.get_style()->get_bg_gc (STATE_NORMAL));
+
+       win->draw_rectangle (controls_ebox.get_style()->get_bg_gc(STATE_NORMAL),
+                            true,
+                            event->area.x,
+                            event->area.y,
+                            event->area.width,
+                            event->area.height);
+
+       win->get_geometry (x, y, w, h, d);
+
+       /* handle/line #1 */
+       
+       win->draw_line (dark, 0, 0, w - 2, 0);
+       win->draw_point (dark, 0, 1);
+       win->draw_line (light, 1, 1, w - 1, 1);
+       win->draw_point (light, w - 1, 0);
+
+       /* handle/line #2 */
+
+       win->draw_line (dark, 0, 4, w - 2, 4);
+       win->draw_point (dark, 0, 5);
+       win->draw_line (light, 1, 5, w - 1, 5);
+       win->draw_point (light, w - 1, 4);
+
+       /* handle/line #3 */
+
+       win->draw_line (dark, 0, 8, w - 2, 8);
+       win->draw_point (dark, 0, 9);
+       win->draw_line (light, 1, 9, w - 1, 9);
+       win->draw_point (light, w - 1, 8);
+
+       return true;
+}
+
index 96db8aba93dccac77c272edb49e3d4a87a0dd7fb..ae4d035af87b1ade2f894f46b2ebcb0ddbf06317 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <gtkmm/box.h>
 #include <gtkmm/frame.h>
+#include <gtkmm/drawingarea.h>
 #include <gtkmm/eventbox.h>
 #include <gtkmm/table.h>
 #include <gtkmm/entry.h>
@@ -32,6 +33,8 @@
 
 #include <gtkmm2ext/focus_entry.h>
 
+#include <pbd/stateful.h>
+
 #include <ardour/types.h>
 #include <ardour/region.h>
 #include <ardour/parameter.h>
@@ -69,7 +72,7 @@ class GhostRegion;
  * This class provides the basic LHS controls and display methods. This should be
  * extended to create functional time-axis based views.
  */
-class TimeAxisView : public virtual AxisView
+class TimeAxisView : public virtual AxisView, public PBD::Stateful
 {
   private:
        enum NamePackingBits {
@@ -78,15 +81,6 @@ class TimeAxisView : public virtual AxisView
        };
 
   public:
-       enum TrackHeight { 
-               Largest,
-               Large,
-               Larger,
-               Normal,
-               Smaller,
-               Small
-       };
-       
        static uint32_t hLargest;
        static uint32_t hLarge;
        static uint32_t hLarger;
@@ -94,23 +88,24 @@ class TimeAxisView : public virtual AxisView
        static uint32_t hSmaller;
        static uint32_t hSmall;
 
-       static uint32_t height_to_pixels (TrackHeight);
-
        TimeAxisView(ARDOUR::Session& sess, PublicEditor& ed, TimeAxisView* parent, ArdourCanvas::Canvas& canvas);
        virtual ~TimeAxisView ();
 
+       XMLNode& get_state (void);
+       int set_state (const XMLNode&);
+
        /* public data: XXX create accessor/mutators for these ?? */
 
        PublicEditor& editor;
        
-       TrackHeight height_style; 
-       uint32_t    height;  /* in canvas units */
-       uint32_t    effective_height;  /* in canvas units */
-       double      y_position;
-       int         order;
+       uint32_t effective_height;  /* in canvas units */
+       double   y_position;
+       int      order;
        
-       ArdourCanvas::Group *canvas_display;
-       Gtk::VBox           *control_parent;
+       uint32_t current_height() const { return height; }
+
+       ArdourCanvas::Group   *canvas_display;
+       Gtk::VBox       *control_parent;
 
        /* The Standard LHS Controls */
        Gtk::Frame    controls_frame;
@@ -119,10 +114,21 @@ class TimeAxisView : public virtual AxisView
        Gtk::Table    controls_table;
        Gtk::EventBox controls_ebox;
        Gtk::VBox     controls_vbox;
+       Gtk::DrawingArea resizer;
+       Gtk::HBox     resizer_box;
        Gtk::HBox     name_hbox;
        Gtk::Frame    name_frame;
        Gtkmm2ext::FocusEntry name_entry;
-       
+
+       bool resizer_button_press (GdkEventButton*);
+       bool resizer_button_release (GdkEventButton*);
+       bool resizer_motion (GdkEventMotion*);
+       bool resizer_expose (GdkEventExpose*);
+
+       double resize_drag_start;
+       int32_t resize_idle_target;
+       void idle_resize (uint32_t);
+
        void hide_name_label ();
        void hide_name_entry ();
        void show_name_label ();
@@ -152,7 +158,7 @@ class TimeAxisView : public virtual AxisView
        virtual void entered () {}
        virtual void exited () {}
 
-       virtual void set_height (TrackHeight h);
+       virtual void set_height (uint32_t h);
        void reset_height();
 
        /**
@@ -222,9 +228,6 @@ class TimeAxisView : public virtual AxisView
        void set_parent (TimeAxisView& p);
        bool has_state () const;
 
-       virtual void set_state (const XMLNode&);
-       virtual XMLNode* get_state_node () { return 0; }
-
        /* call this on the parent */
 
        virtual XMLNode* get_automation_child_xml_node (ARDOUR::Parameter param) { return 0; }
@@ -232,6 +235,7 @@ class TimeAxisView : public virtual AxisView
        typedef std::vector<boost::shared_ptr<TimeAxisView> > Children;
 
   protected:
+       uint32_t height;  /* in canvas units */
 
        string controls_base_unselected_name;
        string controls_base_selected_name;
@@ -327,10 +331,11 @@ class TimeAxisView : public virtual AxisView
        static void compute_controls_size_info ();
        static bool need_size_info;
 
-       void set_heights (TrackHeight);
-       void set_height_pixels (uint32_t h);
+       void set_heights (uint32_t h);
        void color_handler ();
-       list<ArdourCanvas::SimpleLine*> feature_lines;
+
+
+       std::list<ArdourCanvas::SimpleLine*> feature_lines;
        ARDOUR::AnalysisFeatureList analysis_features;
        void reshow_feature_lines ();
 
index f4316efd879ec785692a84661a3bf6f18f9635d3..fa520f4ca1500269d0f68094a8cb4e6e3e631c65 100644 (file)
@@ -70,9 +70,9 @@ double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
  * @param duration the duration of this item
  */
 TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color, 
-                                  nframes_t start, nframes_t duration,
+                                  nframes_t start, nframes_t duration, bool recording,
                                   Visibility vis)
-       : trackview (tv)
+       : trackview (tv), _recregion(recording)
 {
        if (!have_name_font) {
 
@@ -151,7 +151,7 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo
        vestigial_frame->property_x1() = (double) 0.0;
        vestigial_frame->property_y1() = (double) 1.0;
        vestigial_frame->property_x2() = 2.0;
-       vestigial_frame->property_y2() = (double) trackview.height;
+       vestigial_frame->property_y2() = (double) trackview.current_height();
        vestigial_frame->property_outline_what() = 0xF;
        vestigial_frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
        vestigial_frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
@@ -162,7 +162,7 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo
                frame->property_x1() = (double) 0.0;
                frame->property_y1() = (double) 1.0;
                frame->property_x2() = (double) trackview.editor.frame_to_pixel(duration);
-               frame->property_y2() = (double) trackview.height;
+               frame->property_y2() = (double) trackview.current_height();
                frame->property_outline_what() = 0xF;
                frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
                frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
@@ -198,8 +198,8 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo
                        name_highlight->property_x1() = (double) 1.0;
                        name_highlight->property_x2() = (double) (trackview.editor.frame_to_pixel(item_duration)) - 1;
                }
-               name_highlight->property_y1() = (double) (trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE);
-               name_highlight->property_y2() = (double) (trackview.height - 1);
+               name_highlight->property_y1() = (double) (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE);
+               name_highlight->property_y2() = (double) (trackview.current_height() - 1);
                name_highlight->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightFill.get();
                name_highlight->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightOutline.get();
 
@@ -212,10 +212,10 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo
        if (visibility & ShowNameText) {
                name_text = new ArdourCanvas::Text (*group);
                name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET;
-               /* trackview.height is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
+               /* trackview.current_height() is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
                   then NAME_Y_OFFSET to position the text in the vertical center of the highlight
                */
-               name_text->property_y() = (double) trackview.height - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
+               name_text->property_y() = (double) trackview.current_height() - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
                name_text->property_font_desc() = *NAME_FONT;
                name_text->property_anchor() = Gtk::ANCHOR_NW;
 
@@ -804,8 +804,13 @@ TimeAxisViewItem::set_frame_color()
                        UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a);
                        frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
                } else {
-                       UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
-                       frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
+                       if (_recregion) {
+                               UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_RecordingRect.get(), &r, &g, &b, &a);
+                               frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
+                       } else {
+                               UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
+                               frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
+                       }
                }
        }
 }
@@ -1049,3 +1054,4 @@ TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
        item = 0;
        return false;
 }
+
index 18d6638738cab141d121db24249593da17462e28..02becad3e758dc8fd745d8b8237896ecbe24fdd6 100644 (file)
@@ -201,8 +201,8 @@ class TimeAxisViewItem : public Selectable
      */
     void set_name_text(const Glib::ustring& new_name) ;
     
-    virtual void set_y_position_and_height(double y, double h) ;
-    
+    void    set_y_position_and_height (double, double);    
+
     /**
      * 
      */
@@ -291,6 +291,7 @@ class TimeAxisViewItem : public Selectable
      * the destructor, this allows us to capture the source of the deletion
      * event
      */
+
     sigc::signal<void,std::string,void*> ItemRemoved ;
     
     /** Emitted when the name/Id of this item is changed */
@@ -311,8 +312,6 @@ class TimeAxisViewItem : public Selectable
     /** Emitted when the mionimum item duration is changed */
     sigc::signal<void,nframes_t,void*> MinDurationChanged ;
     
-  protected:
-    
     enum Visibility {
            ShowFrame = 0x1,
            ShowNameHighlight = 0x2,
@@ -323,7 +322,7 @@ class TimeAxisViewItem : public Selectable
            HideFrameTB = 0x40,
            FullWidthNameHighlight = 0x80
     };
-
+  protected:
     /**
      * Constructs a new TimeAxisViewItem.
      *
@@ -336,7 +335,7 @@ class TimeAxisViewItem : public Selectable
      * @param duration the duration of this item
      */
     TimeAxisViewItem(const std::string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color, 
-                    nframes_t start, nframes_t duration, Visibility v = Visibility (0));
+                    nframes_t start, nframes_t duration, bool recording = false, Visibility v = Visibility (0));
 
     TimeAxisViewItem (const TimeAxisViewItem& other);
 
@@ -462,6 +461,8 @@ class TimeAxisViewItem : public Selectable
     std::map<Glib::ustring::size_type,int> name_text_size_cache;
     
     Visibility visibility;
+       bool _recregion;
+
 
 }; /* class TimeAxisViewItem */
 
index 6ebedaa129583820af32cf7d4ae64076d7f957a6..37a0ade3fe120e98d62481b6ebe25447b41f89fa 100644 (file)
@@ -20,6 +20,8 @@
 #include <unistd.h>
 #include <cstdio> /* for snprintf, grrr */
 
+#include <glibmm/miscutils.h>
+
 #include <pbd/failed_constructor.h>
 #include <pbd/xml++.h>
 #include <pbd/filesystem.h>
@@ -148,12 +150,10 @@ UIConfiguration::save_state()
 {
        XMLTree tree;
 
-       try
-       {
+       try {
                sys::create_directories (user_config_directory ());
        }
-       catch (const sys::filesystem_error& ex)
-       {
+       catch (const sys::filesystem_error& ex) {
                error << "Could not create user configuration directory" << endmsg;
                return -1;
        }
index a52969268adb0b18b74efaab1f3e15d8b621f801..9008f8b8cd943aae0d71aa1b30f78da711220a65 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <gtkmm2ext/utils.h>
 #include <ardour/configuration.h>
+#include <ardour/configuration.h>
 
 #include <ardour/filesystem_paths.h>
 
@@ -469,39 +470,10 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
                   it does allow.
                */
 
-               int fakekey = GDK_VoidSymbol;
-               int ret = false;
-
-               switch (ev->keyval) {
-               case GDK_Tab:
-               case GDK_ISO_Left_Tab:
-                       fakekey = GDK_nabla;
-                       break;
-
-               case GDK_Up:
-                       fakekey = GDK_uparrow;
-                       break;
-
-               case GDK_Down:
-                       fakekey = GDK_downarrow;
-                       break;
-
-               case GDK_Right:
-                       fakekey = GDK_rightarrow;
-                       break;
-
-               case GDK_Left:
-                       fakekey = GDK_leftarrow;
-                       break;
-
-               default:
-                       break;
-               }
+               uint32_t fakekey = ev->keyval;
 
-               if (fakekey != GDK_VoidSymbol) {
-                       ret = gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state));
-                       
-                       if (ret) {
+               if (possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
+                       if (gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state))) {
                                return true;
                        }
 
@@ -590,18 +562,30 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
 Glib::RefPtr<Gdk::Pixbuf>      
 get_xpm (std::string name)
 {
-       SearchPath spath(ARDOUR::ardour_search_path());
-       spath += ARDOUR::system_data_search_path();
+       if (!xpm_map[name]) {
 
-       spath.add_subdirectory_to_paths("pixmaps");
+               SearchPath spath(ARDOUR::ardour_search_path());
+               spath += ARDOUR::system_data_search_path();
+               
+               spath.add_subdirectory_to_paths("pixmaps");
+               
+               sys::path data_file_path;
+               
+               if (!find_file_in_search_path (spath, name, data_file_path)) {
+                       fatal << string_compose (_("cannot find XPM file for %1"), name) << endmsg;
+                       /*NOTREACHED*/
+               }
 
-       sys::path data_file_path;
+               try {
+                       xpm_map[name] = Gdk::Pixbuf::create_from_file (data_file_path.to_string());
+               }
 
-       if(!find_file_in_search_path (spath, name, data_file_path)) {
-               fatal << string_compose (_("cannot find XPM file for %1"), name) << endmsg;
+               catch(const Glib::Error& e)     {
+                       warning << "Caught Glib::Error: " << e.what() << endmsg;
+               }
        }
 
-       return Gdk::Pixbuf::create_from_file (data_file_path.to_string());
+       return xpm_map[name];
 }
 
 Glib::RefPtr<Gdk::Pixbuf>      
@@ -738,3 +722,42 @@ reset_dpi ()
        DPIReset();//Emit Signal
 }
 
+bool
+possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval)
+{
+       int fakekey = GDK_VoidSymbol;
+
+       switch (keyval) {
+       case GDK_Tab:
+       case GDK_ISO_Left_Tab:
+               fakekey = GDK_nabla;
+               break;
+               
+       case GDK_Up:
+               fakekey = GDK_uparrow;
+               break;
+               
+       case GDK_Down:
+               fakekey = GDK_downarrow;
+               break;
+               
+       case GDK_Right:
+               fakekey = GDK_rightarrow;
+               break;
+               
+       case GDK_Left:
+               fakekey = GDK_leftarrow;
+               break;
+               
+       default:
+               break;
+       }
+       
+       if (fakekey != GDK_VoidSymbol) {
+               keyval = fakekey;
+               return true;
+       } 
+
+       return false;
+}
+               
index 4cf8fc371ba617056c3c2b0f9df041ddc4e9ca83..29c6bda403026c3041c07ddfbae28b04b2116d51 100644 (file)
@@ -76,6 +76,7 @@ bool canvas_item_visible (ArdourCanvas::Item* item);
 void set_color (Gdk::Color&, int);
 
 bool key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev);
+bool possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval);
 
 Glib::RefPtr<Gdk::Pixbuf> get_xpm (std::string);
 Glib::RefPtr<Gdk::Pixbuf> get_icon (const char*);
index 83b95bb5d2750bc779d60302d42a5161b63cf908..8a707183cdaa26907687f0ba520d92e23e35d1d4 100644 (file)
@@ -101,7 +101,7 @@ VisualTimeAxis::VisualTimeAxis(const string & name, PublicEditor& ed, ARDOUR::Se
        hide_button.unset_flags(Gtk::CAN_FOCUS) ;
        visual_button.unset_flags(Gtk::CAN_FOCUS) ;
        
-       set_height(Normal) ;
+       set_height (hNormal) ;
 }
 
 /**
@@ -144,39 +144,25 @@ VisualTimeAxis::name() const
 /**
  * Sets the height of this TrackView to one of the defined TrackHeghts
  *
- * @param h the TrackHeight value to set
+ * @param h 
  */
 void
-VisualTimeAxis::set_height(TrackHeight h)
+VisualTimeAxis::set_height(uint32_t h)
 {
-       TimeAxisView::set_height(h) ;
+       TimeAxisView::set_height(h);
        
-       switch (height)
-       {
-               case Largest:
-               case Large:
-               case Larger:
-               case Normal:
-               {
-                       hide_name_label ();
-                       show_name_entry ();
-                       other_button_hbox.show_all() ;
-                       break;
-               }
-               case Smaller:
-               {
-                       hide_name_label ();
-                       show_name_entry ();
-                       other_button_hbox.hide_all() ;
-                       break;
-               }
-               case Small:
-               {
-                       hide_name_entry ();
-                       show_name_label ();
-                       other_button_hbox.hide_all() ;
-               }
-               break;
+       if (h >= hNormal) {
+               hide_name_label ();
+               show_name_entry ();
+               other_button_hbox.show_all() ;
+       } else if (h >= hSmaller) {
+               hide_name_label ();
+               show_name_entry ();
+               other_button_hbox.hide_all() ;
+       } else if (h >= hSmall) {
+               hide_name_entry ();
+               show_name_label ();
+               other_button_hbox.hide_all() ;
        }
 }
 
index 6d1396bc54a2e1b6c70fa398ca554c726e412ee5..a0dfe654de246f2f12d6a57bd46f2d0faf48d36a 100644 (file)
@@ -93,9 +93,9 @@ class VisualTimeAxis : public TimeAxisView
                /**
                 * Sets the height of this TrackView to one of the defined TrackHeghts
                 *
-                * @param h the TrackHeight value to set
+                * @param h the number of pixels to set the height to
                 */
-               virtual void set_height (TrackHeight h);        
+               virtual void set_height (uint32_t);     
 
                //---------------------------------------------------------------------------------------//
                // Selection Methods
index 9244877d29f27e9e9d52ae753b82bebe2f74a21c..aaf57f233de261515c033c9bcc0728017c540e64 100644 (file)
@@ -328,6 +328,46 @@ bool               CAAudioUnit::CanDo (    int                             inChannelsIn,
        return ValidateChannelPair (inChannelsIn, inChannelsOut, info.mChanInfo, (dataSize / sizeof (AUChannelInfo)));
 }
 
+int    CAAudioUnit::GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt)
+{
+       // this is the default assumption of an audio effect unit
+       Boolean* isWritable = 0;
+       UInt32  dataSize = 0;
+               // lets see if the unit has any channel restrictions
+       OSStatus result = AudioUnitGetPropertyInfo (AU(),
+                                                   kAudioUnitProperty_SupportedNumChannels,
+                                                   kAudioUnitScope_Global, 0,
+                                                   &dataSize, isWritable); //don't care if this is writable
+       
+       // if this property is NOT implemented an FX unit
+       // is expected to deal with same channel valance in and out
+       
+       if (result) 
+       {
+               if (Comp().Desc().IsEffect()) 
+               {
+                       return 1;
+               }
+               else 
+               {
+                       // the au should either really tell us about this
+                       // or we will assume the worst
+                       return -1;
+               }
+       }
+
+       *chaninfo = (AUChannelInfo*) malloc (dataSize);
+       cnt = dataSize / sizeof (AUChannelInfo);
+
+       result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
+                             kAudioUnitScope_Global, 0,
+                             *chaninfo, &dataSize);
+
+       if (result) { return -1; }
+       return 0;
+}
+
+
 bool   CAAudioUnit::ValidateChannelPair (int                           inChannelsIn, 
                                                                                int                             inChannelsOut,
                                                                                const AUChannelInfo * info,
index 6bc31bf30ba66ebafd04d30745d527c5cb081e72..810b81be2fa5ccda5c09ddf9a0fc7ff632a91111 100644 (file)
@@ -218,6 +218,7 @@ public:
        bool                                    HasChannelLayouts (AudioUnitScope               inScope, 
                                                                                        AudioUnitElement                inEl) const;
                
+       int                                     GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt);
        bool                                    GetChannelLayouts (AudioUnitScope               inScope,
                                                                        AudioUnitElement                                inEl,
                                                                        ChannelTagVector                                &outChannelVector) const;
index bddca040321884364299aa632b96267e8f8ef648..c4f65ec81ed4fd784d4999089cb13cefbf8987bf 100644 (file)
@@ -7,7 +7,7 @@ import glob
 appleutility_files = glob.glob('*.cpp') 
 
 Import('env install_prefix')
-appleutility = env.Copy()
+appleutility = env.Clone()
 
 appleutility.Append(LINKFLAGS='-framework AudioToolbox')
 appleutility.Append(LINKFLAGS='-framework AudioUnit')
index 44f4718384666b2bf0652d9404b340060f9d8514..ca6fc0553ed31db2c9951139b6d55c4ba1a86f88 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env final_prefix install_prefix final_config_prefix libraries i18n')
 
-ardour = env.Copy()
+ardour = env.Clone()
 
 #
 # this defines the version number of libardour
@@ -95,6 +95,7 @@ mtc_slave.cc
 midi_clock_slave.cc
 named_selection.cc
 note.cc
+onset_detector.cc
 panner.cc
 parameter.cc
 pcm_utils.cc
@@ -357,7 +358,7 @@ env['BUILDERS']['SharedAsmObject'] = Builder (action = '$CXX -c -fPIC $SOURCE -o
 
 
 always_sse_objects = []
-sse_env = ardour.Copy()
+sse_env = ardour.Clone()
 sse_env.Append (CXXFLAGS="-msse")
 
 if env['FPU_OPTIMIZATION']:
index fecd0fcf4eb3b5947481d3f99cd4d30bfb40a3df..fd873f9a6ffad4c06cfb6a2610e1d0b814af34ea 100644 (file)
@@ -32,6 +32,8 @@
 #include <ardour/configuration.h>
 #include <ardour/types.h>
 
+// #include <jack/jack.h> need this to inline jack_get_microseconds
+
 namespace MIDI {
        class MachineControl;
        class Port;
@@ -57,7 +59,12 @@ namespace ARDOUR {
        const layer_t max_layer = UCHAR_MAX;
 
        microseconds_t get_microseconds ();
-
+/*     {
+        JACK has exported this functionality for a long time now 
+       but inlining this causes problems
+        return (microseconds_t) jack_get_time();
+       }
+*/
        Change new_change ();
 
        extern Change StartChanged;
index 3546545329e5f8f683f31109b529a69993fcf975..fe7dcb58ff8a8a9a58678d9b0d3e4518a9b40d8a 100644 (file)
@@ -58,8 +58,8 @@ class AudioTrack : public Track
        void freeze (InterThreadInfo&);
        void unfreeze ();
 
-       void bounce (InterThreadInfo&);
-       void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
+       boost::shared_ptr<Region> bounce (InterThreadInfo&);
+       boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
 
        int set_state(const XMLNode& node);
 
index dc9a52d5d3c8d2336a0f3afe83170080a56a4cf4..497954092fcbd0a84eed493786bd912c171b8504 100644 (file)
@@ -100,11 +100,12 @@ class AUPlugin : public ARDOUR::Plugin
     
        bool has_editor () const;
        
-       bool fixed_io() const { return false; }
-       int32_t can_support_input_configuration (int32_t in);
-       int32_t compute_output_streams (int32_t nplugins);
-       uint32_t output_streams() const;
-       uint32_t input_streams() const;
+       bool reconfigurable_io() const { return true; }
+       bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+       int32_t count_for_configuration (const ChanCount& in, ChanCount out) const;
+       bool configure_io (ChanCount in, ChanCount& out);
+       ChanCount output_streams() const;
+       ChanCount input_streams() const;
 
        boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
        boost::shared_ptr<CAComponent> get_comp () const { return comp; }
@@ -118,18 +119,19 @@ class AUPlugin : public ARDOUR::Plugin
         boost::shared_ptr<CAComponent> comp;
         boost::shared_ptr<CAAudioUnit> unit;
 
-       AudioStreamBasicDescription streamFormat;
         bool initialized;
-        int format_set;
+       int32_t input_channels;
+       int32_t output_channels;
+       std::vector<std::pair<int,int> > io_configs;
        AudioBufferList* buffers;
        
        UInt32 global_elements;
        UInt32 output_elements;
        UInt32 input_elements;
        
-       int set_output_format ();
-       int set_input_format ();
-       int set_stream_format (int scope, uint32_t cnt);
+       int set_output_format (AudioStreamBasicDescription&);
+       int set_input_format (AudioStreamBasicDescription&);
+       int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
         int _set_block_size (nframes_t nframes);
        void discover_parameters ();
 
@@ -142,10 +144,15 @@ class AUPlugin : public ARDOUR::Plugin
        
        std::vector<AUParameterDescriptor> descriptors;
        void init ();
+
 };
        
 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
 
+struct AUPluginCachedInfo { 
+       std::vector<std::pair<int,int> > io_configs;
+};
+
 class AUPluginInfo : public PluginInfo {
   public:      
         AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
@@ -153,16 +160,29 @@ class AUPluginInfo : public PluginInfo {
 
        PluginPtr load (Session& session);
 
+       AUPluginCachedInfo cache;
+
        static PluginInfoList discover ();
        static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker);
         static std::string stringify_descriptor (const CAComponentDescription&);
 
+       static int load_cached_info ();
+
   private:
        boost::shared_ptr<CAComponentDescription> descriptor;
+       UInt32 version;
 
        static void discover_music (PluginInfoList&);
        static void discover_fx (PluginInfoList&);
        static void discover_by_description (PluginInfoList&, CAComponentDescription&);
+       static Glib::ustring au_cache_path ();
+
+       typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
+       static CachedInfoMap cached_info;
+       
+       static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
+       static void add_cached_info (const std::string&, AUPluginCachedInfo&);
+       static void save_cached_info ();
 };
 
 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
index e1d5e50cc22f96a73190fde0d34f45f6f071639f..89abc6669ac272400517aecd320fb526509ff70a 100644 (file)
@@ -130,13 +130,13 @@ class AudioEngine : public sigc::trackable
        
        const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags);
 
-       uint32_t n_physical_outputs () const;
-       uint32_t n_physical_inputs () const;
-
        bool can_request_hardware_monitoring ();
 
-       void get_physical_outputs (std::vector<std::string>&);
-       void get_physical_inputs (std::vector<std::string>&);
+       uint32_t n_physical_outputs (DataType type) const;
+       uint32_t n_physical_inputs (DataType type) const;
+
+       void get_physical_outputs (DataType type, std::vector<std::string>&);
+       void get_physical_inputs (DataType type, std::vector<std::string>&);
 
        std::string get_nth_physical_output (DataType type, uint32_t n) {
                return get_nth_physical (type, n, JackPortIsInput);
@@ -152,7 +152,7 @@ class AudioEngine : public sigc::trackable
 
        /** Caller may not delete the object pointed to by the return value
        */
-       Port *get_port_by_name (const std::string& name, bool keep = true) const;
+       Port *get_port_by_name (const std::string& name, bool keep = true);
 
        enum TransportState {
                TransportStopped = JackTransportStopped,
@@ -204,27 +204,28 @@ class AudioEngine : public sigc::trackable
        std::string make_port_name_non_relative (std::string);
 
   private:
-       ARDOUR::Session *session;
-       jack_client_t *_jack;
-       std::string jack_client_name;
-       mutable Glib::Mutex _process_lock;
-       Glib::Cond session_removed;
-       bool session_remove_pending;
-       bool _running;
-       bool _has_run;
-       nframes_t _buffer_size;
-       nframes_t _frame_rate;
+       ARDOUR::Session*           session;
+       jack_client_t*            _jack;
+       std::string                jack_client_name;
+       Glib::Mutex               _process_lock;
+       Glib::Cond                 session_removed;
+       bool                       session_remove_pending;
+       bool                      _running;
+       bool                      _has_run;
+       nframes_t                 _buffer_size;
+       nframes_t                 _frame_rate;
        /// number of frames between each check for changes in monitor input
-       nframes_t monitor_check_interval;
+       nframes_t                  monitor_check_interval;
        /// time of the last monitor check in frames
-       nframes_t last_monitor_check;
+       nframes_t                  last_monitor_check;
        /// the number of frames processed since start() was called
-       nframes_t _processed_frames;
-       bool _freewheeling;
-       bool _freewheel_thread_registered;
-       sigc::slot<int,nframes_t> freewheel_action;
-       bool reconnect_on_halt;
-       int _usecs_per_cycle;
+       nframes_t                 _processed_frames;
+       bool                      _freewheeling;
+       bool                      _freewheel_pending;
+       bool                      _freewheel_thread_registered;
+       sigc::slot<int,nframes_t>  freewheel_action;
+       bool                       reconnect_on_halt;
+       int                       _usecs_per_cycle;
 
        SerializedRCUManager<Ports> ports;
 
index 685a083e8d787db43e7775769c51403ca0f28dea..9df26a449b359ad58e5f9a3587716b271ccbbe89 100644 (file)
@@ -32,7 +32,7 @@ class AutoBundle : public Bundle {
        AutoBundle (bool i = true);
        AutoBundle (std::string const &, bool i = true);
 
-       uint32_t nchannels () const;
+       ChanCount nchannels () const;
        const PortList& channel_ports (uint32_t) const;
 
        void set_channels (uint32_t);
index fd943602262572704cfde72ba156a3200b8c75b6..72df6c7fd6323ace8ae4501fb33c3cfc921941d3 100644 (file)
 
 #include <cstdlib>
 #include <cassert>
+#include <cstring>
 #include <iostream>
 #include <boost/utility.hpp>
+
 #include <ardour/types.h>
 #include <ardour/data_type.h>
 #include <ardour/runtime_functions.h>
index ba92063b309dbbc00a9e656f3f1664d9b0a22353..46ba13152e689d45acd724f5ca76102c49be735a 100644 (file)
@@ -22,7 +22,9 @@
 
 #include <string>
 #include <sigc++/signal.h>
+
 #include "ardour/data_type.h"
+#include "ardour/chan_count.h"
 
 namespace ARDOUR {
 
@@ -37,12 +39,13 @@ class Bundle {
        Bundle () : _type (DataType::AUDIO) {}
        Bundle (bool i) : _type (DataType::AUDIO), _ports_are_inputs (i) {}
        Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {}
+
        virtual ~Bundle() {}
 
        /**
         *  @return Number of channels that this Bundle has.
         */
-       virtual uint32_t nchannels () const = 0;
+       virtual ChanCount nchannels () const = 0;
        virtual const PortList& channel_ports (uint32_t) const = 0;
 
        void set_name (std::string const & n) {
index 7a7a2ce41923cfeff685ef030277753d278acbcc..1f455dc308037786725da27d416bca39d7326435 100644 (file)
@@ -124,6 +124,7 @@ CONFIG_VARIABLE (bool, quieten_at_speed, "quieten-at-speed", true)
 CONFIG_VARIABLE (bool, primary_clock_delta_edit_cursor, "primary-clock-delta-edit-cursor", false)
 CONFIG_VARIABLE (bool, secondary_clock_delta_edit_cursor, "secondary-clock-delta-edit-cursor", false)
 CONFIG_VARIABLE (bool, show_track_meters, "show-track-meters", true)
+CONFIG_VARIABLE (bool, locate_while_waiting_for_sync, "locate-while-waiting-for-sync", false)
 
 /* timecode and sync */
 
@@ -159,6 +160,7 @@ CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", tru
 CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi")
 CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour")
 CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false)
+CONFIG_VARIABLE (bool, name_new_markers, "name-new-markers", false)
 CONFIG_VARIABLE (bool, rubberbanding_snaps_to_grid, "rubberbanding-snaps-to-grid", false)
 CONFIG_VARIABLE (long, font_scale, "font-scale", 102400)
 
index 83b6378daee4a93f22b2fe3b6843672be14bb76a..b44e131d8aa8bdaf4df90742770d9dd21c40ebda 100644 (file)
@@ -368,6 +368,7 @@ class IO : public Automatable, public Latent
 
        int create_ports (const XMLNode&);
        int make_connections (const XMLNode&);
+       boost::shared_ptr<Bundle> find_possible_bundle (const string &desired_name, const string &default_name, const string &connection_type_name);
 
        void setup_peak_meters ();
        void meter ();
index e19c0a51ca33e95509b2219ddbf9b19b577368d8..112f306ccb98db6b74bbdaff70921b568f68ac92 100644 (file)
@@ -40,6 +40,7 @@ public:
        void reset ();
        void reset_max ();
        
+       bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; }
        bool configure_io (ChanCount in, ChanCount out);
        
        /** Compute peaks */
index 500502ac4b6cf81812677bdcae2297f0852168fe..6e4677df22372ccae5697305a598d26356305bb3 100644 (file)
@@ -65,8 +65,8 @@ public:
        void freeze (InterThreadInfo&);
        void unfreeze ();
 
-       void bounce (InterThreadInfo&);
-       void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
+       boost::shared_ptr<Region> bounce (InterThreadInfo&);
+       boost::shared_ptr<Region>  bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
 
        int set_state(const XMLNode& node);
 
diff --git a/libs/ardour/ardour/onset_detector.h b/libs/ardour/ardour/onset_detector.h
new file mode 100644 (file)
index 0000000..9243653
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+    Copyright (C) 2008 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.
+
+*/
+
+#ifndef __ardour_onset_detector_h__
+#define __ardour_onset_detector_h__
+
+#include <ardour/audioanalyser.h>
+
+namespace ARDOUR {
+
+class AudioSource;
+class Session;
+
+class OnsetDetector : public AudioAnalyser
+{
+
+  public:
+    OnsetDetector (float sample_rate);
+    ~OnsetDetector();
+
+    static std::string operational_identifier();
+
+    void set_silence_threshold (float);
+    void set_peak_threshold (float);
+    void set_function (int);
+
+    int run (const std::string& path, Readable*, uint32_t channel, AnalysisFeatureList& results);
+
+    static void cleanup_onsets (AnalysisFeatureList&, float sr, float gap_msecs);
+    
+  protected:
+    AnalysisFeatureList* current_results;
+    int use_features (Vamp::Plugin::FeatureSet&, std::ostream*);
+
+    static std::string _op_id;
+};
+
+} /* namespace */
+
+#endif /* __ardour_audioanalyser_h__ */
index 3f1ce03445f50c975d906dd9e618fe7df2788375..d7c2f4bd85154075f93dd1e04322ef93e4f7fbf6 100644 (file)
@@ -54,12 +54,13 @@ class OSC : public BasicUI, public sigc::trackable
        lo_server _osc_server;
        lo_server _osc_unix_server;
        std::string _osc_unix_socket_path;
-   std::string _osc_url_file;
+       std::string _osc_url_file;
        pthread_t _osc_thread;
        int _request_pipe[2];
 
        static void * _osc_receiver(void * arg);
        void osc_receiver();
+       void send(); // This should accept an OSC payload
 
        bool init_osc_thread ();
        void terminate_osc_thread ();
@@ -69,6 +70,11 @@ class OSC : public BasicUI, public sigc::trackable
 
        void session_going_away ();
 
+       // Handlers for "Application Hook" signals
+       void session_loaded( ARDOUR::Session& );
+       void session_exported( std::string, std::string );
+       // end "Application Hook" handles
+
        std::string get_server_url ();
        std::string get_unix_server_url ();
 
@@ -101,18 +107,19 @@ class OSC : public BasicUI, public sigc::trackable
        PATH_CALLBACK(rec_enable_toggle);
        PATH_CALLBACK(toggle_all_rec_enables);
 
-#define PATH_CALLBACK1(name,type) \
+#define PATH_CALLBACK1(name,type,optional)                                     \
         static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
                return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
         } \
         int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \
-                if (argc > 0) { \
-                       name (argv[0]->type); \
-                }\
-               return 0; \
+                if (argc > 0) {                                                \
+                       name (optional argv[0]->type);          \
+                }                                                      \
+               return 0;                                               \
        }
 
-       PATH_CALLBACK1(set_transport_speed,f);
+       PATH_CALLBACK1(set_transport_speed,f,);
+       PATH_CALLBACK1(access_action,s,&);
 };
 
 }
index 73f89f1a918f6221ab70b0f81c94d76cd701f4d3..fec044e88511bc2f5113e5b4651ef68900b691f7 100644 (file)
@@ -145,6 +145,33 @@ class Plugin : public PBD::StatefulDestructible, public Latent
 
        virtual bool has_editor() const = 0;
 
+       sigc::signal<void,uint32_t,float> ParameterChanged;
+
+       /* NOTE: this block of virtual methods looks like the interface
+          to a Processor, but Plugin does not inherit from Processor.
+          It is therefore not required that these precisely match
+          the interface, but it is likely that they will evolve together.
+       */
+
+       /* this returns true if the plugin can change its inputs or outputs on demand.
+          LADSPA, LV2 and VST plugins cannot do this. AudioUnits can.
+       */
+
+       virtual bool reconfigurable_io() const { return false; }
+
+       /* this is only called if reconfigurable_io() returns true */
+       virtual bool configure_io (ChanCount in, ChanCount out) { return true; }
+
+       /* specific types of plugins can overload this. As of September 2008, only
+          AUPlugin does this.
+       */
+       virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return false; }
+       virtual ChanCount output_streams() const;
+       virtual ChanCount input_streams() const;
+
+       PBD::Controllable *get_nth_control (uint32_t, bool do_not_create = false);
+       void make_nth_control (uint32_t, const XMLNode&);
+
        PluginInfoPtr get_info() { return _info; }
        void set_info (const PluginInfoPtr inf) { _info = inf; }
 
index 42c53c487c8663e6b1c27ab2f62fd4365f3be7bf..c19d1132569de3fca4b762e7ab9fc8869bd29882 100644 (file)
@@ -69,13 +69,12 @@ class PluginInsert : public Processor
        bool     set_count (uint32_t num);
        uint32_t get_count () const { return _plugins.size(); }
 
-       virtual bool      can_support_input_configuration (ChanCount in) const;
-       virtual ChanCount output_for_input_configuration (ChanCount in) const;
-       virtual bool      configure_io (ChanCount in, ChanCount out);
+       bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+       bool configure_io (ChanCount in, ChanCount out);
 
        bool is_generator() const;
 
-       void set_parameter (Parameter param, float val);
+       void  set_parameter (Parameter param, float val);
        float get_parameter (Parameter param);
 
        float default_parameter_value (Parameter param);
index 892c8bd75ac7572b1de095ae5f13b5d792908841..858decd0e5faf819e931b92b710f3b9d43ac16ee 100644 (file)
@@ -23,6 +23,7 @@
 #include <list>
 #include <map>
 #include <string>
+#include <set>
 
 #include <ardour/types.h>
 #include <ardour/plugin.h>
@@ -54,7 +55,31 @@ class PluginManager {
 
        static PluginManager* the_manager() { return _manager; }
 
+       void load_favorites ();
+       void save_favorites ();
+       void add_favorite (ARDOUR::PluginType type, std::string unique_id);
+       void remove_favorite (ARDOUR::PluginType type, std::string unique_id);
+       bool is_a_favorite_plugin (const PluginInfoPtr&);
+       
   private:
+       struct FavoritePlugin {
+           ARDOUR::PluginType type;
+           std::string unique_id;
+
+           FavoritePlugin (ARDOUR::PluginType t, std::string id) 
+           : type (t), unique_id (id) {}
+           
+           bool operator==(const FavoritePlugin& other) const {
+                   return other.type == type && other.unique_id == unique_id;
+           }
+
+           bool operator<(const FavoritePlugin& other) const {
+                   return other.type < type || other.unique_id < unique_id;
+           }
+       };
+       typedef std::set<FavoritePlugin> FavoritePluginList;
+       FavoritePluginList favorites;
+
        ARDOUR::PluginInfoList _vst_plugin_info;
        ARDOUR::PluginInfoList _ladspa_plugin_info;
        ARDOUR::PluginInfoList _lv2_plugin_info;
index 93c34da16d9c28d3e0dd915354b268856c7022b6..084022541d3993d3c9639237215e87f0dbc501a8 100644 (file)
@@ -23,7 +23,7 @@
 #include <set>
 #include <vector>
 #include <string>
-
+#include <cstring>
 #include <sigc++/signal.h>
 #include <pbd/failed_constructor.h>
 #include <ardour/ardour.h>
index 1743040bf57945415308c92a93d8c277b5ba9ed0..72f02ff9c746de036923f8dd01de3092104ff995 100644 (file)
@@ -58,9 +58,8 @@ class PortInsert : public IOProcessor
        ChanCount output_streams() const;
        ChanCount input_streams() const;
 
-       virtual bool      can_support_input_configuration (ChanCount in) const;
-       virtual ChanCount output_for_input_configuration (ChanCount in) const;
-       virtual bool      configure_io (ChanCount in, ChanCount out);
+       bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; }
+       bool configure_io (ChanCount in, ChanCount out);
 
        uint32_t bit_slot() const { return bitslot; }
 
index d3e95e8ebffb553cfbd4fee4c70a69ba976b8006..8c4ac8dfe52751c0bc78838a8f7b7876c28e9a61 100644 (file)
@@ -80,7 +80,7 @@ class Processor : public Automatable, public Latent
        virtual void activate () { _active = true; ActiveChanged.emit(); }
        virtual void deactivate () { _active = false; ActiveChanged.emit(); }
        
-       virtual bool configure_io (ChanCount in, ChanCount out) { _configured_input = in; return (_configured = true); }
+       virtual bool configure_io (ChanCount in, ChanCount out);
 
        /* Derived classes should override these, or processor appears as an in-place pass-through */
 
@@ -91,8 +91,7 @@ class Processor : public Automatable, public Latent
         * and write to their output parameter */
        virtual bool is_out_of_place () const { return false; }
 
-       virtual bool      can_support_input_configuration (ChanCount in) const { return true; }
-       virtual ChanCount output_for_input_configuration (ChanCount in) const { return in; }
+       virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const = 0;
        virtual ChanCount output_streams() const { return _configured_input; }
        virtual ChanCount input_streams () const { return _configured_input; }
 
index c7c0b77102f441b5d9c72369a621ff632ac932cb..fb98cb57a7cbbdb1adb434f4454c40c72b7080da 100644 (file)
@@ -359,8 +359,8 @@ class Route : public IO
        void input_change_handler (IOChange, void *src);
        void output_change_handler (IOChange, void *src);
 
-       int reset_plugin_counts (ProcessorStreams*); /* locked */
-       int _reset_plugin_counts (ProcessorStreams*); /* unlocked */
+       int reset_processor_counts (ProcessorStreams*); /* locked */
+       int _reset_processor_counts (ProcessorStreams*); /* unlocked */
 
        /* processor I/O channels and plugin count handling */
 
@@ -372,8 +372,8 @@ class Route : public IO
            ProcessorCount (boost::shared_ptr<ARDOUR::Processor> ins) : processor(ins) {}
        };
        
-       int32_t apply_some_plugin_counts (std::list<ProcessorCount>& iclist);
-       bool    check_some_plugin_counts (std::list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err_streams);
+       int32_t apply_some_processor_counts (std::list<ProcessorCount>& iclist);
+       bool    check_some_processor_counts (std::list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err_streams);
 
        void set_deferred_state ();
        void add_processor_from_xml (const XMLNode&);
index 1ee8bbceca3890c33a1a1a30311f134876e27eef..d5078bd7df566f81bf1bae9ba6beb84924f41207 100644 (file)
@@ -57,16 +57,17 @@ class Send : public IOProcessor
        int set_state(const XMLNode& node);
 
        uint32_t pans_required() const { return _configured_input.n_audio(); }
+       void expect_inputs (const ChanCount&);
 
-       virtual bool      can_support_input_configuration (ChanCount in) const;
-       virtual ChanCount output_for_input_configuration (ChanCount in) const;
-       virtual bool      configure_io (ChanCount in, ChanCount out);
+       bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+       bool configure_io (ChanCount in, ChanCount out);
 
        static uint32_t how_many_sends();
 
   private:
        bool      _metering;
-       uint32_t bitslot;
+       ChanCount expected_inputs;
+       uint32_t  bitslot;
 };
 
 } // namespace ARDOUR
index 00cbc9922e6708b49ff432664b06ae3c7260a9f7..08315c3010614ef958e4a178384ff78c7e93adab 100644 (file)
@@ -434,15 +434,18 @@ class Session : public PBD::StatefulDestructible
        nframes_t worst_input_latency () const { return _worst_input_latency; }
        nframes_t worst_track_latency () const { return _worst_track_latency; }
 
-       int save_state (string snapshot_name, bool pending = false);
-       int restore_state (string snapshot_name);
-       int save_template (string template_name);
-       int save_history (string snapshot_name = "");
-       int restore_history (string snapshot_name);
-       void remove_state (string snapshot_name);
-       void rename_state (string old_name, string new_name);
+       int save_state (std::string snapshot_name, bool pending = false);
+       int restore_state (std::string snapshot_name);
+       int save_template (std::string template_name);
+       int save_history (std::string snapshot_name = "");
+       int restore_history (std::string snapshot_name);
+       void remove_state (std::string snapshot_name);
+       void rename_state (std::string old_name, std::string new_name);
        void remove_pending_capture_state ();
 
+       static int rename_template (std::string old_name, std::string new_name);
+       static int delete_template (std::string name);
+
        sigc::signal<void,string> StateSaved;
        sigc::signal<void> StateReady;
 
@@ -579,7 +582,7 @@ class Session : public PBD::StatefulDestructible
        sigc::signal<void,std::vector<boost::weak_ptr<Region> >& > RegionsAdded;
        sigc::signal<void,boost::weak_ptr<Region> > RegionRemoved;
 
-       int region_name (string& result, string base = string(""), bool newlevel = false) const;
+       int region_name (string& result, string base = string(""), bool newlevel = false);
        string new_region_name (string);
        string path_from_region_name (DataType type, string name, string identifier);
 
@@ -616,9 +619,11 @@ class Session : public PBD::StatefulDestructible
        SlaveSource post_export_slave;
        nframes_t post_export_position;
 
-       int start_export (ARDOUR::ExportSpecification&);
-       int stop_export (ARDOUR::ExportSpecification&);
-       void finalize_audio_export ();
+       int  pre_export ();
+       int  start_export (ARDOUR::ExportSpecification&);
+       int  stop_export (ARDOUR::ExportSpecification&);
+       void finalize_export ();
+       static sigc::signal<void, std::string, std::string> Exported;
 
        void add_source (boost::shared_ptr<Source>);
        void remove_source (boost::weak_ptr<Source>);
@@ -706,9 +711,8 @@ class Session : public PBD::StatefulDestructible
 
        /* flattening stuff */
 
-       int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite,
-                       vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot);
-
+       boost::shared_ptr<Region> write_one_track (AudioTrack&, nframes_t start, nframes_t end, bool overwrite, vector<boost::shared_ptr<Source> >&,
+                                                  InterThreadInfo& wot);
        int freeze (InterThreadInfo&);
 
        /* session-wide solo/mute/rec-enable */
@@ -910,7 +914,7 @@ class Session : public PBD::StatefulDestructible
        void reset_playback_load_min ();
        void reset_capture_load_min ();
 
-       float read_data_rate () const;
+       float read_data_rate () const; // in usec
        float write_data_rate () const;
 
        /* ranges */
@@ -1072,6 +1076,7 @@ class Session : public PBD::StatefulDestructible
        void set_slave_source (SlaveSource);
 
        bool _exporting;
+
        int prepare_to_export (ARDOUR::ExportSpecification&);
 
        void prepare_diskstreams ();
@@ -1393,6 +1398,7 @@ class Session : public PBD::StatefulDestructible
        void set_play_loop (bool yn);
        void overwrite_some_buffers (Diskstream*);
        void flush_all_inserts ();
+       int  micro_locate (nframes_t distance);
        void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
        void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
        void force_locate (nframes_t frame, bool with_roll = false);
@@ -1457,6 +1463,9 @@ class Session : public PBD::StatefulDestructible
 
        /* REGION MANAGEMENT */
 
+       std::map<std::string,uint32_t> region_name_map;
+       void update_region_name_map (boost::shared_ptr<Region>);
+
        mutable Glib::Mutex region_lock;
        typedef map<PBD::ID,boost::shared_ptr<Region> > RegionList;
        RegionList regions;
index 4d5545c0dc4c935a501007c9e866a994e559c899..fedd83ba68aa455415439237de3c143efbeca139 100644 (file)
@@ -76,8 +76,8 @@ class Track : public Route
        virtual void freeze (InterThreadInfo&) = 0;
        virtual void unfreeze () = 0;
 
-       virtual void bounce (InterThreadInfo&) = 0;
-       virtual void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0;
+       virtual boost::shared_ptr<Region> bounce (InterThreadInfo&) = 0;
+       virtual boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0;
 
        XMLNode&    get_state();
        XMLNode&    get_template();
index 954e93d5d14438b39d72a25b13ae777f1cfae30d..c33ddeaed9ba5e1cf1bc836f24003dea17e1f73a 100644 (file)
@@ -35,7 +35,7 @@ class UserBundle : public Bundle, public PBD::Stateful {
        UserBundle (std::string const &);
        UserBundle (XMLNode const &, bool);
 
-       uint32_t nchannels () const;
+       ChanCount nchannels () const;
        const ARDOUR::PortList& channel_ports (uint32_t) const;
 
        void add_channel ();
index 091e1df30f01b920521fab6c91149dd84c93170e..2953c9e074ae55a9faff41225f3432eedc22f57b 100644 (file)
@@ -399,7 +399,7 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram
        /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
 
        if (((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record)) || 
-           (((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled())))) {
+           ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
                
                /* starting to record: compute first+last frames */
 
@@ -524,7 +524,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
 
        commit_should_unlock = false;
 
-       if (!_io->active()) {
+       if (!_io || !_io->active()) {
                _processed = true;
                return 0;
        }
@@ -835,7 +835,7 @@ AudioDiskstream::commit (nframes_t nframes)
 {
        bool need_butler = false;
 
-       if (!_io->active()) {
+       if (!_io || !_io->active()) {
                return false;
        }
 
index a35846ab29e4bc28b21c6c62df2e95408c854be8..cd473d933feaab53b249d0274a4451ea46f88860 100644 (file)
@@ -22,6 +22,7 @@
 #include <libxml/uri.h>
 
 #include <lrdf.h>
+#include <glibmm/miscutils.h>
 
 #include <glibmm/convert.h>
 
@@ -52,6 +53,7 @@ AudioLibrary::AudioLibrary ()
        
        // workaround for possible bug in raptor that crashes when saving to a
        // non-existant file.
+
        touch_file(sfdb_file_path.to_string());
 
        lrdf_read_file(src.c_str());
index 53f918ec4ea94f245fe56233faef5d8c8bee820e..cd05e5fc86b6200c1d7fa52288bf111e657e0b46 100644 (file)
@@ -743,21 +743,18 @@ AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes
        return 0;
 }
 
-void
+boost::shared_ptr<Region>
 AudioTrack::bounce (InterThreadInfo& itt)
 {
        vector<boost::shared_ptr<Source> > srcs;
-       _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
-       itt.done = true;
+       return _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), false, srcs, itt);
 }
 
-
-void
+boost::shared_ptr<Region>
 AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
 {
        vector<boost::shared_ptr<Source> > srcs;
-       _session.write_one_audio_track (*this, start, end, false, srcs, itt);
-       itt.done = true;
+       return _session.write_one_track (*this, start, end, false, srcs, itt);
 }
 
 void
@@ -798,7 +795,9 @@ AudioTrack::freeze (InterThreadInfo& itt)
                return;
        }
 
-       if (_session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) {
+       boost::shared_ptr<Region> res;
+
+       if ((res = _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
                return;
        }
 
index b941bc10bbe4d705fdc6dc27f5a8db521d08e334..4862ddcd12fe410fe5e474fbad075c4c6b0105ad 100644 (file)
 #include <pbd/whitespace.h>
 
 #include <glibmm/thread.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
 
+#include <ardour/ardour.h>
 #include <ardour/audioengine.h>
 #include <ardour/io.h>
 #include <ardour/audio_unit.h>
@@ -43,6 +46,8 @@ using namespace std;
 using namespace PBD;
 using namespace ARDOUR;
 
+AUPluginInfo::CachedInfoMap AUPluginInfo::cached_info;
+
 static OSStatus 
 _render_callback(void *userData,
                 AudioUnitRenderActionFlags *ioActionFlags,
@@ -120,28 +125,12 @@ AUPlugin::init ()
        unit->GetElementCount (kAudioUnitScope_Input, input_elements);
        unit->GetElementCount (kAudioUnitScope_Output, output_elements);
 
-       // set up the basic stream format. these fields do not change
-                           
-       streamFormat.mSampleRate = _session.frame_rate();
-       streamFormat.mFormatID = kAudioFormatLinearPCM;
-       streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved;
-
-#ifdef __LITTLE_ENDIAN__
-       /* relax */
-#else
-       streamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian;
-#endif
-
-       streamFormat.mBitsPerChannel = 32;
-       streamFormat.mFramesPerPacket = 1;
-
-       // subject to later modification as we discover channel counts
-
-       streamFormat.mBytesPerPacket = 4;
-       streamFormat.mBytesPerFrame = 4;
-       streamFormat.mChannelsPerFrame = 1;
+       /* these keep track of *configured* channel set up,
+          not potential set ups.
+       */
 
-       format_set = 0;
+       input_channels = -1;
+       output_channels = -1;
 
        if (_set_block_size (_session.get_block_size())) {
                error << _("AUPlugin: cannot set processing block size") << endmsg;
@@ -396,42 +385,233 @@ AUPlugin::_set_block_size (nframes_t nframes)
        return 0;
 }
 
-int32_t 
-AUPlugin::can_support_input_configuration (int32_t in)
-{      
-       streamFormat.mChannelsPerFrame = in;
+int32_t
+AUPlugin::configure_io (ChanCount in, ChanCount out)
+{
+       AudioStreamBasicDescription streamFormat;
+
+       streamFormat.mSampleRate = _session.frame_rate();
+       streamFormat.mFormatID = kAudioFormatLinearPCM;
+       streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved;
+
+#ifdef __LITTLE_ENDIAN__
+       /* relax */
+#else
+       streamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+#endif
+
+       streamFormat.mBitsPerChannel = 32;
+       streamFormat.mFramesPerPacket = 1;
+
        /* apple says that for non-interleaved data, these
           values always refer to a single channel.
        */
        streamFormat.mBytesPerPacket = 4;
        streamFormat.mBytesPerFrame = 4;
 
-       if (set_input_format () == 0) {
-               return 1;
-       } else {
+       streamFormat.mChannelsPerFrame = in.n_audio();
+
+       if (set_input_format (streamFormat) != 0) {
+               return -1;
+       }
+
+       streamFormat.mChannelsPerFrame = out.n_audio();
+
+       if (set_output_format (streamFormat) != 0) {
                return -1;
        }
+
+       return Plugin::configure_io (in, out);
+}
+
+bool
+AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
+{
+       int32_t ret = count_for_configuration (in, out);
+       return ret >= 0;
+}
+
+int32_t
+AUPlugin::count_for_configuration(ChanCount cin, ChanCount& out) const
+{
+       // XXX as of May 13th 2008, AU plugin support returns a count of either 1 or -1. We never
+       // attempt to multiply-instantiate plugins to meet io configurations.
+
+       int32_t plugcnt = -1;
+       AUPluginInfoPtr pinfo = boost::dynamic_pointer_cast<AUPluginInfo>(get_info());
+       int32_t in = cin.n_audio(); /* XXX handle MIDI one day ??? */
+
+       vector<pair<int,int> >& io_configs = pinfo->cache.io_configs;
+
+       for (vector<pair<int,int> >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) {
+
+               int32_t possible_in = i->first;
+               int32_t possible_out = i->second;
+
+               if (possible_out == 0) {
+                       warning << string_compose (_("AU %1 has zero outputs - configuration ignored"), name()) << endmsg;
+                       continue;
+               }
+
+               if (possible_in == 0) {
+
+                       /* instrument plugin, always legal but throws away inputs ...
+                       */
+
+                       if (possible_out == -1) {
+                               /* out much match in (UNLIKELY!!) */
+                               out.set (DataType::AUDIO, in);
+                               plugcnt = 1;
+                       } else if (possible_out == -2) {
+                               /* any configuration possible, pick matching */
+                               out.set (DataType::AUDIO, in);
+                               plugcnt = 1;
+                       } else if (possible_out < -2) {
+                               /* explicit variable number of outputs, pick maximum */
+                               out.set (DataType::AUDIO, -possible_out);
+                               plugcnt = 1;
+                       } else {
+                               /* exact number of outputs */
+                               out.set (DataType::AUDIO, possible_out);
+                               plugcnt = 1;
+                       }
+               }
+               
+               if (possible_in == -1) {
+
+                       /* wildcard for input */
+
+                       if (possible_out == -1) {
+                               /* out much match in */
+                               out.set (DataType::AUDIO, in);
+                               plugcnt = 1;
+                       } else if (possible_out == -2) {
+                               /* any configuration possible, pick matching */
+                               out.set (DataType::AUDIO, in);
+                               plugcnt = 1;
+                       } else if (possible_out < -2) {
+                               /* explicit variable number of outputs, pick maximum */
+                               out.set (DataType::AUDIO, -possible_out);
+                               plugcnt = 1;
+                       } else {
+                               /* exact number of outputs */
+                               out.set (DataType::AUDIO, possible_out);
+                               plugcnt = 1;
+                       }
+               }       
+                       
+               if (possible_in == -2) {
+
+                       if (possible_out == -1) {
+                               /* any configuration possible, pick matching */
+                               out.set (DataType::AUDIO, in);
+                               plugcnt = 1;
+                       } else if (possible_out == -2) {
+                               error << string_compose (_("AU plugin %1 has illegal IO configuration (-2,-2)"), name())
+                                     << endmsg;
+                               plugcnt = -1;
+                       } else if (possible_out < -2) {
+                               /* explicit variable number of outputs, pick maximum */
+                               out.set (DataType::AUDIO, -possible_out);
+                               plugcnt = 1;
+                       } else {
+                               /* exact number of outputs */
+                               out.set (DataType::AUDIO, possible_out);
+                               plugcnt = 1;
+                       }
+               }
+
+               if (possible_in < -2) {
+
+                       /* explicit variable number of inputs */
+
+                       if (in > -possible_in) {
+                               /* request is too large */
+                               plugcnt = -1;
+                       }
+
+                       if (possible_out == -1) {
+                               /* out must match in */
+                               out.set (DataType::AUDIO, in);
+                               plugcnt = 1;
+                       } else if (possible_out == -2) {
+                               error << string_compose (_("AU plugin %1 has illegal IO configuration (-2,-2)"), name())
+                                     << endmsg;
+                               plugcnt = -1;
+                       } else if (possible_out < -2) {
+                               /* explicit variable number of outputs, pick maximum */
+                               out.set (DataType::AUDIO, -possible_out);
+                               plugcnt = 1;
+                       } else {
+                               /* exact number of outputs */
+                               out.set (DataType::AUDIO, possible_out);
+                               plugcnt = 1;
+                       }
+               }
+
+               if (possible_in == in) {
+
+                       /* exact number of inputs ... must match obviously */
+                       
+                       if (possible_out == -1) {
+                               /* out must match in */
+                               out.set (DataType::AUDIO, in);
+                               plugcnt = 1;
+                       } else if (possible_out == -2) {
+                               /* any output configuration, pick matching */
+                               out.set (DataType::AUDIO, in);
+                               plugcnt = -1;
+                       } else if (possible_out < -2) {
+                               /* explicit variable number of outputs, pick maximum */
+                               out.set (DataType::AUDIO, -possible_out);
+                               plugcnt = 1;
+                       } else {
+                               /* exact number of outputs */
+                               out.set (DataType::AUDIO, possible_out);
+                               plugcnt = 1;
+                       }
+               }
+
+       }
+
+       /* no fit */
+       return plugcnt;
 }
 
 int
-AUPlugin::set_input_format ()
+AUPlugin::set_input_format (AudioStreamBasicDescription& fmt)
 {
-       return set_stream_format (kAudioUnitScope_Input, input_elements);
+       return set_stream_format (kAudioUnitScope_Input, input_elements, fmt);
 }
 
 int
-AUPlugin::set_output_format ()
+AUPlugin::set_output_format (AudioStreamBasicDescription& fmt)
 {
-       return set_stream_format (kAudioUnitScope_Output, output_elements);
+       if (set_stream_format (kAudioUnitScope_Output, output_elements, fmt) != 0) {
+               return -1;
+       }
+
+       if (buffers) {
+               free (buffers);
+               buffers = 0;
+       }
+       
+       buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) + 
+                                             fmt.mChannelsPerFrame * sizeof(AudioBuffer));
+
+       Glib::Mutex::Lock em (_session.engine().process_lock());
+       IO::PortCountChanged (ChanCount (DataType::AUDIO, fmt.mChannelsPerFrame));
+
+       return 0;
 }
 
 int
-AUPlugin::set_stream_format (int scope, uint32_t cnt)
+AUPlugin::set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription& fmt)
 {
        OSErr result;
 
        for (uint32_t i = 0; i < cnt; ++i) {
-               if ((result = unit->SetFormat (scope, i, streamFormat)) != 0) {
+               if ((result = unit->SetFormat (scope, i, fmt)) != 0) {
                        error << string_compose (_("AUPlugin: could not set stream format for %1/%2 (err = %3)"),
                                                 (scope == kAudioUnitScope_Input ? "input" : "output"), i, result) << endmsg;
                        return -1;
@@ -439,60 +619,44 @@ AUPlugin::set_stream_format (int scope, uint32_t cnt)
        }
 
        if (scope == kAudioUnitScope_Input) {
-               format_set |= 0x1;
+               input_channels = fmt.mChannelsPerFrame;
        } else {
-               format_set |= 0x2;
+               output_channels = fmt.mChannelsPerFrame;
        }
 
        return 0;
 }
 
-int32_t 
-AUPlugin::compute_output_streams (int32_t nplugins)
-{
-       /* we will never replicate AU plugins - either they can do the I/O we need
-          or not. thus, we can ignore nplugins entirely.
-       */
-       
-       if (set_output_format() == 0) {
 
-               if (buffers) {
-                       free (buffers);
-                       buffers = 0;
-               }
-
-               buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) + 
-                                                     streamFormat.mChannelsPerFrame * sizeof(AudioBuffer));
-
-               Glib::Mutex::Lock em (_session.engine().process_lock());
-               IO::MoreOutputs (streamFormat.mChannelsPerFrame);
+ChanCount
+AUPlugin::input_streams() const
+{
+       ChanCount in;
 
-               return streamFormat.mChannelsPerFrame;
+       if (input_channels < 0) {
+               warning << string_compose (_("AUPlugin: %1 input_streams() called without any format set!"), name()) << endmsg;
+               in.set_audio (1);
        } else {
-               return -1;
+               in.set_audio (input_channels);
        }
+
+       return in;
 }
 
-uint32_t
+
+ChanCount
 AUPlugin::output_streams() const
 {
-       if (!(format_set & 0x2)) {
+       ChanCount out;
+
+       if (output_channels < 0) {
                warning << string_compose (_("AUPlugin: %1 output_streams() called without any format set!"), name()) << endmsg;
-               return 1;
+               out.set_audio (1);
+       } else {
+               out.set_audio (output_channels);
        }
 
-       return streamFormat.mChannelsPerFrame;
-}
-
-
-uint32_t
-AUPlugin::input_streams() const
-{
-       if (!(format_set & 0x1)) {
-               warning << _("AUPlugin: input_streams() called without any format set!") << endmsg;
-               return 1;
-       }
-       return streamFormat.mChannelsPerFrame;
+       return out;
 }
 
 OSStatus 
@@ -679,13 +843,25 @@ AUPluginInfo::load (Session& session)
        }
 
        catch (failed_constructor &err) {
-               return PluginPtr ((Plugin*) 0);
+               return PluginPtr ();
        }
 }
 
+Glib::ustring
+AUPluginInfo::au_cache_path ()
+{
+       return Glib::build_filename (ARDOUR::get_user_ardour_path(), "au_cache");
+}
+
 PluginInfoList
 AUPluginInfo::discover ()
 {
+       XMLTree tree;
+
+       if (!Glib::file_test (au_cache_path(), Glib::FILE_TEST_EXISTS)) {
+               ARDOUR::BootMessage (_("Discovering AudioUnit plugins (could take some time ...)"));
+       }
+
        PluginInfoList plugs;
        
        discover_fx (plugs);
@@ -839,17 +1015,211 @@ AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescrip
                info->type = ARDOUR::AudioUnit;
                info->unique_id = stringify_descriptor (*info->descriptor);
 
-               /* mark the plugin as having flexible i/o */
+               /* XXX not sure of the best way to handle plugin versioning yet
+                */
+
+               CAComponent cacomp (*info->descriptor);
+
+               if (cacomp.GetResourceVersion (info->version) != noErr) {
+                       info->version = 0;
+               }
                
-               info->n_inputs = -1;
-               info->n_outputs = -1;
+               if (cached_io_configuration (info->unique_id, info->version, cacomp, info->cache, info->name)) {
+
+                       /* here we have to map apple's wildcard system to a simple pair
+                          of values.
+                       */
+
+                       info->n_inputs = ChanCount (DataType::AUDIO, info->cache.io_configs.front().first);
+                       info->n_outputs = ChanCount (DataType::AUDIO, info->cache.io_configs.front().second);
+
+                       if (info->cache.io_configs.size() > 1) {
+                               cerr << "ODD: variable IO config for " << info->unique_id << endl;
+                       }
+
+                       plugs.push_back (info);
 
-               plugs.push_back (info);
+               } else {
+                       error << string_compose (_("Cannot get I/O configuration info for AU %1"), info->name) << endmsg;
+               }
                
                comp = FindNextComponent (comp, &desc);
        }
 }
 
+bool
+AUPluginInfo::cached_io_configuration (const std::string& unique_id, 
+                                      UInt32 version,
+                                      CAComponent& comp, 
+                                      AUPluginCachedInfo& cinfo, 
+                                      const std::string& name)
+{
+       std::string id;
+       char buf[32];
+
+       /* concatenate unique ID with version to provide a key for cached info lookup.
+          this ensures we don't get stale information, or should if plugin developers
+          follow Apple "guidelines".
+        */
+
+       snprintf (buf, sizeof (buf), "%u", version);
+       id = unique_id;
+       id += '/';
+       id += buf;
+
+       CachedInfoMap::iterator cim = cached_info.find (id);
+
+       if (cim != cached_info.end()) {
+               cinfo = cim->second;
+               return true;
+       }
+
+       CAAudioUnit unit;
+       AUChannelInfo* channel_info;
+       UInt32 cnt;
+       int ret;
+       
+       ARDOUR::BootMessage (string_compose (_("Checking AudioUnit: %1"), name));
+       
+       if (CAAudioUnit::Open (comp, unit) != noErr) {
+               return false;
+       }
+
+       if ((ret = unit.GetChannelInfo (&channel_info, cnt)) < 0) {
+               return false;
+       }
+
+       if (ret > 0) {
+               /* no explicit info available */
+
+               cinfo.io_configs.push_back (pair<int,int> (-1, -1));
+
+       } else {
+               
+               /* store each configuration */
+               
+               for (uint32_t n = 0; n < cnt; ++n) {
+                       cinfo.io_configs.push_back (pair<int,int> (channel_info[n].inChannels,
+                                                                  channel_info[n].outChannels));
+               }
+
+               free (channel_info);
+       }
+
+       add_cached_info (id, cinfo);
+       save_cached_info ();
+
+       return true;
+}
+
+void
+AUPluginInfo::add_cached_info (const std::string& id, AUPluginCachedInfo& cinfo)
+{
+       cached_info[id] = cinfo;
+}
+
+void
+AUPluginInfo::save_cached_info ()
+{
+       XMLNode* node;
+
+       node = new XMLNode (X_("AudioUnitPluginCache"));
+       
+       for (map<string,AUPluginCachedInfo>::iterator i = cached_info.begin(); i != cached_info.end(); ++i) {
+               XMLNode* parent = new XMLNode (X_("plugin"));
+               parent->add_property ("id", i->first);
+               node->add_child_nocopy (*parent);
+
+               for (vector<pair<int, int> >::iterator j = i->second.io_configs.begin(); j != i->second.io_configs.end(); ++j) {
+
+                       XMLNode* child = new XMLNode (X_("io"));
+                       char buf[32];
+
+                       snprintf (buf, sizeof (buf), "%d", j->first);
+                       child->add_property (X_("in"), buf);
+                       snprintf (buf, sizeof (buf), "%d", j->second);
+                       child->add_property (X_("out"), buf);
+                       parent->add_child_nocopy (*child);
+               }
+
+       }
+
+       Glib::ustring path = au_cache_path ();
+       XMLTree tree;
+
+       tree.set_root (node);
+
+       if (!tree.write (path)) {
+               error << string_compose (_("could not save AU cache to %1"), path) << endmsg;
+               unlink (path.c_str());
+       }
+}
+
+int
+AUPluginInfo::load_cached_info ()
+{
+       Glib::ustring path = au_cache_path ();
+       XMLTree tree;
+       
+       if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
+               return 0;
+       }
+
+       tree.read (path);
+       const XMLNode* root (tree.root());
+
+       if (root->name() != X_("AudioUnitPluginCache")) {
+               return -1;
+       }
+
+       cached_info.clear ();
+
+       const XMLNodeList children = root->children();
+
+       for (XMLNodeConstIterator iter = children.begin(); iter != children.end(); ++iter) {
+               
+               const XMLNode* child = *iter;
+               
+               if (child->name() == X_("plugin")) {
+
+                       const XMLNode* gchild;
+                       const XMLNodeList gchildren = child->children();
+                       const XMLProperty* prop = child->property (X_("id"));
+
+                       if (!prop) {
+                               continue;
+                       }
+
+                       std::string id = prop->value();
+                       
+                       for (XMLNodeConstIterator giter = gchildren.begin(); giter != gchildren.end(); giter++) {
+
+                               gchild = *giter;
+
+                               if (gchild->name() == X_("io")) {
+
+                                       int in;
+                                       int out;
+                                       const XMLProperty* iprop;
+                                       const XMLProperty* oprop;
+
+                                       if (((iprop = gchild->property (X_("in"))) != 0) &&
+                                           ((oprop = gchild->property (X_("out"))) != 0)) {
+                                               in = atoi (iprop->value());
+                                               out = atoi (iprop->value());
+                                               
+                                               AUPluginCachedInfo cinfo;
+                                               cinfo.io_configs.push_back (pair<int,int> (in, out));
+                                               add_cached_info (id, cinfo);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
 void
 AUPluginInfo::get_names (CAComponentDescription& comp_desc, std::string& name, Glib::ustring& maker)
 {
index a3f5eb9fd11e3090ab8a71655e4f893b850eaa9a..76c0de9b242bedde7f08c1b0881541802b8556f6 100644 (file)
@@ -70,13 +70,12 @@ AudioEngine::AudioEngine (string client_name)
        last_monitor_check = 0;
        monitor_check_interval = max_frames;
        _processed_frames = 0;
-       _freewheeling = false;
        _usecs_per_cycle = 0;
        _jack = 0;
        _frame_rate = 0;
        _buffer_size = 0;
-       _freewheeling = false;
        _freewheel_thread_registered = false;
+       _freewheeling = false;
 
        m_meter_thread = 0;
        g_atomic_int_set (&m_meter_exit, 0);
@@ -84,6 +83,7 @@ AudioEngine::AudioEngine (string client_name)
        if (connect_to_jack (client_name)) {
                throw NoBackendAvailable ();
        }
+
        Port::set_engine (this);
 }
 
@@ -331,8 +331,6 @@ AudioEngine::process_callback (nframes_t nframes)
        if (_freewheeling) {
                /* emit the Freewheel signal and stop freewheeling in the event of trouble */
                if (Freewheel (nframes)) {
-                       cerr << "Freewheeling returned non-zero!\n";
-                       _freewheeling = false;
                        jack_set_freewheel (_jack, false);
                }
 
@@ -847,7 +845,7 @@ AudioEngine::frames_per_cycle ()
  * Note this can return NULL, it will NOT create a port if it is not found (any more).
  */
 Port *
-AudioEngine::get_port_by_name (const string& portname, bool keep) const
+AudioEngine::get_port_by_name (const string& portname, bool keep)
 {
        Glib::Mutex::Lock lm (_process_lock);
 
@@ -923,7 +921,7 @@ AudioEngine::can_request_hardware_monitoring ()
 
 
 uint32_t
-AudioEngine::n_physical_outputs () const
+AudioEngine::n_physical_outputs (DataType type) const
 {
        const char ** ports;
        uint32_t i = 0;
@@ -932,7 +930,7 @@ AudioEngine::n_physical_outputs () const
                return 0;
        }
 
-       if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
+       if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsInput)) == 0) {
                return 0;
        }
 
@@ -943,7 +941,7 @@ AudioEngine::n_physical_outputs () const
 }
 
 uint32_t
-AudioEngine::n_physical_inputs () const
+AudioEngine::n_physical_inputs (DataType type) const
 {
        const char ** ports;
        uint32_t i = 0;
@@ -952,7 +950,7 @@ AudioEngine::n_physical_inputs () const
                return 0;
        }
        
-       if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
+       if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsOutput)) == 0) {
                return 0;
        }
 
@@ -964,7 +962,7 @@ AudioEngine::n_physical_inputs () const
 }
 
 void
-AudioEngine::get_physical_inputs (vector<string>& ins)
+AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
 {
        const char ** ports;
        uint32_t i = 0;
@@ -973,7 +971,7 @@ AudioEngine::get_physical_inputs (vector<string>& ins)
                return;
        }
        
-       if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
+       if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsOutput)) == 0) {
                return;
        }
 
@@ -986,7 +984,7 @@ AudioEngine::get_physical_inputs (vector<string>& ins)
 }
 
 void
-AudioEngine::get_physical_outputs (vector<string>& outs)
+AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
 {
        const char ** ports;
        uint32_t i = 0;
@@ -995,7 +993,7 @@ AudioEngine::get_physical_outputs (vector<string>& outs)
                return;
        }
        
-       if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
+       if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsInput)) == 0) {
                return;
        }
 
@@ -1123,11 +1121,18 @@ AudioEngine::freewheel (bool onoff)
 {
        if (_jack) {
 
-               if (onoff) {
-                       _freewheel_thread_registered = false;
-               }
+               if (onoff != _freewheeling) {
 
-               return jack_set_freewheel (_jack, onoff);
+                       if (onoff) {
+                               _freewheel_thread_registered = false;
+                       }
+
+                       return jack_set_freewheel (_jack, onoff);
+
+               } else {
+                       /* already doing what has been asked for */
+                       return 0;
+               }
 
        } else {
                return -1;
index f5f04eac6dbad1deb6ab2c8a85f98d96a284db55..cbf2e44c5f3aaf312721c7e844d3f3736f3b956c 100644 (file)
@@ -1243,6 +1243,15 @@ AudioRegion::speed_mismatch (float sr) const
 void
 AudioRegion::source_offset_changed ()
 {
+       /* XXX this fixes a crash that should not occur. It does occur
+          becauses regions are not being deleted when a session
+          is unloaded. That bug must be fixed.
+       */
+
+       if (_sources.empty()) {
+               return;
+       }
+
        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
 
        if (afs && afs->destructive()) {
index 01dea08d3e2fc15f48e74c3e30bf872c538f95a8..8e68b315877e0b87e0499db9f6bcc5e8113a947e 100644 (file)
@@ -214,7 +214,7 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path)
                
                /* we found it in the peaks dir, so check it out */
                
-               if (statbuf.st_size == 0 || (statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
+               if (statbuf.st_size == 0 || ((nframes_t) statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
                        // empty
                        _peaks_built = false;
                } else {
index 9da32bbb7af2fd0ff854bd5d083002477dbe4b8c..fc7076860158c227fb8f8af066dfa053904e01be 100644 (file)
@@ -13,17 +13,17 @@ ARDOUR::AutoBundle::AutoBundle (std::string const & n, bool i)
        
 }
 
-uint32_t
+ARDOUR::ChanCount
 ARDOUR::AutoBundle::nchannels () const
 {
        Glib::Mutex::Lock lm (_ports_mutex);
-       return _ports.size ();
+       return ChanCount (type(), _ports.size ());
 }
 
 const ARDOUR::PortList&
 ARDOUR::AutoBundle::channel_ports (uint32_t c) const
 {
-       assert (c < nchannels());
+       assert (c < nchannels().get (type()));
 
        Glib::Mutex::Lock lm (_ports_mutex);
        return _ports[c];
@@ -39,7 +39,7 @@ ARDOUR::AutoBundle::set_channels (uint32_t n)
 void
 ARDOUR::AutoBundle::set_port (uint32_t c, std::string const & p)
 {
-       assert (c < nchannels ());
+       assert (c < nchannels ().get (type()));
 
        Glib::Mutex::Lock lm (_ports_mutex);
        _ports[c].resize (1);
index b164d418abcd2daa33b05462f376dd220e001589..56dfd99f024729cf26201bb02f7e72da5e8ee374 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <glib.h>  
 #include <glib/gstdio.h> /* for g_stat() */
+#include <glibmm/miscutils.h>
 
 #include <pbd/failed_constructor.h>
 #include <pbd/xml++.h>
index f3dfa28165c089339433c5f6d41d14545ff46dee..213e7504b0f5f997d69d699edc9fe622192ec510 100644 (file)
@@ -84,7 +84,6 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
 {
        _in = in;
        _out = out;
-
        _anchor_point = ap;
        _follow_overlap = false;
 
index 1397a7d959e199a3cecb5920d9193df567dddf0f..3401d8c48a2d3977fb1289cb0790c5cf60f2800c 100644 (file)
 #include <fst.h>
 #endif
 
+#ifdef HAVE_AUDIOUNITS
+#include <ardour/audio_unit.h>
+#endif
+
 #ifdef __SSE__
 #include <xmmintrin.h>
 #endif
@@ -347,6 +351,10 @@ ARDOUR::init (bool use_vst, bool try_optimization)
        }
 #endif
 
+#ifdef HAVE_AUDIOUNITS
+       AUPluginInfo::load_cached_info ();
+#endif
+
        /* Make VAMP look in our library ahead of anything else */
 
        char *p = getenv ("VAMP_PATH");
@@ -393,11 +401,7 @@ ARDOUR::cleanup ()
 microseconds_t
 ARDOUR::get_microseconds ()
 {
-       /* XXX need JACK to export its functionality */
-
-       struct timeval now;
-       gettimeofday (&now, 0);
-       return now.tv_sec * 1000000ULL + now.tv_usec;
+       return (microseconds_t) jack_get_time ();
 }
 
 ARDOUR::Change
@@ -431,7 +435,6 @@ void
 ARDOUR::find_bindings_files (map<string,string>& files)
 {
        vector<sys::path> found;
-
        SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
 
        if (getenv ("ARDOUR_SAE")) {
index d79c930e6dd8f3186b317303e2e44808833d81a2..d4afda8b5a3a39df2c114549892029a86bfe7658 100644 (file)
@@ -459,15 +459,16 @@ Session::import_audiofiles (import_status& status)
                        if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
                                afs->update_header(0, *now, xnow);
                                afs->done_with_peakfile_writes ();
-                       }
-                       
-                       /* now that there is data there, requeue the file for analysis */
                        
-                       if (Config->get_auto_analyse_audio()) {
-                               Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
+                               /* now that there is data there, requeue the file for analysis */
+                               
+                               if (Config->get_auto_analyse_audio()) {
+                                       Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
+                               }
                        }
-
+                       
                        /* don't create tracks for empty MIDI sources (channels) */
+
                        if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
                                x = all_new_sources.erase(x);
                        } else {
index 5d4b41cf3231ad08deb9780a78735a9a377c493e..1b3c2e237808c85c14c4d902e1e5189cd48d4cd7 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <sigc++/bind.h>
 
+#include <glibmm.h>
 #include <glibmm/thread.h>
 
 #include <pbd/xml++.h>
@@ -358,14 +359,16 @@ IO::check_bundles (std::vector<UserBundleInfo>& list, const PortSet& ports)
        
        for (std::vector<UserBundleInfo>::iterator i = list.begin(); i != list.end(); ++i) {
 
-               uint32_t const N = i->bundle->nchannels ();
+               ChanCount const N = i->bundle->nchannels ();
 
-               if (ports.num_ports() < N) {
+               if (ports.num_ports (default_type()) < N.get (default_type())) {
                        continue;
                }
 
                bool ok = true;
-               for (uint32_t j = 0; j < N; ++j) {
+               uint32_t n = N.get (default_type());
+
+               for (uint32_t j = 0; j < n; ++j) {
                        /* Every port on bundle channel j must be connected to our input j */
                        PortList const pl = i->bundle->channel_ports (j);
                        for (uint32_t k = 0; k < pl.size(); ++k) {
@@ -730,7 +733,7 @@ IO::add_input_port (string source, void* src, DataType type)
                { 
                        Glib::Mutex::Lock lm (io_lock);
 
-                       if (n_inputs() >= _input_maximum) {
+                       if (_input_maximum.get(type) >= 0 && n_inputs().get (type) >= _input_maximum.get (type)) {
                                return -1;
                        }
 
@@ -1460,16 +1463,12 @@ IO::load_automation (string path)
        float version;
        LocaleGuard lg (X_("POSIX"));
 
-       fullpath = _session.automation_dir();
-       fullpath += path;
+       fullpath = Glib::build_filename(_session.automation_dir(), path);
 
        in.open (fullpath.c_str());
 
        if (!in) {
-               fullpath = _session.automation_dir();
-               fullpath += _session.snap_name();
-               fullpath += '-';
-               fullpath += path;
+               fullpath = Glib::build_filename(_session.automation_dir(), _session.snap_name() + '-' + path);
 
                in.open (fullpath.c_str());
 
@@ -1573,23 +1572,138 @@ IO::ports_became_legal ()
        return ret;
 }
 
+boost::shared_ptr<Bundle>
+IO::find_possible_bundle (const string &desired_name, const string &default_name, const string &bundle_type_name) 
+{
+       static const string digits = "0123456789";
+
+       boost::shared_ptr<Bundle> c = _session.bundle_by_name (desired_name);
+
+       if (!c) {
+               int bundle_number, mask;
+               string possible_name;
+               bool stereo = false;
+               string::size_type last_non_digit_pos;
+
+               error << string_compose(_("Unknown bundle \"%1\" listed for %2 of %3"), desired_name, bundle_type_name, _name)
+                     << endmsg;
+
+               // find numeric suffix of desired name
+               bundle_number = 0;
+               
+               last_non_digit_pos = desired_name.find_last_not_of(digits);
+
+               if (last_non_digit_pos != string::npos) {
+                       stringstream s;
+                       s << desired_name.substr(last_non_digit_pos);
+                       s >> bundle_number;
+               }
+       
+               // see if it's a stereo connection e.g. "in 3+4"
+
+               if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
+                       int left_bundle_number = 0;
+                       string::size_type left_last_non_digit_pos;
+
+                       left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
+
+                       if (left_last_non_digit_pos != string::npos) {
+                               stringstream s;
+                               s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
+                               s >> left_bundle_number;
+
+                               if (left_bundle_number > 0 && left_bundle_number + 1 == bundle_number) {
+                                       bundle_number--;
+                                       stereo = true;
+                               }
+                       }
+               }
+
+               // make 0-based
+               if (bundle_number)
+                       bundle_number--;
+
+               // find highest set bit
+               mask = 1;
+               while ((mask <= bundle_number) && (mask <<= 1));
+               
+               // "wrap" bundle number into largest possible power of 2 
+               // that works...
+
+               while (mask) {
+
+                       if (bundle_number & mask) {
+                               bundle_number &= ~mask;
+                               
+                               stringstream s;
+                               s << default_name << " " << bundle_number + 1;
+
+                               if (stereo) {
+                                       s << "+" << bundle_number + 2;
+                               }
+                               
+                               possible_name = s.str();
+
+                               if ((c = _session.bundle_by_name (possible_name)) != 0) {
+                                       break;
+                               }
+                       }
+                       mask >>= 1;
+               }
+               if (c) {
+                       info << string_compose (_("Bundle %1 was not available - \"%2\" used instead"), desired_name, possible_name)
+                            << endmsg;
+               } else {
+                       error << string_compose(_("No %1 bundles available as a replacement"), bundle_type_name)
+                             << endmsg;
+               }
+
+       }
+
+       return c;
+
+}
+
 int
 IO::create_ports (const XMLNode& node)
 {
        XMLProperty const * prop;
-       int num_inputs = 0;
-       int num_outputs = 0;
+       ChanCount num_inputs;
+       ChanCount num_outputs;
+
+       if ((prop = node.property ("input-connection")) != 0) {
 
-       if ((prop = node.property ("inputs")) != 0) {
-               num_inputs = count (prop->value().begin(), prop->value().end(), '{');
+               boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
+               
+               if (!c) {
+                       return -1;
+               } 
+
+               num_inputs = c->nchannels();
+
+       } else if ((prop = node.property ("inputs")) != 0) {
+
+               num_inputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
+       }
+       
+       if ((prop = node.property ("output-connection")) != 0) {
+
+               boost::shared_ptr<Bundle> c = find_possible_bundle(prop->value(), _("out"), _("output"));
+
+               if (!c) {
+                       return -1;
+               } 
+
+               num_outputs = c->nchannels ();
+               
        } else if ((prop = node.property ("outputs")) != 0) {
-               num_outputs = count (prop->value().begin(), prop->value().end(), '{');
+
+               num_outputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
        }
 
        no_panner_reset = true;
 
-       // FIXME: audio-only
-       if (ensure_io (ChanCount(DataType::AUDIO, num_inputs), ChanCount(DataType::AUDIO, num_outputs), true, this)) {
+       if (ensure_io (num_inputs, num_outputs, true, this)) {
                error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
                return -1;
        }
@@ -1606,17 +1720,35 @@ IO::create_ports (const XMLNode& node)
 int
 IO::make_connections (const XMLNode& node)
 {
-       XMLProperty const * prop;
-       
-       if ((prop = node.property ("inputs")) != 0) {
+
+       const XMLProperty* prop;
+
+       if ((prop = node.property ("input-connection")) != 0) {
+               boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
+               
+               if (!c) {
+                       return -1;
+               } 
+
+               connect_input_ports_to_bundle (c, this);
+
+       } else if ((prop = node.property ("inputs")) != 0) {
                if (set_inputs (prop->value())) {
                        error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
                        return -1;
                }
        }
 
-                               
-       if ((prop = node.property ("outputs")) != 0) {
+       if ((prop = node.property ("output-connection")) != 0) {
+               boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("out"), _("output"));
+               
+               if (!c) {
+                       return -1;
+               } 
+               
+               connect_output_ports_to_bundle (c, this);
+               
+       } else if ((prop = node.property ("outputs")) != 0) {
                if (set_outputs (prop->value())) {
                        error << string_compose(_("improper output channel list in XML node (%1)"), prop->value()) << endmsg;
                        return -1;
@@ -1628,23 +1760,19 @@ IO::make_connections (const XMLNode& node)
                if ((*i)->name() == "InputBundle") {
                        XMLProperty const * prop = (*i)->property ("name");
                        if (prop) {
-                               boost::shared_ptr<Bundle> b = _session.bundle_by_name (prop->value());
+                               boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("in"), _("input"));
                                if (b) {
                                        connect_input_ports_to_bundle (b, this);
-                               } else {
-                                       error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
                                }
                        }
                        
                } else if ((*i)->name() == "OutputBundle") {
                        XMLProperty const * prop = (*i)->property ("name");
                        if (prop) {
-                               boost::shared_ptr<Bundle> b = _session.bundle_by_name (prop->value());
+                               boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("out"), _("output"));
                                if (b) {
                                        connect_output_ports_to_bundle (b, this);
-                               } else {
-                                       error << string_compose(_("Unknown bundle \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
-                               }
+                               } 
                        }
                }
        }
@@ -1924,9 +2052,10 @@ IO::connect_input_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
                /* Connect to the bundle, not worrying about any connections
                   that are already made. */
 
-               uint32_t const channels = c->nchannels ();
-               
-               for (uint32_t n = 0; n < channels; ++n) {
+               ChanCount const channels = c->nchannels ();
+               uint32_t cnt = channels.get (default_type());
+
+               for (uint32_t n = 0; n < cnt; ++n) {
                        const PortList& pl = c->channel_ports (n);
 
                        for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
@@ -1973,9 +2102,10 @@ IO::connect_output_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
                /* Connect to the bundle, not worrying about any connections
                   that are already made. */
 
-               uint32_t const channels = c->nchannels ();
+               ChanCount const channels = c->nchannels ();
+               uint32_t cnt = channels.get (default_type());
 
-               for (uint32_t n = 0; n < channels; ++n) {
+               for (uint32_t n = 0; n < cnt; ++n) {
 
                        const PortList& pl = c->channel_ports (n);
 
@@ -2105,8 +2235,8 @@ IO::GainControl::get_value (void) const
 void
 IO::setup_peak_meters()
 {
-       ChanCount max_streams = std::max(_inputs.count(), _outputs.count());
-       _meter->configure_io(max_streams, max_streams);
+       ChanCount max_streams = std::max (_inputs.count(), _outputs.count());
+       _meter->configure_io (max_streams, max_streams);
 }
 
 /**
@@ -2496,11 +2626,12 @@ void
 IO::maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
 {
        boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b);
+
        if (ab == 0 || ab->ports_are_outputs() == false) {
                return;
        }
-
-       if (ab->nchannels () != n_inputs().n_total ()) {
+       
+       if (ab->nchannels().get (default_type()) != n_inputs().n_total ()) {
                return;
        }
 
@@ -2552,7 +2683,7 @@ IO::maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<bo
                return;
        }
 
-       if (ab->nchannels () != n_outputs().n_total ()) {
+       if (ab->nchannels ().get (default_type()) != n_outputs().n_total ()) {
                return;
        }
 
index 0da75810ca4fd4c1661f89b031b2ea9c59fd7d98..3654e03a9dcd7ab8081b272390c412e1fe8d7483 100644 (file)
@@ -100,6 +100,7 @@ Location::set_start (nframes_t s)
                        _end = s;
 
                        start_changed(this); /* EMIT SIGNAL */
+                       end_changed(this); /* EMIT SIGNAL */
 
                        if ( is_start() ) {
 
@@ -137,7 +138,17 @@ Location::set_end (nframes_t e)
                if (_start != e) {
                        _start = e;
                        _end = e;
+                       start_changed(this); /* EMIT SIGNAL */
                        end_changed(this); /* EMIT SIGNAL */
+
+                       if ( is_start() ) {
+                               Session::StartTimeChanged (); /* EMIT SIGNAL */
+                       }
+
+                       if ( is_end() ) {
+                               Session::EndTimeChanged (); /* EMIT SIGNAL */
+                       }
+
                }
                return 0;
        }
index 4553458831d25e7abde7ddb8f784d5d3c60461e0..a38c851c215055707c7d29437937be0bc7ecb0cb 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <cstdlib>
 #include <cmath>
+#include <cstring>
 
 #include <pbd/compose.h>
 #include <pbd/error.h>
index e75c1d89caf5cad0ba0d428ffa9b1b90b643b2ec..aedfd17be865201fa1340f17c59089591478c9d2 100644 (file)
@@ -95,8 +95,9 @@ bool
 PeakMeter::configure_io (ChanCount in, ChanCount out)
 {
        /* we're transparent no matter what.  fight the power. */
-       if (out != in)
+       if (out != in) {
                return false;
+       }
 
        uint32_t limit = in.n_total();
 
@@ -116,9 +117,7 @@ PeakMeter::configure_io (ChanCount in, ChanCount out)
        assert(_visible_peak_power.size() == limit);
        assert(_max_peak_power.size() == limit);
 
-       Processor::configure_io(in, out);
-
-       return true;
+       return Processor::configure_io (in, out);
 }
 
 /** To be driven by the Meter signal from IO.
index 1000e68ba67bec35f0fe60541f331b8e53088440..efb6e5b8d9090bb8a32dd36736addbb799bfd32f 100644 (file)
@@ -661,21 +661,23 @@ MidiTrack::set_latency_delay (nframes_t longest_session_latency)
        _diskstream->set_roll_delay (_roll_delay);
 }
 
-void
+boost::shared_ptr<Region>
 MidiTrack::bounce (InterThreadInfo& itt)
 {
        throw;
-       //vector<MidiSource*> srcs;
-       //_session.write_one_midi_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
+       // vector<MidiSource*> srcs;
+       // return _session.write_one_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
+       return boost::shared_ptr<Region> ();
 }
 
 
-void
+boost::shared_ptr<Region>
 MidiTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
 {
        throw;
        //vector<MidiSource*> srcs;
-       //_session.write_one_midi_track (*this, start, end, false, srcs, itt);
+       //return _session.write_one_track (*this, start, end, false, srcs, itt);
+       return boost::shared_ptr<Region> ();
 }
 
 void
@@ -732,7 +734,7 @@ MidiTrack::MidiControl::set_value(float val)
        size_t size = 3;
 
        if ( ! _list->automation_playback()) {
-               uint8_t ev[3] = { _list->parameter().channel(), int(val), 0.0 };
+               uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 };
                switch(_list->parameter().type()) {
                case MidiCCAutomation:
                        ev[0] += MIDI_CMD_CONTROL;
diff --git a/libs/ardour/onset_detector.cc b/libs/ardour/onset_detector.cc
new file mode 100644 (file)
index 0000000..f58e64a
--- /dev/null
@@ -0,0 +1,126 @@
+#include <ardour/onset_detector.h>
+
+#include "i18n.h"
+
+using namespace Vamp;
+using namespace ARDOUR;
+using namespace std;
+
+/* need a static initializer function for this */
+
+string OnsetDetector::_op_id = X_("libardourvampplugins:aubioonset:2");
+
+OnsetDetector::OnsetDetector (float sr)
+       : AudioAnalyser (sr, X_("libardourvampplugins:aubioonset"))
+{
+       /* update the op_id */
+
+       _op_id = X_("libardourvampplugins:aubioonset");
+       
+       // XXX this should load the above-named plugin and get the current version
+       
+       _op_id += ":2";
+}
+
+OnsetDetector::~OnsetDetector()
+{
+}
+
+string
+OnsetDetector::operational_identifier()
+{
+       return _op_id;
+}
+
+int
+OnsetDetector::run (const std::string& path, Readable* src, uint32_t channel, AnalysisFeatureList& results)
+{
+       current_results = &results;
+       int ret = analyse (path, src, channel);
+
+       current_results = 0;
+       return ret;
+}
+
+int
+OnsetDetector::use_features (Plugin::FeatureSet& features, ostream* out)
+{
+       const Plugin::FeatureList& fl (features[0]);
+
+       for (Plugin::FeatureList::const_iterator f = fl.begin(); f != fl.end(); ++f) {
+               
+               if ((*f).hasTimestamp) {
+
+                       if (out) {
+                               (*out) << (*f).timestamp.toString() << endl;
+                       } 
+                       
+                       current_results->push_back (RealTime::realTime2Frame ((*f).timestamp, (nframes_t) floor(sample_rate)));
+               }
+       }
+
+       return 0;
+}
+
+void
+OnsetDetector::set_silence_threshold (float val)
+{
+       if (plugin) {
+               plugin->setParameter ("silencethreshold", val);
+       }
+}
+
+void
+OnsetDetector::set_peak_threshold (float val)
+{
+       if (plugin) {
+               plugin->setParameter ("peakpickthreshold", val);
+       }
+}
+
+void
+OnsetDetector::set_function (int val)
+{
+       if (plugin) {
+               plugin->setParameter ("onsettype", (float) val);
+       }
+}
+
+void
+OnsetDetector::cleanup_onsets (AnalysisFeatureList& t, float sr, float gap_msecs)
+{
+       if (t.empty()) {
+               return;
+       }
+
+       t.sort ();
+       
+       /* remove duplicates or other things that are too close */
+       
+       AnalysisFeatureList::iterator i = t.begin();
+       AnalysisFeatureList::iterator f, b;
+       const nframes64_t gap_frames = (nframes64_t) floor (gap_msecs * (sr / 1000.0));
+       
+       while (i != t.end()) {
+
+               // move front iterator to just past i, and back iterator the same place
+               
+               f = i;
+               ++f;
+               b = f;
+
+               // move f until we find a new value that is far enough away
+               
+               while ((f != t.end()) && (((*f) - (*i)) < gap_frames)) {
+                       ++f;
+               }
+
+               i = f;
+
+               // if f moved forward from b, we had duplicates/too-close points: get rid of them
+
+               if (b != f) {
+                       t.erase (b, f);
+               }
+       }
+}
index b0bd35b8c69faa6c673336a93828ef1cca17a60e..0c58040ad62a72f73481852f3fce04ee8df08ba3 100644 (file)
@@ -28,6 +28,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+#include <glibmm/miscutils.h>
+
 #include <pbd/pthread_utils.h>
 #include <pbd/file_utils.h>
 
@@ -183,6 +185,7 @@ OSC::register_callbacks()
 #define REGISTER_CALLBACK(serv,path,types, function) lo_server_add_method (serv, path, types, OSC::_ ## function, this)
                
                REGISTER_CALLBACK (serv, "/ardour/add_marker", "", add_marker);
+               REGISTER_CALLBACK (serv, "/ardour/access_action", "s", access_action);
                REGISTER_CALLBACK (serv, "/ardour/loop_toggle", "", loop_toggle);
                REGISTER_CALLBACK (serv, "/ardour/goto_start", "", goto_start);
                REGISTER_CALLBACK (serv, "/ardour/goto_end", "", goto_end);
@@ -409,6 +412,10 @@ OSC::set_session (Session& s)
 {
        session = &s;
        session->GoingAway.connect (mem_fun (*this, &OSC::session_going_away));
+
+       // "Application Hooks"
+       session_loaded( s );
+       session->Exported.connect( mem_fun( *this, &OSC::session_exported ) );
 }
 
 void
@@ -417,6 +424,21 @@ OSC::session_going_away ()
        session = 0;
 }
 
+// "Application Hook" Handlers //
+void
+OSC::session_loaded( Session& s ) {
+       lo_address listener = lo_address_new( NULL, "7770" );
+       lo_send( listener, "/session/loaded", "ss", s.path().c_str(), s.name().c_str() );
+}
+
+void
+OSC::session_exported( std::string path, std::string name ) {
+       lo_address listener = lo_address_new( NULL, "7770" );
+       lo_send( listener, "/session/exported", "ss", path.c_str(), name.c_str() );
+}
+
+// end "Application Hook" Handlers //
+
 /* path callbacks */
 
 int 
index ca4c51fa975f01801162fde4e4427527dfd45add..2163ba5cc0a4554a8cdcede85af0fad45db3c6b6 100644 (file)
@@ -1115,8 +1115,7 @@ Panner::set_state (const XMLNode& node)
 
                /* automation path is relative */
                
-               automation_path = _session.automation_dir();
-               automation_path += prop->value ();
+               automation_path = Glib::build_filename(_session.automation_dir(), prop->value ());
        } 
 
        return 0;
@@ -1416,11 +1415,8 @@ Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, nframes_t start_frame
 void
 Panner::set_name (string str)
 {
-       automation_path = _session.automation_dir();
-       automation_path += _session.snap_name();
-       automation_path += "-pan-";
-       automation_path += legalize_for_path (str);
-       automation_path += ".automation";
+       automation_path = Glib::build_filename(_session.automation_dir(), 
+               _session.snap_name() + "-pan-" + legalize_for_path (str) + ".automation");
 }
 
 int
index 3d218448dddad09c36ed3858b757b77e5ebc78ae..c52a027915a4692bb56e6bee5958fe079be2a715 100644 (file)
@@ -241,3 +241,22 @@ ARDOUR::find_plugin(Session& session, string identifier, PluginType type)
        return PluginPtr ((Plugin*) 0);
 }
 
+ChanCount
+Plugin::output_streams () const
+{
+       /* LADSPA & VST should not get here because they do not
+          return "infinite" i/o counts.
+       */
+       return ChanCount::ZERO;
+}
+
+ChanCount
+Plugin::input_streams () const
+{
+       /* LADSPA & VST should not get here because they do not
+          return "infinite" i/o counts.
+       */
+       return ChanCount::ZERO;
+}
+
+
index 26d344dee4331c4d993a475fdb01ee4a13f7bcf0..f44a5df003b1f3329337bbefeaee749d4b044cdc 100644 (file)
@@ -162,19 +162,34 @@ PluginInsert::auto_state_changed (Parameter which)
 ChanCount
 PluginInsert::output_streams() const
 {
-       if (_configured)
-               return output_for_input_configuration(_configured_input);
-       else
-               return natural_output_streams();
+       ChanCount out = _plugins.front()->get_info()->n_outputs;
+
+       if (out == ChanCount::INFINITE) {
+
+               return _plugins.front()->output_streams ();
+
+       } else {
+
+               out.set_audio (out.n_audio() * _plugins.size());
+               out.set_midi (out.n_midi() * _plugins.size());
+
+               return out;
+       }
 }
 
 ChanCount
 PluginInsert::input_streams() const
 {
-       if (_configured)
-               return _configured_input;
-       else
-               return natural_input_streams();
+       ChanCount in = _plugins[0]->get_info()->n_inputs;
+       
+       if (in == ChanCount::INFINITE) {
+               return _plugins[0]->input_streams ();
+       } else {
+               in.set_audio (in.n_audio() * _plugins.size());
+               in.set_midi (in.n_midi() * _plugins.size());
+
+               return in;
+       }
 }
 
 ChanCount
@@ -473,31 +488,42 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
 bool
 PluginInsert::configure_io (ChanCount in, ChanCount out)
 {
-       ChanCount matching_out = output_for_input_configuration(out);
-       if (matching_out != out) {
-               _configured = false;
+       if (set_count (count_for_configuration (in, out)) < 0) {
+               return false;
+       }
+
+       /* if we're running replicated plugins, each plugin has
+          the same i/o configuration and we may need to announce how many
+          output streams there are.
+
+          if we running a single plugin, we need to configure it.
+       */
+
+       if (_plugins.front()->configure_io (in, out) < 0) {
                return false;
-       } else {
-               bool success = set_count (count_for_configuration(in, out));
-               if (success)
-                       Processor::configure_io(in, out);
-               return success;
        }
+
+       return Processor::configure_io (in, out);
 }
 
 bool
-PluginInsert::can_support_input_configuration (ChanCount in) const
+PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
 {
+       if (_plugins.front()->reconfigurable_io()) {
+               /* plugin has flexible I/O, so delegate to it */
+               return _plugins.front()->can_support_io_configuration (in, out);
+       }
+
        ChanCount outputs = _plugins[0]->get_info()->n_outputs;
        ChanCount inputs = _plugins[0]->get_info()->n_inputs;
 
-       /* see output_for_input_configuration below */
        if ((inputs.n_total() == 0)
                        || (inputs.n_total() == 1 && outputs == inputs)
                        || (inputs.n_total() == 1 && outputs == inputs
                                && ((inputs.n_audio() == 0 && in.n_audio() == 0)
                                        || (inputs.n_midi() == 0 && in.n_midi() == 0)))
                        || (inputs == in)) {
+               out = outputs;
                return true;
        }
 
@@ -513,60 +539,31 @@ PluginInsert::can_support_input_configuration (ChanCount in) const
                }
        }
 
-       if (can_replicate && (in.n_total() % inputs.n_total() == 0)) {
-               return true;
-       } else {
+       if (!can_replicate || (in.n_total() % inputs.n_total() != 0)) {
                return false;
        }
-}
-
-ChanCount
-PluginInsert::output_for_input_configuration (ChanCount in) const
-{
-       ChanCount outputs = _plugins[0]->get_info()->n_outputs;
-       ChanCount inputs = _plugins[0]->get_info()->n_inputs;
 
        if (inputs.n_total() == 0) {
                /* instrument plugin, always legal, but throws away any existing streams */
-               return outputs;
-       }
-
-       if (inputs.n_total() == 1 && outputs == inputs
+               out = outputs;
+       } else if (inputs.n_total() == 1 && outputs == inputs
                        && ((inputs.n_audio() == 0 && in.n_audio() == 0)
-                               || (inputs.n_midi() == 0 && in.n_midi() == 0))) {
-               /* mono plugin, replicate as needed to match in */
-               return in;
-       }
-
-       if (inputs == in) {
+                           || (inputs.n_midi() == 0 && in.n_midi() == 0))) {
+               /* mono, single-typed plugin, replicate as needed to match in */
+               out = in;
+       } else if (inputs == in) {
                /* exact match */
-               return outputs;
-       }
-
-       bool can_replicate = true;
-
-       /* if number of inputs is a factor of the requested input
-          configuration for every type, we can replicate.
-       */
-       for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
-               if (inputs.get(*t) >= in.get(*t) || (in.get(*t) % inputs.get(*t) != 0)) {
-                       can_replicate = false;
-                       break;
-               }
-       }
-
-       if (can_replicate && (inputs.n_total() % in.n_total() == 0)) {
-               ChanCount output;
-               
+               out = outputs;
+       } else {
+               /* replicate - note that we've already verified that
+                  the replication count is constant across all data types.
+               */
                for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
-                       output.set(*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t)));
+                       out.set (*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t)));
                }
-
-               return output;
        }
-
-       /* sorry */
-       return ChanCount();
+               
+       return true;
 }
 
 /* Number of plugin instances required to support a given channel configuration.
@@ -575,6 +572,12 @@ PluginInsert::output_for_input_configuration (ChanCount in) const
 int32_t
 PluginInsert::count_for_configuration (ChanCount in, ChanCount out) const
 {
+       if (_plugins.front()->reconfigurable_io()) {
+               /* plugin has flexible I/O, so the answer is always 1 */
+               /* this could change if we ever decide to replicate AU's */
+               return 1;
+       }
+
        // FIXME: take 'out' into consideration
        
        ChanCount outputs = _plugins[0]->get_info()->n_outputs;
index 6ff780a25fad387fbdb5f744502391f875692edd..e7c2aecd2df5839eb57c15bc03150bab7942c416 100644 (file)
 #include <cstdio>
 #include <lrdf.h>
 #include <dlfcn.h>
+#include <cstdlib>
+#include <fstream>
 
 #ifdef VST_SUPPORT
 #include <fst.h>
 #include <pbd/basename.h>
-#include <string.h>
+#include <cstring>
 #endif // VST_SUPPORT
 
+#include <glibmm/miscutils.h>
+
 #include <pbd/pathscanner.h>
 
 #include <ardour/ladspa.h>
@@ -38,6 +42,7 @@
 #include <ardour/plugin_manager.h>
 #include <ardour/plugin.h>
 #include <ardour/ladspa_plugin.h>
+#include <ardour/filesystem_paths.h>
 
 #ifdef HAVE_SLV2
 #include <slv2/slv2.h>
@@ -50,6 +55,7 @@
 
 #ifdef HAVE_AUDIOUNITS
 #include <ardour/audio_unit.h>
+#include <Carbon/Carbon.h>
 #endif
 
 #include <pbd/error.h>
@@ -59,6 +65,7 @@
 
 using namespace ARDOUR;
 using namespace PBD;
+using namespace std;
 
 PluginManager* PluginManager::_manager = 0;
 
@@ -67,6 +74,16 @@ PluginManager::PluginManager ()
        char* s;
        string lrdf_path;
 
+       load_favorites ();
+
+#ifdef GTKOSX
+       ProcessSerialNumber psn = { 0, kCurrentProcess }; 
+       OSStatus returnCode = TransformProcessType(& psn, kProcessTransformToForegroundApplication);
+       if( returnCode != 0) {
+               error << _("Cannot become GUI app") << endmsg;
+       }
+#endif
+
        if ((s = getenv ("LADSPA_RDF_PATH"))){
                lrdf_path = s;
        }
@@ -487,3 +504,107 @@ PluginManager::vst_discover (string path)
 }
 
 #endif // VST_SUPPORT
+
+bool
+PluginManager::is_a_favorite_plugin (const PluginInfoPtr& pi)
+{
+       FavoritePlugin fp (pi->type, pi->unique_id);
+       return find (favorites.begin(), favorites.end(), fp) !=  favorites.end();
+}
+
+void
+PluginManager::save_favorites ()
+{
+       ofstream ofs;
+       sys::path path = user_config_directory();
+       path /= "favorite_plugins";
+
+       ofs.open (path.to_string().c_str(), ios_base::openmode (ios::out|ios::trunc));
+
+       if (!ofs) {
+               return;
+       }
+
+       for (FavoritePluginList::iterator i = favorites.begin(); i != favorites.end(); ++i) {
+               switch ((*i).type) {
+               case LADSPA:
+                       ofs << "LADSPA";
+                       break;
+               case AudioUnit:
+                       ofs << "AudioUnit";
+                       break;
+               case LV2:
+                       ofs << "LV2";
+                       break;
+               case VST:
+                       ofs << "VST";
+                       break;
+               }
+               
+               ofs << ' ' << (*i).unique_id << endl;
+       }
+
+       ofs.close ();
+}
+
+void
+PluginManager::load_favorites ()
+{
+       sys::path path = user_config_directory();
+       path /= "favorite_plugins";
+       ifstream ifs (path.to_string().c_str());
+
+       if (!ifs) {
+               return;
+       }
+       
+       std::string stype;
+       std::string id;
+       PluginType type;
+
+       while (ifs) {
+
+               ifs >> stype;
+               if (!ifs) {
+                       break;
+
+               }
+               ifs >> id;
+               if (!ifs) {
+                       break;
+               }
+
+               if (stype == "LADSPA") {
+                       type = LADSPA;
+               } else if (stype == "AudioUnit") {
+                       type = AudioUnit;
+               } else if (stype == "LV2") {
+                       type = LV2;
+               } else if (stype == "VST") {
+                       type = VST;
+               } else {
+                       error << string_compose (_("unknown favorite plugin type \"%1\" - ignored"), stype)
+                             << endmsg;
+                       continue;
+               }
+               
+               add_favorite (type, id);
+       }
+       
+       ifs.close ();
+}
+
+void
+PluginManager::add_favorite (PluginType t, string id)
+{
+       FavoritePlugin fp (t, id);
+       pair<FavoritePluginList::iterator,bool> res = favorites.insert (fp);
+       cerr << "Added " << t << " " << id << " success ? " << res.second << endl;
+}
+
+void
+PluginManager::remove_favorite (PluginType t, string id)
+{
+       FavoritePlugin fp (t, id);
+       favorites.erase (fp);
+}
index ddc7f108bba02ebd93ef702d82d019fb15c8dd24..58be548f8e667cb473604edb6c3c399f743a8828 100644 (file)
@@ -1972,6 +1972,10 @@ msgstr "Fogredigering"
 msgid "Slide Edit"
 msgstr "Glidredigering"
 
+#: libs/ardour/utils.cc:372 libs/ardour/utils.cc:388
+msgid "Lock Edit"
+msgstr "LÃ¥st redigering"
+
 #: libs/ardour/utils.cc:309
 msgid "programming error: unknown edit mode string \"%1\""
 msgstr ""
index e14835b0832bda0491bdbe706e06746b37082f14..8c33d989dd4e42f9f1a92e9b07009edb0626c7fe 100644 (file)
@@ -172,36 +172,6 @@ PortInsert::signal_latency() const
        return _session.engine().frames_per_cycle() + _io->input_latency();
 }
 
-bool
-PortInsert::can_support_input_configuration (ChanCount in) const
-{
-       if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
-
-               /* not configured yet */
-
-               return true; /* we can support anything the first time we're asked */
-
-       } else {
-
-               /* the "input" config for a port insert corresponds to how
-                  many output ports it will have.
-               */
-
-               if (_io->output_maximum() == in) {
-
-                       return true;
-               } 
-       }
-
-       return false;
-}
-
-ChanCount
-PortInsert::output_for_input_configuration (ChanCount in) const
-{
-       return in;
-}
-
 bool
 PortInsert::configure_io (ChanCount in, ChanCount out)
 {
@@ -209,7 +179,6 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
           the last request config. or something like that.
        */
 
-
        /* this is a bit odd: 
 
           the number of inputs we are required to handle corresponds 
@@ -224,12 +193,11 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
        _io->set_input_maximum (out);
        _io->set_input_minimum (out);
 
-       bool success = (_io->ensure_io (out, in, false, this) == 0);
-
-       if (success)
-               return Processor::configure_io(in, out);
-       else
+       if (_io->ensure_io (out, in, false, this) != 0) {
                return false;
+       }
+
+       return Processor::configure_io (in, out);
 }
 
 ChanCount
index cea33fbe32ff6f48f61b3007ca0fc1e9b2859bc4..486a75703bb59758ca7f54be175de0ca33fb67be 100644 (file)
@@ -272,3 +272,16 @@ Processor::set_state (const XMLNode& node)
        return 0;
 }
 
+bool
+Processor::configure_io (ChanCount in, ChanCount out)
+{
+       /* this class assumes static output stream count.
+          Derived classes must override, and must set "out"
+          to reflect "in" before calling this.
+       */
+
+       _configured_input = in; 
+       _configured = true;
+
+       return true;
+}
index 4daf5cb33a233569eb99c80d6fce52b1a51017a0..9d8ac311b79635c431bb2e0e2c9bba4a1130f423 100644 (file)
@@ -74,21 +74,89 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
        nframes_t pos = 0;
        int avail = 0;
 
-       // note: this_time_fraction is a ratio of original length. 1.0 = no change, 
-       // 0.5 is half as long, 2.0 is twice as long, etc.
+       cerr << "RBEffect: source region: position = " << region->position()
+            << ", start = " << region->start()
+            << ", length = " << region->length() 
+            << ", ancestral_start = " << region->ancestral_start()
+            << ", ancestral_length = " << region->ancestral_length()
+            << ", stretch " << region->stretch()
+            << ", shift " << region->shift() << endl;
+
+       /*
+          We have two cases to consider:
+         
+          1. The region has not been stretched before.
+         
+          In this case, we just want to read region->length() frames
+          from region->start().
+         
+          We will create a new region of region->length() *
+          tsr.time_fraction frames.  The new region will have its
+          start set to 0 (because it has a new audio file that begins
+          at the start of the stretched area) and its ancestral_start
+          set to region->start() (so that we know where to begin
+          reading if we want to stretch it again).
+         
+          2. The region has been stretched before.
+         
+          The region starts at region->start() frames into its
+          (possibly previously stretched) source file.  But we don't
+          want to read from its source file; we want to read from the
+          file it was originally stretched from.
+          
+          The region's source begins at region->ancestral_start()
+          frames into its master source file.  Thus, we need to start
+          reading at region->ancestral_start() + (region->start() /
+          region->stretch()) frames into the master source.  This
+          value will also become the ancestral_start for the new
+          region.
+          
+          We cannot use region->ancestral_length() to establish how
+          many frames to read, because it won't be up to date if the
+          region has been trimmed since it was last stretched.  We
+          must read region->length() / region->stretch() frames and
+          stretch them by tsr.time_fraction * region->stretch(), for
+          a new region of region->length() * tsr.time_fraction
+          frames.
+         
+          Case 1 is of course a special case of 2, where
+          region->ancestral_start() == 0 and region->stretch() == 1.
+         
+          When we ask to read from a region, we supply a position on
+          the global timeline.  The read function calculates the
+          offset into the source as (position - region->position()) +
+          region->start().  This calculation is used regardless of
+          whether we are reading from a master or
+          previously-stretched region.  In order to read from a point
+          n frames into the master source, we need to provide n -
+          region->start() + region->position() as our position
+          argument to master_read_at().
+         
+          Note that region->ancestral_length() is not used.
+         
+          I hope this is clear.
+       */
+
+       double stretch = region->stretch() * tsr.time_fraction;
+       double shift = region->shift() * tsr.pitch_fraction;
 
-       double this_time_fraction = tsr.time_fraction * region->stretch ();
-       double this_pitch_fraction = tsr.pitch_fraction * region->shift ();
+       nframes_t read_start = region->ancestral_start() +
+               nframes_t(region->start() / (double)region->stretch());
 
-       RubberBandStretcher stretcher (session.frame_rate(), region->n_channels(),
-                                      (RubberBandStretcher::Options) tsr.opts,
-                                      this_time_fraction, this_pitch_fraction);
+       nframes_t read_duration =
+               nframes_t(region->length() / (double)region->stretch());
+
+       uint32_t channels = region->n_channels();
+
+       RubberBandStretcher stretcher
+               (session.frame_rate(), channels,
+                (RubberBandStretcher::Options) tsr.opts, stretch, shift);
        
        tsr.progress = 0.0f;
        tsr.done = false;
 
-       uint32_t channels = region->n_channels();
-       nframes_t duration = region->ancestral_length();
+       stretcher.setExpectedInputDuration(read_duration);
+       stretcher.setDebugLevel(1);
 
        stretcher.setExpectedInputDuration(duration);
        stretcher.setDebugLevel(1);
@@ -97,14 +165,14 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
           digits just to disambiguate close but not identical FX
        */
 
-       if (this_time_fraction == 1.0) {
-               snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_pitch_fraction * 100.0f));
-       } else if (this_pitch_fraction == 1.0) {
-               snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_time_fraction * 100.0f));
+       if (stretch == 1.0) {
+               snprintf (suffix, sizeof (suffix), "@%d", (int) floor (shift * 100.0f));
+       } else if (shift == 1.0) {
+               snprintf (suffix, sizeof (suffix), "@%d", (int) floor (stretch * 100.0f));
        } else {
                snprintf (suffix, sizeof (suffix), "@%d-%d", 
-                         (int) floor (this_time_fraction * 100.0f),
-                         (int) floor (this_pitch_fraction * 100.0f));
+                         (int) floor (stretch * 100.0f),
+                         (int) floor (shift * 100.0f));
        }
 
        /* create new sources */
@@ -131,22 +199,26 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
        done = 0;
 
        try { 
-               while (pos < duration && !tsr.cancel) {
+               while (pos < read_duration && !tsr.cancel) {
                        
                        nframes_t this_read = 0;
                        
                        for (uint32_t i = 0; i < channels; ++i) {
                                
                                this_read = 0;
+
                                nframes_t this_time;
+                               this_time = min(bufsize, read_duration - pos);
                                
-                               this_time = min(bufsize, duration - pos);
-                               
+                               nframes_t this_position;
+                               this_position = read_start + pos -
+                                       region->start() + region->position();
+
                                this_read = region->master_read_at
                                        (buffers[i],
                                         buffers[i],
                                         gain_buffer,
-                                        pos + region->position(),
+                                        this_position,
                                         this_time,
                                         i);
                                
@@ -161,15 +233,15 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
                        pos += this_read;
                        done += this_read;
 
-                       tsr.progress = ((float) done / duration) * 0.25;
+                       tsr.progress = ((float) done / read_duration) * 0.25;
 
-                       stretcher.study(buffers, this_read, pos == duration);
+                       stretcher.study(buffers, this_read, pos == read_duration);
                }
                
                done = 0;
                pos = 0;
 
-               while (pos < duration && !tsr.cancel) {
+               while (pos < read_duration && !tsr.cancel) {
                        
                        nframes_t this_read = 0;
                        
@@ -177,14 +249,17 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
                                
                                this_read = 0;
                                nframes_t this_time;
-                               
-                               this_time = min(bufsize, duration - pos);
+                               this_time = min(bufsize, read_duration - pos);
+
+                               nframes_t this_position;
+                               this_position = read_start + pos -
+                                       region->start() + region->position();
                                
                                this_read = region->master_read_at
                                        (buffers[i],
                                         buffers[i],
                                         gain_buffer,
-                                        pos + region->position(),
+                                        this_position,
                                         this_time,
                                         i);
                                
@@ -199,9 +274,9 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
                        pos += this_read;
                        done += this_read;
 
-                       tsr.progress = 0.25 + ((float) done / duration) * 0.75;
+                       tsr.progress = 0.25 + ((float) done / read_duration) * 0.75;
 
-                       stretcher.process(buffers, this_read, pos == duration);
+                       stretcher.process(buffers, this_read, pos == read_duration);
 
                        int avail = 0;
 
@@ -261,10 +336,11 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
 
        for (vector<boost::shared_ptr<AudioRegion> >::iterator x = results.begin(); x != results.end(); ++x) {
 
-               (*x)->set_ancestral_data (region->ancestral_start(),
-                                         region->ancestral_length(),
-                                         this_time_fraction,
-                                         this_pitch_fraction );
+
+               (*x)->set_ancestral_data (read_start,
+                                         read_duration,
+                                         stretch,
+                                         shift);
                (*x)->set_master_sources (region->get_master_sources());
        }
 
index 9b8668dd88b00699cb4b7d580e4e9e58a86eb056..d7f5ad132fab200b22a75abbac05ce5690e9e55a 100644 (file)
 #include <unistd.h>
 #include <fstream>
 #include <algorithm>
+
+#include <glibmm/miscutils.h>
+
 #include <pbd/error.h>
+
 #include <ardour/configuration.h>
 #include <ardour/filesystem_paths.h>
 #include <ardour/recent_sessions.h>
index a6d153f3592040003a97e4301d57632371e2b1a7..6676222b54cf573e4e0f1e34bb9f7309eb6b468b 100644 (file)
@@ -185,6 +185,7 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes
                _sync_position = other->_sync_position;
        }
 
+
        for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) {
                if (unique_srcs.find (*i) == unique_srcs.end()) {
                        (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
@@ -388,6 +389,7 @@ Region::set_name (const std::string& str)
 void
 Region::set_length (nframes_t len, void *src)
 {
+       //cerr << "Region::set_length() len = " << len << endl;
        if (_flags & Locked) {
                return;
        }
index 84d816724054b699f1a4a0ac7458913736c85501..88925a7f1695b2216ba6dd38c1ab1c17804f12b1 100644 (file)
@@ -72,7 +72,7 @@ RegionFactory::create (boost::shared_ptr<const Region> region)
 {
        boost::shared_ptr<const AudioRegion> ar;
        boost::shared_ptr<const MidiRegion> mr;
-       
+
        if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) {
                boost::shared_ptr<Region> ret (new AudioRegion (ar));
                /* pure copy constructor - no CheckNewRegion emitted */
@@ -101,7 +101,11 @@ boost::shared_ptr<Region>
 RegionFactory::create (Session& session, XMLNode& node, bool yn)
 {
        boost::shared_ptr<Region> r = session.XMLRegionFactory (node, yn);
-       CheckNewRegion (r);
+
+       if (r) {
+               CheckNewRegion (r);
+       }
+
        return r;
 }
        
index e655efedb251df855e7f389d18616ff292745cde..638c0260569df83a6a7849ed39f92e28115d7221 100644 (file)
@@ -813,7 +813,7 @@ Route::set_mute (bool yn, void *src)
 int
 Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
 {
-       ChanCount old_rmo = processor_max_outs;
+       ChanCount old_pmo = processor_max_outs;
 
        if (!_session.engine().connected()) {
                return 1;
@@ -827,8 +827,15 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
 
                //processor->set_default_type(_default_type);
 
+               _processors.push_back (processor);
+
+               if (_reset_processor_counts (err)) {
+                       _processors.pop_back ();
+                       _reset_processor_counts (0); // it worked before we tried to add it ...
+                       return -1;
+               }
+
                if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
-                       pi->set_count (1);
                        
                        if (pi->natural_input_streams() == ChanCount::ZERO) {
                                /* generator plugin */
@@ -841,15 +848,22 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
 
                // Set up processor list channels.  This will set processor->[input|output]_streams(),
                // configure redirect ports properly, etc.
-               if (_reset_plugin_counts (err)) {
+               if (_reset_processor_counts (err)) {
                        _processors.pop_back ();
-                       _reset_plugin_counts (0); // it worked before we tried to add it ...
+                       _reset_processor_counts (0); // it worked before we tried to add it ...
                        return -1;
                }
 
                // Ensure peak vector sizes before the plugin is activated
-               ChanCount potential_max_streams = max(processor->input_streams(), processor->output_streams());
-               _meter->configure_io(potential_max_streams, potential_max_streams);
+
+               ChanCount potential_max_streams;
+
+               potential_max_streams.set (DataType::AUDIO, max (processor->input_streams().n_audio(), 
+                                                                processor->output_streams().n_audio()));
+               potential_max_streams.set (DataType::MIDI, max (processor->input_streams().n_midi(), 
+                                                               processor->output_streams().n_midi()));
+
+               _meter->configure_io (potential_max_streams, potential_max_streams);
 
                processor->activate ();
                processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
@@ -857,7 +871,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
                _user_latency = 0;
        }
        
-       if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+       if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
                reset_panner ();
        }
 
@@ -869,7 +883,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
 int
 Route::add_processors (const ProcessorList& others, ProcessorStreams* err)
 {
-       ChanCount old_rmo = processor_max_outs;
+       ChanCount old_pmo = processor_max_outs;
 
        if (!_session.engine().connected()) {
                return 1;
@@ -896,14 +910,14 @@ Route::add_processors (const ProcessorList& others, ProcessorStreams* err)
                        }
 
                        // Ensure peak vector sizes before the plugin is activated
-                       _meter->configure_io(potential_max_streams, potential_max_streams);
+                       _meter->configure_io (potential_max_streams, potential_max_streams);
 
                        _processors.push_back (*i);
                        
-                       if (_reset_plugin_counts (err)) {
+                       if (_reset_processor_counts (err)) {
                                ++existing_end;
                                _processors.erase (existing_end, _processors.end());
-                               _reset_plugin_counts (0); // it worked before we tried to add it ...
+                               _reset_processor_counts (0); // it worked before we tried to add it ...
                                return -1;
                        }
                        
@@ -914,7 +928,7 @@ Route::add_processors (const ProcessorList& others, ProcessorStreams* err)
                _user_latency = 0;
        }
        
-       if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+       if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
                reset_panner ();
        }
 
@@ -1064,7 +1078,7 @@ Route::pre_fader_streams() const
 void
 Route::clear_processors (Placement p)
 {
-       const ChanCount old_rmo = processor_max_outs;
+       const ChanCount old_pmo = processor_max_outs;
 
        if (!_session.engine().connected()) {
                return;
@@ -1088,7 +1102,7 @@ Route::clear_processors (Placement p)
        }
 
        /* FIXME: can't see how this test can ever fire */
-       if (processor_max_outs != old_rmo) {
+       if (processor_max_outs != old_pmo) {
                reset_panner ();
        }
        
@@ -1100,7 +1114,7 @@ Route::clear_processors (Placement p)
 int
 Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
 {
-       ChanCount old_rmo = processor_max_outs;
+       ChanCount old_pmo = processor_max_outs;
 
        if (!_session.engine().connected()) {
                return 1;
@@ -1118,7 +1132,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
 
                                ProcessorList::iterator tmp;
 
-                               /* move along, see failure case for reset_plugin_counts()
+                               /* move along, see failure case for reset_processor_counts()
                                   where we may need to reprocessor the processor.
                                */
 
@@ -1152,30 +1166,29 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
                        return 1;
                }
 
-               if (_reset_plugin_counts (err)) {
+               if (_reset_processor_counts (err)) {
                        /* get back to where we where */
                        _processors.insert (i, processor);
                        /* we know this will work, because it worked before :) */
-                       _reset_plugin_counts (0);
+                       _reset_processor_counts (0);
                        return -1;
                }
 
-               bool foo = false;
+               _have_internal_generator = false;
 
                for (i = _processors.begin(); i != _processors.end(); ++i) {
                        boost::shared_ptr<PluginInsert> pi;
                        
                        if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
                                if (pi->is_generator()) {
-                                       foo = true;
+                                       _have_internal_generator = true;
+                                       break;
                                }
                        }
                }
-
-               _have_internal_generator = foo;
        }
 
-       if (old_rmo != processor_max_outs) {
+       if (old_pmo != processor_max_outs) {
                reset_panner ();
        }
 
@@ -1186,27 +1199,32 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
 }
 
 int
-Route::reset_plugin_counts (ProcessorStreams* err)
+Route::reset_processor_counts (ProcessorStreams* err)
 {
        Glib::RWLock::WriterLock lm (_processor_lock);
-       return _reset_plugin_counts (err);
+       return _reset_processor_counts (err);
 }
 
 
 int
-Route::_reset_plugin_counts (ProcessorStreams* err)
+Route::_reset_processor_counts (ProcessorStreams* err)
 {
        ProcessorList::iterator r;
-       map<Placement,list<ProcessorCount> > processor_map;
-       ChanCount initial_streams;
-       ChanCount post_fader_input;
+       uint32_t insert_cnt = 0;
+       uint32_t send_cnt = 0;
+       map<Placement,list<ProcessorCount> > proc_map;
+       ProcessorList::iterator prev;
+       ChanCount initial_streams = n_inputs ();
+       ChanCount previous_initial_streams = n_inputs ();
        int ret = -1;
+       uint32_t max_audio = 0;
+       uint32_t max_midi = 0;
 
-       /* Process each placement in order, checking to see if we 
-          can really do what has been requested.
-       */
+       processor_max_outs.reset ();
        
-       /* divide processors up by placement so we get the signal flow
+       /* Step 1: build a map that links each insert to an in/out channel count 
+
+          Divide inserts up by placement so we get the signal flow
           properly modelled. we need to do this because the _processors
           list is not sorted by placement, and because other reasons may 
           exist now or in the future for this separate treatment.
@@ -1216,60 +1234,146 @@ Route::_reset_plugin_counts (ProcessorStreams* err)
        
        for (r = _processors.begin(); r != _processors.end(); ++r) {
 
-               boost::shared_ptr<Processor> processor;
+               boost::shared_ptr<PluginInsert> plugin_insert;
+               boost::shared_ptr<PortInsert> port_insert;
+
+               if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert>(*r)) != 0) {
+
+                       ++insert_cnt;
+                       proc_map[(*r)->placement()].push_back (ProcessorCount (*r));
+
+                       /* reset plugin counts back to one for now so
+                          that we have a predictable, controlled
+                          state to try to configure.
+                       */
 
-               if ((processor = boost::dynamic_pointer_cast<Processor>(*r)) != 0) {
-                       processor_map[processor->placement()].push_back (ProcessorCount (processor));
+                       plugin_insert->set_count (1);
+
+               } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert>(*r)) != 0) {
+                       
+                       ++insert_cnt;
+                       proc_map[(*r)->placement()].push_back (ProcessorCount (*r));
+
+               } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
+                       ++send_cnt;
                }
        }
        
+       if (insert_cnt == 0) {
+               if (send_cnt) {
+                       goto recompute;
+               } else {
+                       ret = 0;
+                       goto streamcount;
+               }
+       }
+
+       /* Now process each placement in order, checking to see if we 
+          can really do what has been requested.
+       */
+
        /* A: PreFader */
        
-       if ( ! check_some_plugin_counts (processor_map[PreFader], n_inputs (), err)) {
+       if (check_some_processor_counts (proc_map[PreFader], n_inputs (), err)) {
                goto streamcount;
        }
 
-       post_fader_input = (err ? err->count : n_inputs());
+       if (!proc_map[PreFader].empty()) {
+               previous_initial_streams = n_inputs ();
+               for (list<ProcessorCount>::iterator i = proc_map[PreFader].begin(); i != proc_map[PreFader].end(); i++) {
+                       if (i->processor->can_support_io_configuration (previous_initial_streams, initial_streams) < 0) {
+                               goto streamcount;
+                       }
+                       previous_initial_streams = initial_streams;
+               }
+       }
 
        /* B: PostFader */
 
-       if ( ! check_some_plugin_counts (processor_map[PostFader], post_fader_input, err)) {
+       if (check_some_processor_counts (proc_map[PostFader], initial_streams, err)) {
                goto streamcount;
        }
 
+       if (!proc_map[PostFader].empty()) {
+               for (list<ProcessorCount>::iterator i = proc_map[PostFader].begin(); i != proc_map[PostFader].end(); i++) {
+                       if (i->processor->can_support_io_configuration (previous_initial_streams, initial_streams) < 0) {
+                               goto streamcount;
+                       }
+                       previous_initial_streams = initial_streams;
+               }
+       }
+
        /* OK, everything can be set up correctly, so lets do it */
 
-       apply_some_plugin_counts (processor_map[PreFader]);
-       apply_some_plugin_counts (processor_map[PostFader]);
+       apply_some_processor_counts (proc_map[PreFader]);
+       apply_some_processor_counts (proc_map[PostFader]);
 
        /* recompute max outs of any processor */
 
        ret = 0;
 
-  streamcount:
-       processor_max_outs.reset();
+  recompute:
 
-       for (r = _processors.begin(); r != _processors.end(); ++r) {
-               processor_max_outs = max ((*r)->output_streams (), processor_max_outs);
+       processor_max_outs.reset ();
+       prev = _processors.end();
+
+       for (r = _processors.begin(); r != _processors.end(); prev = r, ++r) {
+               boost::shared_ptr<Send> s;
+
+               if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
+                       if (r == _processors.begin()) {
+                               s->expect_inputs (n_inputs());
+                       } else {
+                               s->expect_inputs ((*prev)->output_streams());
+                       }
+
+               } else {
+                       
+                       /* don't pay any attention to send output configuration, since it doesn't
+                          affect the route.
+                        */
+                       
+                       max_audio = max ((*r)->output_streams ().n_audio(), max_audio);
+                       max_midi = max ((*r)->output_streams ().n_midi(), max_midi);
+               }
        }
 
+       processor_max_outs.set (DataType::AUDIO, max_audio);
+       processor_max_outs.set (DataType::MIDI, max_midi);
+                       
+       /* we're done */
        return 0;
+
+  streamcount:
+       for (r = _processors.begin(); r != _processors.end(); ++r) {
+               max_audio = max ((*r)->output_streams ().n_audio(), max_audio);
+               max_midi = max ((*r)->output_streams ().n_midi(), max_midi);
+       }
+
+       processor_max_outs.set (DataType::AUDIO, max_audio);
+       processor_max_outs.set (DataType::MIDI, max_midi);
+
+       return ret;
 }                                 
 
 int32_t
-Route::apply_some_plugin_counts (list<ProcessorCount>& iclist)
+Route::apply_some_processor_counts (list<ProcessorCount>& iclist)
 {
        list<ProcessorCount>::iterator i;
-
+       
        for (i = iclist.begin(); i != iclist.end(); ++i) {
-               
-               cerr << "now applying for " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl;
 
-               if ((*i).processor->configure_io ((*i).in, (*i).out)) {
+               ProcessorCount& pc (*i);
+
+               cerr << "now applying for " << (*i).processor->name() << " in = " << pc.in.n_audio() << " out = " << pc.out.n_audio() << endl;
+
+               if (pc.processor->configure_io (pc.in, pc.out)) {
                        return -1;
                }
+
                /* make sure that however many we have, they are all active */
-               (*i).processor->activate ();
+
+               pc.processor->activate ();
        }
 
        return 0;
@@ -1281,7 +1385,7 @@ Route::apply_some_plugin_counts (list<ProcessorCount>& iclist)
  * Otherwise, \a err is set to the output of the list.
  */
 bool
-Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err)
+Route::check_some_processor_counts (list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err)
 {
        list<ProcessorCount>::iterator i;
        size_t index = 0;
@@ -1291,12 +1395,11 @@ Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount require
                err->count = required_inputs;
        }
 
-       for (i = iclist.begin(); i != iclist.end(); ++i) {
-
+       for (i = iclist.begin(); i != iclist.end(); ++i, ++index) {
 
                cerr << "Checking whether " << (*i).processor->name() << " can support " << required_inputs.n_audio() << " inputs\n";
 
-               if ((*i).processor->can_support_input_configuration (required_inputs) < 0) {
+               if (!(*i).processor->can_support_io_configuration (required_inputs, (*i).out)) {
                        if (err) {
                                err->index = index;
                                err->count = required_inputs;
@@ -1305,20 +1408,7 @@ Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount require
                }
                
                (*i).in = required_inputs;
-               (*i).out = (*i).processor->output_for_input_configuration (required_inputs);
-
-               cerr << "config looks like " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl;
-
                required_inputs = (*i).out;
-               
-               ++index;
-       }
-                       
-       if (err) {
-               if (!iclist.empty()) {
-                       err->index = index;
-                       err->count = iclist.back().processor->output_for_input_configuration(required_inputs);
-               }
        }
 
        return true;
@@ -1327,7 +1417,7 @@ Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount require
 int
 Route::copy_processors (const Route& other, Placement placement, ProcessorStreams* err)
 {
-       ChanCount old_rmo = processor_max_outs;
+       ChanCount old_pmo = processor_max_outs;
 
        ProcessorList to_be_deleted;
 
@@ -1362,7 +1452,7 @@ Route::copy_processors (const Route& other, Placement placement, ProcessorStream
 
                /* reset plugin stream handling */
 
-               if (_reset_plugin_counts (err)) {
+               if (_reset_processor_counts (err)) {
 
                        /* FAILED COPY ATTEMPT: we have to restore order */
 
@@ -1383,7 +1473,7 @@ Route::copy_processors (const Route& other, Placement placement, ProcessorStream
                        /* restore the natural order */
 
                        _processors = the_copy;
-                       processor_max_outs = old_rmo;
+                       processor_max_outs = old_pmo;
 
                        /* we failed, even though things are OK again */
 
@@ -1397,7 +1487,7 @@ Route::copy_processors (const Route& other, Placement placement, ProcessorStream
                }
        }
 
-       if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+       if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
                reset_panner ();
        }
 
@@ -1457,7 +1547,7 @@ Route::sort_processors (ProcessorStreams* err)
        {
                ProcessorSorter comparator;
                Glib::RWLock::WriterLock lm (_processor_lock);
-               ChanCount old_rmo = processor_max_outs;
+               ChanCount old_pmo = processor_max_outs;
 
                /* the sweet power of C++ ... */
 
@@ -1465,9 +1555,9 @@ Route::sort_processors (ProcessorStreams* err)
 
                _processors.sort (comparator);
        
-               if (_reset_plugin_counts (err)) {
+               if (_reset_processor_counts (err)) {
                        _processors = as_it_was_before;
-                       processor_max_outs = old_rmo;
+                       processor_max_outs = old_pmo;
                        return -1;
                } 
        } 
@@ -2334,7 +2424,7 @@ void
 Route::input_change_handler (IOChange change, void *ignored)
 {
        if (change & ConfigurationChanged) {
-               reset_plugin_counts (0);
+               reset_processor_counts (0);
        }
 }
 
@@ -2346,7 +2436,7 @@ Route::output_change_handler (IOChange change, void *ignored)
                        _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().n_audio()), true, this);
                }
                
-               reset_plugin_counts (0);
+               reset_processor_counts (0);
        }
 }
 
@@ -2540,6 +2630,11 @@ Route::update_total_latency ()
                }
        }
 
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+       cerr << _name << ": internal redirect latency = " << _own_latency << endl;
+#endif
+
        set_port_latency (_own_latency);
        
        if (!_user_latency) {
@@ -2558,6 +2653,11 @@ Route::update_total_latency ()
                signal_latency_changed (); /* EMIT SIGNAL */
        }
        
+#ifdef DEBUG_LATENCY
+       cerr << _name << ": input latency = " << input_latency() << " total = "
+            << _own_latency << endl;
+#endif
+
        return _own_latency;
 }
 
index 736a443c721137e91a9e9237518d1d73f455cb94..a80e99a1ee216277807fe3fd46baf1a5112b842e 100644 (file)
@@ -156,13 +156,13 @@ Send::set_metering (bool yn)
 }
 
 bool
-Send::can_support_input_configuration (ChanCount in) const
+Send::can_support_io_configuration (const ChanCount& in, ChanCount& out_is_ignored) const
 {
        if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
 
                /* not configured yet */
 
-               return true; /* we can support anything the first time we're asked */
+               return 1; /* we can support anything the first time we're asked */
 
        } else {
 
@@ -171,42 +171,35 @@ Send::can_support_input_configuration (ChanCount in) const
                */
 
                if (_io->output_maximum() == in) {
-
-                       return true;
+                       return 1;
                } 
        }
 
-       return false;
-}
-
-ChanCount
-Send::output_for_input_configuration (ChanCount in) const
-{
-       // from the internal (Insert) perspective a Send does not modify its input whatsoever
-       return in;
+       return -1;
 }
 
 bool
 Send::configure_io (ChanCount in, ChanCount out)
 {
        /* we're transparent no matter what.  fight the power. */
-       if (out != in)
+
+       if (out != in) {
                return false;
+       }
 
        _io->set_output_maximum (in);
        _io->set_output_minimum (in);
        _io->set_input_maximum (ChanCount::ZERO);
        _io->set_input_minimum (ChanCount::ZERO);
 
-       bool success = _io->ensure_io (ChanCount::ZERO, in, false, this) == 0;
-
-       if (success) {
-               Processor::configure_io(in, out);
-               _io->reset_panner();
-               return true;
-       } else {
+       if (_io->ensure_io (ChanCount::ZERO, in, false, this) != 0) {
                return false;
        }
+
+       Processor::configure_io(in, out);
+       _io->reset_panner();
+
+       return true;
 }
 
 ChanCount
@@ -226,3 +219,11 @@ Send::input_streams() const
 }
 
 
+void
+Send::expect_inputs (const ChanCount& expected)
+{
+       if (expected != expected_inputs) {
+               expected_inputs = expected;
+               _io->reset_panner ();
+       }
+}
index 1124b8960fbadc3e28b01aff867155219129642c..311e272903e510136bc3745a225827f1fded1143 100644 (file)
@@ -115,9 +115,9 @@ sigc::signal<void> Session::SendFeedback;
 sigc::signal<void> Session::SMPTEOffsetChanged;
 sigc::signal<void> Session::StartTimeChanged;
 sigc::signal<void> Session::EndTimeChanged;
-
 sigc::signal<void> Session::AutoBindingOn;
 sigc::signal<void> Session::AutoBindingOff;
+sigc::signal<void, std::string, std::string> Session::Exported;
 
 Session::Session (AudioEngine &eng,
                  const string& fullpath,
@@ -140,6 +140,7 @@ Session::Session (AudioEngine &eng,
          diskstreams (new DiskstreamList),
          routes (new RouteList),
          auditioner ((Auditioner*) 0),
+         _total_free_4k_blocks (0),
          _bundle_xml_node (0),
          _click_io ((IO*) 0),
          main_outs (0)
@@ -152,8 +153,8 @@ Session::Session (AudioEngine &eng,
 
        cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
 
-       n_physical_outputs = _engine.n_physical_outputs();
-       n_physical_inputs =  _engine.n_physical_inputs();
+       n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
+       n_physical_inputs =  _engine.n_physical_inputs(DataType::AUDIO);
 
        first_stage_init (fullpath, snapshot_name);
 
@@ -210,6 +211,7 @@ Session::Session (AudioEngine &eng,
          midi_requests (16),
          diskstreams (new DiskstreamList),
          routes (new RouteList),
+         _total_free_4k_blocks (0),
          _bundle_xml_node (0),
          main_outs (0)
 
@@ -222,8 +224,8 @@ Session::Session (AudioEngine &eng,
 
        cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
 
-       n_physical_outputs = _engine.n_physical_outputs();
-       n_physical_inputs = _engine.n_physical_inputs();
+       n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
+       n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
 
        if (n_physical_inputs) {
                n_physical_inputs = max (requested_physical_in, n_physical_inputs);
@@ -1086,6 +1088,12 @@ Session::handle_locations_changed (Locations::LocationList& locations)
                        set_loop = true;
                }
 
+               if (location->is_start()) {
+                       start_location = location;
+               }
+               if (location->is_end()) {
+                       end_location = location;
+               }
        }
 
        if (!set_loop) {
@@ -1523,16 +1531,16 @@ Session::new_midi_track (TrackMode mode, uint32_t how_many)
                }
        }
 
-       /*
+#if 0  
        vector<string> physinputs;
        vector<string> physoutputs;
+
+       _engine.get_physical_outputs (DataType::MIDI, physoutputs);
+       _engine.get_physical_inputs (DataType::MIDI, physinputs);
        uint32_t nphysical_in;
        uint32_t nphysical_out;
-
-       _engine.get_physical_outputs (physoutputs);
-       _engine.get_physical_inputs (physinputs);
-       control_id = ntracks() + nbusses() + 1;
-       */
+       control_id = ntracks() + nbusses();
+#endif
 
        while (how_many) {
 
@@ -1555,7 +1563,7 @@ Session::new_midi_track (TrackMode mode, uint32_t how_many)
                } while (track_id < (UINT_MAX-1));
 
                /*
-               if (Config->get_input_auto_connect() & AutoConnectPhysical) {
+                 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
                        nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
                } else {
                        nphysical_in = 0;
@@ -1703,8 +1711,8 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
        uint32_t nphysical_in;
        uint32_t nphysical_out;
 
-       _engine.get_physical_outputs (physoutputs);
-       _engine.get_physical_inputs (physinputs);
+       _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
+       _engine.get_physical_inputs (DataType::AUDIO, physinputs);
        control_id = ntracks() + nbusses() + 1;
 
        while (how_many) {
@@ -1889,8 +1897,8 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_
        vector<string> physinputs;
        vector<string> physoutputs;
 
-       _engine.get_physical_outputs (physoutputs);
-       _engine.get_physical_inputs (physinputs);
+       _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
+       _engine.get_physical_inputs (DataType::AUDIO, physinputs);
        control_id = ntracks() + nbusses() + 1;
 
        while (how_many) {
@@ -2418,6 +2426,8 @@ Session::get_maximum_extent () const
        boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
 
        for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
+               if ((*i)->destructive())  //ignore tape tracks when getting max extents
+                       continue;
                boost::shared_ptr<Playlist> pl = (*i)->playlist();
                if ((me = pl->get_maximum_extent()) > max) {
                        max = me;
@@ -2509,7 +2519,7 @@ Session::new_region_name (string old)
 }
 
 int
-Session::region_name (string& result, string base, bool newlevel) const
+Session::region_name (string& result, string base, bool newlevel)
 {
        char buf[16];
        string subbase;
@@ -2521,15 +2531,11 @@ Session::region_name (string& result, string base, bool newlevel) const
                Glib::Mutex::Lock lm (region_lock);
 
                snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
-
-
                result = "region.";
                result += buf;
 
        } else {
 
-               /* XXX this is going to be slow. optimize me later */
-
                if (newlevel) {
                        subbase = base;
                } else {
@@ -2543,37 +2549,25 @@ Session::region_name (string& result, string base, bool newlevel) const
 
                }
 
-               bool name_taken = true;
-
                {
                        Glib::Mutex::Lock lm (region_lock);
 
-                       for (int n = 1; n < 5000; ++n) {
-
-                               result = subbase;
-                               snprintf (buf, sizeof (buf), ".%d", n);
-                               result += buf;
+                       map<string,uint32_t>::iterator x;
 
-                               name_taken = false;
+                       result = subbase;
 
-                               for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
-                                       if (i->second->name() == result) {
-                                               name_taken = true;
-                                               break;
-                                       }
-                               }
+                       if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
+                               result += ".1";
+                               region_name_map[subbase] = 1;
+                       } else {
+                               x->second++;
+                               snprintf (buf, sizeof (buf), ".%d", x->second);
 
-                               if (!name_taken) {
-                                       break;
-                               }
+                               result += buf;
                        }
                }
-
-               if (name_taken) {
-                       fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
-                       /*NOTREACHED*/
-               }
        }
+
        return 0;
 }
 
@@ -2635,7 +2629,7 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
           add the region to the region list.
        */
 
-       set_dirty();
+       set_dirty ();
 
        if (added) {
 
@@ -2660,6 +2654,8 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
 
                        region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
                        region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
+
+                       update_region_name_map (region);
                }
 
                if (!v.empty()) {
@@ -2668,6 +2664,25 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
        }
 }
 
+void
+Session::update_region_name_map (boost::shared_ptr<Region> region)
+{
+       string::size_type last_period = region->name().find_last_of ('.');
+       
+       if (last_period != string::npos && last_period < region->name().length() - 1) {
+               
+               string base = region->name().substr (0, last_period);
+               string number = region->name().substr (last_period+1);
+               map<string,uint32_t>::iterator x;
+               
+               /* note that if there is no number, we get zero from atoi,
+                  which is just fine
+               */
+               
+               region_name_map[base] = atoi (number);
+       }
+}
+
 void
 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
 {
@@ -2681,6 +2696,10 @@ Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_regio
                /* relay hidden changes */
                RegionHiddenChange (region);
        }
+
+       if (what_changed & NameChanged) {
+               update_region_name_map (region);
+       }
 }
 
 void
@@ -4022,11 +4041,11 @@ Session::freeze (InterThreadInfo& itt)
        return 0;
 }
 
-int
-Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
-                              bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
+boost::shared_ptr<Region>
+Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,   
+                         bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
 {
-       int ret = -1;
+       boost::shared_ptr<Region> result;
        boost::shared_ptr<Playlist> playlist;
        boost::shared_ptr<AudioFileSource> fsource;
        uint32_t x;
@@ -4038,6 +4057,13 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
        BufferSet buffers;
        SessionDirectory sdir(get_best_session_directory_for_new_source ());
        const string sound_dir = sdir.sound_path().to_string();
+       nframes_t len = end - start;
+
+       if (end <= start) {
+               error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
+                                        end, start) << endmsg;
+               return result;
+       }
 
        // any bigger than this seems to cause stack overflows in called functions
        const nframes_t chunk_size = (128 * 1024)/4;
@@ -4142,21 +4168,19 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
 
                /* construct a region to represent the bounced material */
 
-               boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
-                                                                          region_name_from_path (srcs.front()->name(), true));
-
-               ret = 0;
+               result = RegionFactory::create (srcs, 0, srcs.front()->length(), 
+                                               region_name_from_path (srcs.front()->name(), true));
        }
 
   out:
-       if (ret) {
+       if (!result) {
                for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
                        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
 
                        if (afs) {
                                afs->mark_for_remove ();
                        }
-
+                       
                        (*src)->drop_references ();
                }
 
@@ -4171,7 +4195,7 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
 
        g_atomic_int_set (&processing_prohibited, 0);
 
-       return ret;
+       return result;
 }
 
 BufferSet&
index ec5de23caffbc537f74fb58719a0b15e614a6a92..eac71fb5d1eda01d9abfd46700bdd78c292c0816 100644 (file)
@@ -171,7 +171,8 @@ Session::butler_thread_work ()
        uint32_t err = 0;
        int32_t bytes;
        bool compute_io;
-       struct timeval begin, end;
+       microseconds_t begin, end;
+
        struct pollfd pfd[1];
        bool disk_work_outstanding = false;
        DiskstreamList::iterator i;
@@ -248,7 +249,7 @@ Session::butler_thread_work ()
                bytes = 0;
                compute_io = true;
 
-               gettimeofday (&begin, 0);
+               begin = get_microseconds();
 
                boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
 
@@ -295,17 +296,16 @@ Session::butler_thread_work ()
                }
 
                if (compute_io) {
-                       gettimeofday (&end, 0);
-                       
-                       double b = begin.tv_sec  + (begin.tv_usec/1000000.0);
-                       double e = end.tv_sec + (end.tv_usec / 1000000.0);
-                       
-                       _read_data_rate = bytes / (e - b);
+                       end = get_microseconds(); 
+                       if(end-begin > 0) {
+                       _read_data_rate = (float) bytes / (float) (end - begin);
+                       } else { _read_data_rate = 0; // infinity better
+                        }
                }
 
                bytes = 0;
                compute_io = true;
-               gettimeofday (&begin, 0);
+               begin = get_microseconds();
 
                for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) {
                        // cerr << "write behind for " << (*i)->name () << endl;
@@ -349,12 +349,13 @@ Session::butler_thread_work ()
                }
 
                if (compute_io) {
-                       gettimeofday (&end, 0);
-                       
-                       double b = begin.tv_sec  + (begin.tv_usec/1000000.0);
-                       double e = end.tv_sec + (end.tv_usec / 1000000.0);
-                       
-                       _write_data_rate = bytes / (e - b);
+                       // there are no apparent users for this calculation?
+                       end = get_microseconds();
+                       if(end-begin > 0) {
+                       _write_data_rate = (float) bytes / (float) (end - begin);
+                       } else {
+                       _write_data_rate = 0; // Well, infinity would be better
+                       }
                }
                
                if (!disk_work_outstanding) {
@@ -421,7 +422,7 @@ Session::read_data_rate () const
        /* disk i/o in excess of 10000MB/sec indicate the buffer cache
           in action. ignore it.
        */
-       return _read_data_rate > 10485760000.0f ? 0.0f : _read_data_rate;
+       return _read_data_rate > 10485.7600000f ? 0.0f : _read_data_rate;
 }
 
 float
@@ -430,7 +431,7 @@ Session::write_data_rate () const
        /* disk i/o in excess of 10000MB/sec indicate the buffer cache
           in action. ignore it.
        */
-       return _write_data_rate > 10485760000.0f ? 0.0f : _write_data_rate;
+       return _write_data_rate > 10485.7600000f ? 0.0f : _write_data_rate;
 }
 
 uint32_t
index e8670e719923c8bd5fbda3d9a1dd9fc44c913364..72bc3f23d71e29aae9863afebd39d306bba55787 100644 (file)
@@ -72,7 +72,7 @@ Session::memento_command_factory(XMLNode *n)
            before = new XMLNode(*n->children().front());
            after = new XMLNode(*n->children().back());
            child = before;
-    }
+    } 
                    
     if (!child)
     {
index 49b6d9b1503851a941a787c06529ba7ddcf12bde..0111e4ed0bdb4003498b6c58d688b436c8fd887b 100644 (file)
@@ -254,6 +254,12 @@ ExportSpecification::prepare (nframes_t blocksize, nframes_t frate)
                output_data = (void*) malloc (sample_bytes * out_samples_max);
        }
 
+       pos = start_frame;
+       end_frame = end_frame;
+       total_frames = end_frame - start_frame;
+       running = true; 
+       do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */
+
        return 0;
 }
 
@@ -436,14 +442,10 @@ Session::start_export (ExportSpecification& spec)
                return -1;
        }
 
-       spec.pos = spec.start_frame;
-       spec.end_frame = spec.end_frame;
-       spec.total_frames = spec.end_frame - spec.start_frame;
-       spec.running = true; 
-       spec.do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */
-
        spec.freewheel_connection = _engine.Freewheel.connect (sigc::bind (mem_fun (*this, &Session::process_export), &spec));
 
+       cerr << "Start export at pos = " << spec.pos << endl;
+
        return _engine.freewheel (true);
 }
 
@@ -455,14 +457,14 @@ Session::stop_export (ExportSpecification& spec)
        spec.freewheel_connection.disconnect ();
        spec.clear (); /* resets running/stop etc */
 
+       Exported (spec.path, name());
+
        return 0;
 }
 
-int 
-Session::prepare_to_export (ExportSpecification& spec)
+int
+Session::pre_export ()
 {
-       int ret = -1;
-
        wait_till_butler_finished ();
 
        /* take everyone out of awrite to avoid disasters */
@@ -475,6 +477,27 @@ Session::prepare_to_export (ExportSpecification& spec)
                }
        }
 
+       /* make sure we are actually rolling */
+
+       if (get_record_enabled()) {
+               disable_record (false);
+       }
+
+       /* no slaving */
+
+       post_export_slave = Config->get_slave_source ();
+       post_export_position = _transport_frame;
+
+       Config->set_slave_source (None);
+
+       return 0;
+}
+
+int 
+Session::prepare_to_export (ExportSpecification& spec)
+{
+       int ret = -1;
+
        /* get everyone to the right position */
 
        {
@@ -490,22 +513,21 @@ Session::prepare_to_export (ExportSpecification& spec)
                }
        }
 
-       /* make sure we are actually rolling */
+       cerr << "Everybdy is at " << spec.start_frame << endl;
 
-       if (get_record_enabled()) {
-               disable_record (false);
-       }
+       /* we just did the core part of a locate() call above, but
+          for the sake of any GUI, put the _transport_frame in
+          the right place too.
+       */
 
+       _transport_frame = spec.start_frame;
        _exporting = true;
-       
-       /* no slaving */
-
-       post_export_slave = Config->get_slave_source ();
-       post_export_position = _transport_frame;
-
-       Config->set_slave_source (None);
 
-       /* get transport ready */
+       /* get transport ready. note how this is calling butler functions
+          from a non-butler thread. we waited for the butler to stop
+          what it was doing earlier in Session::pre_export() and nothing
+          since then has re-awakened it.
+        */
 
        set_transport_speed (1.0, false);
        butler_transport_work ();
@@ -528,6 +550,10 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
        int ret = -1;
        nframes_t this_nframes;
 
+       cerr << "Export process at pos = " << spec->pos << " _exporting = "
+            << _exporting << " running = " << spec->running << " stop = "
+            << spec->stop << endl;
+
        /* This is not required to be RT-safe because we are running while freewheeling */
 
        if (spec->do_freewheel == false) {
@@ -545,12 +571,14 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
 
        if (!_exporting) {
                /* finished, but still freewheeling */
-               process_without_events (nframes);
+               cerr << "\tExport ... not exporting yet, no_roll() for " << nframes <<endl;
+               no_roll (nframes, 0);
                return 0;
        }
-               
+       
        if (!spec->running || spec->stop || (this_nframes = min ((spec->end_frame - spec->pos), nframes)) == 0) {
-               process_without_events (nframes);
+               cerr << "\tExport ... not running or at end, no_roll() for " << nframes <<endl;
+               no_roll (nframes, 0);
                return stop_export (*spec);
        }
 
@@ -604,6 +632,8 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
                }
        }
 
+       cerr << "\tprocess " << nframes << endl;
+
        if (spec->process (nframes)) {
                goto out;
        }
@@ -611,6 +641,8 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
        spec->pos += nframes;
        spec->progress = 1.0 - (((float) spec->end_frame - spec->pos) / spec->total_frames);
 
+       cerr << "\t@ " << spec->pos << " prog = " << spec->progress << endl;
+
        /* and we're good to go */
 
        ret = 0;
@@ -629,7 +661,7 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
 }
 
 void
-Session::finalize_audio_export ()
+Session::finalize_export ()
 {
        _engine.freewheel (false);
        _exporting = false;
index d6890b31ae3f34346b9ba8d2d58a6ffe72d34247..abe802548ad6e55846b2085f02f18c18a5a2ba87 100644 (file)
@@ -867,18 +867,38 @@ Session::maybe_sync_start (nframes_t& nframes, nframes_t& offset)
 
        if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
 
+               /* generate silence up to the sync point, then
+                  adjust nframes + offset to reflect whatever
+                  is left to do.
+               */
+
                no_roll (sync_offset, 0);
                nframes -= sync_offset;
                offset += sync_offset;
                waiting_for_sync_offset = false;
                
                if (nframes == 0) {
-                       return true; // done
+                       return true; // done, nothing left to process
                }
                
        } else {
+
+               /* sync offset point is not within this process()
+                  cycle, so just generate silence. and don't bother 
+                  with any fancy stuff here, just the minimal silence.
+               */
+
+               g_atomic_int_inc (&processing_prohibited);
                no_roll (nframes, 0);
-               return true; // done
+               g_atomic_int_dec_and_test (&processing_prohibited);
+
+               if (Config->get_locate_while_waiting_for_sync()) {
+                       if (micro_locate (nframes)) {
+                               /* XXX ERROR !!! XXX */
+                       }
+               }
+
+               return true; // done, nothing left to process
        }
 
        return false;
index c228f3c47b92ae1d27dbc9c9f4a9ee3d0705ecee..8ebf3ab07b1f27d7e779596bf02512667552b020 100644 (file)
@@ -432,8 +432,9 @@ Session::setup_raid_path (string path)
        AudioFileSource::set_search_path (sound_search_path.to_string ());
        SMFSource::set_search_path (midi_search_path.to_string ());
 
+
        // reset the round-robin soundfile path thingie
-       
+
        last_rr_session_dir = session_dirs.begin();
 }
 
@@ -1794,6 +1795,43 @@ Session::save_template (string template_name)
        return 0;
 }
 
+int
+Session::rename_template (string old_name, string new_name) 
+{
+       sys::path old_path (user_template_directory());
+       old_path /= old_name + template_suffix;
+
+       sys::path new_path(user_template_directory());
+       new_path /= new_name + template_suffix;
+
+       if (sys::exists (new_path)) {
+               warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
+                                         new_path.to_string()) << endmsg;
+               return -1;
+       }
+
+       try {
+               sys::rename (old_path, new_path);
+               return 0;
+       } catch (...) {
+               return -1;
+       }
+}
+
+int
+Session::delete_template (string name) 
+{
+       sys::path path = user_template_directory();
+       path /= name + template_suffix;
+
+       try {
+               sys::remove (path);
+               return 0;
+       } catch (...) {
+               return -1;
+       }
+}
+
 void
 Session::refresh_disk_space ()
 {
@@ -2009,17 +2047,13 @@ Session::XMLNamedSelectionFactory (const XMLNode& node)
 string
 Session::automation_dir () const
 {
-       string res = _path;
-       res += "automation/";
-       return res;
+       return Glib::build_filename (_path, "automation");
 }
 
 string
 Session::analysis_dir () const
 {
-       string res = _path;
-       res += "analysis/";
-       return res;
+       return Glib::build_filename (_path, "analysis");
 }
 
 int
index 61a741d0fb5d27d2ad9bd10b92379d3828a80231..cc94595f8c1b04f7fbc069624ece18c554d1793c 100644 (file)
@@ -138,7 +138,7 @@ Session::realtime_stop (bool abort)
 
        // FIXME: where should this really be? [DR]
        //send_full_time_code();
-       deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame);
+       deliver_mmc (MIDI::MachineControl::cmdStop, 0);
        deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
 
        if (_transport_speed < 0.0f) {
@@ -658,6 +658,25 @@ Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush,
        }
 }
 
+int
+Session::micro_locate (nframes_t distance)
+{
+       boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+       
+       for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+               if (!(*i)->can_internal_playback_seek (distance)) {
+                       return -1;
+               }
+       }
+
+       for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+               (*i)->internal_playback_seek (distance);
+       }
+       
+       _transport_frame += distance;
+       return 0;
+}
+
 void
 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
 {
@@ -1314,6 +1333,11 @@ Session::update_latency_compensation (bool with_stop, bool abort)
 
        _worst_track_latency = 0;
 
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+       cerr << "\n---------------------------------\nUPDATE LATENCY\n";
+#endif
+
        boost::shared_ptr<RouteList> r = routes.reader ();
 
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
@@ -1340,6 +1364,10 @@ Session::update_latency_compensation (bool with_stop, bool abort)
                _engine.update_total_latencies ();
        }
 
+#ifdef DEBUG_LATENCY
+       cerr << "\tworst was " << _worst_track_latency << endl;
+#endif
+
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
                (*i)->set_latency_delay (_worst_track_latency);
        }
index ab090381b4d27caea3a4d676b7e4910d3b109181..b6efe27d36dad6447e158ccd8a4cac209bbe3f82 100644 (file)
 #include <cstring>
 #include <cerrno>
 #include <climits>
+#include <cstdarg>
 
 #include <pwd.h>
 #include <sys/utsname.h>
 #include <sys/stat.h>
 
 #include <glibmm/miscutils.h>
+
 #include <ardour/sndfilesource.h>
 #include <ardour/sndfile_helpers.h>
 #include <ardour/utils.h>
+#include <ardour/version.h>
 
 #include "i18n.h"
 
@@ -44,6 +47,22 @@ const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSou
                                                                                           AudioFileSource::Removable|
                                                                                           AudioFileSource::RemovableIfEmpty|
                                                                                           AudioFileSource::CanRename);
+
+static void
+snprintf_bounded_null_filled (char* target, size_t target_size, char* fmt, ...)
+{
+       char buf[target_size+1];
+       va_list ap;
+
+       va_start (ap, fmt);
+       vsnprintf (buf, target_size+1, fmt, ap);
+       va_end (ap);
+
+       memset (target, 0, target_size);
+       memcpy (target, buf, target_size);
+
+}
+
 SndFileSource::SndFileSource (Session& s, const XMLNode& node)
        : AudioFileSource (s, node)
 {
@@ -140,21 +159,8 @@ SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, Heade
                _broadcast_info = new SF_BROADCAST_INFO;
                memset (_broadcast_info, 0, sizeof (*_broadcast_info));
                
-               snprintf (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
-               
-               struct utsname utsinfo;
-
-               if (uname (&utsinfo)) {
-                       error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
-                       return;
-               }
-               
-               snprintf (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour:%s:%s:%s:%s:%s)", 
-                         Glib::get_real_name().c_str(),
-                         utsinfo.nodename,
-                         utsinfo.sysname,
-                         utsinfo.release,
-                         utsinfo.version);
+               snprintf_bounded_null_filled (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
+               snprintf_bounded_null_filled (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour %s)", Glib::get_real_name().c_str());
                
                _broadcast_info->version = 1;  
                _broadcast_info->time_reference_low = 0;  
@@ -162,7 +168,7 @@ SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, Heade
                
                /* XXX do something about this field */
                
-               snprintf (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
+               snprintf_bounded_null_filled (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
                
                /* coding history is added by libsndfile */
 
@@ -533,25 +539,25 @@ SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow
        /* random code is 9 digits */
        
        int random_code = random() % 999999999;
+
+       snprintf_bounded_null_filled (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
+                                     Config->get_bwf_country_code().c_str(),
+                                     Config->get_bwf_organization_code().c_str(),
+                                     bwf_serial_number,
+                                     now.tm_hour,
+                                     now.tm_min,
+                                     now.tm_sec,
+                                     random_code);
        
-       snprintf (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
-                 Config->get_bwf_country_code().c_str(),
-                 Config->get_bwf_organization_code().c_str(),
-                 bwf_serial_number,
-                 now.tm_hour,
-                 now.tm_min,
-                 now.tm_sec,
-                 random_code);
-       
-       snprintf (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
-                 1900 + now.tm_year,
-                 now.tm_mon,
-                 now.tm_mday);
+       snprintf_bounded_null_filled (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
+                                     1900 + now.tm_year,
+                                     now.tm_mon + 1, // move from 0..11 to 1..12
+                                     now.tm_mday);
        
-       snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
-                 now.tm_hour,
-                 now.tm_min,
-                 now.tm_sec);
+       snprintf_bounded_null_filled (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
+                                     now.tm_hour,
+                                     now.tm_min,
+                                     now.tm_sec);
 
        /* now update header position taking header offset into account */
        
index 53389976598699089d5c216be4e4dd385b650e13..0b7c0f3d9e4cc658c0cbc2e2652b4a4c91bcfaf3 100644 (file)
@@ -129,10 +129,12 @@ SourceFactory::create (Session& s, const XMLNode& node, bool defer_peaks)
        DataType type = DataType::AUDIO;
        const XMLProperty* prop = node.property("type");
 
-       if (prop) {
-               type = DataType(prop->value());
+       if (!prop) {
+               return boost::shared_ptr<Source>();
        }
 
+       type = DataType (prop->value());
+
        if (type == DataType::AUDIO) {
 
                try {
index 052105cc855148d3c9dd18ad01d6fedee17a3354..ed52fd70a95cf1a608569d98caef96eb2d9a6343 100644 (file)
@@ -104,6 +104,11 @@ Track::update_total_latency ()
                }
        }
 
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+       cerr << _name << ": internal redirect (final) latency = " << _own_latency << endl;
+#endif
+
        set_port_latency (_own_latency);
 
        if (old != _own_latency) {
index 471d823496a05a9260659c949a27c5a51572200c..b9d115bc400c7473db6b32246e4b732d07dad34b 100644 (file)
@@ -23,17 +23,17 @@ ARDOUR::UserBundle::UserBundle (XMLNode const & x, bool i)
        }
 }
 
-uint32_t
+ARDOUR::ChanCount
 ARDOUR::UserBundle::nchannels () const
 {
        Glib::Mutex::Lock lm (_ports_mutex);
-       return _ports.size ();
+       return ChanCount (type(), _ports.size ());
 }
 
 const ARDOUR::PortList&
 ARDOUR::UserBundle::channel_ports (uint32_t n) const
 {
-       assert (n < nchannels ());
+       assert (n < nchannels ().get (type()));
 
        Glib::Mutex::Lock lm (_ports_mutex);
        return _ports[n];
@@ -42,7 +42,7 @@ ARDOUR::UserBundle::channel_ports (uint32_t n) const
 void
 ARDOUR::UserBundle::add_port_to_channel (uint32_t c, std::string const & p)
 {
-       assert (c < nchannels ());
+       assert (c < nchannels ().get (type()));
        
        PortsWillChange (c);
 
@@ -57,7 +57,7 @@ ARDOUR::UserBundle::add_port_to_channel (uint32_t c, std::string const & p)
 void
 ARDOUR::UserBundle::remove_port_from_channel (uint32_t c, std::string const & p)
 {
-       assert (c < nchannels ());
+       assert (c < nchannels ().get (type()));
 
        PortsWillChange (c);
 
@@ -75,7 +75,7 @@ ARDOUR::UserBundle::remove_port_from_channel (uint32_t c, std::string const & p)
 bool
 ARDOUR::UserBundle::port_attached_to_channel (uint32_t c, std::string const & p) const
 {
-       assert (c < nchannels ());
+       assert (c < nchannels ().get (type()));
 
        Glib::Mutex::Lock lm (_ports_mutex);
        return std::find (_ports[c].begin(), _ports[c].end(), p) != _ports[c].end();
@@ -110,7 +110,7 @@ ARDOUR::UserBundle::set_channels (uint32_t n)
 void
 ARDOUR::UserBundle::remove_channel (uint32_t r)
 {
-       assert (r < nchannels ());
+       assert (r < nchannels ().get (type()));
 
        ConfigurationWillChange ();
 
index 58443bd0053a937b8333dcaa117b6700631e5ef3..1906d92b887dfe3f5c9f52e10927f43baa121300 100644 (file)
@@ -25,6 +25,7 @@
 #include <cmath>
 #include <cctype>
 #include <string>
+#include <cstring>
 #include <cerrno>
 #include <iostream>
 #include <sys/types.h>
index 47b5cb4fba792f011af025b1ab5fbf18b5cec9ad..11169a74de8f02fd78cbe116ec8fd0d24219e7fd 100644 (file)
 #include <algorithm>
 #include <vector>
 #include <string>
-#include <ctype.h>
+#include <cctype>
 
 #include <cstdlib>
 #include <cstdio> // so libraptor doesn't complain
 #include <cmath>
 #include <dirent.h>
-#include <string.h> // for memmove
+#include <cstring> // for memmove
 #include <sys/stat.h>
 #include <cerrno>
 
+#include <glibmm/ustring.h>
+#include <glibmm/miscutils.h>
+
 #include <lrdf.h>
 #include <fst.h>
 
@@ -156,13 +159,12 @@ VSTPlugin::get_state()
 
                /* save it to a file */
 
-               string path;
+               Glib::ustring path = Glib::build_filename (get_user_ardour_path (), "vst");
                struct stat sbuf;
 
                sys::path user_vst_directory(user_config_directory());
        
                user_vst_directory /= "vst";
-
                path = user_vst_directory.to_string();
 
                if (stat (path.c_str(), &sbuf)) {
@@ -187,7 +189,7 @@ VSTPlugin::get_state()
                        return *root;
                }
                
-               path += "something";
+               path = Glib::build_filename (path, "something");
                
                /* store information */
 
index 3af7019e52bc2dfec3e9c0750b6ace1243abe284..cb3dfa9c1a45ec395cfe9f6195cb756453dd084c 100644 (file)
@@ -8,7 +8,7 @@ cairomm_files = glob.glob('cairomm/*.cc')
 
 Import('env libraries install_prefix')
 
-cairomm = env.Copy()
+cairomm = env.Clone()
 cairomm.Merge([libraries['cairo']])
 
 cairomm.Append(CXXFLAGS='-DHAVE_CONFIG_H')
index 3b496fb3f1a42be258c049d94dbcc826eae3f443..bd460f971e8a9c29c8be93c9c4095a46956c7d53 100644 (file)
@@ -19,7 +19,7 @@ libclearlooks_files = [
 
 Import ('env install_prefix')
 
-clearlooks = env.Copy()
+clearlooks = env.Clone()
 
 clearlooks.Replace(CCFLAGS = ' `pkg-config --cflags gtk+-2.0 cairo` ',
                    LINKFLAGS = ' `pkg-config --libs gtk+-2.0 cairo` ')
index bdffd959b5745c55ce2a3d8b44036db515f6b991..576283d73cd7d5132836c3f756697815605ed424 100644 (file)
@@ -8,7 +8,7 @@ import glob
 fst_src = glob.glob('*.c')
 
 Import('env install_prefix')
-fst = env.Copy(CC="winegcc")
+fst = env.Clone(CC="winegcc")
 fst.Append (CPPPATH=".")
 
 if fst['VST']:
index 66434396a3d9b562c38d5d0f8c1488d5b6d1e5f6..bbf65ad2283a221b7b2aa971a52f4e6f254d274c 100644 (file)
@@ -9,7 +9,7 @@ glibmm2_files = glob.glob('glib/glibmm/*.cc')
 
 Import('env libraries install_prefix')
 
-glibmm2 = env.Copy()
+glibmm2 = env.Clone()
 glibmm2.Merge([libraries['sigc2'], libraries['glib2']])
 glibmm2.Append(LIBPATH='#libs/glibmm2',
                  CPPPATH='#libs/glibmm2/glib')
index 4e4bfa308f1b44e428741fc9b5ae5c1900e365ff..140cc376afb3a11ce6f1372512f68f90f190410e 100644 (file)
@@ -1,4 +1,4 @@
-/* glib/glibmmconfig.h.  Generated from glibmmconfig.h.in by configure.  */
+/* glib/glibmmconfig.h.  Generated by configure.  */
 #ifndef _GLIBMM_CONFIG_H
 #define _GLIBMM_CONFIG_H 1
 
@@ -78,7 +78,7 @@
 #ifdef GLIBMM_DLL
   #if defined(GLIBMM_BUILD) && defined(_WINDLL)
     /* Do not dllexport as it is handled by gendef on MSVC */
-    #define GLIBMM_API 
+    #define GLIBMM_API
   #elif !defined(GLIBMM_BUILD)
     #define GLIBMM_API __declspec(dllimport)
   #else
index c1e5fb849ec1e815f904b41bd69b96fd8ee76312..b1f479c3867d23546e9f10d2698705a9125ced2c 100644 (file)
@@ -7,7 +7,7 @@ import glob
 atkmm_files = glob.glob('atkmm/*.cc')
 
 Import('env libraries install_prefix')
-atkmm = env.Copy()
+atkmm = env.Clone()
 atkmm.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'] ])
 
 libatkmm = atkmm.SharedLibrary('atkmm', atkmm_files)
index dca82665dc97a5e44978f4ac7605416f47873a82..4155cc74ba5496797d8d210419024039f1095630 100644 (file)
@@ -7,7 +7,7 @@ import glob
 gdkmm2_files = glob.glob('gdkmm/*.cc')
 
 Import('env libraries install_prefix')
-gdkmm2 = env.Copy()
+gdkmm2 = env.Clone()
 gdkmm2.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'], libraries['pangomm'], libraries['cairomm']])
 gdkmm2.Append(CXXFLAGS=["-Ilibs/gtkmm2/gtk", "-DGLIBMM_EXCEPTIONS_ENABLED"])
 
index 32e45a131e4a6b165ecd6ed90387bf533592d82b..217ce5d48c0b587c328893dcd50e4b785f315f64 100644 (file)
@@ -7,7 +7,7 @@ import glob
 gtkmm2_files = glob.glob('gtkmm/*.cc')
 
 Import('env libraries install_prefix')
-gtkmm2 = env.Copy()
+gtkmm2 = env.Clone()
 gtkmm2.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'], libraries['pangomm'], libraries['atkmm'], libraries['gdkmm2'], libraries['cairomm'], libraries['gtk2-unix-print'] ])
 gtkmm2.Append(CXXFLAGS = ['-DGLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED', '-DGLIBMM_PROPERTIES_ENABLED', '-DGLIBMM_EXCEPTIONS_ENABLED'])
 
index 02d75193a08181902798b3335de61aa666ebb1c4..4b7bae8d1d0ae541795a93054638ea08f8e02cb6 100644 (file)
@@ -7,7 +7,7 @@ import glob
 pangomm_files = glob.glob('pangomm/*.cc')
 
 Import('env libraries install_prefix')
-pangomm = env.Copy()
+pangomm = env.Clone()
 pangomm.Merge([libraries['glibmm2'], libraries['pango'], libraries['sigc2'], libraries['cairomm'], libraries['cairo'], libraries['pangocairo'] ])
 
 if pangomm['IS_OSX']:
index a0ef88e6d1fac063e82bd7a31fc511fa01925457..3a3bd351d7586d952bdd8d29ddb132fe79e35d96 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env final_prefix install_prefix libraries i18n')
 
-gtkmm2ext = env.Copy()
+gtkmm2ext = env.Clone()
 gtkmm2ext.Merge ([ 
     libraries['sigc2'], 
     libraries['pbd'],
@@ -48,9 +48,7 @@ fastmeter.cc
 focus_entry.cc
 grouped_buttons.cc
 gtk_ui.cc
-hexentry.cc
 idle_adjustment.cc
-pathlist.cc
 pixfader.cc
 pixscroller.cc
 popup.cc
index a3b2a13bf5aaf37ed08a4e5bab6910c7cd95a880..90954e57b35f4c56eba9645a5c309ba29760ea4b 100644 (file)
@@ -36,7 +36,7 @@ using namespace Gtk;
 using namespace Gtkmm2ext;
 
 BarController::BarController (Gtk::Adjustment& adj,
-                             PBD::Controllable& mc,
+                             boost::shared_ptr<PBD::Controllable> mc,
                              sigc::slot<void,char*,unsigned int> lc) 
 
        : adjustment (adj),
index 90f95f82ef44b174d8241acc5ba477e91f357412..6c60deaa8ffbd71c22ea7eeff054a46386b584b5 100644 (file)
@@ -31,7 +31,7 @@ using namespace Gtkmm2ext;
 using namespace std;
 using namespace PBD;
 
-BindingProxy::BindingProxy (Controllable& c)
+BindingProxy::BindingProxy (boost::shared_ptr<Controllable> c)
        : prompter (0),
          controllable (c),
          bind_button (2),
@@ -65,7 +65,7 @@ bool
 BindingProxy::button_press_handler (GdkEventButton *ev)
 {
        if ((ev->state & bind_statemask) && ev->button == bind_button) { 
-               if (Controllable::StartLearning (&controllable)) {
+               if (Controllable::StartLearning (controllable.get())) {
                        string prompt = _("operate controller now");
                        if (prompter == 0) {
                                prompter = new PopUp (Gtk::WIN_POS_MOUSE, 30000, false);
@@ -73,7 +73,7 @@ BindingProxy::button_press_handler (GdkEventButton *ev)
                        }
                        prompter->set_text (prompt);
                        prompter->touch (); // shows popup
-                       learning_connection = controllable.LearningFinished.connect (mem_fun (*this, &BindingProxy::learning_finished));
+                       learning_connection = controllable->LearningFinished.connect (mem_fun (*this, &BindingProxy::learning_finished));
                }
                return true;
        }
@@ -95,7 +95,7 @@ bool
 BindingProxy::prompter_hiding (GdkEventAny *ev)
 {
        learning_connection.disconnect ();
-       Controllable::StopLearning (&controllable);
+       Controllable::StopLearning (controllable.get());
        return false;
 }
 
index 63c36558f1ce8f09931e34dd3c613a10b79a899b..bdd8919d36411343b97fd8a71e4f84407a76f3e3 100644 (file)
@@ -25,7 +25,7 @@
 #include <gtkmm2ext/fastmeter.h>
 #include <gtkmm2ext/utils.h>
 #include <gtkmm/style.h>
-#include <string.h>
+#include <cstring>
 
 #define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; }
 #define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; }
index f00c6cd1e1673042c2b9be17f041b43a6f41ff37..4ca23b024088ec7f9eb0337e38848d366f13d97e 100644 (file)
@@ -65,7 +65,6 @@ UI::UI (string namestr, int *argc, char ***argv)
        : AbstractUI<UIRequest> (namestr, true)
 {
        theMain = new Main (argc, argv);
-       tips = new Tooltips;
 
        _active = false;
 
index fe67e9ecec83a7877d24f8e06746dfaea1bfa1f7..5e9a6fed906501886fc79766f74a71f894a00982 100644 (file)
@@ -34,7 +34,7 @@ class BarController : public Gtk::Frame
   public:
        typedef sigc::slot<void,char*,unsigned int> LabelCallback;
 
-       BarController (Gtk::Adjustment& adj, PBD::Controllable&, LabelCallback lc = LabelCallback());
+       BarController (Gtk::Adjustment& adj, boost::shared_ptr<PBD::Controllable>, LabelCallback lc = LabelCallback());
 
        virtual ~BarController () {}
        
@@ -63,7 +63,7 @@ class BarController : public Gtk::Frame
        /* export this to allow direct connection to button events */
 
        Gtk::Widget& event_widget() { return darea; }
-       PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+       boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
 
   protected:
        Gtk::Adjustment&    adjustment;
index 1cde32c5bab3da9f613bb4fe73f345a5fb0249ce..844dc27d086ae6167a3d70a1b3de79dca1d17a83 100644 (file)
@@ -32,9 +32,9 @@ namespace PBD {
 class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
 {
    public:
-       BindableToggleButton (PBD::Controllable& c) : binding_proxy (c) {}
+       BindableToggleButton (boost::shared_ptr<PBD::Controllable> c) : binding_proxy (c) {}
 
-       explicit BindableToggleButton (PBD::Controllable& c, const std::string &label)
+       explicit BindableToggleButton (boost::shared_ptr<PBD::Controllable> c, const std::string &label)
                : Gtkmm2ext::StatefulToggleButton (label), binding_proxy (c) {}
 
        virtual ~BindableToggleButton() {}
@@ -48,7 +48,8 @@ class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
                }
        }
        
-       PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+       boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
+
   private:
        BindingProxy binding_proxy;
 };
@@ -56,9 +57,9 @@ class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
 class BindableButton : public Gtkmm2ext::StatefulButton
 {
    public:
-       BindableButton (PBD::Controllable& c) : binding_proxy (c) {}
+       BindableButton (boost::shared_ptr<PBD::Controllable> c) : binding_proxy (c) {}
 
-       explicit BindableButton (PBD::Controllable& c, const std::string &label)
+       explicit BindableButton (boost::shared_ptr<PBD::Controllable> c, const std::string &label)
                : Gtkmm2ext::StatefulButton (label), binding_proxy (c) {}
 
        ~BindableButton() {}
@@ -72,7 +73,7 @@ class BindableButton : public Gtkmm2ext::StatefulButton
                }
        }
 
-       PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+       boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
 
   private:
        BindingProxy binding_proxy;
index dd9b94319df27df59d3257a1051d172d158e3c1d..ecb95bf8156feabb68af0c968845a2698873ef3b 100644 (file)
@@ -24,6 +24,7 @@
 #include <string>
 
 #include <gtkmm2ext/popup.h>
+#include <boost/shared_ptr.hpp>
 
 namespace PBD {
        class Controllable;
@@ -32,7 +33,7 @@ namespace PBD {
 class BindingProxy : public sigc::trackable
 {
    public:
-       BindingProxy (PBD::Controllable&);
+       BindingProxy (boost::shared_ptr<PBD::Controllable>);
        virtual ~BindingProxy();
        
        void set_bind_button_state (guint button, guint statemask);
@@ -40,11 +41,11 @@ class BindingProxy : public sigc::trackable
 
        bool button_press_handler (GdkEventButton *);
 
-       PBD::Controllable* get_controllable() { return &controllable; }
-  protected:
+       boost::shared_ptr<PBD::Controllable> get_controllable() { return controllable; }
 
+  protected:
        Gtkmm2ext::PopUp*  prompter;
-       PBD::Controllable& controllable;
+       boost::shared_ptr<PBD::Controllable> controllable;
        guint bind_button;
        guint bind_statemask;
        sigc::connection learning_connection;
index 0c2ff0d7982c78f4072d5c486b61f6c684ad92f1..22ac517672903a06a5a9da17380014b0c842c026 100644 (file)
@@ -31,7 +31,6 @@
 #include <gtkmm/style.h>
 #include <gtkmm/textbuffer.h>
 #include <gtkmm/main.h>
-#include <gtkmm/tooltips.h>
 #include <gdkmm/color.h>
 #include <pbd/abstract_ui.h>
 #include <pbd/ringbufferNPT.h>
@@ -150,7 +149,6 @@ class UI : public Receiver, public AbstractUI<UIRequest>
        static pthread_t gui_thread;
        bool _active;
        Gtk::Main *theMain;
-       Gtk::Tooltips *tips;
        TextViewer *errors;
        Glib::RefPtr<Gtk::TextBuffer::Tag> error_ptag;
        Glib::RefPtr<Gtk::TextBuffer::Tag> error_mtag;
diff --git a/libs/gtkmm2ext/gtkmm2ext/hexentry.h b/libs/gtkmm2ext/gtkmm2ext/hexentry.h
deleted file mode 100644 (file)
index 410f542..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-    Copyright (C) 1999 Paul Barton-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.
-
-*/
-
-#ifndef __gtkmm2ext_hexentry_h__
-#define __gtkmm2ext_hexentry_h__
-
-#include <gtkmm.h>
-
-namespace Gtkmm2ext {
-
-class HexEntry : public Gtk::Entry
-
-{
-  public:
-       /* Take a byte-level representation of a series of hexadecimal
-          values and use them to set the displayed text of the entry.
-          Eg. if hexbuf[0] = 0xff and hexbuf[1] = 0xa1 and buflen = 2,
-          then the text will be set to "ff a1".
-       */
-
-       void set_hex (unsigned char *hexbuf, unsigned int buflen);
-
-       /* puts byte-level representation of current entry text
-          into hexbuf, and returns number of bytes written there.
-
-          NOTE: this will release the existing memory pointed to
-          by hexbuf if buflen indicates that it is not long enough
-          to hold the new representation, and hexbuf is not zero.
-
-          If the returned length is zero, the contents of hexbuf 
-          are undefined.
-       */
-
-       unsigned int get_hex (unsigned char *hexbuf, size_t buflen);
-
-  private:
-       bool on_key_press_event (GdkEventKey *);
-};
-
-} /* namespace */
-
-#endif /* __gtkmm2ext_hexentry_h__ */
diff --git a/libs/gtkmm2ext/gtkmm2ext/pathlist.h b/libs/gtkmm2ext/gtkmm2ext/pathlist.h
deleted file mode 100644 (file)
index f4a5973..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-    Copyright (C) 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.
-
-*/
-
-#ifndef __gtkmm2ext_pathlist_h__
-#define __gtkmm2ext_pathlist_h__
-
-#include <vector>
-#include <string>
-
-#include <gtkmm.h>
-
-namespace Gtkmm2ext {
-
-class PathList : public Gtk::VBox
-{
-  public:
-       PathList ();
-       ~PathList () {};
-               
-       std::vector<std::string> get_paths ();
-       void set_paths (std::vector<std::string> paths);
-       
-       sigc::signal<void> PathsUpdated;
-       
-  protected:
-       Gtk::Button    add_btn;
-       Gtk::Button    subtract_btn;
-
-       void add_btn_clicked ();
-       void subtract_btn_clicked ();
-
-  private:
-       struct PathColumns : public Gtk::TreeModel::ColumnRecord {
-               PathColumns() { add (paths); }
-               Gtk::TreeModelColumn<std::string> paths;
-       };
-       PathColumns path_columns;
-       
-       Glib::RefPtr<Gtk::ListStore> _store;
-       Gtk::TreeView  _view;
-       
-       void selection_changed ();
-};
-
-} // namespace Gtkmm2ext
-
-#endif // __gtkmm2ext_pathlist_h__
index 60c8eef660aaf332edac9c930fb8404ccbc4e436..46f70dacd8d3b22d772b9ecc3d98c5faffa252df 100644 (file)
@@ -24,6 +24,8 @@
 #include <gtkmm2ext/pixfader.h>
 #include <gtkmm2ext/binding_proxy.h>
 
+#include <boost/shared_ptr.hpp>
+
 namespace Gtkmm2ext {
        class Pix;
 }
@@ -39,9 +41,9 @@ class SliderController : public Gtkmm2ext::PixFader
   public:
        SliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                          Gtk::Adjustment* adj, int orientation,
-                         PBD::Controllable&,
+                         boost::shared_ptr<PBD::Controllable>,
                          bool with_numeric = true);
-
+       
         virtual ~SliderController () {}
 
        void set_value (float);
@@ -64,7 +66,7 @@ class VSliderController : public SliderController
   public:
        VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                           Gtk::Adjustment *adj,
-                          PBD::Controllable&,
+                          boost::shared_ptr<PBD::Controllable>,
                           bool with_numeric = true);
 };
 
@@ -73,7 +75,7 @@ class HSliderController : public SliderController
   public:
        HSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                           Gtk::Adjustment *adj,
-                          PBD::Controllable&,
+                          boost::shared_ptr<PBD::Controllable>,
                           bool with_numeric = true);
 };
 
diff --git a/libs/gtkmm2ext/hexentry.cc b/libs/gtkmm2ext/hexentry.cc
deleted file mode 100644 (file)
index 9862cac..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-    Copyright (C) 2000 Paul Barton-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.
-
-    $Id$
-*/
-
-#include <stdio.h> /* for sprintf, sigh ... */
-#include <string>
-#include <ctype.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtkmm2ext/hexentry.h>
-
-using namespace std;
-using namespace Gtkmm2ext;
-
-bool
-HexEntry::on_key_press_event (GdkEventKey *ev)
-
-{
-       if ((ev->keyval >= GDK_a && ev->keyval <= GDK_f) ||
-           (ev->keyval >= GDK_A && ev->keyval <= GDK_A) ||
-           (ev->keyval >= GDK_0 && ev->keyval <= GDK_9) ||
-           ev->keyval == GDK_space || 
-           ev->keyval == GDK_Tab ||
-           ev->keyval == GDK_Return ||
-           ev->keyval == GDK_BackSpace ||
-           ev->keyval == GDK_Delete) {
-               return Gtk::Entry::on_key_press_event (ev);
-       } else {
-               gdk_beep ();
-               return FALSE;
-       }
-}
-
-
-void
-HexEntry::set_hex (unsigned char *msg, unsigned int len) 
-       
-{
-       /* create a textual representation of the MIDI message */
-       
-       if (msg && len) {
-               char *rep;
-               
-               rep = new char[(len * 3) + 1];
-               for (size_t i = 0; i < len; i++) {
-                       sprintf (&rep[i*3], "%02x ", msg[i]);
-               }
-               rep[len * 3] = '\0';
-               set_text (rep);
-               delete [] rep;
-       } else {
-               set_text ("");
-       }
-}
-
-unsigned int
-HexEntry::get_hex (unsigned char *hexbuf, size_t buflen)
-
-{
-       int fetched_len;
-       char buf[3];
-       string text = get_text();
-       string::size_type length = text.length ();
-       string::size_type offset;
-
-       fetched_len = 0;
-       buf[2] = '\0';
-       offset = 0;
-
-       while (1) {
-               offset = text.find_first_of ("abcdef0123456789", offset);
-
-               if (offset == string::npos) {
-                       break;
-               }
-
-               /* grab two characters, but no more */
-               
-               buf[0] = text[offset];
-
-               if (offset < length - 1) {
-                       buf[1] = text[offset+1];
-                       offset += 2;
-               } else {
-                       buf[1] = '\0';
-                       offset += 1;
-               }
-
-               hexbuf[fetched_len++] = (char) strtol (buf, 0, 16);
-       }
-
-       return fetched_len;
-}
-
-
diff --git a/libs/gtkmm2ext/pathlist.cc b/libs/gtkmm2ext/pathlist.cc
deleted file mode 100644 (file)
index 7b3448e..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-    Copyright (C) 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.
-
-*/
-
-#include <gtkmm2ext/pathlist.h>
-
-#include "i18n.h"
-
-using namespace std;
-using namespace Gtkmm2ext;
-
-PathList::PathList ()
-       :
-       add_btn(_("+")),
-       subtract_btn(_("-")),
-       path_columns(),
-       _store(Gtk::ListStore::create(path_columns)),
-       _view(_store)
-{
-       _view.append_column(_("Paths"), path_columns.paths);
-       _view.set_size_request(-1, 100);
-       _view.set_headers_visible (false);
-       
-       Gtk::ScrolledWindow* scroll = manage(new Gtk::ScrolledWindow);
-       scroll->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
-       scroll->add(_view);
-       
-       add (*scroll);
-       
-       Gtk::HBox* btn_box = manage(new Gtk::HBox);
-       btn_box->add(add_btn);
-       btn_box->add(subtract_btn);
-
-       add (*btn_box);
-       
-       add_btn.signal_clicked().connect (mem_fun(*this, &PathList::add_btn_clicked));
-       subtract_btn.signal_clicked().connect (mem_fun(*this, &PathList::subtract_btn_clicked));
-       _view.get_selection()->signal_changed().connect (mem_fun(*this, &PathList::selection_changed));
-}
-
-vector<string>
-PathList::get_paths ()
-{
-       vector<string> paths;
-       
-       Gtk::TreeModel::Children children(_store->children());
-       
-       for (Gtk::TreeIter iter = children.begin(); iter != children.end(); ++iter) {
-               Gtk::ListStore::Row row = *iter;
-               
-               paths.push_back(row[path_columns.paths]);
-       }
-       
-       return paths;
-}
-
-void
-PathList::set_paths (vector<string> paths)
-{
-       _store->clear();
-       
-       for (vector<string>::iterator i = paths.begin(); i != paths.end(); ++i) {
-               Gtk::ListStore::iterator iter = _store->append();
-               Gtk::ListStore::Row row = *iter;
-               row[path_columns.paths] = *i;
-       }
-}
-
-void
-PathList::add_btn_clicked ()
-{
-       Gtk::FileChooserDialog path_chooser (_("Path Chooser"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
-       
-       path_chooser.add_button (Gtk::Stock::ADD, Gtk::RESPONSE_OK);
-       path_chooser.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-       
-       int result = path_chooser.run ();
-       
-       if (result == Gtk::RESPONSE_OK) {
-               string pathname = path_chooser.get_filename();
-               
-               if (pathname.length ()) {
-                       Gtk::ListStore::iterator iter = _store->append ();
-                       Gtk::ListStore::Row row = *iter;
-                       row[path_columns.paths] = pathname;
-                       
-                       PathsUpdated (); // EMIT_SIGNAL
-               }
-       }
-}
-
-void
-PathList::subtract_btn_clicked ()
-{
-       Gtk::ListStore::iterator iter = _view.get_selection()->get_selected();
-       _store->erase (iter);
-       
-       PathsUpdated (); // EMIT_SIGNAL
-}
-
-void
-PathList::selection_changed ()
-{
-       if (_view.get_selection()->count_selected_rows ()) {
-               subtract_btn.set_sensitive (true);
-       } else {
-               subtract_btn.set_sensitive (false);
-       }
-}
index 93dfb27ae2568baa2a1847e512b4498ff05aa052..92fd9d078b7ee5d442debdc817a139d21e8f4660 100644 (file)
@@ -30,7 +30,7 @@ using namespace PBD;
 
 SliderController::SliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                                    Gtk::Adjustment *adj,  int orientation,
-                                   Controllable& c,
+                                   boost::shared_ptr<Controllable> c,
                                    bool with_numeric)
 
        : PixFader (image, *adj, orientation),
@@ -60,7 +60,7 @@ SliderController::on_button_press_event (GdkEventButton *ev)
 
 VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                                      Gtk::Adjustment *adj,
-                                     Controllable& control,
+                                     boost::shared_ptr<Controllable> control,
                                      bool with_numeric)
 
        : SliderController (image, adj, VERT, control, with_numeric)
@@ -76,7 +76,7 @@ VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
 
 HSliderController::HSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                                      Gtk::Adjustment *adj,
-                                     Controllable& control,
+                                     boost::shared_ptr<Controllable> control,
                                      bool with_numeric)
        
        : SliderController (image, adj, HORIZ, control, with_numeric)
index 790762228767544922c52e3a563231253db82850..273fbe84df3f7565e80ce4010198bb7144faa6c3 100644 (file)
@@ -7,7 +7,7 @@ import glob
 gnomecanvasmm_files = glob.glob('libgnomecanvasmm/*.cc')
 
 Import('env libraries install_prefix')
-gnomecanvasmm = env.Copy()
+gnomecanvasmm = env.Clone()
 gnomecanvasmm.Merge([libraries['glibmm2'],
                      libraries['gtk2'],
                      libraries['sigc2'],
index 63c5285346e8db67b17950306c9c13ab955daa5d..70cdb637b1ea607d7dfbff6da2db3ef12e7b4152 100644 (file)
@@ -7,7 +7,7 @@ import glob
 sndfile_files = glob.glob('src/*.c') + glob.glob('src/GSM610/*.c') + glob.glob('src/G72x/*.c')
 
 Import('env install_prefix libraries use_flac')
-sndfile = env.Copy()
+sndfile = env.Clone()
 if use_flac:
     sndfile.Merge([libraries['flac'] ])
 
index 0915db9f3f32a9d4b38ff9eee3ab8d5f53e8e91b..222e9e249a565e26d008aa918e920de63f41fc1f 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env libraries install_prefix')
 
-midi2 = env.Copy()
+midi2 = env.Clone()
 midi2.Merge([ libraries['sigc2'], 
              libraries['xml'], 
              libraries['glibmm2'], 
index 1d45dc57f510a82b1ce9738103ef10594b5c874f..f612b4707af1fe0c5cf2075b05308fe424b08213 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <cstring>
 #include <string>
+#include <cstring>
 #include <cstdlib>
 #include <midi++/types.h>
 
index 87173f0874768bdfb7c0ce24e7ef59d4bf3bc99a..4b65e3ee385675ceb7ab19fc67d023ba1085a31c 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env libraries i18n install_prefix')
 
-pbd = env.Copy()
+pbd = env.Clone()
 
 domain = 'libpbd'
 
index 94d039ba8633aef20c4d9f462527831a7e996de6..0dbe6baf5227a5d18305a4c322330b6e1e8ab971 100644 (file)
@@ -21,7 +21,8 @@
 #include <stdint.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <errno.h>
+#include <cerrno>
+#include <cstring>
 
 #include <pbd/base_ui.h>
 #include <pbd/error.h>
@@ -85,20 +86,20 @@ BaseUI::setup_signal_pipe ()
        */
 
        if (pipe (signal_pipe)) {
-               error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, std::strerror (errno))
+               error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, ::strerror (errno))
                      << endmsg;
 
                return -1;
        }
 
        if (fcntl (signal_pipe[0], F_SETFL, O_NONBLOCK)) {
-               error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, std::strerror (errno))
+               error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, ::strerror (errno))
                      << endmsg;
                return -1;
        }
 
        if (fcntl (signal_pipe[1], F_SETFL, O_NONBLOCK)) {
-               error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, std::strerror (errno))
+               error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, ::strerror (errno))
                      << endmsg;
                return -1;
        }
index 7674410ec914ad3b3bfcbbfec0aa0c0b33050d08..7033e5f3b1b16bb79cb20b957613aca8323eae4a 100644 (file)
     $Id$
 */
 
-#include <ctype.h>
+#include <cctype>
 
-#include <string.h>
-#include <stdlib.h>
+#include <cstring>
+#include <cstdlib>
 
 #include <pbd/enumwriter.h>
 #include <pbd/error.h>
index f6850a57dc92a18de5bd94901356069e084fa2fe..76150824c7c4275c91398b8f7294e4165656a5fa 100644 (file)
@@ -1,5 +1,5 @@
 #define _XOPEN_SOURCE 600
-#include <stdlib.h>
+#include <cstdlib>
 #include <stdint.h>
 
 #include <pbd/fpu.h>
index acc549890a81c65eb469528cf36009575dc695db..f2731463431b30da1c37cb68cf2ef317afcce57f 100644 (file)
@@ -21,6 +21,7 @@
 #include <cstdio>
 #include <cstring>
 #include <string>
+#include <cstring>
 #include <limits.h>
 
 #include <pbd/mountpoint.h>
index eb913cc910d923b7f5e7d43471056639df411c97..e12df5efac696b19bb823bf4848eae58cf494e1f 100644 (file)
@@ -21,6 +21,7 @@
 #include <cstring>
 #include <cstdlib>
 #include <cstdio>
+#include <cstring>
 #include <vector>
 #include <dirent.h>
 
index e335f4418e7a34850a2cd087c667b8703bec4b40..e6c07cfdbe89b949432812609328afbf43c52e5c 100644 (file)
@@ -44,15 +44,11 @@ class FunctorCommand : public Command
        typedef typename FunctorMap::iterator FunctorMapIterator;
 
        public:
-       FunctorCommand(
-               std::string functor,
-               obj_type object,
-               arg_type b,
-               arg_type a
-       ) : functor_name(functor), 
-               object(object),
-               before(b),
-               after(a) 
+       FunctorCommand(std::string functor, obj_type& object, arg_type b, arg_type a) 
+               : functor_name(functor)
+               , object(object)
+               , before(b)
+               , after(a) 
        {
                method = find_functor(functor);
 
@@ -76,6 +72,7 @@ class FunctorCommand : public Command
                std::stringstream ss;
                
                XMLNode *node = new XMLNode("FunctorCommand");
+               node->add_property("type_name", typeid(obj_type).name());
                node->add_property("functor", functor_name);
                ss << before;
                node->add_property("before", ss.str());
index 434429e69d7d93e386b5a1a0e96272243c920035..46de65153e070a3a6e3b727cad155e9eebf63ba3 100644 (file)
@@ -21,6 +21,7 @@
 #include <cstdlib>
 #include <iostream>
 #include <vector>
+#include <cstdlib>
 
 #include <pbd/pool.h>
 #include <pbd/error.h>
index dc9a5e18abca108db3a2c314680cfa7d566b2041..39dd46be3d523c1399c321de692ed1c6f8c2970d 100644 (file)
@@ -30,7 +30,7 @@ PBD::trace_twb ()
 #ifdef HAVE_EXECINFO
 
 #include <execinfo.h>
-#include <stdlib.h>
+#include <cstdlib>
 
 void
 PBD::stacktrace (std::ostream& out, int levels)
index aeff37cce72e3f6dc70a9136b97e8df8a1f218fe..f04b4d94313d770cf078eb4ab4bf8d4acdbf3592 100644 (file)
@@ -21,6 +21,7 @@
 #include <iostream>
 #include <string>
 #include <sstream>
+#include <time.h>
 
 #include <pbd/undo.h>
 #include <pbd/xml++.h>
@@ -34,6 +35,7 @@ using namespace sigc;
 UndoTransaction::UndoTransaction ()
        : _clearing(false)
 {
+       gettimeofday (&_timestamp, 0);
 }
 
 UndoTransaction::UndoTransaction (const UndoTransaction& rhs)
index 9ac1ef48ee49de7c64e77df336e33b30b4f7f2fa..8d6bc93c243524f182a296f2f5e9a48cecd850a7 100644 (file)
@@ -25,6 +25,7 @@ env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ar
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'NEWS', 'README', 'AUTHORS', 'ChangeLog',
                                        'configure', 'configure.ac', 'Makefile.am', 'SConscript',
+                                       'config.sub', 'config.guess',
                                        'sigc++/Makefile.in', 
                                        'sigc++config.h',
                                        'sigc++config.h.in',
index 1c8ff7049d8f3aaa9741c53e7f3145d9b76a77d8..894e786e16c1d0d94dfc08d6b475270fe1418d6a 100755 (executable)
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Common stub for a few missing GNU programs while installing.
 
-scriptversion=2006-05-10.23
+scriptversion=2005-06-08.21
 
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
 #   Free Software Foundation, Inc.
 # Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
@@ -33,8 +33,6 @@ if test $# -eq 0; then
 fi
 
 run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
 
 # In the cases where this matters, `missing' is being run in the
 # srcdir already.
@@ -46,7 +44,7 @@ fi
 
 msg="missing on your system"
 
-case $1 in
+case "$1" in
 --run)
   # Try to run requested program, and just exit if it succeeds.
   run=
@@ -79,7 +77,6 @@ Supported PROGRAM values:
   aclocal      touch file \`aclocal.m4'
   autoconf     touch file \`configure'
   autoheader   touch file \`config.h.in'
-  autom4te     touch the output file, or create a stub one
   automake     touch all \`Makefile.in' files
   bison        create \`y.tab.[ch]', if possible, from existing .[ch]
   flex         create \`lex.yy.c', if possible, from existing .c
@@ -109,7 +106,7 @@ esac
 # Now exit if we have it, but it failed.  Also exit now if we
 # don't have it and --version was passed (most likely to detect
 # the program).
-case $1 in
+case "$1" in
   lex|yacc)
     # Not GNU programs, they don't have --version.
     ;;
@@ -138,7 +135,7 @@ esac
 
 # If it does not exist, or fails to run (possibly an outdated version),
 # try to emulate it.
-case $1 in
+case "$1" in
   aclocal*)
     echo 1>&2 "\
 WARNING: \`$1' is $msg.  You should only need it if
@@ -167,7 +164,7 @@ WARNING: \`$1' is $msg.  You should only need it if
     test -z "$files" && files="config.h"
     touch_files=
     for f in $files; do
-      case $f in
+      case "$f" in
       *:*) touch_files="$touch_files "`echo "$f" |
                                       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
       *) touch_files="$touch_files $f.in";;
@@ -195,8 +192,8 @@ WARNING: \`$1' is needed, but is $msg.
          You can get \`$1' as part of \`Autoconf' from any GNU
          archive site."
 
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
     if test -f "$file"; then
        touch $file
     else
@@ -217,25 +214,25 @@ WARNING: \`$1' $msg.  You should only need it if
          in order for those modifications to take effect.  You can get
          \`Bison' from any GNU archive site."
     rm -f y.tab.c y.tab.h
-    if test $# -ne 1; then
+    if [ $# -ne 1 ]; then
         eval LASTARG="\${$#}"
-       case $LASTARG in
+       case "$LASTARG" in
        *.y)
            SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
-           if test -f "$SRCFILE"; then
+           if [ -f "$SRCFILE" ]; then
                 cp "$SRCFILE" y.tab.c
            fi
            SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
-           if test -f "$SRCFILE"; then
+           if [ -f "$SRCFILE" ]; then
                 cp "$SRCFILE" y.tab.h
            fi
          ;;
        esac
     fi
-    if test ! -f y.tab.h; then
+    if [ ! -f y.tab.h ]; then
        echo >y.tab.h
     fi
-    if test ! -f y.tab.c; then
+    if [ ! -f y.tab.c ]; then
        echo 'main() { return 0; }' >y.tab.c
     fi
     ;;
@@ -247,18 +244,18 @@ WARNING: \`$1' is $msg.  You should only need it if
          in order for those modifications to take effect.  You can get
          \`Flex' from any GNU archive site."
     rm -f lex.yy.c
-    if test $# -ne 1; then
+    if [ $# -ne 1 ]; then
         eval LASTARG="\${$#}"
-       case $LASTARG in
+       case "$LASTARG" in
        *.l)
            SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
-           if test -f "$SRCFILE"; then
+           if [ -f "$SRCFILE" ]; then
                 cp "$SRCFILE" lex.yy.c
            fi
          ;;
        esac
     fi
-    if test ! -f lex.yy.c; then
+    if [ ! -f lex.yy.c ]; then
        echo 'main() { return 0; }' >lex.yy.c
     fi
     ;;
@@ -270,9 +267,11 @@ WARNING: \`$1' is $msg.  You should only need it if
         \`Help2man' package in order for those modifications to take
         effect.  You can get \`Help2man' from any GNU archive site."
 
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
-    if test -f "$file"; then
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+       file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
        touch $file
     else
        test -z "$file" || exec >$file
@@ -290,17 +289,11 @@ WARNING: \`$1' is $msg.  You should only need it if
          DU, IRIX).  You might want to install the \`Texinfo' package or
          the \`GNU make' package.  Grab either from any GNU archive site."
     # The file to touch is that specified with -o ...
-    file=`echo "$*" | sed -n "$sed_output"`
-    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
     if test -z "$file"; then
       # ... or it is the one specified with @setfilename ...
       infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
-      file=`sed -n '
-       /^@setfilename/{
-         s/.* \([^ ]*\) *$/\1/
-         p
-         q
-       }' $infile`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
       # ... or it is derived from the source name (dir/f.texi becomes f.info)
       test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
     fi
@@ -324,13 +317,13 @@ WARNING: \`$1' is $msg.  You should only need it if
     fi
     firstarg="$1"
     if shift; then
-       case $firstarg in
+       case "$firstarg" in
        *o*)
            firstarg=`echo "$firstarg" | sed s/o//`
            tar "$firstarg" "$@" && exit 0
            ;;
        esac
-       case $firstarg in
+       case "$firstarg" in
        *h*)
            firstarg=`echo "$firstarg" | sed s/h//`
            tar "$firstarg" "$@" && exit 0
index d135218c54cf45cac785ed7224cfb8926610ab33..d77c19d864dfdbb8a7826bfa9b54d6f91b8426e9 100644 (file)
@@ -41,9 +41,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 #include <memory.h>
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
 #include "AAFilter.h"
 #include "FIRFilter.h"
 
index f158ee7949391ec48bf461515fbe765fb79a8fd0..613d8f9c48f8a5d63012dce703df3386023a62cc 100644 (file)
 //
 ////////////////////////////////////////////////////////////////////////////////
 
-#include <stdlib.h>
+#include <cstdlib>
 #include <memory.h>
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
 #include <stdexcept>
 
 #include "FIFOSampleBuffer.h"
index d2d54d5274684c787a082ff6b23988010a00318d..bf42895c2612eea244c222674a1c675ae9cbc24b 100644 (file)
@@ -48,8 +48,8 @@
 #ifndef FIFOSamplePipe_H
 #define FIFOSamplePipe_H
 
-#include <assert.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cstdlib>
 #include "STTypes.h"
 
 namespace soundtouch
index cc9c40d883ecb8d9ccad726a6314e2e369bfd1f0..1723195733d8597929ba0cc64d82dfe3379711a5 100644 (file)
@@ -40,9 +40,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 #include <memory.h>
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
 #include <stdexcept>
 #include "FIRFilter.h"
 #include "cpu_detect.h"
index 493d5326f20ab529364ce2538fcc08f178eff3d6..3000e37e4a9fb18843f57028cb76a7df6cfe364a 100644 (file)
 ////////////////////////////////////////////////////////////////////////////////
 
 #include <memory.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
+#include <cassert>
+#include <cstdlib>
+#include <cstdio>
+#include <climits>
 #include "RateTransposer.h"
 #include "AAFilter.h"
 
index 417d00b3474978393b2b7ade5e67c2b3debfdbf9..bfd1892212039d962c515bfcc73884513c3f40a1 100644 (file)
@@ -16,7 +16,7 @@ cpu_detect_x86_gcc.cpp
 """)
 
 Import('env install_prefix')
-st = env.Copy()
+st = env.Clone()
 st.Append(CCFLAGS="-DHAVE_CONFIG_H -D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
 
 libst = st.SharedLibrary('soundtouch', soundtouch_files)
index c71c65967f8ae0673e8df3e61b4404709bd14d06..d08dbc20284825862a98a64277127aeb272e46d0 100644 (file)
 //
 ////////////////////////////////////////////////////////////////////////////////
 
-#include <string.h>
-#include <stdlib.h>
+#include <cstring>
+#include <cstdlib>
 #include <memory.h>
-#include <limits.h>
-#include <math.h>
-#include <assert.h>
+#include <climits>
+#include <cmath>
+#include <cassert>
 
 #include "STTypes.h"
 #include "cpu_detect.h"
index fcc11dbae301797bb3460676dd0f353dd1c81f4c..22cb1f4961015b2fc5ef22027676a38582620e9f 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env final_prefix install_prefix final_config_prefix libraries i18n')
 
-cp = env.Copy()
+cp = env.Clone()
 
 #
 # this defines the version number of libardour_cp
@@ -38,7 +38,6 @@ cp.Merge ([
     libraries['pbd'],
     libraries['midi++2'],
     libraries['xml'],
-    libraries['usb'],
     libraries['glib2'],
     libraries['glibmm2']
        ])
index 44445192be017b44875c19a1ee29700001ce1b40..71d579480589e050d59ee253ee539d7e9b637b3e 100644 (file)
@@ -30,6 +30,8 @@
 using namespace ARDOUR;
 using ARDOUR::nframes_t;
 
+sigc::signal<void,std::string,std::string> BasicUI::AccessAction;
+
 BasicUI::BasicUI (Session& s)
        : session (&s)
 {
@@ -51,6 +53,17 @@ BasicUI::register_thread (std::string name)
        PBD::ThreadCreated (pthread_self(), name);
 }
 
+
+void
+BasicUI::access_action ( std::string action_path ) 
+{
+       int split_at = action_path.find( "/" );
+       std::string group = action_path.substr( 0, split_at );
+       std::string item = action_path.substr( split_at + 1 );
+
+       AccessAction( group, item );
+}
+
 void
 BasicUI::loop_toggle () 
 {
index 7bc6b25c32508ce8f6943e794a58df6424974001..c8b5a2a0b65102f26872e6674df59c74c6bf6fae 100644 (file)
@@ -42,6 +42,8 @@ class BasicUI {
        /* transport control */
 
        void loop_toggle ();
+       void access_action ( std::string action_path );
+       static sigc::signal<void,std::string,std::string> AccessAction;
        void goto_start ();
        void goto_end ();
        void rewind ();
index 099e35de521e5f32721456f43915bb408be6f48d..0f05e379ccddae3fbd4cbfeacfdbde90545d9afb 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env final_prefix install_prefix final_config_prefix libraries i18n')
 
-tranzport = env.Copy()
+tranzport = env.Clone()
 
 #
 # this defines the version number of libardour_tranzport
index 051a61f148c79efbb57820de57468c6584e0edc0..833f06923aaa52e44375f93e44815c2871672c82 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env final_prefix install_prefix final_config_prefix libraries i18n')
 
-genericmidi = env.Copy()
+genericmidi = env.Clone()
 
 #
 # this defines the version number of libardour_genericmidi
index 488265892030b9bcfac85bd023e8c7807bdd76a8..45ce63d3cda93da1480800a777470eb1c3ddf23f 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env final_prefix install_prefix final_config_prefix libraries i18n')
 
-mackie = env.Copy()
+mackie = env.Clone()
 
 #
 # this defines the version number of libardour_mackie
index 504edc603185822b955fc1bb4c3ea047f91beaa9..26ecc511eb2420adf898a3330784742a2874d632 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env final_prefix install_prefix final_config_prefix libraries i18n')
 
-powermate = env.Copy()
+powermate = env.Clone()
 
 #
 # this defines the version number of powermate
index 8b3051af20b7e93ea2555298a58594267605602f..6f3cf154567f1bccce84a61d9ebcfc0d2173d96f 100644 (file)
@@ -6,9 +6,9 @@
 
 
 #include <linux/input.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
+#include <cstring>
+#include <cerrno>
+#include <cstdio>
 #include <unistd.h>
 #include <fcntl.h>
 
index 5e14be31d35da197e9d1989fc643244d786c6430..fddd66c95d2e99f8a7e29e7587e819db64a4f334 100644 (file)
@@ -6,7 +6,7 @@ import glob
 
 Import('env final_prefix install_prefix final_config_prefix libraries i18n')
 
-tranzport = env.Copy()
+tranzport = env.Clone()
 
 #
 # this defines the version number of libardour_tranzport
index ab19358868bf3ae7b25c49e34d6248b3b9d6459c..74d6c7d528ec5d4e3d0e32ecfbdb59fa59bab3db 100644 (file)
@@ -18,6 +18,7 @@
  *  
  *   */
 
+#include <cstring>
 #include <tranzport_control_protocol.h>
 #include <cstring>
 
diff --git a/libs/vamp-plugins/Onset.cpp b/libs/vamp-plugins/Onset.cpp
new file mode 100644 (file)
index 0000000..d475b11
--- /dev/null
@@ -0,0 +1,280 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vamp feature extraction plugins using Paul Brossier's Aubio library.
+
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006 Chris Cannam.
+    
+    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.  See the file
+    COPYING included with this distribution for more information.
+
+*/
+
+#include <math.h>
+#include "Onset.h"
+
+using std::string;
+using std::vector;
+using std::cerr;
+using std::endl;
+
+Onset::Onset(float inputSampleRate) :
+    Plugin(inputSampleRate),
+    m_ibuf(0),
+    m_fftgrain(0),
+    m_onset(0),
+    m_pv(0),
+    m_peakpick(0),
+    m_onsetdet(0),
+    m_onsettype(aubio_onset_complex),
+    m_threshold(0.3),
+    m_silence(-90),
+    m_channelCount(1)
+{
+}
+
+Onset::~Onset()
+{
+    if (m_onsetdet) aubio_onsetdetection_free(m_onsetdet);
+    if (m_ibuf) del_fvec(m_ibuf);
+    if (m_onset) del_fvec(m_onset);
+    if (m_fftgrain) del_cvec(m_fftgrain);
+    if (m_pv) del_aubio_pvoc(m_pv);
+    if (m_peakpick) del_aubio_peakpicker(m_peakpick);
+}
+
+string
+Onset::getIdentifier() const
+{
+    return "aubioonset";
+}
+
+string
+Onset::getName() const
+{
+    return "Aubio Onset Detector";
+}
+
+string
+Onset::getDescription() const
+{
+    return "Estimate note onset times";
+}
+
+string
+Onset::getMaker() const
+{
+    return "Paul Brossier (plugin by Chris Cannam)";
+}
+
+int
+Onset::getPluginVersion() const
+{
+    return 1;
+}
+
+string
+Onset::getCopyright() const
+{
+    return "GPL";
+}
+
+bool
+Onset::initialise(size_t channels, size_t stepSize, size_t blockSize)
+{
+    m_channelCount = channels;
+    m_stepSize = stepSize;
+    m_blockSize = blockSize;
+
+    m_ibuf = new_fvec(stepSize, channels);
+    m_onset = new_fvec(1, channels);
+    m_fftgrain = new_cvec(blockSize, channels);
+    m_pv = new_aubio_pvoc(blockSize, stepSize, channels);
+    m_peakpick = new_aubio_peakpicker(m_threshold);
+
+    m_onsetdet = new_aubio_onsetdetection(m_onsettype, blockSize, channels);
+    
+    m_delay = Vamp::RealTime::frame2RealTime(4 * stepSize,
+                                             lrintf(m_inputSampleRate));
+
+    m_lastOnset = Vamp::RealTime::zeroTime - m_delay - m_delay;
+
+    return true;
+}
+
+void
+Onset::reset()
+{
+}
+
+size_t
+Onset::getPreferredStepSize() const
+{
+    return 512;
+}
+
+size_t
+Onset::getPreferredBlockSize() const
+{
+    return 2 * getPreferredStepSize();
+}
+
+Onset::ParameterList
+Onset::getParameterDescriptors() const
+{
+    ParameterList list;
+    
+    ParameterDescriptor desc;
+    desc.identifier = "onsettype";
+    desc.name = "Onset Detection Function Type";
+    desc.minValue = 0;
+    desc.maxValue = 6;
+    desc.defaultValue = (int)aubio_onset_complex;
+    desc.isQuantized = true;
+    desc.quantizeStep = 1;
+    desc.valueNames.push_back("Energy Based");
+    desc.valueNames.push_back("Spectral Difference");
+    desc.valueNames.push_back("High-Frequency Content");
+    desc.valueNames.push_back("Complex Domain");
+    desc.valueNames.push_back("Phase Deviation");
+    desc.valueNames.push_back("Kullback-Liebler");
+    desc.valueNames.push_back("Modified Kullback-Liebler");
+    list.push_back(desc);
+
+    desc = ParameterDescriptor();
+    desc.identifier = "peakpickthreshold";
+    desc.name = "Peak Picker Threshold";
+    desc.minValue = 0;
+    desc.maxValue = 1;
+    desc.defaultValue = 0.3;
+    desc.isQuantized = false;
+    list.push_back(desc);
+
+    desc = ParameterDescriptor();
+    desc.identifier = "silencethreshold";
+    desc.name = "Silence Threshold";
+    desc.minValue = -120;
+    desc.maxValue = 0;
+    desc.defaultValue = -90;
+    desc.unit = "dB";
+    desc.isQuantized = false;
+    list.push_back(desc);
+
+    return list;
+}
+
+float
+Onset::getParameter(std::string param) const
+{
+    if (param == "onsettype") {
+        return m_onsettype;
+    } else if (param == "peakpickthreshold") {
+        return m_threshold;
+    } else if (param == "silencethreshold") {
+        return m_silence;
+    } else {
+        return 0.0;
+    }
+}
+
+void
+Onset::setParameter(std::string param, float value)
+{
+    if (param == "onsettype") {
+        switch (lrintf(value)) {
+        case 0: m_onsettype = aubio_onset_energy; break;
+        case 1: m_onsettype = aubio_onset_specdiff; break;
+        case 2: m_onsettype = aubio_onset_hfc; break;
+        case 3: m_onsettype = aubio_onset_complex; break;
+        case 4: m_onsettype = aubio_onset_phase; break;
+        case 5: m_onsettype = aubio_onset_kl; break;
+        case 6: m_onsettype = aubio_onset_mkl; break;
+        }
+    } else if (param == "peakpickthreshold") {
+        m_threshold = value;
+    } else if (param == "silencethreshold") {
+        m_silence = value;
+    }
+}
+
+Onset::OutputList
+Onset::getOutputDescriptors() const
+{
+    OutputList list;
+
+    OutputDescriptor d;
+    d.identifier = "onsets";
+    d.name = "Onsets";
+    d.unit = "";
+    d.hasFixedBinCount = true;
+    d.binCount = 0;
+    d.sampleType = OutputDescriptor::VariableSampleRate;
+    d.sampleRate = 0;
+    list.push_back(d);
+
+    d = OutputDescriptor();
+    d.identifier = "detectionfunction";
+    d.name = "Onset Detection Function";
+    d.unit = "";
+    d.hasFixedBinCount = true;
+    d.binCount = m_channelCount;
+    d.hasKnownExtents = false;
+    d.isQuantized = false;
+    d.sampleType = OutputDescriptor::OneSamplePerStep;
+    list.push_back(d);
+
+    return list;
+}
+
+Onset::FeatureSet
+Onset::process(const float *const *inputBuffers,
+               Vamp::RealTime timestamp)
+{
+    for (size_t i = 0; i < m_stepSize; ++i) {
+        for (size_t j = 0; j < m_channelCount; ++j) {
+            fvec_write_sample(m_ibuf, inputBuffers[j][i], j, i);
+        }
+    }
+
+    aubio_pvoc_do(m_pv, m_ibuf, m_fftgrain);
+    aubio_onsetdetection(m_onsetdet, m_fftgrain, m_onset);
+
+    bool isonset = aubio_peakpick_pimrt(m_onset, m_peakpick);
+
+    if (isonset) {
+        if (aubio_silence_detection(m_ibuf, m_silence)) {
+            isonset = false;
+        }
+    }
+
+    FeatureSet returnFeatures;
+
+    if (isonset) {
+        if (timestamp - m_lastOnset >= m_delay) {
+            Feature onsettime;
+            onsettime.hasTimestamp = true;
+            if (timestamp < m_delay) timestamp = m_delay;
+            onsettime.timestamp = timestamp - m_delay;
+            returnFeatures[0].push_back(onsettime);
+            m_lastOnset = timestamp;
+        }
+    }
+    Feature feature;
+    for (size_t j = 0; j < m_channelCount; ++j) {
+        feature.values.push_back(m_onset->data[j][0]);
+    }
+    returnFeatures[1].push_back(feature);
+
+    return returnFeatures;
+}
+
+Onset::FeatureSet
+Onset::getRemainingFeatures()
+{
+    return FeatureSet();
+}
+
diff --git a/libs/vamp-plugins/Onset.h b/libs/vamp-plugins/Onset.h
new file mode 100644 (file)
index 0000000..314e107
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vamp feature extraction plugins using Paul Brossier's Aubio library.
+
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006 Chris Cannam.
+    
+    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.  See the file
+    COPYING included with this distribution for more information.
+
+*/
+
+#ifndef _ONSET_PLUGIN_H_
+#define _ONSET_PLUGIN_H_
+
+#include <vamp-sdk/Plugin.h>
+#include <aubio/aubio.h>
+
+class Onset : public Vamp::Plugin
+{
+public:
+    Onset(float inputSampleRate);
+    virtual ~Onset();
+
+    bool initialise(size_t channels, size_t stepSize, size_t blockSize);
+    void reset();
+
+    InputDomain getInputDomain() const { return TimeDomain; }
+
+    std::string getIdentifier() const;
+    std::string getName() const;
+    std::string getDescription() const;
+    std::string getMaker() const;
+    int getPluginVersion() const;
+    std::string getCopyright() const;
+
+    ParameterList getParameterDescriptors() const;
+    float getParameter(std::string) const;
+    void setParameter(std::string, float);
+
+    size_t getPreferredStepSize() const;
+    size_t getPreferredBlockSize() const;
+
+    OutputList getOutputDescriptors() const;
+
+    FeatureSet process(const float *const *inputBuffers,
+                       Vamp::RealTime timestamp);
+
+    FeatureSet getRemainingFeatures();
+
+protected:
+    fvec_t *m_ibuf;
+    cvec_t *m_fftgrain;
+    fvec_t *m_onset;
+    aubio_pvoc_t *m_pv;
+    aubio_pickpeak_t *m_peakpick;
+    aubio_onsetdetection_t *m_onsetdet;
+    aubio_onsetdetection_type m_onsettype;
+    float m_threshold;
+    float m_silence;
+    size_t m_stepSize;
+    size_t m_blockSize;
+    size_t m_channelCount;
+    Vamp::RealTime m_delay;
+    Vamp::RealTime m_lastOnset;
+};
+
+
+#endif
index 6b8159bd8c64490923ca999584f4dd5480c63dbb..d0796af092f95950092b016e44e8b0e0d1a4354a 100644 (file)
@@ -4,17 +4,33 @@ import os
 import os.path
 import glob
 
-plugin_files = glob.glob ("*.cpp")
+plugin_files = Split("""
+plugins.cpp
+AmplitudeFollower.cpp
+PercussionOnsetDetector.cpp
+SpectralCentroid.cpp
+ZeroCrossing.cpp
+""")
+
+aubio_files = Split ("""
+Onset.cpp
+""")
 
 Import('env install_prefix libraries')
-vampplugs = env.Copy()
+vampplugs = env.Clone()
 
 vampplugs.Append (CPPATH='#libs/vamp-sdk/vamp', CXXFLAGS="-Ilibs/vamp-sdk")
 vampplugs.Merge ([libraries['vamp'],
                   libraries['vamphost']
                   ])
 
-libvampplugins = vampplugs.SharedLibrary('ardourvampplugins', plugin_files)
+sources = plugin_files
+
+if vampplugs['AUBIO']:
+    sources += aubio_files
+    vampplugs.Merge ([libraries['aubio']])
+
+libvampplugins = vampplugs.SharedLibrary('ardourvampplugins', sources)
 
 Default(libvampplugins)
 
@@ -22,5 +38,5 @@ env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ar
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript' ] +
-                                     plugin_files +
+                                     plugin_files + aubio_files +
                                      glob.glob('*.h')))
index 25c6e6c0d4319074e500b4b090d5d4945b8aad5f..c45912be9b1d07306718ee5cfdbb175744e499e8 100644 (file)
 #include "SpectralCentroid.h"
 #include "PercussionOnsetDetector.h"
 #include "AmplitudeFollower.h"
+#include "Onset.h"
 
 static Vamp::PluginAdapter<ZeroCrossing> zeroCrossingAdapter;
 static Vamp::PluginAdapter<SpectralCentroid> spectralCentroidAdapter;
 static Vamp::PluginAdapter<PercussionOnsetDetector> percussionOnsetAdapter;
 static Vamp::PluginAdapter<AmplitudeFollower> amplitudeAdapter;
+static Vamp::PluginAdapter<Onset> onsetAdapter;
 
 const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int version,
                                                     unsigned int index)
@@ -57,6 +59,7 @@ const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int version,
     case  1: return spectralCentroidAdapter.getDescriptor();
     case  2: return percussionOnsetAdapter.getDescriptor();
     case  3: return amplitudeAdapter.getDescriptor();
+    case  4: return onsetAdapter.getDescriptor();
     default: return 0;
     }
 }
index 79046e2fc02440e22453deebb25a071c82b52a2d..be1834896b3477987bf8ccb3302983f9dcad66ed 100644 (file)
@@ -20,7 +20,7 @@ vamp-sdk/RealTime.cpp
 """)
 
 Import('env install_prefix libraries')
-vampsdk = env.Copy()
+vampsdk = env.Clone()
 
 vampsdk.Merge ([libraries['fftw3'], libraries['fftw3f']])
 
index 24f91e5f502321da12fadc56a143447b79292144..334c11103c565e91eda4a57fd2a4ba1c7883a81c 100644 (file)
@@ -34,7 +34,7 @@
     authorization.
 */
 
-#include <stdlib.h>
+#include <cstdlib>
 #include "PluginHostAdapter.h"
 
 namespace Vamp
index 9d627a75cfa04937327fa8d2a7adf60c04ea2183..e9d75ee181294f613baa0953b55d167243d57f7d 100644 (file)
@@ -40,6 +40,8 @@
 #include "PluginChannelAdapter.h"
 #include "PluginBufferingAdapter.h"
 
+#include <string>
+#include <cstring>
 #include <fstream>
 #include <cctype> // tolower
 #include <cstring>
index 8a6c6772728d6851a5ef257e2d38c8ebb051f5c4..3fbbd7acc417dc5766e4f2947c0fadc17a5bede6 100644 (file)
       <tbody>
         <row>
           <entry>
-            <keycombo><keycap>a</keycap> </keycombo>
+            <keycombo><keycap>a</keycap></keycombo>
           </entry>
 
           <entry>
-            relative alignment of region sync points or starts
+            align regions using sync points and keeping relative positions
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Meta</keycap><keycap>a</keycap> </keycombo>
+            <keycombo><keycap>Alt</keycap><keycap>a</keycap></keycombo>
           </entry>
 
           <entry>
-            absolute alignment of region sync points or starts
+            align region ends
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>a</keycap>
-            </keycombo>
+            <keycombo><keycap>Shift</keycap><keycap>a</keycap></keycombo>
           </entry>
 
           <entry>
-            relative alignment of region ends
+            align region sync points without keeping relative positions
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>Meta</keycap><keycap>a</keycap>
-            </keycombo>
+            <keycombo><keycap>Mod4</keycap><keycap>a</keycap></keycombo>
           </entry>
 
           <entry>
-            align region ends
+            align region starts and keeping relative positions
           </entry>
         </row>
       </tbody>
index e9b3eb4d0888d8c6788cf8be3b58974c07d177cb..1a3bae80828cc75d61060cb4d1e1c97d3b23a7e7 100644 (file)
       <tbody>
         <row>
           <entry>
-            <keycombo><keycap>left arrow</keycap> </keycombo>
+            <keycombo><keycap>f</keycap></keycombo>
           </entry>
 
           <entry>
-            move editor timeline earlier
+            fit tracks
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>b</keycap> </keycombo>
+            <keycombo><keycap>Up</keycap></keycombo>
           </entry>
 
           <entry>
-            move editor timeline earlier
+            step tracks up
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>right arrow</keycap> </keycombo>
+            <keycombo><keycap>Down</keycap></keycombo>
           </entry>
 
           <entry>
-            move editor timeline later
+            step tracks down
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>f</keycap> </keycombo>
+            <keycombo><keycap>Page_Down</keycap></keycombo>
           </entry>
 
           <entry>
-            move editor timeline later
+            scroll tracks down
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Page_Up</keycap> </keycombo>
+            <keycombo><keycap>Page_Up</keycap></keycombo>
           </entry>
 
           <entry>
-            scroll track display up
+            scroll tracks up
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Page_Down</keycap> </keycombo>
+            <keycombo><keycap>Shift</keycap><keycap>e</keycap></keycombo>
           </entry>
 
           <entry>
-            scroll track display down
-          </entry>
-        </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Up arrow</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            step track display up
-          </entry>
-        </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Down arrow</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            step track display down
+            show editor mixer
           </entry>
         </row>
       </tbody>
index 1190e3efa7fc4f5e4cccc7c1f1d5e6dd26310a1c..25fc749c53e806013820c32d58be1144f9a43f31 100644 (file)
         </row>
       </thead>
       <tbody>
+        <row>
+          <entry>
+            <keycombo><keycap>`</keycap></keycombo>
+          </entry>
+
+          <entry>
+            cycle-edit-point
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>~</keycap></keycombo>
+          </entry>
+
+          <entry>
+            cycle-edit-point-with-marker
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>e</keycap></keycombo>
+          </entry>
+
+          <entry>
+            set-edit-point
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>Return</keycap></keycombo>
+          </entry>
+
+          <entry>
+            edit-to-playhead
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>F1</keycap></keycombo>
+          </entry>
+
+          <entry>
+            edit-cursor-to-range-start
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>F2</keycap></keycombo>
+          </entry>
+
+          <entry>
+            edit-cursor-to-range-end
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>'</keycap></keycombo>
+          </entry>
+
+          <entry>
+            edit-cursor-to-previous-region-sync
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>;</keycap></keycombo>
+          </entry>
+
+          <entry>
+            edit-cursor-to-next-region-sync
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>Left</keycap></keycombo>
+          </entry>
+
+          <entry>
+            selected-marker-to-previous-region-boundary
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>Right</keycap></keycombo>
+          </entry>
+
+          <entry>
+            selected-marker-to-next-region-boundary
+          </entry>
+        </row>
+
         <row>
           <entry>
             <keycombo><keycap>e</keycap> </keycombo>
           </entry>
 
           <entry>
-            position edit cursor at mouse pointer
+            position selected marker at mouse pointer
           </entry>
         </row>
 
           </entry>
 
           <entry>
-            move edit cursor to playhead
+            move selected marker to playhead
           </entry>
         </row>
 
           </entry>
 
           <entry>
-            move edit cursor to earlier region start
+            move selected marker to earlier region start
           </entry>
         </row>
 
           </entry>
 
           <entry>
-            move edit cursor to earlier region end
+            move selected marker to earlier region end
           </entry>
         </row>
 
           </entry>
 
           <entry>
-            move edit cursor to next region start
+            move selected marker to next region start
           </entry>
         </row>
 
           </entry>
 
           <entry>
-            move edit cursor to next region end
+            move selected marker to next region end
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>&#8221;&#8221;&#8217;</keycap> </keycombo>
+            <keycombo><keycap>'</keycap> </keycombo>
           </entry>
 
           <entry>
-            move edit cursor to next region sync
+            move selected marker to next region sync
           </entry>
         </row>
 
           </entry>
 
           <entry>
-            moved edit cursor to previous region sync
+            moved selected marker to previous region sync
           </entry>
         </row>
 
           </entry>
 
           <entry>
-            move edit cursor to start of range selection (if defined)
+            move selected marker to start of range selection (if defined)
           </entry>
         </row>
 
           </entry>
 
           <entry>
-            move edit cursor to end of range selection (if defined)
+            move selected marker to end of range selection (if defined)
           </entry>
         </row>
       </tbody>
index d83c446578e11453d2613dafce44699e0c0a0275..62cabda4bd8ab5064d048713d892f86666d39c79 100644 (file)
 
         <row>
           <entry>
-            <keycombo><keycap>Keypad &gt;</keycap> </keycombo>
+            <keycombo><keycap>]</keycap></keycombo>
           </entry>
 
           <entry>
-            move playhead to next marker
+            set loop range from edit range
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Keypad &lt;</keycap> </keycombo>
+            <keycombo><keycap>Alt</keycap><keycap>]</keycap></keycombo>
           </entry>
 
           <entry>
-            move playhead to previous marker
+            set loop range from selected region(s)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>[</keycap></keycombo>
+          </entry>
+
+          <entry>
+            set punch range from edit range
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>[</keycap></keycombo>
+          </entry>
+
+          <entry>
+            set punch range from selected region(s)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_1</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 1
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_2</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 2
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_3</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 3
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_4</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 4
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_5</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 5
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_6</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 6
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_7</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 7
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_8</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 8
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>KP_9</keycap></keycombo>
+          </entry>
+
+          <entry>
+            goto mark 9
           </entry>
         </row>
       </tbody>
diff --git a/manual/xml/editor_marker_bindings.xml b/manual/xml/editor_marker_bindings.xml
new file mode 100644 (file)
index 0000000..b7ecc11
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+]>
+
+<section id="sn-editor-canvas-key-bindings">
+  <title>Mark &amp; Range Key Bindings</title>
+  <table id="tbl-editor-canvas-key-bindings">
+    <title>Editor Canvas Key Bindings</title>
+    <tgroup cols = "2">
+      <colspec colnum="1" colname="Key Binding" colwidth="1"/>
+      <colspec colnum="2" colname="Action" colwidth= "2"/>
+      <thead>
+        <row>
+          <entry>
+            Key Binding
+          </entry>
+
+          <entry>
+            Action
+          </entry>
+        </row>
+      </thead>
+      <tbody></tbody>
+    </tgroup>
+  </table>
+<!--
+       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
+               href="Some_Subsection.xml" />
+       -->
+</section>
index 1fd40d13ea3c96a5e05ec24b0795bbb5d49eda15..343869357b5afc2ff2c80947f7c7e8e72a8619cf 100644 (file)
       <tbody>
         <row>
           <entry>
-            <keycombo><keycap>l</keycap> </keycombo>
+            <keycombo><keycap>1</keycap></keycombo>
           </entry>
 
           <entry>
-            toggle auto loop
+            toggle edit mode
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>f</keycap> </keycombo>
+            <keycombo><keycap>2</keycap></keycombo>
+          </entry>
+
+          <entry>
+            cycle snap mode
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>3</keycap></keycombo>
+          </entry>
+
+          <entry>
+            cycle snap choice
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>f</keycap> </keycombo>
           </entry>
 
           <entry>
             toggle follow playhead
           </entry>
         </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>9</keycap></keycombo>
+          </entry>
+
+          <entry>
+            set tempo from region
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>0</keycap></keycombo>
+          </entry>
+
+          <entry>
+            set tempo from edit range
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>t</keycap></keycombo>
+          </entry>
+
+          <entry>
+            insert time
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>Delete</keycap></keycombo>
+          </entry>
+
+          <entry>
+            remove last capture
+          </entry>
+        </row>
       </tbody>
     </tgroup>
   </table>
index 8c0560d0b885422bfce91bccf64a8c9f52852b57..0d9ce0ff3278c5e90cfa0f69f96a86e24b60a20d 100644 (file)
@@ -6,6 +6,11 @@
 
 <section id="sn-editor-nudging-key-bindings">
   <title>Nudging Key Bindings</title>
+  <para>
+    Nudging will move selected regions if there are any, otherwise the
+    playhead.
+  </para>
+
   <table id="tbl-editor-nudging-key-bindings">
     <title>Nudging Key Bindings</title>
     <tgroup cols = "2">
@@ -25,7 +30,7 @@
       <tbody>
         <row>
           <entry>
-            <keycombo><keycap>+</keycap> </keycombo> (keypad)
+            <keycombo><keycap>Keypad +</keycap></keycombo>
           </entry>
 
           <entry>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>+</keycap> </keycombo>
-            (keypad)
-          </entry>
-
-          <entry>
-            nudge next forward
-          </entry>
-        </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>-</keycap> </keycombo> (keypad)
+            <keycombo><keycap>Keypad -</keycap></keycombo>
           </entry>
 
           <entry>
             nudge backward
           </entry>
         </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>-</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            nudge next backward
-          </entry>
-        </row>
       </tbody>
     </tgroup>
   </table>
index 52024cbb59e939b4c7e7840cfd98ffc3523ae60b..5edb25911d6b0fe78775d71420a3d1712625048b 100644 (file)
         </row>
       </thead>
       <tbody>
+        <row>
+          <entry>
+            <keycombo><keycap>Home</keycap></keycombo>
+          </entry>
+
+          <entry>
+            Move playhead to session start
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>End</keycap></keycombo>
+          </entry>
+
+          <entry>
+            Move playhead to session end
+          </entry>
+        </row>
+
         <row>
           <entry>
             <keycombo><keycap>p</keycap> </keycombo>
           </entry>
 
           <entry>
-            move playhead to edit cursor
+            move playhead to selected marker (if any)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>Return</keycap>
+            </keycombo>
+          </entry>
+
+          <entry>
+            move selected marker (if any) to playhead
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>.</keycap></keycombo>
+          </entry>
+
+          <entry>
+            playhead to next region boundary
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>.</keycap></keycombo>
+          </entry>
+
+          <entry>
+            playhead to next region sync
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>,</keycap></keycombo>
+          </entry>
+
+          <entry>
+            playhead to previous region boundary
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>,</keycap></keycombo>
+          </entry>
+
+          <entry>
+            playhead to previous region sync
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>Right</keycap></keycombo>
+          </entry>
+
+          <entry>
+            tab to transient forwards
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Tab</keycap> </keycombo>
+            <keycombo><keycap>Ctrl</keycap><keycap>Left</keycap></keycombo>
           </entry>
 
           <entry>
-            move playhead to later region start
+            tab to transient backwards
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>Tab</keycap> </keycombo>
+            <keycombo><keycap>Left</keycap></keycombo>
           </entry>
 
           <entry>
-            move playhead to later region end
+            playhead to previous region boundary
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>`</keycap> </keycombo>
+            <keycombo><keycap>Alt</keycap><keycap>Left</keycap></keycombo>
           </entry>
 
           <entry>
-            move playhead to earlier region start
+            nudge playhead backward
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>`</keycap> </keycombo>
+            <keycombo><keycap>Right</keycap></keycombo>
           </entry>
 
           <entry>
-            move playhead to next mark
+            playhead to next region boundary
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>|</keycap> </keycombo> (keypad)
+            <keycombo><keycap>Alt</keycap><keycap>Right</keycap></keycombo>
           </entry>
 
           <entry>
-            move playhead to previous mark
+            nudge playhead forward
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>l</keycap> </keycombo>
+            <keycombo><keycap>Ctrl</keycap><keycap>Keypad
+            Right</keycap></keycombo>
           </entry>
 
           <entry>
-            center screen around playhead
+            jump forward to mark
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>g</keycap> </keycombo>
+            <keycombo><keycap>Ctrl</keycap><keycap>Keypad
+            Left</keycap></keycombo>
           </entry>
 
           <entry>
-            goto
+            jump backward to mark
           </entry>
         </row>
       </tbody>
index 111de889de98119b573fac6446365ddb00bb0e3a..b6d20e85048967e3c6203db71a0adaff6700da9b 100644 (file)
       <tbody>
         <row>
           <entry>
-            <keycombo><keycap>Keypad Down arrow</keycap> </keycombo>
+            <keycombo><keycap>F6</keycap></keycombo>
           </entry>
 
           <entry>
-            begin range definition while transport rolls
+            select range using edit range
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Keypad Up arrow</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            end range definition while transport rolls
-          </entry>
-        </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Shift</keycap><keycap>Tab</keycap> </keycombo>
+            <keycombo><keycap>&gt;</keycap></keycombo>
           </entry>
 
           <entry>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>Tab</keycap>
-            </keycombo>
+            <keycombo><keycap>&lt;</keycap></keycombo>
           </entry>
 
           <entry>
             extend range to start of region
           </entry>
         </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Meta</keycap><keycap>s</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            duplicate range
-          </entry>
-        </row>
       </tbody>
     </tgroup>
   </table>
index e830c2c338586ee42736c8c89485e6ee503f5cfd..8896588c65ee87425ff010ecbcab5c27680880dd 100644 (file)
@@ -6,6 +6,13 @@
 
 <section id="sn-editor-region-operation-key-bindings">
   <title>Region Operations Key Bindings</title>
+  <para>
+    Region operations generally operate on the currently selected regions,
+    if any. If none are selected but 1 or more tracks are selected then
+    regions in those tracks at the edit point will be used. If no tracks are
+    selected, then any region at the edit point will be used.
+  </para>
+
   <table id="tbl-editor-region-operation-key-bindings">
     <title>Region Operation Key Bindings</title>
     <tgroup cols = "2">
           </entry>
 
           <entry>
-            split region(s) at mouse
+            split region(s) at edit point
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Alt</keycap><keycap>s</keycap> </keycombo>
+            <keycombo><keycap>i</keycap></keycombo>
           </entry>
 
           <entry>
-            split region(s) at edit cursor
+            insert region (from region list)
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Insert</keycap> </keycombo>
+            <keycombo><keycap>d</keycap></keycombo>
           </entry>
 
           <entry>
-            insert selected region (from region list)
+            duplicate region
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Meta</keycap><keycap>d</keycap> </keycombo>
+            <keycombo><keycap>n</keycap></keycombo>
           </entry>
 
           <entry>
-            duplicate region
+            normalize region
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Alt</keycap><keycap>r</keycap> </keycombo>
+            <keycombo><keycap>m</keycap></keycombo>
           </entry>
 
           <entry>
-            reverse region
+            mute/unmute region
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Alt</keycap><keycap>n</keycap> </keycombo>
+            <keycombo><keycap>~</keycap></keycombo>
           </entry>
 
           <entry>
-            normalize region
+            boost region gain
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>&amp;</keycap></keycombo>
+          </entry>
+
+          <entry>
+            cut region gain
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>h</keycap></keycombo>
+          </entry>
+
+          <entry>
+            play selected regions
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>j</keycap></keycombo>
+          </entry>
+
+          <entry>
+            trim to start at edit point
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>k</keycap></keycombo>
+          </entry>
+
+          <entry>
+            trim to end at edit point
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>/</keycap></keycombo>
+          </entry>
+
+          <entry>
+            set fade in length (via edit point)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>\</keycap></keycombo>
+          </entry>
+
+          <entry>
+            set fade out length (via edit point)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Shift</keycap><keycap>{</keycap></keycombo>
+          </entry>
+
+          <entry>
+            trim from start to edit point
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Shift</keycap><keycap>}</keycap></keycombo>
+          </entry>
+
+          <entry>
+            trim from edit point to end
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>F3</keycap></keycombo>
+          </entry>
+
+          <entry>
+            crop (to edit range)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>F4</keycap></keycombo>
+          </entry>
+
+          <entry>
+            separate (using edit range)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>v</keycap></keycombo>
+          </entry>
+
+          <entry>
+            set region sync point(s) at edit point
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>F5</keycap></keycombo>
+          </entry>
+
+          <entry>
+            pitch shift region
           </entry>
         </row>
       </tbody>
diff --git a/manual/xml/editor_selection_key_bindings.xml b/manual/xml/editor_selection_key_bindings.xml
new file mode 100644 (file)
index 0000000..d8f2e62
--- /dev/null
@@ -0,0 +1,142 @@
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+]>
+
+<section id="sn-editor-selection-key-bindings">
+  <title>Selection Key Bindings</title>
+  <table id="tbl-selection-key-bindings">
+    <title>Selection Key Bindings</title>
+    <tgroup cols = "2">
+      <colspec colnum="1" colname="Key Binding" colwidth="1"/>
+      <colspec colnum="2" colname="Action" colwidth= "2"/>
+      <thead>
+        <row>
+          <entry>
+            Key Binding
+          </entry>
+
+          <entry>
+            Action
+          </entry>
+        </row>
+      </thead>
+      <tbody>
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>a</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select all
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>p</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select all before playhead
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Shift</keycap><keycap>Ctrl</keycap><keycap>p</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select all after playhead
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>u</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select all within edit range
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Shift</keycap><keycap>i</keycap></keycombo>
+          </entry>
+
+          <entry>
+            invert selection
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Shift</keycap><keycap>Ctrl</keycap><keycap>e</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select all after edit cursor
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>e</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select all before edit cursor
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>d</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select all in punch range
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>l</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select all in loop range
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>Up</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select prev route
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>Down</keycap></keycombo>
+          </entry>
+
+          <entry>
+            select next route
+          </entry>
+        </row>
+      </tbody>
+    </tgroup>
+  </table>
+<!--
+       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
+               href="Some_Subsection.xml" />
+       -->
+</section>
index b8afa14bfed586cc1048dd4852b10a22608fbf83..1b30a217caca5f48406d834753a0174e54aacdea 100644 (file)
@@ -5,7 +5,12 @@
 ]>
 
 <section id="sn-editor-zoom-key-bindings">
-  <title>Zoom Key Bindings</title>
+  <title>Zoom and Visual State Key Bindings</title>
+  <para>
+    By default, 12 function keys (F1-F12) are assigned to visual state
+    management. All of them are represented in the table as "Fn".
+  </para>
+
   <table id="tbl-editor-zoom-key-bindings">
     <title>Editor Zoom Key Bindings</title>
     <tgroup cols = "2">
 
         <row>
           <entry>
-            <keycombo><keycap>Z</keycap> </keycombo>
+            <keycombo><keycap>z</keycap> </keycombo>
           </entry>
 
           <entry>
             switch zoom focus to playhead
           </entry>
         </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>Alt</keycap><keycap>z</keycap>
+            </keycombo>
+          </entry>
+
+          <entry>
+            Zoom to fit selected region(s) (time axis only)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>z</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Zoom to fit selected region(s) (time axis &amp; vertical axis)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Shift</keycap><keycap>z</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Undo zoom change
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>Fn</keycap></keycombo>
+          </entry>
+
+          <entry>
+            Save current visual state as VS #n (hold for 2 secs)
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Ctrl</keycap><keycap>Fn</keycap></keycombo>
+          </entry>
+
+          <entry>
+            Restore visual state #n (occurs on key release)
+          </entry>
+        </row>
       </tbody>
     </tgroup>
   </table>
index edf77ad113cfd4369e25afe07412bd579c498f21..79b8693798fe4690da828e69bdd8fe8257450848 100644 (file)
           </entry>
         </row>
 
-        <row>
-          <entry>
-            <keycombo><keycap>Alt</keycap><keycap>e</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            Raise the Editor Window
-          </entry>
-        </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Alt</keycap><keycap>m</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            Toggle display of the locations window
-          </entry>
-        </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Alt</keycap><keycap>c</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            Toggle display of the options editor
-          </entry>
-        </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>t</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            Add a track or bus
-          </entry>
-        </row>
-
         <row>
           <entry>
             <keycombo><keycap>Ctrl</keycap><keycap>s</keycap> </keycombo>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>q</keycap> </keycombo>
-          </entry>
-
-          <entry>
-            Quit
-          </entry>
-        </row>
-
-        <row>
-          <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>u</keycap> </keycombo>
+            <keycombo><keycap>Alt</keycap><keycap>i</keycap> </keycombo>
           </entry>
 
           <entry>
-            Starts a prefix entry sequence
+            Import existing files into a session.
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>m</keycap> </keycombo>
+            <keycombo><keycap>Ctrl</keycap><keycap>q</keycap> </keycombo>
           </entry>
 
           <entry>
-            Toggle sending MIDI feedback
+            Quit
           </entry>
         </row>
       </tbody>
index f3b50810a75f14aa293c81cc709cac12e0a6d33e..3aff10c6d4b04cc1d0a3f9bc1bd560e2bcb3d8ba 100644 (file)
     <title>Key Bindings</title>
     <para>
       Note that all keyboard bindings can be changed in either the system or
-      the user's Ardour configuration file
-      (<filename>$HOME/.ardour/ardour.rc</filename>).
+      the user's Ardour key bindings file
+      (<filename>$HOME/.ardour2/ardour.bindings</filename>).
     </para>
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
                href="general_key_bindings.xml" />
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
-               href="transport_key_bindings.xml" />
+               href="window_key_bindings.xml" />
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
-               href="mixer_window_key_bindings.xml" />
+               href="transport_key_bindings.xml" />
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
                href="editor_window_key_bindings.xml" />
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
@@ -33,6 +33,8 @@
                href="editor_aligning_key_bindings.xml" />
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
                href="editor_standard_editing_key_bindings.xml" />
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
+               href="editor_selection_key_bindings.xml" />
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
                href="editor_range_operations_key_bindings.xml" />
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
index c2a3954b19c381ed3478681d88fe40784360fc9a..4026cb64cbece8ffbfab0f031e05189096e53d2f 100644 (file)
 
         <row>
           <entry>
-            <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>space</keycap></keycombo>
+            <keycombo><keycap>Ctrl</keycap><keycap>space</keycap></keycombo>
           </entry>
 
           <entry>
-            Raise the Editor Window
+            One-touch record (start transport &amp; recording)
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Shift</keycap><keycap>r</keycap></keycombo>
+            <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>space</keycap></keycombo>
           </entry>
 
           <entry>
-            Toggle transport record-enable state
+            Toggle transport motion, deleting any recorded material if
+            recording
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>Home</keycap></keycombo>
+            <keycombo><keycap>Shift</keycap><keycap>r</keycap></keycombo>
           </entry>
 
           <entry>
-            Move playhead to start
+            Toggle transport record-enable state
           </entry>
         </row>
 
         <row>
           <entry>
-            <keycombo><keycap>End</keycap></keycombo>
+            <keycombo><keycap>l</keycap> </keycombo>
           </entry>
 
           <entry>
-            Move playhead to end
+            toggle looping
           </entry>
         </row>
       </tbody>
diff --git a/manual/xml/window_key_bindings.xml b/manual/xml/window_key_bindings.xml
new file mode 100644 (file)
index 0000000..e75bf5a
--- /dev/null
@@ -0,0 +1,112 @@
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+]>
+
+<section id="sn-window-key-bindings">
+  <title>Window Visibility Key Bindings</title>
+  <table id="tbl-window-key-bindings">
+    <title>Window Visibility Key Bindings</title>
+    <tgroup cols = "2">
+      <colspec colnum="1" colname="Key Binding" colwidth="1"/>
+      <colspec colnum="2" colname="Action" colwidth= "2"/>
+      <thead>
+        <row>
+          <entry>
+            Key Binding
+          </entry>
+
+          <entry>
+            Action
+          </entry>
+        </row>
+      </thead>
+      <tbody>
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>e</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Raise editor window
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>m</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Raise mixer window
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>l</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Toggle locations window
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>b</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Toggle "big clock" window
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>k</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Toggle key bindings window
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>f</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Toggle Rhythm Ferret window
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>o</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Toggle preferences window
+          </entry>
+        </row>
+
+        <row>
+          <entry>
+            <keycombo><keycap>Alt</keycap><keycap>c</keycap> </keycombo>
+          </entry>
+
+          <entry>
+            Toggle color manager window
+          </entry>
+        </row>
+      </tbody>
+    </tgroup>
+  </table>
+<!--
+       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
+               href="Some_Subsection.xml" />
+       -->
+</section>
index 35346c92675ecad3538532b2201f8309af6fcc33..b3717976d04040bd65d5d540b325d8bdb302db6d 100644 (file)
@@ -1,4 +1,4 @@
 #ifndef __ardour_svn_revision_h__
 #define __ardour_svn_revision_h__
-static const char* ardour_svn_revision = "3201";
+static const char* ardour_svn_revision = "3530";
 #endif
index ebb903cf37023c1d084535b597e69d1a6d78c888..3123d0cb1f2d2b479570707dc2e55c640495b72d 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 # Ardour session synthesizer
-# (c)Sampo Savolainen 2007
+# (c)Sampo Savolainen 2007-2008
 #
 # GPL
 # This reads an Ardour session file and creates zero-signal source files
@@ -13,14 +13,31 @@ use IO::Handle;
 
 use ARDOUR::SourceInfoLoader;
 
+my $usage = "usage: synthesize_sources.pl samplerate [session name, the name must match the directory and the .ardour file in it] [options: -sine for 440hz sine waves in wave files]\n";
 
-my ($samplerate, $sessionName) = @ARGV;
+my ($samplerate, $sessionName, @options) = @ARGV;
 
 if ( ! -d $sessionName || ! -f $sessionName."/".$sessionName.".ardour" ) {
-       print "usage: synthesize_sources.pl samplerate [session name, the name must match the directory and the .ardour file in it]\n";
+       print $usage;
        exit;
 }
 
+my $waveType = "silent";
+
+foreach my $o (@options) {
+       if ($o eq "-sine") {
+               $waveType = "sine";
+       } elsif ($o eq "-silent") {
+               $waveType = "silent";
+       } else {
+               print "unknown parameter ".$o."\n";
+               print $usage;
+               exit;
+
+       }
+       
+}
+
 my $sessionFile = $sessionName."/".$sessionName.".ardour";
 
 
@@ -52,9 +69,10 @@ my %sources = %{$handler->{Sources}};
 
 foreach my $tmp (keys %sources) {
        
-       print "Generating ".$audioFileDirectory."/".$sources{$tmp}->{name}.".wav\n";
+       print "Generating ".$audioFileDirectory."/".$sources{$tmp}->{name}."\n";
 
-       system("sox", 
+       my @cmd = 
+              ("sox", 
               "-t", "raw",        # /dev/zero is raw :)
               "-r", $samplerate,  # set sample rate
               "-c", "1",          # 1 channel
@@ -68,7 +86,11 @@ foreach my $tmp (keys %sources) {
               "trim", "0", $sources{$tmp}->{calculated_length}."s" # trim silence to wanted sample amount
               );
 
+       if ($waveType eq "sine") {
+               @cmd = (@cmd, "synth","sin","%0", "vol", "0.2", "fade","q","0.01s", $sources{$tmp}->{calculated_length}."s" , "0.01s");
+       }
 
+       system(@cmd);
 }
 
 
index c4254dc5ed2bd7ff3917e761689d04679439ea22..342f6562832f9a91aef3e17ac205a73c94527f1f 100644 (file)
@@ -8,7 +8,7 @@ from stat import *
 
 Import('env install_prefix final_prefix config_prefix subst_dict libraries')
 
-ardour_vst = env.Copy()
+ardour_vst = env.Clone()
 
 sources = Split ("""
 winmain.c