Merged with trunk R1283.
authorDavid Robillard <d@drobilla.net>
Tue, 9 Jan 2007 23:24:54 +0000 (23:24 +0000)
committerDavid Robillard <d@drobilla.net>
Tue, 9 Jan 2007 23:24:54 +0000 (23:24 +0000)
NOTE: Compiles, but broken (crash on adding MIDI track).

git-svn-id: svn://localhost/ardour2/branches/midi@1292 d708f5d6-7413-0410-9779-e7cbd77b26cf

271 files changed:
DOCUMENTATION/AUTHORS
PACKAGER_README
SConstruct
gtk2_ardour/SConscript
gtk2_ardour/about.cc
gtk2_ardour/analysis_window.cc
gtk2_ardour/ardbg
gtk2_ardour/ardev
gtk2_ardour/ardev_common.sh
gtk2_ardour/ardev_common.sh.in [new file with mode: 0644]
gtk2_ardour/ardour.bindings
gtk2_ardour/ardour.menus
gtk2_ardour/ardour.sh.in
gtk2_ardour/ardour2_ui.rc
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui2.cc
gtk2_ardour/ardour_ui_dependents.cc
gtk2_ardour/ardour_ui_dialogs.cc
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/ardour_ui_options.cc
gtk2_ardour/arprof
gtk2_ardour/arval
gtk2_ardour/audio_clock.cc
gtk2_ardour/audio_clock.h
gtk2_ardour/audio_region_editor.cc
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.cc
gtk2_ardour/audio_time_axis.h
gtk2_ardour/automation_line.cc
gtk2_ardour/automation_line.h
gtk2_ardour/automation_time_axis.cc
gtk2_ardour/automation_time_axis.h
gtk2_ardour/canvas-waveview.c
gtk2_ardour/canvas-waveview.h
gtk2_ardour/crossfade_edit.cc
gtk2_ardour/crossfade_view.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_canvas_events.cc
gtk2_ardour/editor_edit_groups.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_list.cc
gtk2_ardour/editor_timefx.cc
gtk2_ardour/editor_xpms
gtk2_ardour/enums.cc [new file with mode: 0644]
gtk2_ardour/enums.h
gtk2_ardour/export_dialog.cc
gtk2_ardour/fft_graph.cc
gtk2_ardour/gain_meter.cc
gtk2_ardour/gain_meter.h
gtk2_ardour/icons/ardour_icon_16px.png [new file with mode: 0644]
gtk2_ardour/icons/ardour_icon_22px.png [new file with mode: 0644]
gtk2_ardour/icons/ardour_icon_32px.png [new file with mode: 0644]
gtk2_ardour/icons/ardour_icon_48px.png [new file with mode: 0644]
gtk2_ardour/icons/fader_belt.png [new file with mode: 0644]
gtk2_ardour/io_selector.cc
gtk2_ardour/ladspa_pluginui.cc
gtk2_ardour/location_ui.cc
gtk2_ardour/logmeter.h
gtk2_ardour/main.cc
gtk2_ardour/meter_bridge.cc
gtk2_ardour/mixer_strip.cc
gtk2_ardour/mixer_strip.h
gtk2_ardour/mixer_ui.cc
gtk2_ardour/new_session_dialog.cc
gtk2_ardour/option_editor.cc
gtk2_ardour/option_editor.h
gtk2_ardour/opts.cc
gtk2_ardour/opts.h
gtk2_ardour/panner.cc [new file with mode: 0644]
gtk2_ardour/panner.h [new file with mode: 0644]
gtk2_ardour/panner2d.cc
gtk2_ardour/panner_ui.cc
gtk2_ardour/panner_ui.h
gtk2_ardour/pixmaps/SConscript
gtk2_ardour/playlist_selection.h
gtk2_ardour/playlist_selector.cc
gtk2_ardour/playlist_selector.h
gtk2_ardour/plugin_ui.cc
gtk2_ardour/po/de_DE.po
gtk2_ardour/po/sv_SE.po
gtk2_ardour/public_editor.h
gtk2_ardour/redirect_box.cc
gtk2_ardour/redirect_box.h
gtk2_ardour/region_gain_line.cc
gtk2_ardour/region_gain_line.h
gtk2_ardour/region_view.cc
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/selection.cc
gtk2_ardour/selection.h
gtk2_ardour/sfdb_ui.cc
gtk2_ardour/sfdb_ui.h
gtk2_ardour/time_axis_view.cc
gtk2_ardour/time_axis_view.h
gtk2_ardour/time_axis_view_item.cc
gtk2_ardour/utils.cc
gtk2_ardour/utils.h
gtk2_ardour/visual_time_axis.cc
gtk2_ardour/waveview.cc
gtk2_ardour/waveview.h
libs/appleutility/SConscript
libs/ardour/SConscript
libs/ardour/ardour/audio_diskstream.h
libs/ardour/ardour/audio_library.h
libs/ardour/ardour/audioengine.h
libs/ardour/ardour/audiofilesource.h
libs/ardour/ardour/audioplaylist.h
libs/ardour/ardour/audiosource.h
libs/ardour/ardour/automation_event.h
libs/ardour/ardour/configuration_vars.h
libs/ardour/ardour/crossfade.h
libs/ardour/ardour/cycles.h
libs/ardour/ardour/diskstream.h
libs/ardour/ardour/insert.h
libs/ardour/ardour/io.h
libs/ardour/ardour/location.h
libs/ardour/ardour/meter.h
libs/ardour/ardour/midi_diskstream.h
libs/ardour/ardour/midi_playlist.h
libs/ardour/ardour/named_selection.h
libs/ardour/ardour/playlist.h
libs/ardour/ardour/playlist_factory.h [new file with mode: 0644]
libs/ardour/ardour/redirect.h
libs/ardour/ardour/region.h
libs/ardour/ardour/route.h
libs/ardour/ardour/route_group.h
libs/ardour/ardour/send.h
libs/ardour/ardour/session.h
libs/ardour/ardour/session_playlist.h
libs/ardour/ardour/source.h
libs/ardour/ardour/track.h
libs/ardour/ardour/types.h
libs/ardour/ardour/utils.h
libs/ardour/audio_diskstream.cc
libs/ardour/audio_library.cc
libs/ardour/audio_playlist.cc
libs/ardour/audio_track.cc
libs/ardour/audioengine.cc
libs/ardour/audiofilesource.cc
libs/ardour/audioregion.cc
libs/ardour/audiosource.cc
libs/ardour/auditioner.cc
libs/ardour/automation_event.cc
libs/ardour/configuration.cc
libs/ardour/control_protocol_manager.cc
libs/ardour/crossfade.cc
libs/ardour/diskstream.cc
libs/ardour/enums.cc [new file with mode: 0644]
libs/ardour/globals.cc
libs/ardour/import.cc
libs/ardour/insert.cc
libs/ardour/io.cc
libs/ardour/location.cc
libs/ardour/meter.cc
libs/ardour/midi_diskstream.cc
libs/ardour/midi_playlist.cc
libs/ardour/midi_port.cc
libs/ardour/midi_track.cc
libs/ardour/named_selection.cc
libs/ardour/panner.cc
libs/ardour/playlist.cc
libs/ardour/playlist_factory.cc
libs/ardour/plugin_manager.cc
libs/ardour/redirect.cc
libs/ardour/region.cc
libs/ardour/route.cc
libs/ardour/route_group.cc
libs/ardour/send.cc
libs/ardour/session.cc
libs/ardour/session_butler.cc
libs/ardour/session_command.cc
libs/ardour/session_events.cc
libs/ardour/session_midi.cc
libs/ardour/session_process.cc
libs/ardour/session_state.cc
libs/ardour/session_time.cc
libs/ardour/session_transport.cc
libs/ardour/smf_source.cc
libs/ardour/sndfilesource.cc
libs/ardour/source.cc
libs/ardour/source_factory.cc
libs/ardour/tempo.cc
libs/ardour/utils.cc
libs/clearlooks/SConscript
libs/flowcanvas/SConscript
libs/fst/SConscript
libs/fst/fstinfofile.c
libs/glibmm2/SConscript
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/focus_entry.cc [new file with mode: 0644]
libs/gtkmm2ext/gtkmm2ext/barcontroller.h
libs/gtkmm2ext/gtkmm2ext/focus_entry.h [new file with mode: 0644]
libs/gtkmm2ext/gtkmm2ext/pixfader.h [new file with mode: 0644]
libs/gtkmm2ext/gtkmm2ext/slider_controller.h
libs/gtkmm2ext/pixfader.cc [new file with mode: 0644]
libs/gtkmm2ext/prompter.cc
libs/gtkmm2ext/slider_controller.cc
libs/gtkmm2ext/tearoff.cc
libs/libglademm/SConscript
libs/libgnomecanvasmm/SConscript
libs/libsndfile/SConscript
libs/libsndfile/configure
libs/midi++2/SConscript
libs/midi++2/jack_midiport.cc
libs/pbd/SConscript
libs/pbd/basename.cc
libs/pbd/controllable.cc
libs/pbd/copyfile.cc [new file with mode: 0644]
libs/pbd/enumwriter.cc [new file with mode: 0644]
libs/pbd/pbd/basename.h
libs/pbd/pbd/copyfile.h [new file with mode: 0644]
libs/pbd/pbd/enumwriter.h [new file with mode: 0644]
libs/pbd/pbd/tokenizer.h
libs/pbd/pbd/undo.h
libs/pbd/pbd/whitespace.h
libs/pbd/undo.cc
libs/pbd/whitespace.cc
libs/sigc++2/SConscript
libs/soundtouch/SConscript
libs/soundtouch/STTypes.h
libs/surfaces/control_protocol/SConscript
libs/surfaces/control_protocol/control_protocol/smpte.h
libs/surfaces/control_protocol/smpte.cc
libs/surfaces/generic_midi/SConscript
libs/surfaces/generic_midi/generic_midi_control_protocol.cc
libs/surfaces/generic_midi/midicontrollable.cc
libs/surfaces/generic_midi/midicontrollable.h
libs/surfaces/tranzport/SConscript
libs/surfaces/tranzport/tranzport_control_protocol.cc
libs/surfaces/tranzport/tranzport_control_protocol.h
svn_revision.h
templates/SConscript
tools/osx_packaging/Ardour2.icns
tools/osx_packaging/COPYING [new file with mode: 0644]
tools/osx_packaging/app_build.rb
tools/osx_packaging/ardour2_mac_ui.rc
tools/osx_packaging/bin/exporter
tools/osx_packaging/etc/gtk-2.0/gdk-pixbuf.loaders [new file with mode: 0644]
tools/osx_packaging/etc/gtk-2.0/gtk.immodules [new file with mode: 0644]
tools/osx_packaging/etc/pango/pango.modules [new file with mode: 0644]
tools/osx_packaging/etc/pango/pangorc [new file with mode: 0644]
tools/osx_packaging/etc/pango/pangox.aliases [new file with mode: 0644]
tools/osx_packaging/etc/profile.d/gtk+2-shlibs.csh [new file with mode: 0644]
tools/osx_packaging/etc/profile.d/gtk+2-shlibs.sh [new file with mode: 0644]
tools/osx_packaging/etc/profile.d/libxml2-bin.csh [new file with mode: 0644]
tools/osx_packaging/etc/profile.d/libxml2-bin.sh [new file with mode: 0644]
tools/osx_packaging/script
vst/SConscript

index a406deac660a6762dd55010262b88aa37d4cf6d0..027521670b910dbfb7e23bdc2bedda1fff9c465f 100644 (file)
@@ -59,6 +59,8 @@ mantis and some not, fairly continuously for several months. He then
 moved on to write SSE assembler routines to handle the CPU-hungry
 metering and mixing routines.
 
+Brian Ahr contributed many small fixes for ardour 2.0.
+
 Smaller (but not necessarily minor) patches were received from the
 following people:
 
@@ -73,3 +75,4 @@ following people:
   Rob Holland
   Joshua Leachman
   Per Sigmond
+  Nimal Ratnayake
\ No newline at end of file
index 36017496be7c4ec082ee3b53970a92fb4c860812..303df707f0eb141831a69fc1d7c364169053adaf 100644 (file)
@@ -12,4 +12,4 @@ file) will be removed.
 (2) STANDARD TEMPLATES
 
 The templates in ./templates are intended for installation in
-$prefix/share/ardour/templates.
+$prefix/share/ardour2/templates.
index 27e04b2ee11e4c5e7cfc973276575c52fbd0296c..f1a9a5e707b41f1f580670e15e7a373561dfd415 100644 (file)
@@ -16,7 +16,7 @@ import SCons.Node.FS
 SConsignFile()
 EnsureSConsVersion(0, 96)
 
-version = '2.0beta8'
+ardour_version = '2.0beta10'
 
 subst_dict = { }
 
@@ -39,10 +39,11 @@ opts.AddOptions(
     BoolOption('LIBLO', 'Compile with support for liblo library', 1),
     BoolOption('NLS', 'Set to turn on i18n support', 1),
     PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
-    BoolOption('SURFACES', 'Build support for control surfaces', 0),
+    BoolOption('SURFACES', 'Build support for control surfaces', 1),
     BoolOption('SYSLIBS', 'USE AT YOUR OWN RISK: CANCELS ALL SUPPORT FROM ARDOUR AUTHORS: Use existing system versions of various libraries instead of internal ones', 0),
     BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
-    BoolOption('VST', 'Compile with support for VST', 0)
+    BoolOption('VST', 'Compile with support for VST', 0),
+    BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 0)
 )
 
 #----------------------------------------------------------------------
@@ -75,11 +76,11 @@ class LibraryInfo(Environment):
 
 env = LibraryInfo (options = opts,
                    CPPPATH = [ '.' ],
-                   VERSION = version,
-                   TARBALL='ardour-' + version + '.tar.bz2',
+                   VERSION = ardour_version,
+                   TARBALL='ardour-' + ardour_version + '.tar.bz2',
                    DISTFILES = [ ],
-                   DISTTREE  = '#ardour-' + version,
-                   DISTCHECKDIR = '#ardour-' + version + '/check'
+                   DISTTREE  = '#ardour-' + ardour_version,
+                   DISTCHECKDIR = '#ardour-' + ardour_version + '/check'
                    )
 
 env.ENV_update(os.environ)
@@ -233,7 +234,8 @@ def i18n (buildenv, sources, installenv):
 
 
 def fetch_svn_revision (path):
-    cmd = "svn info "
+    cmd = "LANG= "
+    cmd += "svn info "
     cmd += path
     cmd += " | awk '/^Revision:/ { print $2}'"
     return commands.getoutput (cmd)
@@ -388,6 +390,57 @@ if env['VST']:
         print "OK, VST support will be enabled"
 
 
+#######################
+# Dependency Checking #
+#######################
+
+deps = \
+{
+       'glib-2.0'             : '2.10.1',
+       'gthread-2.0'          : '2.10.1',
+       'gtk+-2.0'             : '2.8.1',
+       'libxml-2.0'           : '2.6.0',
+       'samplerate'           : '0.1.0',
+       'raptor'               : '1.4.2',
+       'lrdf'                 : '0.4.0',
+       'jack'                 : '0.101.1',
+       'libgnomecanvas-2.0'   : '2.0'
+}
+
+def DependenciesRequiredMessage():
+       print 'You do not have the necessary dependencies required to build ardour'
+       print 'Please consult http://ardour.org/building for more information'
+
+def CheckPKGConfig(context, version):
+     context.Message( 'Checking for pkg-config version >= %s... ' %version )
+     ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
+     context.Result( ret )
+     return ret
+
+def CheckPKGVersion(context, name, version):
+     context.Message( 'Checking for %s... ' % name )
+     ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0]
+     context.Result( ret )
+     return ret
+
+conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
+                                       'CheckPKGVersion' : CheckPKGVersion })
+
+# I think a more recent version is needed on win32
+min_pkg_config_version = '0.8.0'
+
+if not conf.CheckPKGConfig(min_pkg_config_version):
+     print 'pkg-config >= %s not found.' % min_pkg_config_version
+     Exit(1)
+
+for pkg, version in deps.iteritems():
+       if not conf.CheckPKGVersion( pkg, version ):
+               print '%s >= %s not found.' %(pkg, version)
+               DependenciesRequiredMessage()
+               Exit(1)
+
+env = conf.Finish()
+
 # ----------------------------------------------------------------------
 # Construction environment setup
 # ----------------------------------------------------------------------
@@ -411,6 +464,13 @@ libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
 if env['FFT_ANALYSIS']:
        libraries['fftw3f'] = LibraryInfo()
        libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
+        #
+        # Check for fftw3 header as well as the library
+        conf = Configure (libraries['fftw3f'])
+        if conf.CheckHeader ('fftw3.h') == False:
+                print "FFT Analysis cannot be compiled without the FFTW3 headers, which don't seem to be installed"
+                sys.exit (1)
+        libraries['fftw3f'] = conf.Finish();
 
 libraries['jack'] = LibraryInfo()
 libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
@@ -450,10 +510,194 @@ libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPP
 libraries['pbd']    = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
 libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
 
+
+# SCons should really do this for us
+
+conf = Configure (env)
+
+have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
+if have_cxx[0] != 1:
+    print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
+    sys.exit (1)
+else:
+    print "Congratulations, you have a functioning C++ compiler."
+
+env = conf.Finish()
+
+
+#
+# Compiler flags and other system-dependent stuff
+#
+
+opt_flags = []
+debug_flags = [ '-g' ]
+
+# guess at the platform, used to define compiler flags
+
+config_guess = os.popen("tools/config.guess").read()[:-1]
+
+config_cpu = 0
+config_arch = 1
+config_kernel = 2
+config_os = 3
+config = config_guess.split ("-")
+
+print "system triple: " + config_guess
+
+# Autodetect
+if env['DIST_TARGET'] == 'auto':
+    if config[config_arch] == 'apple':
+        # The [.] matches to the dot after the major version, "." would match any character
+        if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
+            env['DIST_TARGET'] = 'panther'
+        else:
+            env['DIST_TARGET'] = 'tiger'
+    else:
+        if re.search ("x86_64", config[config_cpu]) != None:
+            env['DIST_TARGET'] = 'x86_64'
+        elif re.search("i[0-5]86", config[config_cpu]) != None:
+            env['DIST_TARGET'] = 'i386'
+        elif re.search("powerpc", config[config_cpu]) != None:
+            env['DIST_TARGET'] = 'powerpc'
+        else:
+            env['DIST_TARGET'] = 'i686'
+    print "\n*******************************"
+    print "detected DIST_TARGET = " + env['DIST_TARGET']
+    print "*******************************\n"
+
+
+if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
+    #
+    # Apple/PowerPC optimization options
+    #
+    # -mcpu=7450 does not reliably work with gcc 3.*
+    #
+    if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
+        if config[config_arch] == 'apple':
+            ## opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
+            # to support g3s but still have some optimization for above
+            opt_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
+        else:
+            opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
+    else:
+        opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
+    opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
+    opt_flags.extend (["-Os"])
+
+elif ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)) and env['DIST_TARGET'] != 'none':
+    
+    build_host_supports_sse = 0
+    
+    debug_flags.append ("-DARCH_X86")
+    opt_flags.append ("-DARCH_X86")
+    
+    if config[config_kernel] == 'linux' :
+        
+        if env['DIST_TARGET'] != 'i386':
+            
+            flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
+            x86_flags = flag_line.split (": ")[1:][0].split (' ')
+            
+            if "mmx" in x86_flags:
+                opt_flags.append ("-mmmx")
+            if "sse" in x86_flags:
+                build_host_supports_sse = 1
+            if "3dnow" in x86_flags:
+                opt_flags.append ("-m3dnow")
+            
+            if config[config_cpu] == "i586":
+                opt_flags.append ("-march=i586")
+            elif config[config_cpu] == "i686":
+                opt_flags.append ("-march=i686")
+    
+    if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
+        opt_flags.extend (["-msse", "-mfpmath=sse"])
+        debug_flags.extend (["-msse", "-mfpmath=sse"])
+# end of processor-specific section
+
+# optimization section
+if env['FPU_OPTIMIZATION']:
+    if env['DIST_TARGET'] == 'tiger':
+        opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
+        debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
+        libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
+    elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
+        opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
+        debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
+        if env['DIST_TARGET'] == 'x86_64':
+            opt_flags.append ("-DUSE_X86_64_ASM")
+            debug_flags.append ("-DUSE_X86_64_ASM")
+        if build_host_supports_sse != 1:
+            print "\nWarning: you are building Ardour with SSE support even though your system does not support these instructions. (This may not be an error, especially if you are a package maintainer)"
+# end optimization section
+
+# handle x86/x86_64 libdir properly
+
+if env['DIST_TARGET'] == 'x86_64':
+    env['LIBDIR']='lib64'
+else:
+    env['LIBDIR']='lib'
+
+#
+# save off guessed arch element in an env
+#
+env.Append(CONFIG_ARCH=config[config_arch])
+
+
+#
+# ARCH="..." overrides all
+#
+
+if env['ARCH'] != '':
+    opt_flags = env['ARCH'].split()
+
+#
+# prepend boiler plate optimization flags
+#
+
+opt_flags[:0] = [
+    "-O3",
+    "-fomit-frame-pointer",
+    "-ffast-math",
+    "-fstrength-reduce"
+    ]
+
+if env['DEBUG'] == 1:
+    env.Append(CCFLAGS=" ".join (debug_flags))
+else:
+    env.Append(CCFLAGS=" ".join (opt_flags))
+
+#
+# warnings flags
+#
+
+env.Append(CCFLAGS="-Wall")
+env.Append(CXXFLAGS="-Woverloaded-virtual")
+
+if env['EXTRA_WARN']:
+    env.Append(CCFLAGS="-Wextra -pedantic")
+    env.Append(CXXFLAGS="-ansi")
+
+if env['LIBLO']:
+    env.Append(CCFLAGS="-DHAVE_LIBLO")
+
+
+#
+# fix scons nitpickiness on APPLE
+#
+
+
+def prep_libcheck(topenv, libinfo):
+    if topenv['DIST_TARGET'] == 'panther' or topenv['DIST_TARGET'] == 'tiger':
+        libinfo.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
+
+prep_libcheck(env, env)
+
 #
 # Check for libusb
 
 libraries['usb'] = LibraryInfo ()
+prep_libcheck(env, libraries['usb'])
 
 conf = Configure (libraries['usb'])
 if conf.CheckLib ('usb', 'usb_interrupt_write'):
@@ -467,6 +711,8 @@ libraries['usb'] = conf.Finish ()
 # Check for FLAC
 
 libraries['flac'] = LibraryInfo ()
+prep_libcheck(env, libraries['flac'])
+libraries['flac'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib")
 
 conf = Configure (libraries['flac'])
 conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX')
@@ -478,6 +724,8 @@ libraries['flac'] = conf.Finish ()
 # boost (we don't link against boost, just use some header files)
 
 libraries['boost'] = LibraryInfo ()
+prep_libcheck(env, libraries['boost'])
+libraries['boost'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/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."
@@ -490,7 +738,8 @@ libraries['boost'] = conf.Finish ()
 
 if env['LIBLO']:
     libraries['lo'] = LibraryInfo ()
-    
+    prep_libcheck(env, libraries['lo'])
+
     conf = Configure (libraries['lo'])
     if conf.CheckLib ('lo', 'lo_server_new') == False:
         print "liblo does not appear to be installed."
@@ -502,6 +751,7 @@ if env['LIBLO']:
 # Check for dmalloc
 
 libraries['dmalloc'] = LibraryInfo ()
+prep_libcheck(env, libraries['dmalloc'])
 
 #
 # look for the threaded version
@@ -546,6 +796,24 @@ else:
 env = conf.Finish()
 
 if env['SYSLIBS']:
+
+    syslibdeps = \
+    {
+        'sigc++-2.0'           : '2.0',
+        'gtkmm-2.4'            : '2.8',
+        'libgnomecanvasmm-2.6' : '2.12.0'
+    }
+
+    conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig,
+                    'CheckPKGVersion' : CheckPKGVersion })
+
+    for pkg, version in syslibdeps.iteritems():
+        if not conf.CheckPKGVersion( pkg, version ):
+            print '%s >= %s not found.' %(pkg, version)
+            DependenciesRequiredMessage()
+            Exit(1)
+       
+    env = conf.Finish()
     
     libraries['sigc2'] = LibraryInfo()
     libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
@@ -680,15 +948,17 @@ else:
         ]
 
 #
-# always build the LGPL control protocol lib, since we link against it ourselves
-# ditto for generic MIDI
+# * always build the LGPL control protocol lib, since we link against it from libardour
+# * ditto for generic MIDI
+# * tranzport checks whether it should build internally, but we need here so that
+#   its included in the tarball
 #
 
-surface_subdirs = [ 'libs/surfaces/control_protocol', 'libs/surfaces/generic_midi' ]
+surface_subdirs = [ 'libs/surfaces/control_protocol', 'libs/surfaces/generic_midi', 'libs/surfaces/tranzport' ]
 
 if env['SURFACES']:
     if have_libusb:
-        surface_subdirs += [ 'libs/surfaces/tranzport' ]
+        env['TRANZPORT'] = 'yes'
     if os.access ('libs/surfaces/sony9pin', os.F_OK):
         surface_subdirs += [ 'libs/surfaces/sony9pin' ]
 
@@ -737,177 +1007,12 @@ if os.environ.has_key('TERM'):
 if os.environ.has_key('HOME'):
        env['HOME'] = os.environ['HOME']
 
-# SCons should really do this for us
-
-conf = Configure (env)
-
-have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
-if have_cxx[0] != 1:
-    print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
-    sys.exit (1)
-else:
-    print "Congratulations, you have a functioning C++ compiler."
-
-env = conf.Finish()
-
-#
-# Compiler flags and other system-dependent stuff
-#
-
-opt_flags = []
-debug_flags = [ '-g' ]
-
-# guess at the platform, used to define compiler flags
-
-config_guess = os.popen("tools/config.guess").read()[:-1]
-
-config_cpu = 0
-config_arch = 1
-config_kernel = 2
-config_os = 3
-config = config_guess.split ("-")
-
-print "system triple: " + config_guess
-
-# Autodetect
-if env['DIST_TARGET'] == 'auto':
-    if config[config_arch] == 'apple':
-        # The [.] matches to the dot after the major version, "." would match any character
-        if re.search ("darwin[0-7][.]", config[config_kernel]) != None:
-            env['DIST_TARGET'] = 'panther'
-        else:
-            env['DIST_TARGET'] = 'tiger'
-    else:
-        if re.search ("x86_64", config[config_cpu]) != None:
-            env['DIST_TARGET'] = 'x86_64'
-        elif re.search("i[0-5]86", config[config_cpu]) != None:
-            env['DIST_TARGET'] = 'i386'
-        elif re.search("powerpc", config[config_cpu]) != None:
-            env['DIST_TARGET'] = 'powerpc'
-        else:
-            env['DIST_TARGET'] = 'i686'
-    print "\n*******************************"
-    print "detected DIST_TARGET = " + env['DIST_TARGET']
-    print "*******************************\n"
-
-
-if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
-    #
-    # Apple/PowerPC optimization options
-    #
-    # -mcpu=7450 does not reliably work with gcc 3.*
-    #
-    if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
-        if config[config_arch] == 'apple':
-            opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
-        else:
-            opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
-    else:
-        opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
-    opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
-
-elif ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)) and env['DIST_TARGET'] != 'none':
-    
-    build_host_supports_sse = 0
-    
-    debug_flags.append ("-DARCH_X86")
-    opt_flags.append ("-DARCH_X86")
-    
-    if config[config_kernel] == 'linux' :
-        
-        if env['DIST_TARGET'] != 'i386':
-            
-            flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
-            x86_flags = flag_line.split (": ")[1:][0].split (' ')
-            
-            if "mmx" in x86_flags:
-                opt_flags.append ("-mmmx")
-            if "sse" in x86_flags:
-                build_host_supports_sse = 1
-            if "3dnow" in x86_flags:
-                opt_flags.append ("-m3dnow")
-            
-            if config[config_cpu] == "i586":
-                opt_flags.append ("-march=i586")
-            elif config[config_cpu] == "i686":
-                opt_flags.append ("-march=i686")
-    
-    if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
-        opt_flags.extend (["-msse", "-mfpmath=sse"])
-        debug_flags.extend (["-msse", "-mfpmath=sse"])
-# end of processor-specific section
-
-# optimization section
-if env['FPU_OPTIMIZATION']:
-    if env['DIST_TARGET'] == 'tiger':
-        opt_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
-        debug_flags.append ("-DBUILD_VECLIB_OPTIMIZATIONS")
-        libraries['core'].Append(LINKFLAGS= '-framework Accelerate')
-    elif env['DIST_TARGET'] == 'i686' or env['DIST_TARGET'] == 'x86_64':
-        opt_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
-        debug_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
-        if env['DIST_TARGET'] == 'x86_64':
-            opt_flags.append ("-DUSE_X86_64_ASM")
-            debug_flags.append ("-DUSE_X86_64_ASM")
-        if build_host_supports_sse != 1:
-            print "\nWarning: you are building Ardour with SSE support even though your system does not support these instructions. (This may not be an error, especially if you are a package maintainer)"
-# end optimization section
-
-#
-# save off guessed arch element in an env
-#
-env.Append(CONFIG_ARCH=config[config_arch])
-
-
-#
-# ARCH="..." overrides all
-#
-
-if env['ARCH'] != '':
-    opt_flags = env['ARCH'].split()
-
-#
-# prepend boiler plate optimization flags
-#
-
-opt_flags[:0] = [
-    "-O3",
-    "-fomit-frame-pointer",
-    "-ffast-math",
-    "-fstrength-reduce"
-    ]
-
-if env['DEBUG'] == 1:
-    env.Append(CCFLAGS=" ".join (debug_flags))
-else:
-    env.Append(CCFLAGS=" ".join (opt_flags))
-
-#
-# warnings flags
-#
-
-env.Append(CCFLAGS="-Wall")
-env.Append(CXXFLAGS="-Woverloaded-virtual")
-
-if env['EXTRA_WARN']:
-    env.Append(CCFLAGS="-Wextra -pedantic")
-    env.Append(CXXFLAGS="-ansi")
-
-if env['LIBLO']:
-    env.Append(CCFLAGS="-DHAVE_LIBLO")
-
 #
 # everybody needs this
 #
 
 env.Merge ([ libraries['core'] ])
 
-#
-# fix scons nitpickiness on APPLE
-#
-
-if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
-    env.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
 
 #
 # i18n support
@@ -944,7 +1049,7 @@ env = conf.Finish()
 if env['NLS'] == 1:
     env.Append(CCFLAGS="-DENABLE_NLS")
 
-Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
+Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n ardour_version subst_dict')
 
 #
 # the configuration file may be system dependent
index bf8e4f560ed9ef14a1dabe2ba1da8cc2805f754d..dfd94ea5af50eba7d40b142fac8394583d0b0ebb 100644 (file)
@@ -4,7 +4,7 @@ import os
 import os.path
 import glob
 
-Import('env install_prefix final_prefix config_prefix libraries i18n version')
+Import('env install_prefix final_prefix config_prefix libraries i18n ardour_version')
 
 gtkardour = env.Copy()
 gtkmmtests = env.Copy()
@@ -112,6 +112,7 @@ color_manager.cc
 crossfade_edit.cc
 crossfade_view.cc
 curvetest.cc
+enums.cc
 editing.cc
 editor.cc
 editor_actions.cc
@@ -169,6 +170,7 @@ new_session_dialog.cc
 option_editor.cc
 opts.cc
 pan_automation_time_axis.cc
+panner.cc
 panner2d.cc
 panner_ui.cc
 playlist_selector.cc
@@ -262,7 +264,7 @@ versionflag = '-DVERSIONSTRING=\\\"' + env['VERSION'] + '\\\"'
 
 gtkardour.Append(CXXFLAGS=versionflag)
 
-executable = 'ardour.bin'
+executable = 'ardour-' + ardour_version
 
 ardour = gtkardour.Program(target = executable, source = gtkardour_files + extra_sources)
 ardourlib = gtkardour.SharedLibrary(target = 'ardourgtk', source = gtkardour_files + extra_sources)
@@ -274,14 +276,22 @@ tt = gtkmmtests.Program(target = 'tt', source = tt_files)
 
 my_subst_dict = { }
 my_subst_dict['%INSTALL_PREFIX%'] = final_prefix
+my_subst_dict['%LIBDIR%'] = env['LIBDIR']
+my_subst_dict['%VERSION%'] = ardour_version
 
 ardoursh = env.SubstInFile ('ardour.sh','ardour.sh.in', SUBST_DICT = my_subst_dict);
 env.AddPostAction (ardoursh, Chmod ('$TARGET', 0755))
 
+ardourdev = env.SubstInFile ('ardev_common.sh','ardev_common.sh.in', SUBST_DICT = my_subst_dict);
+env.AddPostAction (ardourdev, Chmod ('$TARGET', 0755))
+
+Default(ardourdev)
+Default(ardoursh)
+
 if env['VST']:
        Default(ardourlib)
        # the library - into the library dir
-       env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), ardourlib))
+       env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), ardourlib))
 else:
 
        if env['VERSIONED']:
@@ -292,7 +302,7 @@ else:
         #install
 
        # the executable - into the library dir
-       env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), ardour))
+       env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), ardour))
        # the script - into the bin dir
        env.Alias('install', env.InstallAs(os.path.join(install_prefix, 'bin')+'/ardour2', ardoursh))
 
@@ -305,9 +315,9 @@ env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour
 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.bindings'))
 env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.colors'))
 # data files
-env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour2'), 'splash.png'))
-env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour2/pixmaps'), pixmap_files))
-env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour2/icons'), icon_files))
+env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour2'), 'splash.png'))
+env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour2', 'pixmaps'), pixmap_files))
+env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour2', 'icons'), icon_files))
 
 env.Alias ('version', gtkardour.VersionBuild(['version.cc','version.h'], []))
                
index 959830725e02187eeaa879d01365cd7c761da373..34bb98199c33561fbd6dd8a321de8fe120e678f3 100644 (file)
@@ -145,6 +145,8 @@ static const char* authors[] = {
        N_("Stefan Kersten"),
        N_("Christopher George"),
        N_("Robert Jordens"),
+       N_("Brian Ahr"),
+       N_("Nimal Ratnayake"),
        0
 };
 
index 163ac981b9391855c94f39a3af1b8e6e19cf79f0..3752726c046085688f8914d01de3cb16323ac478 100644 (file)
@@ -61,7 +61,7 @@ AnalysisWindow::AnalysisWindow()
        tlmodel = Gtk::ListStore::create(tlcols);
        track_list.set_model (tlmodel);
        track_list.append_column(_("Track"), tlcols.trackname);
-       track_list.append_column_editable(_("Visible"), tlcols.visible);
+       track_list.append_column_editable(_("Show"), tlcols.visible);
        track_list.set_headers_visible(true);
        track_list.set_reorderable(false);
        track_list.get_selection()->set_mode (Gtk::SELECTION_NONE);
@@ -228,8 +228,8 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
        
        
                for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) {
-                       ARDOUR::AudioPlaylist *pl
-                               = dynamic_cast<ARDOUR::AudioPlaylist*>((*i)->playlist());
+                       boost::shared_ptr<AudioPlaylist> pl
+                               = boost::dynamic_pointer_cast<AudioPlaylist>((*i)->playlist());
 
                        if (!pl)
                                continue;
@@ -246,7 +246,7 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                        if (source_selection_ranges_rb.get_active()) {
 //                             cerr << "Analyzing ranges on track " << *&rui->route().name() << endl;
                                
-                               for (std::list<ARDOUR::AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
+                               for (std::list<AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
 
                                        nframes_t i = 0;
                                        int n;
index 933b5ba720c44c1fa45a746e7c9cdbca763c9e40..95466a42b8b314ec5cf32ed45ebeec922aecaeac 100755 (executable)
@@ -1,4 +1,4 @@
 #!/bin/sh
 dir=`dirname "$0"`
 . $dir/ardev_common.sh
-exec gdb gtk2_ardour/ardour.bin $*
+exec gdb $EXECUTABLE $*
index 04719908b48a51d8bc76f43d655ccec5b8b45359..3b65b2ec7938180c3f7ca179831ce2171cb71e9b 100755 (executable)
@@ -1,3 +1,3 @@
 #!/bin/sh
 . `dirname "$0"`/ardev_common.sh
-exec gtk2_ardour/ardour.bin --novst $*
+exec $EXECUTABLE "$*"
index d4109de8bb7c2cdda92a0568175f7fcd72311a8f..3cef2254d2a45784740e3fba37a80c98f5a7ec4c 100755 (executable)
@@ -13,3 +13,4 @@ export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
 # For the internal clearlooks engine
 export GTK_PATH=$PWD/libs/clearlooks:~/.ardour2
 
+EXECUTABLE=gtk2_ardour/ardour-2.0beta10
diff --git a/gtk2_ardour/ardev_common.sh.in b/gtk2_ardour/ardev_common.sh.in
new file mode 100644 (file)
index 0000000..6017dcd
--- /dev/null
@@ -0,0 +1,16 @@
+cd `dirname "$0"`/..
+
+#export G_DEBUG=fatal_criticals
+
+export ARDOUR_PATH=gtk2_ardour/icons:gtk2_ardour/pixmaps:gtk2_ardour
+export GTK_PATH=libs/clearlooks
+
+
+export LD_LIBRARY_PATH=libs/surfaces/control_protocol:libs/ardour:libs/midi++2:libs/pbd:libs/soundtouch:libs/gtkmm2ext:libs/sigc++2:libs/glibmm2:libs/gtkmm2/atk:libs/gtkmm2/pango:libs/gtkmm2/gdk:libs/gtkmm2/gtk:libs/libgnomecanvasmm:libs/libsndfile:libs/appleutility:$LD_LIBRARY_PATH
+
+# DYLD_LIBRARY_PATH is for darwin.
+export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
+# For the internal clearlooks engine
+export GTK_PATH=$PWD/libs/clearlooks:~/.ardour2
+
+EXECUTABLE=gtk2_ardour/ardour-%VERSION%
index 5a0eb469b7fbc7b33b6373ee294c0af02eab2ae9..8d280b536d44980cf30b5b3bbc2f5f5e15deb5f5 100644 (file)
-; this file is NOT an automated accelerator map dump
-
-(gtk_accel_path "<Actions>/Transport/ToggleRoll" "space")
-(gtk_accel_path "<Actions>/Transport/ToggleRollForgetCapture" "<control>space")
-(gtk_accel_path "<Actions>/Transport/Forward" "<control>Right")
-(gtk_accel_path "<Actions>/Transport/Rewind" "<control>Left")
-(gtk_accel_path "<Actions>/Transport/GotoZero" "KP_Insert")
-(gtk_accel_path "<Actions>/Transport/GotoStart" "Home")
-(gtk_accel_path "<Actions>/Transport/GotoEnd" "End")
-
-(gtk_accel_path "<Actions>/Editor/align-regions-sync-relative" "a")
-(gtk_accel_path "<Actions>/Editor/crop" "c")
-(gtk_accel_path "<Actions>/Editor/duplicate-region" "d")
-(gtk_accel_path "<Actions>/Editor/set-edit-cursor" "e")
-(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-gain" "g")
-(gtk_accel_path "<Actions>/Editor/split-region" "s")
-(gtk_accel_path "<Actions>/Editor/set-region-sync-position" "v")
-(gtk_accel_path "<Actions>/Editor/mute-unmute-region" "m")
-(gtk_accel_path "<Actions>/Editor/insert-region" "i")
-(gtk_accel_path "<Actions>/Editor/normalize-region" "n")
-(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-object" "o")
-(gtk_accel_path "<Actions>/Transport/loop" "l")
-(gtk_accel_path "<Actions>/Editor/set-playhead" "p")
+; ardour-2.0beta10 GtkAccelMap rc-file         -*- scheme -*-
+; this file is an automated accelerator map dump
+;
+; (gtk_accel_path "<Actions>/RegionList/RegionListSort" "")
+(gtk_accel_path "<Actions>/Common/Quit" "<Control>q")
+(gtk_accel_path "<Actions>/Common/Save" "<Control>s")
+; (gtk_accel_path "<Actions>/Editor/Pullup" "")
+; (gtk_accel_path "<Actions>/Editor/zoom-to-session" "")
+; (gtk_accel_path "<Actions>/JACK/JACKReconnect" "")
+; (gtk_accel_path "<Actions>/Editor/Autoconnect" "")
+; (gtk_accel_path "<Actions>/Editor/Edit" "")
+(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-end" "<Control>grave")
+; (gtk_accel_path "<Actions>/redirectmenu/copy" "")
+; (gtk_accel_path "<Actions>/options/MeterFalloffFaster" "")
+(gtk_accel_path "<Actions>/Transport/ToggleRollForgetCapture" "<Control>space")
+(gtk_accel_path "<Actions>/Transport/Record" "<Shift>r")
+; (gtk_accel_path "<Actions>/RegionList/SortByRegionLength" "")
+; (gtk_accel_path "<Actions>/options/MeterFalloffSlowest" "")
+; (gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-sync" "")
+; (gtk_accel_path "<Actions>/redirectmenu/deactivate_all" "")
+; (gtk_accel_path "<Actions>/RegionList/SortByRegionPosition" "")
+; (gtk_accel_path "<Actions>/Editor/ZoomFocus" "")
+; (gtk_accel_path "<Actions>/options/MeterFalloffSlow" "")
+; (gtk_accel_path "<Actions>/RegionList/rlHide" "")
+; (gtk_accel_path "<Actions>/Main/Metering" "")
+(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-end" "<Control>Tab")
+; (gtk_accel_path "<Actions>/Zoom/zoom-focus-playhead" "")
+; (gtk_accel_path "<Actions>/Editor/center-edit-cursor" "")
+; (gtk_accel_path "<Actions>/Editor/Monitoring" "")
+; (gtk_accel_path "<Actions>/redirectmenu/deactivate" "")
+; (gtk_accel_path "<Actions>/options/LatchedRecordEnable" "")
+; (gtk_accel_path "<Actions>/Transport/TogglePunchIn" "")
+; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsPercentage" "")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-start" "bracketleft")
+; (gtk_accel_path "<Actions>/Main/Close" "")
+; (gtk_accel_path "<Actions>/Main/New" "")
+(gtk_accel_path "<Actions>/Editor/nudge-next-backward" "<Control>KP_Subtract")
+; (gtk_accel_path "<Actions>/Editor/EditSelectRangeOptions" "")
+; (gtk_accel_path "<Actions>/Transport/ToggleTimeMaster" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-thirds" "")
+(gtk_accel_path "<Actions>/Editor/align-regions-start-relative" "<Shift>a")
+; (gtk_accel_path "<Actions>/Main/Export" "")
+(gtk_accel_path "<Actions>/Editor/jump-forward-to-mark" "<Control>KP_Right")
+; (gtk_accel_path "<Actions>/Editor/Smpte30" "")
+; (gtk_accel_path "<Actions>/Editor/playhead-to-range-start" "")
+; (gtk_accel_path "<Actions>/Editor/Subframes" "")
+; (gtk_accel_path "<Actions>/Editor/Smpte2997drop" "")
+; (gtk_accel_path "<Actions>/Main/AddTrackBus" "")
+(gtk_accel_path "<Actions>/Editor/align-regions-end" "<Control><Mod2>a")
+; (gtk_accel_path "<Actions>/JACK/JACKDisconnect" "")
+; (gtk_accel_path "<Actions>/options/MeterFalloffFast" "")
+; (gtk_accel_path "<Actions>/options/FileDataFormatFloat" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-region-end" "")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-sync" "semicolon")
+; (gtk_accel_path "<Actions>/options/StopRecordingOnXrun" "")
+; (gtk_accel_path "<Actions>/Editor/addExternalAudioToRegionList" "")
+; (gtk_accel_path "<Actions>/RegionList/SortDescending" "")
+; (gtk_accel_path "<Actions>/options/DoNotRunPluginsWhileRecording" "")
+; (gtk_accel_path "<Actions>/Editor/PullupNone" "")
 (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-range" "r")
-(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t")
-(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "z")
-
-(gtk_accel_path "<Actions>/Transport/Record" "<shift>r")
-
-
+(gtk_accel_path "<Actions>/Editor/jump-backward-to-mark" "<Control>KP_Left")
+; (gtk_accel_path "<Actions>/Main/AudioFileFormatData" "")
+; (gtk_accel_path "<Actions>/options/MeterFalloffFastest" "")
+(gtk_accel_path "<Actions>/Editor/audition-at-mouse" "period")
+(gtk_accel_path "<Actions>/Transport/Forward" "<Control>Right")
+; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-seconds" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-frame" "")
+; (gtk_accel_path "<Actions>/Main/ExportSelection" "")
+; (gtk_accel_path "<Actions>/options/StopPluginsWithTransport" "")
+(gtk_accel_path "<Actions>/Editor/editor-paste" "<Control>v")
+(gtk_accel_path "<Actions>/Editor/scroll-tracks-down" "Page_Down")
+; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-minutes" "")
+(gtk_accel_path "<Actions>/Editor/normalize-region" "n")
 (gtk_accel_path "<Actions>/Editor/nudge-forward" "KP_Add")
-(gtk_accel_path "<Actions>/Editor/nudge-next-forward" "<control>KP_Add")
+; (gtk_accel_path "<Actions>/Main/FlushWastebasket" "")
+; (gtk_accel_path "<Actions>/RegionList/SortByRegionEndinFile" "")
+; (gtk_accel_path "<Actions>/Editor/ToggleMeasureVisibility" "")
+; (gtk_accel_path "<Actions>/Zoom/zoom-focus-center" "")
 (gtk_accel_path "<Actions>/Editor/nudge-backward" "KP_Subtract")
-(gtk_accel_path "<Actions>/Editor/nudge-next-backward" "<control>KP_Subtract")
-
-(gtk_accel_path "<Actions>/Editor/show-editor-mixer" "<shift>e")
-
-(gtk_accel_path "<Actions>/Common/goto-editor" "<alt>e")
-(gtk_accel_path "<Actions>/Common/goto-mixer" "<alt>m")
-(gtk_accel_path "<Actions>/Common/ToggleSoundFileBrowser" "<alt>f")
-(gtk_accel_path "<Actions>/Common/ToggleLocations" "<alt>l")
-(gtk_accel_path "<Actions>/Common/ToggleBigClock" "<alt>b")
-(gtk_accel_path "<Actions>/Common/ToggleColorManager" "<alt>c")
-
-(gtk_accel_path "<Actions>/Editor/editor-copy" "<control>c")
-(gtk_accel_path "<Actions>/Common/Quit" "<control>q")
-(gtk_accel_path "<Actions>/Editor/redo" "<control>r")
-(gtk_accel_path "<Actions>/Common/Save" "<control>s")
-(gtk_accel_path "<Actions>/Editor/editor-paste" "<control>v")
-(gtk_accel_path "<Actions>/Editor/editor-cut" "<control>x")
-(gtk_accel_path "<Actions>/Editor/editor-delete" "Delete")
-(gtk_accel_path "<Actions>/Editor/undo" "<control>z")
-
-(gtk_accel_path "<Actions>/Editor/scroll-tracks-down" "Page_Down")
+; (gtk_accel_path "<Actions>/options/LatchedSolo" "")
+; (gtk_accel_path "<Actions>/options/MeterHoldOff" "")
+; (gtk_accel_path "<Actions>/options/OutputAutoConnectMaster" "")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency64" "")
+(gtk_accel_path "<Actions>/Editor/undo" "<Control>z")
+(gtk_accel_path "<Actions>/Editor/insert-region" "i")
+; (gtk_accel_path "<Actions>/Editor/center-playhead" "")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-start" "bracketright")
+; (gtk_accel_path "<Actions>/Snap/snap-to-region-start" "")
+; (gtk_accel_path "<Actions>/Editor/View" "")
+; (gtk_accel_path "<Actions>/Editor/Layering" "")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency4096" "")
 (gtk_accel_path "<Actions>/Editor/scroll-tracks-up" "Page_Up")
-(gtk_accel_path "<Actions>/Editor/scroll-backward" "leftarrow")
-(gtk_accel_path "<Actions>/Editor/scroll-forward" "rightarrow")
+(gtk_accel_path "<Actions>/Editor/set-edit-cursor" "e")
+; (gtk_accel_path "<Actions>/Editor/Smpte30drop" "")
+; (gtk_accel_path "<Actions>/Zoom/zoom-focus-edit" "")
+(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-start" "grave")
+; (gtk_accel_path "<Actions>/Editor/EditCursorMovementOptions" "")
+; (gtk_accel_path "<Actions>/redirectmenu/activate_all" "")
+; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsTapeTrack" "")
+; (gtk_accel_path "<Actions>/redirectmenu/paste" "")
+; (gtk_accel_path "<Actions>/Editor/Smpte25" "")
+; (gtk_accel_path "<Actions>/Main/MeteringFallOffRate" "")
+; (gtk_accel_path "<Actions>/options/UseHardwareMonitoring" "")
+; (gtk_accel_path "<Actions>/Editor/Smpte24" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-mark" "")
+; (gtk_accel_path "<Actions>/Editor/CrossfadesShort" "")
+; (gtk_accel_path "<Actions>/Editor/Smpte5994" "")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency8192" "")
 (gtk_accel_path "<Actions>/Editor/step-tracks-down" "downarrow")
-(gtk_accel_path "<Actions>/Editor/step-tracks-up" "uparrow")
-(gtk_accel_path "<Actions>/Editor/playhead-to-edit" "Return")
+; (gtk_accel_path "<Actions>/Editor/toggle-xfades-visible" "")
+(gtk_accel_path "<Actions>/Editor/extend-range-to-end-of-region" "rightanglebracket")
+(gtk_accel_path "<Actions>/Editor/scroll-backward" "leftarrow")
+(gtk_accel_path "<Actions>/Editor/start-range" "<Control>KP_Down")
+; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsSemitones" "")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency128" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-beat" "")
+; (gtk_accel_path "<Actions>/Editor/RegionEditOps" "")
+; (gtk_accel_path "<Actions>/Editor/snap-magnetic" "")
+; (gtk_accel_path "<Actions>/Editor/playhead-to-range-end" "")
+(gtk_accel_path "<Actions>/Editor/align-regions-sync-relative" "a")
+; (gtk_accel_path "<Actions>/Editor/EditSelectRegionOptions" "")
+(gtk_accel_path "<Actions>/Editor/crop" "c")
+; (gtk_accel_path "<Actions>/redirectmenu/newsend" "")
+; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurfaceSubMenu" "")
+; (gtk_accel_path "<Actions>/Editor/MeterFalloff" "")
+; (gtk_accel_path "<Actions>/RegionList/rlRemove" "")
+(gtk_accel_path "<Actions>/Transport/GotoStart" "Home")
+(gtk_accel_path "<Actions>/Editor/split-region" "s")
+; (gtk_accel_path "<Actions>/Transport/ToggleAutoInput" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-thirtyseconds" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-minutes" "")
+(gtk_accel_path "<Actions>/Editor/align-regions-sync" "<Mod2>a")
+; (gtk_accel_path "<Actions>/Main/Windows" "")
+; (gtk_accel_path "<Actions>/Main/CleanupUnused" "")
+; (gtk_accel_path "<Actions>/redirectmenu/deselectall" "")
+; (gtk_accel_path "<Actions>/options/SoloViaBus" "")
+(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "z")
+; (gtk_accel_path "<Actions>/RegionList/rlAudition" "")
+(gtk_accel_path "<Actions>/Editor/set-region-sync-position" "v")
+; (gtk_accel_path "<Actions>/Editor/PullupPlus4Plus1" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-region-boundary" "")
+; (gtk_accel_path "<Actions>/JACK/JACK" "")
+(gtk_accel_path "<Actions>/Editor/editor-cut" "<Control>x")
+; (gtk_accel_path "<Actions>/RegionList/SortAscending" "")
+; (gtk_accel_path "<Actions>/Main/Help" "")
+; (gtk_accel_path "<Actions>/options/UseExternalMonitoring" "")
+; (gtk_accel_path "<Actions>/Editor/Smpte23976" "")
+(gtk_accel_path "<Actions>/Common/goto-editor" "<Alt>e")
+(gtk_accel_path "<Actions>/Editor/select-all" "<Control>a")
+(gtk_accel_path "<Actions>/Editor/nudge-next-forward" "<Control>KP_Add")
+; (gtk_accel_path "<Actions>/Snap/snap-to-eighths" "")
+(gtk_accel_path "<Actions>/Editor/select-all-after-playhead" "<Shift><Control>p")
+(gtk_accel_path "<Actions>/Common/ToggleMaximalEditor" "F11")
+; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileLength" "")
+; (gtk_accel_path "<Actions>/Editor/Timecode" "")
+; (gtk_accel_path "<Actions>/Transport/PlaySelection" "")
+; (gtk_accel_path "<Actions>/Editor/PullupMinus4Minus1" "")
+(gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<Shift><Control>e")
+; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileName" "")
+(gtk_accel_path "<Actions>/Editor/finish-range" "<Control>KP_Up")
+(gtk_accel_path "<Actions>/Transport/Loop" "l")
+; (gtk_accel_path "<Actions>/Editor/CrossfadesFull" "")
+(gtk_accel_path "<Actions>/Editor/finish-add-range" "<Shift><Control>KP_Up")
+; (gtk_accel_path "<Actions>/Transport/ToggleClick" "")
+; (gtk_accel_path "<Actions>/options/SendMTC" "")
+; (gtk_accel_path "<Actions>/Transport/TogglePunchOut" "")
+(gtk_accel_path "<Actions>/Editor/select-all-in-loop-range" "<Control>l")
+(gtk_accel_path "<Actions>/Editor/show-editor-mixer" "<Shift>e")
+; (gtk_accel_path "<Actions>/options/SoloInPlace" "")
+; (gtk_accel_path "<Actions>/Main/Options" "")
+; (gtk_accel_path "<Actions>/options/MeterFalloffMedium" "")
+(gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "f")
+; (gtk_accel_path "<Actions>/Main/SaveTemplate" "")
+; (gtk_accel_path "<Actions>/RegionList/SortByRegionStartinFile" "")
+; (gtk_accel_path "<Actions>/options/GainReduceFastTransport" "")
+; (gtk_accel_path "<Actions>/Common/ToggleInspector" "")
+; (gtk_accel_path "<Actions>/Transport/ToggleAutoPlay" "")
+; (gtk_accel_path "<Actions>/Editor/playhead-to-next-region-sync" "")
 (gtk_accel_path "<Actions>/Editor/edit-to-playhead" "<Alt>Return")
-
+; (gtk_accel_path "<Actions>/Editor/LayerMoveAddHigher" "")
+; (gtk_accel_path "<Actions>/Editor/Smpte60" "")
+; (gtk_accel_path "<Actions>/Main/Open" "")
+(gtk_accel_path "<Actions>/Editor/scroll-forward" "rightarrow")
+; (gtk_accel_path "<Actions>/Zoom/zoom-focus-left" "")
+; (gtk_accel_path "<Actions>/Main/TransportOptions" "")
+; (gtk_accel_path "<Actions>/Main/ControlSurfaces" "")
+; (gtk_accel_path "<Actions>/options/FileHeaderFormatBWF" "")
+; (gtk_accel_path "<Actions>/Transport/ToggleAutoReturn" "")
+; (gtk_accel_path "<Actions>/Editor/Smpte2997" "")
+; (gtk_accel_path "<Actions>/Editor/ToggleWaveformVisibility" "")
+(gtk_accel_path "<Actions>/Editor/redo" "<Control>r")
+; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsRegion" "")
+; (gtk_accel_path "<Actions>/Main/ExportSession" "")
+; (gtk_accel_path "<Actions>/options/InputAutoConnectPhysical" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-edit-cursor" "")
 (gtk_accel_path "<Actions>/Editor/temporal-zoom-in" "minus")
-(gtk_accel_path "<Actions>/Editor/temporal-zoom-out" "equal")
-
-(gtk_accel_path "<Actions>/Editor/select-all" "<control>a")
-(gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<shift><Control>e")
-(gtk_accel_path "<Actions>/Editor/select-all-before-edit-cursor" "<control>e")
-(gtk_accel_path "<Actions>/Editor/select-all-after-playhead" "<shift><Control>p")
-(gtk_accel_path "<Actions>/Editor/select-all-before-playhead" "<control>p")
-(gtk_accel_path "<Actions>/Editor/select-all-between-cursors" "u")
-(gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<Control>d")
-(gtk_accel_path "<Actions>/Editor/select-all-in-loop-range" "<Control>l")
-
+; (gtk_accel_path "<Actions>/JACK/Latency" "")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-end" "F2")
+; (gtk_accel_path "<Actions>/redirectmenu/rename" "")
+; (gtk_accel_path "<Actions>/RegionList/rlShowAuto" "")
+(gtk_accel_path "<Actions>/Editor/select-all-before-playhead" "<Control>p")
+; (gtk_accel_path "<Actions>/Editor/addExistingAudioFiles" "")
+; (gtk_accel_path "<Actions>/Main/Session" "")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "F1")
+; (gtk_accel_path "<Actions>/Main/AudioFileFormat" "")
+(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t")
+; (gtk_accel_path "<Actions>/Transport/Transport" "")
+; (gtk_accel_path "<Actions>/RegionList/SortByRegionName" "")
+; (gtk_accel_path "<Actions>/Main/KeyMouse Actions" "")
+(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-gain" "g")
+; (gtk_accel_path "<Actions>/Snap/snap-to-frame" "")
+; (gtk_accel_path "<Actions>/Editor/SnapTo" "")
+; (gtk_accel_path "<Actions>/Editor/Crossfades" "")
+; (gtk_accel_path "<Actions>/Editor/PullupPlus4" "")
+(gtk_accel_path "<Actions>/Editor/add-location-from-playhead" "KP_Enter")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-end" "<Control>bracketleft")
+; (gtk_accel_path "<Actions>/Main/MeteringHoldTime" "")
+; (gtk_accel_path "<Actions>/Editor/PullupPlus1" "")
+; (gtk_accel_path "<Actions>/Editor/Smpte24976" "")
+; (gtk_accel_path "<Actions>/options/FileDataFormat24bit" "")
+; (gtk_accel_path "<Actions>/Editor/SnapMode" "")
+(gtk_accel_path "<Actions>/Common/ToggleOptionsEditor" "<Control>o")
+; (gtk_accel_path "<Actions>/Editor/PullupMinus4" "")
+(gtk_accel_path "<Actions>/Common/goto-mixer" "<Alt>m")
+; (gtk_accel_path "<Actions>/Editor/addExternalAudioToTrack" "")
+; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileCreationDate" "")
+; (gtk_accel_path "<Actions>/redirectmenu/activate" "")
 (gtk_accel_path "<Actions>/Editor/extend-range-to-start-of-region" "leftanglebracket")
-(gtk_accel_path "<Actions>/Editor/extend-range-to-end-of-region" "rightanglebracket")
-
-(gtk_accel_path "<Actions>/Editor/align-regions-sync" "<mod2>a")
-(gtk_accel_path "<Actions>/Editor/align-regions-end" "<mod2><control>a")
-(gtk_accel_path "<Actions>/Editor/align-regions-start-relative" "<shift>a")
-
-(gtk_accel_path "<Actions>/Editor/brush-at-mouse" "<control>b")
-(gtk_accel_path "<Actions>/Editor/audition-at-mouse" "period")
-
+; (gtk_accel_path "<Actions>/Editor/PullupMinus1" "")
+; (gtk_accel_path "<Actions>/Editor/snap-normal" "")
+; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsTrack" "")
+(gtk_accel_path "<Actions>/Common/ToggleBigClock" "<Alt>b")
+; (gtk_accel_path "<Actions>/Snap/snap-to-asixteenthbeat" "")
+(gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<Control>d")
+; (gtk_accel_path "<Actions>/redirectmenu/edit" "")
+(gtk_accel_path "<Actions>/Editor/duplicate-region" "d")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency2048" "")
+; (gtk_accel_path "<Actions>/Editor/ToggleWaveformsWhileRecording" "")
+; (gtk_accel_path "<Actions>/Zoom/zoom-focus-right" "")
+(gtk_accel_path "<Actions>/Editor/remove-last-capture" "<Control>Delete")
+; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE" "")
+(gtk_accel_path "<Actions>/Transport/GotoZero" "KP_Insert")
+(gtk_accel_path "<Actions>/Transport/GotoEnd" "End")
+; (gtk_accel_path "<Actions>/redirectmenu/cut" "")
+; (gtk_accel_path "<Actions>/redirectmenu/newinsert" "")
+; (gtk_accel_path "<Actions>/options/UseMMC" "")
+; (gtk_accel_path "<Actions>/options/MeterFalloffOff" "")
+(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-object" "o")
+; (gtk_accel_path "<Actions>/Editor/PullupMinus4Plus1" "")
+; (gtk_accel_path "<Actions>/Editor/MeterHold" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-cd-frame" "")
+; (gtk_accel_path "<Actions>/options/StopTransportAtEndOfSession" "")
+; (gtk_accel_path "<Actions>/Main/Cleanup" "")
+; (gtk_accel_path "<Actions>/Main/Snapshot" "")
+; (gtk_accel_path "<Actions>/Transport/ToggleVideoSync" "")
+(gtk_accel_path "<Actions>/Transport/ToggleRoll" "space")
+; (gtk_accel_path "<Actions>/RegionList/SortBySourceFilesystem" "")
+(gtk_accel_path "<Actions>/Common/ToggleColorManager" "<Alt>c")
+; (gtk_accel_path "<Actions>/Common/About" "")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency32" "")
+(gtk_accel_path "<Actions>/Editor/playhead-to-edit" "Return")
+; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE64" "")
+(gtk_accel_path "<Actions>/Editor/brush-at-mouse" "<Control>b")
+; (gtk_accel_path "<Actions>/RegionList/rlShowAll" "")
+(gtk_accel_path "<Actions>/Transport/Rewind" "<Control>Left")
+; (gtk_accel_path "<Actions>/RegionList/SortByRegionTimestamp" "")
+; (gtk_accel_path "<Actions>/options/VerifyRemoveLastCapture" "")
+; (gtk_accel_path "<Actions>/options/OutputAutoConnectPhysical" "")
+(gtk_accel_path "<Actions>/Editor/step-tracks-up" "uparrow")
 (gtk_accel_path "<Actions>/Editor/playhead-to-next-region-start" "Tab")
-(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-end" "<Control>Tab")
-
-(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-start" "grave")
-(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-end" "<control>grave")
-
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-start" "bracketleft")
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-end" "<Control>bracketleft")
-
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-start" "bracketright")
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-end" "<Control>bracketright")
-
+; (gtk_accel_path "<Actions>/options/SendMMC" "")
+; (gtk_accel_path "<Actions>/Editor/toggle-auto-xfades" "")
+; (gtk_accel_path "<Actions>/Main/AudioFileFormatHeader" "")
+; (gtk_accel_path "<Actions>/options/MeterHoldShort" "")
+; (gtk_accel_path "<Actions>/options/MeterHoldMedium" "")
+(gtk_accel_path "<Actions>/Editor/select-all-before-edit-cursor" "<Control>e")
+; (gtk_accel_path "<Actions>/Editor/Subframes80" "")
+; (gtk_accel_path "<Actions>/options/FileHeaderFormatCAF" "")
+(gtk_accel_path "<Actions>/Common/ToggleLocations" "<Alt>l")
+; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurface" "")
+(gtk_accel_path "<Actions>/Editor/editor-delete" "Delete")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency256" "")
+(gtk_accel_path "<Actions>/Editor/select-all-between-cursors" "u")
+; (gtk_accel_path "<Actions>/Editor/LayerAddHigher" "")
+; (gtk_accel_path "<Actions>/Editor/Solo" "")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency1024" "")
+; (gtk_accel_path "<Actions>/Main/ExportRangeMarkers" "")
+(gtk_accel_path "<Actions>/Editor/set-playhead" "p")
+; (gtk_accel_path "<Actions>/Editor/toggle-xfades-active" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-bar" "")
+; (gtk_accel_path "<Actions>/Editor/LayerLaterHigher" "")
+; (gtk_accel_path "<Actions>/redirectmenu/selectall" "")
+(gtk_accel_path "<Actions>/Editor/editor-copy" "<Control>c")
+; (gtk_accel_path "<Actions>/Snap/snap-to-quarters" "")
+(gtk_accel_path "<Actions>/Editor/temporal-zoom-out" "equal")
+; (gtk_accel_path "<Actions>/options/UseSoftwareMonitoring" "")
+; (gtk_accel_path "<Actions>/Editor/Subframes100" "")
+(gtk_accel_path "<Actions>/Editor/mute-unmute-region" "m")
+; (gtk_accel_path "<Actions>/options/OutputAutoConnectManual" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-region-sync" "")
 (gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-sync" "apostrophe")
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-sync" "semicolon")
-
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "F1")
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-end" "F2")
-(gtk_accel_path "<Actions>/Common/ToggleMaximalEditor" "F11")
-
-(gtk_accel_path "<Actions>/Editor/jump-forward-to-mark" "<control>KP_Right")
-(gtk_accel_path "<Actions>/Editor/jump-backward-to-mark" "<control>KP_Left")
-
-(gtk_accel_path "<Actions>/Editor/start-range" "<control>KP_Down")
-(gtk_accel_path "<Actions>/Editor/finish-range" "<control>KP_Up")
-(gtk_accel_path "<Actions>/Editor/finish-add-range" "<shift><control>KP_Up")
-
-
-(gtk_accel_path "<Actions>/Editor/add-location-from-playhead" "KP_Enter")
-
-
+; (gtk_accel_path "<Actions>/redirectmenu/clear" "")
+; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurfaceFeedback" "")
+; (gtk_accel_path "<Actions>/Editor/PullupPlus4Minus1" "")
+; (gtk_accel_path "<Actions>/JACK/JACKLatency512" "")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-end" "<Control>bracketright")
+; (gtk_accel_path "<Actions>/Main/Recent" "")
+; (gtk_accel_path "<Actions>/redirectmenu/newplugin" "")
+; (gtk_accel_path "<Actions>/options/InputAutoConnectManual" "")
+; (gtk_accel_path "<Actions>/options/MeterHoldLong" "")
+; (gtk_accel_path "<Actions>/Snap/snap-to-seconds" "")
index 97441e5023516bebba182f9b887ebb687633d20e..cf56e2ad9fe4c5d906032f26b73606bbe4b41c11 100644 (file)
@@ -81,6 +81,7 @@
                <menuitem action='editor-delete'/>
                <menuitem action='editor-copy'/>
                <menuitem action='editor-paste'/>
+              <menuitem action='remove-last-capture'/>
                <separator/>       
                <menu action="EditSelectRangeOptions">
                    <menuitem action='extend-range-to-start-of-region'/>
                   <menuitem action="nudge-backward"/>
                   <menuitem action="nudge-next-backward"/>
               </menu>
+              <menu name='KeyMouse Actions' action='KeyMouse Actions'>
+                       <menuitem action='audition-at-mouse'/>
+                               <menuitem action='brush-at-mouse'/>
+                               <menuitem action='set-edit-cursor'/>
+                               <menuitem action='mute-unmute-region'/>
+                       <menuitem action='set-playhead'/>
+                       <menuitem action='split-region'/>
+                       <menuitem action='set-region-sync-position'/>
+                       <separator/>
+                       <menuitem action='set-mouse-mode-object'/>
+                       <menuitem action='set-mouse-mode-range'/>
+                       <menuitem action='set-mouse-mode-gain'/>
+                       <menuitem action='set-mouse-mode-zoom'/>
+                       <menuitem action='set-mouse-mode-timefx'/>
+          </menu>
         </menu>         
         <menu name='View' action = 'View'>
                <menu name='ZoomFocus' action='ZoomFocus'>
                <menuitem action='goto-editor'/>
                <menuitem action='goto-mixer'/>
                <menuitem action='ToggleOptionsEditor'/>
-               <menuitem action='ToggleSoundFileBrowser'/>
                <menuitem action='ToggleInspector'/>
                <menuitem action='ToggleLocations'/>
                <menuitem action='ToggleColorManager'/>
                <menuitem action='ToggleBigClock'/>
               <separator/>
-              <menuitem action='About'/>
         </menu>
         <menu name='Options' action='Options'>
               <menu action='AudioFileFormat'>
                   <menuitem action='Smpte24'/>
                   <menuitem action='Smpte24976'/>
                   <menuitem action='Smpte25'/>
-                  <menuitem action='Smpte2997drop'/>
                   <menuitem action='Smpte2997'/>
-                  <menuitem action='Smpte30drop'/>
+                  <menuitem action='Smpte2997drop'/>
                   <menuitem action='Smpte30'/>
+                  <menuitem action='Smpte30drop'/>
                   <menuitem action='Smpte5994'/>
                   <menuitem action='Smpte60'/>
                </menu>
                   <menuitem action='PullupMinus4'/>
                   <menuitem action='PullupMinus4Minus1'/>
                </menu>
+              <menu action='Subframes'>
+                  <menuitem action='Subframes80'/>
+                  <menuitem action='Subframes100'/>
+               </menu>
                <separator/>
                <menu action='Autoconnect'>
                    <menuitem action='InputAutoConnectPhysical'/>
               <separator/>
          </menu>
         <menu name='Help' action='Help'>
-              <menu name='KeyMouse Actions' action='KeyMouse Actions'>
-                       <menuitem action='audition-at-mouse'/>
-                               <menuitem action='brush-at-mouse'/>
-                               <menuitem action='set-edit-cursor'/>
-                               <menuitem action='mute-unmute-region'/>
-                       <menuitem action='set-playhead'/>
-                       <menuitem action='split-region'/>
-                       <menuitem action='set-region-sync-position'/>
-                       <separator/>
-                       <menuitem action='set-mouse-mode-object'/>
-                       <menuitem action='set-mouse-mode-range'/>
-                       <menuitem action='set-mouse-mode-gain'/>
-                       <menuitem action='set-mouse-mode-zoom'/>
-                       <menuitem action='set-mouse-mode-timefx'/>
-               </menu>
+            <menuitem action='About'/>
        </menu>
      </menubar>
 
index 107321024b6c79e0d62c7871cdf335b5b0a64888..1bf1ffa94bf3b56cc4425a9936dfcdcb9daf667d 100644 (file)
@@ -1,11 +1,11 @@
 #!/bin/sh
 
-export GTK_PATH=%INSTALL_PREFIX%/lib/ardour2:$GTK_PATH
+export GTK_PATH=%INSTALL_PREFIX%/%LIBDIR%/ardour2:$GTK_PATH
 
-export LD_LIBRARY_PATH=%INSTALL_PREFIX%/lib/ardour2:$LD_LIBRARY_PATH 
+export LD_LIBRARY_PATH=%INSTALL_PREFIX%/%LIBDIR%/ardour2:$LD_LIBRARY_PATH 
 # DYLD_LIBRARY_PATH is for Darwin
 export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
 
-exec %INSTALL_PREFIX%/lib/ardour2/ardour.bin $*
+exec %INSTALL_PREFIX%/%LIBDIR%/ardour2/ardour-%VERSION% $*
 
 
index d01534086895a3c3774eb9bc5cc59a6d20295b45..249edddbf4095d05e558119080ed90a7b5200b5d 100644 (file)
@@ -58,6 +58,11 @@ style "plugin_maker_text"
        fg[NORMAL] = { 0.80, 0.80, 0.80 }
 }
 
+style "automation_track_name"
+{
+       font_name = "sans italic 8"
+}
+
 style "first_action_message" 
 {
        font_name = "sans medium 34"
@@ -75,7 +80,7 @@ style "marker_text"
 
 style "time_axis_view_item_name"
 {
-       font_name = "sans medium 8"
+       font_name = "sans 6"
 }
 
 style "default_base" = "medium_text"
@@ -137,8 +142,9 @@ style "transport_base" = "medium_bold_text"
   bg[SELECTED] = { 0, 0, 0 }
 }
 /*
-style "black_mackie_menu_bar" = "medium_bold_text"
+style "black_mackie_menu_bar"
 {
+  font_name = "sans bold 9"
   fg[NORMAL] = { 1.0, 1.0, 1.0 }
   bg[NORMAL] = { 0, 0, 0 }
 }
@@ -190,6 +196,12 @@ style "track_rec_enable_button" = "small_button"
        bg[PRELIGHT] =   { 1.0, 0.0, 0.0 }
 }
 
+style "gain_fader"
+{
+       bg[NORMAL] =   { 0.269, 0.269, 0.300}
+       bg[ACTIVE] =   { 0.152, 0.152, 0.168 }
+}
+
 style "mixer_rec_enable_button" = "track_rec_enable_button"
 {
        font_name = "sans 7"
@@ -442,12 +454,17 @@ style "medium_bold_entry"  = "medium_bold_text"
        base[SELECTED] = { 0, 0, 0 }
 }
 
-
 style "small_entry" = "small_text"
 {
        fg[NORMAL] = { 0.70, 0.70, 0.70 }
-       fg[ACTIVE] = { 0.70, 0.70, 0.70 }
+       fg[ACTIVE] = { 0, 1.0, 0 }
+       fg[SELECTED] = { 0, 1.0, 0 }
+       text[NORMAL] = { 0.70, 0.70, 0.70 }
+       text[ACTIVE] = { 0, 1.0, 0 }
+       text[SELECTED] = { 0, 1.0, 0 }
        bg[NORMAL] = { 0.0, 0.0, 0.0 }
+       bg[SELECTED] = { 0.0, 0.0, 0.0 }
+       bg[SELECTED] = { 0.0, 0.0, 0.0 }
        base[NORMAL] = { 0, 0, 0 }
        base[ACTIVE] = { 0, 0, 0 }
        base[SELECTED] = { 0, 0, 0 }
@@ -481,9 +498,25 @@ style "small_red_on_black_entry"  = "small_bold_text"
        bg[ACTIVE] = { 0.0, 0.0, 0.0 }
 }
 
-style "big_clock_display" = "medium_entry"
+style "non_recording_big_clock_display" = "medium_entry"
+{
+       font_name = "sans 60"
+
+       fg[NORMAL] = { 0.50, 1.0, 0.50 }
+       fg[ACTIVE] = { 1.0, 0, 0.0 }
+       fg[SELECTED] = { 1.0, 0, 0 }
+       fg[PRELIGHT] = { 1.0, 0, 0.0 }
+       fg[INSENSITIVE] = { 1.0, 0, 0.0 }
+       
+       base[NORMAL] = { 0.0, 0.0, 0.0 }
+       base[ACTIVE] = { 0.0, 0.0, 0.0 }
+       bg[NORMAL] = { 0.0, 0.0, 0.0 }
+       bg[ACTIVE] = { 0.7, 0.0, 0.0 }  
+}
+
+style "recording_big_clock_display" = "non_recording_big_clock_display"
 {
-       font_name = "courier bold 34"
+       fg[NORMAL] = { 1.0, 0, 0 }
 }
 
 style "transport_clock_display"
@@ -504,7 +537,7 @@ style "transport_clock_display"
 
 style "tempo_meter_clock_display"
 {
-       font_name = "sans 8"
+       font_name = "sans 7"
        fg[NORMAL] = { 1.0, 1.0, 1.0 }
        fg[ACTIVE] = { 1.0, 1.0, 0.0 }
        fg[SELECTED] = { 1.0, 0, 0 }
@@ -836,16 +869,16 @@ style "flashing_alert" = "very_small_text"
 style "selected_io_selector_port_list" = "medium_bold_text"
 {
 
-       GtkTreeView::even-row-color = { 0.64, 0.68, 0.54 }
-       GtkTreeView::odd-row-color = { 0.64, 0.68, 0.54 }
+       GtkTreeView::even-row-color = { 0, 0, 0 }
+       GtkTreeView::odd-row-color = { 0, 0, 0 }
 
 # fg is used to color the fg (text) of the column header button
 
-       fg[NORMAL] = { 0.80, 0.80, 0.70 }
-       fg[SELECTED] = { 0.80, 0.80, 0.70 }
-       fg[ACTIVE] = { 0.80, 0.80, 0.70 }
-       fg[PRELIGHT] = { 0.80, 0.80, 0.70 }
-       fg[INSENSITIVE] = { 0.80, 0.80, 0.70 }
+       fg[NORMAL] = { 0.85, 0.85, 0.85 }
+       fg[SELECTED] = { 0.85, 0.85, 0.85 }
+       fg[ACTIVE] = { 0.85, 0.85, 0.85 }
+       fg[PRELIGHT] = { 0.85, 0.85, 0.85 }
+       fg[INSENSITIVE] = { 0.85, 0.85, 0.85 }
 
 # bg is used used to color the background of the column header button
 
@@ -857,29 +890,30 @@ style "selected_io_selector_port_list" = "medium_bold_text"
 
 # text is used to color the treeview row text
 
-       text[NORMAL] = { 0.80, 0.80, 0.70 }
-       text[SELECTED] = { 0.80, 0.80, 0.70 }
+       text[NORMAL] = { 0.85, 0.85, 0.85 }
+       text[SELECTED] = { 0.85, 0.85, 0.85 }
 
 # base is used to color a treeview with no rows
 
-       base[NORMAL] = { 0.64, 0.68, 0.54 }
-       base[ACTIVE] = { 0.64, 0.68, 0.54 }
-       base[PRELIGHT] = { 0.64, 0.68, 0.54 }
-       base[INSENSITIVE] = { 0.64, 0.68, 0.54 }
-       base[SELECTED] = { 0.64, 0.68, 0.54 }
+       base[NORMAL] = { 0.20, 0.20, 0.25 }
+       base[ACTIVE] = { 0.20, 0.20, 0.25 }
+       base[PRELIGHT] = { 0.20, 0.20, 0.25 }
+       base[INSENSITIVE] = { 0.20, 0.20, 0.25 }
+       base[SELECTED] = { 0.20, 0.20, 0.25 }
 
 }
 
 style "io_selector_port_list" = "medium_text"
 {
-
+       GtkTreeView::even-row-color = { 0.20, 0.20, 0.25 }
+       GtkTreeView::odd-row-color = { 0.20, 0.20, 0.25 }
 # fg is used to color the fg (text) of the column header button
 
-       fg[NORMAL] = { 0.80, 0.80, 0.70 }
-       fg[SELECTED] = { 0.80, 0.80, 0.70 }
-       fg[ACTIVE] = { 0.80, 0.80, 0.70 }
-       fg[PRELIGHT] = { 0.80, 0.80, 0.70 }
-       fg[INSENSITIVE] = { 0.80, 0.80, 0.70 }
+       fg[NORMAL] = { 0.70, 0.70, 0.70 }
+       fg[SELECTED] = { 0.70, 0.70, 0.70 }
+       fg[ACTIVE] = { 0.70, 0.70, 0.70 }
+       fg[PRELIGHT] = { 0.70, 0.70, 0.70 }
+       fg[INSENSITIVE] = { 0.70, 0.70, 0.70 }
 
 # bg is used used to color the background of the column header button
 
@@ -891,16 +925,16 @@ style "io_selector_port_list" = "medium_text"
 
 # text is used to color the treeview row text
 
-       text[NORMAL] = { 0.80, 0.80, 0.70 }
-       text[SELECTED] = { 0.80, 0.80, 0.70 }
+       text[NORMAL] = { 0.80, 0.80, 0.80 }
+       text[SELECTED] = { 0.80, 0.80, 0.80 }
 
 # base is used to color a treeview with no rows
 
-       base[NORMAL] = { 0, 0, 0 }
-       base[ACTIVE] = { 0, 0, 0 }
-       base[PRELIGHT] = { 0, 0, 0 }
-       base[INSENSITIVE] = { 0, 0, 0 }
-       base[SELECTED] = { 0, 0, 0 }
+       base[NORMAL] = { 0.20, 0.20, 0.25 }
+       base[ACTIVE] = { 0.20, 0.20, 0.25 }
+       base[PRELIGHT] = { 0.20, 0.20, 0.25 }
+       base[INSENSITIVE] = { 0.20, 0.20, 0.25 }
+       base[SELECTED] = { 0.20, 0.20, 0.25 }
 }
 
 style "io_selector_notebook" = "default_base"
@@ -937,15 +971,15 @@ style "pan_slider"
 {
        font_name = "sans 8"
 
-       fg[NORMAL] = { 0.67, 0.23, 0.22 }
-       fg[ACTIVE] = { 0.67, 0.23, 0.22 }
-       fg[INSENSITIVE] = {0.32, 0.39, 0.45 } # matches default_base
+       fg[NORMAL] = { 0.22, 0.73, 0.22 }
+       fg[ACTIVE] = { 0.22, 0.73, 0.22 }
+       fg[INSENSITIVE] = {0.22, 0.53, 0.22 } 
        fg[SELECTED] = { 0.67, 0.23, 0.22 }
        fg[PRELIGHT] = { 0.67, 0.23, 0.22 }
 
-       bg[NORMAL] = { 0, 0, 0 }
+       bg[NORMAL] = { 0.05, 0.05, 0.05 }
        bg[ACTIVE] = { 0, 0, 0 }
-       bg[INSENSITIVE] = {0.32, 0.39, 0.45 } # matches default_base
+       bg[INSENSITIVE] = {0.12, 0.19, 0.25 } 
        bg[SELECTED] = { 0, 0, 0 }
        bg[PRELIGHT] = { 0, 0, 0 }
 
@@ -954,6 +988,15 @@ style "pan_slider"
        text[INSENSITIVE] = { 0.70, 0.70, 0.70 }
        text[SELECTED] = { 0.70, 0.70, 0.70 }
        text[PRELIGHT] = { 0.70, 0.70, 0.70 }
+
+       # used to draw the triangular indicators 
+
+       base[NORMAL] = { 0.80, 0.80, 0.80 }
+       base[ACTIVE] =  { 0.80, 0.80, 0.80 }
+       base[INSENSITIVE] = {0.6, 0.6, 0.6 }
+       base[SELECTED] = { 0.80, 0.80, 0.80 }
+       base[PRELIGHT] = { 0.80, 0.80, 0.80 }
+
 }
 
 style "region_list_whole_file"
@@ -971,7 +1014,7 @@ style "ardour_button" ="default_buttons_menus"
 widget "*FirstActionMessage" style "first_action_message"
 widget "*VerboseCanvasCursor" style "verbose_canvas_cursor"
 widget "*MarkerText" style "marker_text"
-widget "*TimeAxisViewItemName" style "time_axis_view_item_name"
+widget "*TimeAxisViewItemName*" style "time_axis_view_item_name"
 #widget "*ExportProgress" style "default_buttons_menus"
 widget "*ExportFileLabel" style "small_bold_text"
 widget "*ExportFormatLabel" style "medium_bold_text"
@@ -1073,11 +1116,16 @@ widget "*ErrorMessage" style "error_message"
 widget "*FatalMessage" style "fatal_message"
 widget "*InfoMessage" style "info_message"
 widget "*WarningMessage" style "warning_message"
-widget "*BigClockDisplay" style "big_clock_display"
+widget "*BigClockNonRecording" style "non_recording_big_clock_display"
+widget "*BigClockRecording" style "recording_big_clock_display"
 widget "*TransportClockDisplay" style "transport_clock_display"
 widget "*SecondaryClockDisplay" style "transport_clock_display"
-widget "*BBTTempoLabel" style "tempo_meter_clock_display"
-widget "*BBTMeterLabel" style "tempo_meter_clock_display"
+widget "*AudioClockFramesUpperInfo" style "tempo_meter_clock_display"
+widget "*AudioClockFramesLowerInfo" style "tempo_meter_clock_display"
+widget "*AudioClockSMPTEUpperInfo" style "tempo_meter_clock_display"
+widget "*AudioClockSMPTELowerInfo" style "tempo_meter_clock_display"
+widget "*AudioClockBBTUpperInfo" style "tempo_meter_clock_display"
+widget "*AudioClockBBTLowerInfo" style "tempo_meter_clock_display"
 widget "*SelectionStartClock" style "default_clock_display"
 widget "*SelectionEndClock" style "default_clock_display"
 widget "*EditCursorClock" style "default_clock_display"
@@ -1115,9 +1163,9 @@ widget "*AudioBusControlsBaseSelected" style "edit_controls_base_selected"
 widget "*AudioTimeAxisViewControlsBaseUnselected" style "audio_track_base"
 widget "*AudioTrackStripBase" style "audio_track_base"
 widget "*AudioTrackControlsBaseUnselected" style "audio_track_base"
-widget "*AudioTrackFader" style "audio_track_base"
+widget "*AudioTrackFader" style "gain_fader"
 widget "*AudioBusStripBase" style "audio_bus_base"
-widget "*AudioBusFader" style "audio_bus_base"
+widget "*AudioBusFader" style "gain_fader"
 widget "*MidiBusControlsBaseUnselected" style "midi_bus_base"
 widget "*MidiBusControlsBaseInactiveUnselected" style "track_controls_inactive"
 widget "*MidiBusControlsBaseInactiveSelected" style "track_controls_inactive"
@@ -1153,6 +1201,7 @@ widget "*MouseModeButton*" style "default_buttons_menus"
 widget "*EditorMainCanvas" style "main_canvas_area"
 widget "*AudioTrackControlsBaseInactiveUnselected" style "track_controls_inactive"
 widget "*AutomationTrackControlsBaseInactiveUnselected" style "track_controls_inactive"
+widget "*AutomationTrackName" style "automation_track_name"
 widget "*AudioTrackControlsBaseInactiveSelected" style "track_controls_inactive"
 widget "*AutomationTrackControlsBaseInactiveSelected" style "track_controls_inactive"
 widget "*AudioTrackStripBaseInactive" style "track_controls_inactive"
@@ -1196,6 +1245,7 @@ widget "*MixerStripSpeedBase*" style "small_entry"
 widget "*MixerStripSpeedBaseNotOne" style "small_red_on_black_entry"
 widget "*MixerStripSpeedBaseNotOne*" style "small_red_on_black_entry"
 widget "*MixerStripGainDisplay" style "small_entry"
+widget "*MixerStripGainDisplay*" style "small_entry"
 widget "*MixerStripGainUnitButton" style "very_small_button"
 widget "*MixerStripGainUnitButton*" style "very_small_button"
 widget "*MixerStripMeterPreButton" style "very_small_button"
index 58e60f7627e7795d3cb25b3c85b5cd73053cf598..b85278b8b55779e04623e0e46a95277220edca6c 100644 (file)
@@ -38,6 +38,7 @@
 #include <pbd/compose.h>
 #include <pbd/pathscanner.h>
 #include <pbd/failed_constructor.h>
+#include <pbd/enumwriter.h>
 #include <gtkmm2ext/gtk_ui.h>
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/click_box.h>
@@ -96,10 +97,10 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
 
        : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
          
-         primary_clock (X_("TransportClockDisplay"), true, false, true),
-         secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
-         preroll_clock (X_("PreRollClock"), true, true),
-         postroll_clock (X_("PostRollClock"), true, true),
+         primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
+         secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
+         preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
+         postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
 
          /* adjuster table */
 
@@ -112,7 +113,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
 
          /* big clock */
 
-         big_clock ("BigClockDisplay", true),
+         big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true),
 
          /* transport */
 
@@ -145,7 +146,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        color_manager = new ColorManager();
 
        std::string color_file = ARDOUR::find_config_file("ardour.colors");
-       
+
        color_manager->load (color_file);
 
        editor = 0;
@@ -160,7 +161,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        route_params = 0;
        option_editor = 0;
        location_ui = 0;
-       sfdb = 0;
        open_session_selector = 0;
        have_configure_timeout = false;
        have_disk_overrun_displayed = false;
@@ -168,6 +168,10 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        _will_create_new_session_automatically = false;
        session_loaded = false;
        last_speed_displayed = -1.0f;
+       keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
+
+       can_save_keybindings = false;
+       Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
 
        last_configure_time.tv_sec = 0;
        last_configure_time.tv_usec = 0;
@@ -248,6 +252,10 @@ ARDOUR_UI::set_engine (AudioEngine& e)
                throw failed_constructor();
        }
        
+       /* listen to clock mode changes */
+
+       AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
+
        /* start the time-of-day-clock */
        
        update_wall_clock ();
@@ -349,22 +357,13 @@ ARDOUR_UI::save_ardour_state ()
                Config->add_instant_xml (mnode, get_user_ardour_path());
        }
 
-       /* keybindings */
-
-       AccelMap::save ("ardour.saved_bindings");
+       save_keybindings ();
 }
 
 void
 ARDOUR_UI::startup ()
 {
-       /* Once the UI is up and running, start the audio engine. Doing
-          this before the UI is up and running can cause problems
-          when not running with SCHED_FIFO, because the amount of
-          CPU and disk work needed to get the UI started can interfere
-          with the scheduling of the audio thread.
-       */
-
-       Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
+       // relax
 }
 
 void
@@ -392,6 +391,11 @@ If you still wish to quit, please use the\n\n\
                        break;
                }
        }
+
+       if (session) {
+               session->set_deletion_in_progress ();
+       }
+       engine->stop (true);
        Config->save_state();
        quit ();
 }
@@ -448,7 +452,8 @@ ARDOUR_UI::ask_about_saving_session (const string & what)
 
        save_the_session = 0;
 
-       editor->ensure_float (window);
+       window.set_keep_above (true);
+       window.present ();
 
        ResponseType r = (ResponseType) window.run();
 
@@ -1303,14 +1308,6 @@ ARDOUR_UI::do_engine_start ()
                engine->start();
        }
 
-       catch (AudioEngine::PortRegistrationFailure& err) {
-               engine->stop ();
-               error << _("Unable to create all required ports")
-                     << endmsg;
-               unload_session ();
-               return -1;
-       }
-
        catch (...) {
                engine->stop ();
                error << _("Unable to start the session running")
@@ -1332,14 +1329,6 @@ ARDOUR_UI::start_engine ()
                        */
                        session->save_state ("");
                }
-
-               /* there is too much going on, in too many threads, for us to 
-                  end up with a clean session. So wait 1 second after loading,
-                  and fix it up. its ugly, but until i come across a better
-                  solution, its what we have.
-               */
-
-               Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
        }
 
        return FALSE;
@@ -1348,7 +1337,9 @@ ARDOUR_UI::start_engine ()
 void
 ARDOUR_UI::update_clocks ()
 {
-        Clock (session->audible_frame()); /* EMIT_SIGNAL */
+       if (!editor || !editor->dragging_playhead()) {
+               Clock (session->audible_frame()); /* EMIT_SIGNAL */
+       }
 }
 
 void
@@ -1635,7 +1626,7 @@ ARDOUR_UI::save_template ()
 }
 
 void
-ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
+ARDOUR_UI::new_session (std::string predetermined_path)
 {
        string session_name;
        string session_path;
@@ -1748,7 +1739,7 @@ ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
 
 
                                        msg.set_name (X_("CleanupDialog"));
-                                       msg.set_wmclass (_("existing_session"), "Ardour");
+                                       msg.set_wmclass (X_("existing_session"), "Ardour");
                                        msg.set_position (Gtk::WIN_POS_MOUSE);
                                        
                                        switch (msg.run()) {
@@ -1854,9 +1845,8 @@ ARDOUR_UI::load_session (const string & path, const string & snap_name, string*
        /* if it already exists, we must have write access */
 
        if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
-               MessageDialog msg (*editor, _("\
-You do not have write access to this session.\n\
-This prevents the session from being loaded."));
+               MessageDialog msg (*editor, _("You do not have write access to this session.\n"
+                                             "This prevents the session from being loaded."));
                msg.run ();
                return -1;
        }
@@ -1876,22 +1866,14 @@ This prevents the session from being loaded."));
        Config->set_current_owner (ConfigVariableBase::Interface);
 
        session_loaded = true;
-
+       
        goto_editor_window ();
 
-       return 0;
-}
-
-int
-ARDOUR_UI::make_session_clean ()
-{
        if (session) {
                session->set_clean ();
        }
 
-       show ();
-
-       return FALSE;
+       return 0;
 }
 
 int
@@ -2096,7 +2078,7 @@ After cleanup, unused audio files will be moved to a \
        checker.set_default_response (RESPONSE_CANCEL);
 
        checker.set_name (_("CleanupDialog"));
-       checker.set_wmclass (_("ardour_cleanup"), "Ardour");
+       checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
        checker.set_position (Gtk::WIN_POS_MOUSE);
 
        switch (checker.run()) {
@@ -2396,7 +2378,7 @@ ARDOUR_UI::cmdline_new_session (string path)
                path = str;
        }
 
-       new_session (false, path);
+       new_session (path);
 
        _will_create_new_session_automatically = false; /* done it */
        return FALSE; /* don't call it again */
@@ -2450,3 +2432,69 @@ ARDOUR_UI::use_config ()
                ract->set_active ();
        }       
 }
+
+void
+ARDOUR_UI::update_transport_clocks (nframes_t pos)
+{
+       primary_clock.set (pos);
+       secondary_clock.set (pos);
+
+       if (big_clock_window) {
+               big_clock.set (pos);
+       }
+}
+
+void
+ARDOUR_UI::record_state_changed ()
+{
+       if (!session || !big_clock_window) {
+               /* why bother - the clock isn't visible */
+               return;
+       }
+
+       switch (session->record_status()) {
+       case Session::Recording:
+               big_clock.set_name ("BigClockRecording");
+               break;
+       default:
+               big_clock.set_name ("BigClockNonRecording");
+               break;
+       }
+}
+
+void
+ARDOUR_UI::set_keybindings_path (string path)
+{
+       keybindings_path = path;
+}
+
+void
+ARDOUR_UI::save_keybindings ()
+{
+       if (can_save_keybindings) {
+               AccelMap::save (keybindings_path);
+       } 
+}
+
+bool
+ARDOUR_UI::first_idle ()
+{
+       can_save_keybindings = true;
+       return false;
+}
+
+void
+ARDOUR_UI::store_clock_modes ()
+{
+       XMLNode* node = new XMLNode(X_("ClockModes"));
+
+       for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
+               node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
+       }
+
+       session->add_extra_xml (*node);
+       session->set_dirty ();
+}
+
+
+               
index 60b3b309b946fc345c8e2854ef793d6991c6142b..92f2cc103d9187c800c463ea99004b74fd9fab56 100644 (file)
@@ -70,7 +70,6 @@ class OptionEditor;
 class Mixer_UI;
 class ConnectionEditor;
 class RouteParams_UI;
-class SoundFileBrowser;
 class About;
 class AddRouteDialog;
 class NewSessionDialog;
@@ -129,7 +128,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
                _will_create_new_session_automatically = yn;
        }
 
-        void new_session(bool startup = false, std::string path = string());
+        void new_session(std::string path = string());
        gint cmdline_new_session (string path);
        int  unload_session ();
        void close_session(); 
@@ -185,6 +184,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        AudioClock preroll_clock;
        AudioClock postroll_clock;
 
+       void store_clock_modes ();
+       void restore_clock_modes ();
+
        void add_route ();
        
        void session_add_audio_track (int input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many) {
@@ -204,6 +206,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        }*/
 
        void set_engine (ARDOUR::AudioEngine&);
+       gint start_engine ();
 
        gint exit_on_main_window_close (GdkEventAny *);
 
@@ -213,6 +216,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void set_native_file_header_format (ARDOUR::HeaderFormat sf);
        void set_native_file_data_format (ARDOUR::SampleFormat sf);
 
+       void set_keybindings_path (std::string path);
+       void save_keybindings ();
+
   protected:
        friend class PublicEditor;
 
@@ -297,7 +303,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void queue_transport_change ();
        void map_transport_state ();
        int32_t do_engine_start ();
-       gint start_engine ();
        
        void engine_halted ();
        void engine_stopped ();
@@ -331,6 +336,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        Gtk::Frame   big_clock_frame;
        Gtk::Window* big_clock_window;
 
+       void update_transport_clocks (nframes_t pos);
+       void record_state_changed ();
+
        /* Transport Control */
 
        void detach_tearoff (Gtk::Box* parent, Gtk::Widget* contents);
@@ -538,6 +546,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void connect_to_session (ARDOUR::Session *);
        void connect_dependents_to_session (ARDOUR::Session *);
        void we_have_dependents ();
+       
+       std::string keybindings_path;
+
        void setup_keybindings ();
        void setup_session_options ();
        
@@ -570,11 +581,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        /* route dialog */
 
        AddRouteDialog *add_route_dialog;
-
-       /* SoundFile Browser */
-       SoundFileBrowser *sfdb;
-       void toggle_sound_file_browser ();
-       int create_sound_file_browser ();
        
        /* Keyboard Handling */
        
@@ -669,7 +675,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void map_meter_falloff ();
 
        void toggle_control_protocol (ARDOUR::ControlProtocolInfo*);
-       void toggle_control_protocol_feedback (ARDOUR::ControlProtocolInfo*, const char* group_name, const char* action_name);
+       void toggle_control_protocol_feedback (ARDOUR::ControlProtocolInfo*, const char* group_name, std::string action_name);
+
+       bool can_save_keybindings;
+       bool first_idle ();
 };
 
 #endif /* __ardour_gui_h__ */
index 25fe14423340031fe9c63fce1c0828d0fcb56c8d..27b852982ac249cf19706b8441688bb47e5e776e 100644 (file)
@@ -609,7 +609,7 @@ ARDOUR_UI::show_shuttle_context_menu ()
                build_shuttle_context_menu ();
        }
 
-       shuttle_context_menu->popup (1, 0);
+       shuttle_context_menu->popup (1, gtk_get_current_event_time());
 }
 
 void
@@ -815,7 +815,7 @@ ARDOUR_UI::shuttle_unit_clicked ()
        if (shuttle_unit_menu == 0) {
                shuttle_unit_menu = dynamic_cast<Menu*> (ActionManager::get_widget ("/ShuttleUnitPopup"));
        }
-       shuttle_unit_menu->popup (1, 0);
+       shuttle_unit_menu->popup (1, gtk_get_current_event_time());
 }
 
 void
index bf096f86c1a729728c1dd4eeb0f66e6c2fb63e76..9c6daa8952f724a439cfcbdb0894432cb0b94956 100644 (file)
@@ -27,6 +27,7 @@
 #include <gtkmm/accelmap.h>
 
 #include <pbd/error.h>
+
 #include "ardour_ui.h"
 #include "public_editor.h"
 #include "mixer_ui.h"
@@ -57,6 +58,17 @@ void
 ARDOUR_UI::we_have_dependents ()
 {
        setup_keybindings ();
+       editor->UpdateAllTransportClocks.connect (mem_fun (*this, &ARDOUR_UI::update_transport_clocks));
+}
+
+static void 
+accel_map_changed (GtkAccelMap* map,
+                  gchar* path,
+                  guint  key,
+                  GdkModifierType mod,
+                  gpointer arg)
+{
+       static_cast<ARDOUR_UI*>(arg)->save_keybindings ();
 }
 
 void
@@ -65,13 +77,20 @@ ARDOUR_UI::setup_keybindings ()
        install_actions ();
        RedirectBox::register_actions ();
        
-       std::string key_binding_file = ARDOUR::find_config_file("ardour.bindings");
+       cerr << "loading bindings from " << keybindings_path << endl;
 
        try {
-               AccelMap::load (key_binding_file);
+               AccelMap::load (keybindings_path);
        } catch (...) {
-               error << "ardour key bindings file not found" << endmsg;
+               error << string_compose (_("Ardour key bindings file not found at \"%1\" or contains errors."), keybindings_path)
+                     << endmsg;
        }
+
+       /* catch changes */
+
+       GtkAccelMap* accelmap = gtk_accel_map_get();
+       g_signal_connect (accelmap, "changed", (GCallback) accel_map_changed, this);
+
 }
 
 void
@@ -81,8 +100,8 @@ ARDOUR_UI::connect_dependents_to_session (ARDOUR::Session *s)
        mixer->connect_to_session (s);
 
        /* its safe to do this now */
-
-       s->restore_history (s->snap_name());
+       
+       s->restore_history ("");
 }
 
 void
index fe5963c53572f5557afa9f5931bc1755ec350b41..a9a61176a903089ef0d6ac6abdfe34bb8353e11f 100644 (file)
@@ -50,6 +50,7 @@ ARDOUR_UI::connect_to_session (Session *s)
        session = s;
 
        session->HaltOnXrun.connect (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
+       session->RecordStateChanged.connect (mem_fun (*this, &ARDOUR_UI::record_state_changed));
 
        /* sensitize menu bar options that are now valid */
 
@@ -92,10 +93,6 @@ ARDOUR_UI::connect_to_session (Session *s)
                option_editor->set_session (s);
        }
 
-       if (sfdb) {
-               sfdb->set_session (s);
-       }
-
        setup_session_options ();
 
        Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
@@ -345,36 +342,6 @@ ARDOUR_UI::toggle_route_params_window ()
        }
 }
 
-int
-ARDOUR_UI::create_sound_file_browser ()
-{
-       if (sfdb == 0) {
-               sfdb = new SoundFileBrowser (_("Sound File Browser"), session);
-               sfdb->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSoundFileBrowser")));
-       }
-       return 0;
-}
-       
-void
-ARDOUR_UI::toggle_sound_file_browser ()
-{
-       if (create_sound_file_browser()) {
-               return;
-       }
-
-       RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSoundFileBrowser"));
-       if (act) {
-               RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
-       
-               if (tact->get_active()) {
-                       sfdb->show_all();
-                       sfdb->present();
-               } else {
-                       sfdb->hide ();
-               }
-       }
-}
-
 void
 ARDOUR_UI::handle_locations_change (Location* ignored)
 {
index d1931a22d53b33295df278a074096960d4b4c962..df2fda78c94de70556ec8c9185a0096851f59477 100644 (file)
@@ -80,7 +80,7 @@ ARDOUR_UI::install_actions ()
        ActionManager::register_action (main_actions, X_("Sync"), _("Sync"));
        ActionManager::register_action (main_actions, X_("Options"), _("Options"));
        ActionManager::register_action (main_actions, X_("TransportOptions"), _("Options"));
-        ActionManager::register_action (main_actions, X_("Help"), _("Help"));
+       ActionManager::register_action (main_actions, X_("Help"), _("Help"));
        ActionManager::register_action (main_actions, X_("KeyMouse Actions"), _("KeyMouse Actions"));
        ActionManager::register_action (main_actions, X_("AudioFileFormat"), _("Audio File Format"));
        ActionManager::register_action (main_actions, X_("AudioFileFormatHeader"), _("Header"));
@@ -92,7 +92,7 @@ ARDOUR_UI::install_actions ()
 
        /* the real actions */
 
-       act = ActionManager::register_action (main_actions, X_("New"), _("New"),  bind (mem_fun(*this, &ARDOUR_UI::new_session), false, string ()));
+       act = ActionManager::register_action (main_actions, X_("New"), _("New"),  bind (mem_fun(*this, &ARDOUR_UI::new_session), string ()));
 
        ActionManager::register_action (main_actions, X_("Open"), _("Open"),  mem_fun(*this, &ARDOUR_UI::open_session));
        ActionManager::register_action (main_actions, X_("Recent"), _("Recent"),  mem_fun(*this, &ARDOUR_UI::open_recent_session));
@@ -189,7 +189,6 @@ ARDOUR_UI::install_actions ()
 
        ActionManager::register_action (common_actions, X_("goto-editor"), _("Show Editor"),  mem_fun(*this, &ARDOUR_UI::goto_editor_window));
        ActionManager::register_action (common_actions, X_("goto-mixer"), _("Show Mixer"),  mem_fun(*this, &ARDOUR_UI::goto_mixer_window));
-       ActionManager::register_toggle_action (common_actions, X_("ToggleSoundFileBrowser"), _("Sound File Browser"), mem_fun(*this, &ARDOUR_UI::toggle_sound_file_browser));
        ActionManager::register_toggle_action (common_actions, X_("ToggleOptionsEditor"), _("Options Editor"), mem_fun(*this, &ARDOUR_UI::toggle_options_window));
        act = ActionManager::register_toggle_action (common_actions, X_("ToggleInspector"), _("Track/Bus Inspector"), mem_fun(*this, &ARDOUR_UI::toggle_route_params_window));
        ActionManager::session_sensitive_actions.push_back (act);
@@ -483,7 +482,7 @@ ARDOUR_UI::toggle_control_protocol (ControlProtocolInfo* cpi)
 }
 
 void
-ARDOUR_UI::toggle_control_protocol_feedback (ControlProtocolInfo* cpi, const char* group, const char* action)
+ARDOUR_UI::toggle_control_protocol_feedback (ControlProtocolInfo* cpi, const char* group, string action)
 {
        if (!session) {
                /* this happens when we build the menu bar when control protocol support
@@ -494,14 +493,17 @@ ARDOUR_UI::toggle_control_protocol_feedback (ControlProtocolInfo* cpi, const cha
        }
 
        if (cpi->protocol) {
-               Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (group, action);
+               Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (group, action.c_str());
 
                if (act) {
                        Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
-                       bool x = tact->get_active();
 
-                       if (tact && x != cpi->protocol->get_feedback()) {
-                               cpi->protocol->set_feedback (!x);
+                       if (tact) {
+                               bool x = tact->get_active();
+
+                               if (x != cpi->protocol->get_feedback()) {
+                                       cpi->protocol->set_feedback (x);
+                               }
                        }
                }
        }
@@ -556,7 +558,7 @@ ARDOUR_UI::build_control_surface_menu ()
                                                                                                  (bind (mem_fun (*this, &ARDOUR_UI::toggle_control_protocol_feedback), 
                                                                                                         *i, 
                                                                                                         "Editor",
-                                                                                                        action_name.c_str())));
+                                                                                                        action_name)));
                                
                                ui += "<menu action='";
                                ui += submenu_name;
index 707d3109f7275d5ec2dfb3c24eb9cdb243839854..d0f523481f24485ffd8cc87414dee302c8aeda58 100644 (file)
@@ -236,7 +236,7 @@ ARDOUR_UI::set_monitor_model (MonitorModel model)
                break;
 
        default:
-               fatal << string_compose (_("programming error: unknown solo model in ARDOUR_UI::set_solo_model: %1"), model) << endmsg;
+               fatal << string_compose (_("programming error: unknown monitor model in ARDOUR_UI::set_monitor_model: %1"), model) << endmsg;
                /*NOTREACHED*/
        }
 
@@ -416,9 +416,9 @@ ARDOUR_UI::map_solo_model ()
        const char* on;
 
        if (Config->get_solo_model() == InverseMute) {
-               on = "SoloInPlace";
+               on = X_("SoloInPlace");
        } else {
-               on = "SoloViaBus";
+               on = X_("SoloViaBus");
        }
 
        Glib::RefPtr<Action> act = ActionManager::get_action ("options", on);
@@ -587,10 +587,8 @@ ARDOUR_UI::map_meter_falloff ()
 {
        const char* action = X_("MeterFalloffMedium");
 
-       /* XXX hack alert. Fix this. Please */
-
        float val = Config->get_meter_falloff ();
-       MeterFalloff code = (MeterFalloff) (int) (floor (val));
+       MeterFalloff code = meter_falloff_from_float(val);
 
        switch (code) {
        case MeterFalloffOff:
@@ -840,6 +838,14 @@ ARDOUR_UI::parameter_changed (const char* parameter_name)
                map_meter_falloff ();
        } else if (PARAM_IS ("verify-remove-last-capture")) {
                ActionManager::map_some_state ("options", "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture);
+       } else if (PARAM_IS ("video-pullup") || PARAM_IS ("smpte-format")) {
+               if (session) {
+                       primary_clock.set (session->audible_frame(), true);
+                       secondary_clock.set (session->audible_frame(), true);
+               } else {
+                       primary_clock.set (0, true);
+                       secondary_clock.set (0, true);
+               }
        }
 
 #undef PARAM_IS
index 8af65b5fe3987daaa2a9c2963b167c7641e201d9..05a469cb1763d38a773af6bf3f8dd1bed6ec2a36 100755 (executable)
@@ -5,5 +5,5 @@ if [ gprofhelper.c -nt gprofhelper.so ] ; then
     gcc -shared -nostdlib -fPIC gprofhelper.c -o gprofhelper.so -lpthread -ldl || exit 1
 fi
 
-export LD_LIBRARY_PATH=../libs/ardour/.libs
-LDPRELOAD=./gprofhelper.so ./ardev $*
+. ardev_common.sh
+LDPRELOAD=./gprofhelper.so $EXECUTABLE $*
index a1dc501d3fbd554792791808f7ea24070a119bc4..920e7cb1a897efe5a09927dfdc24e0325b6fa3b7 100755 (executable)
@@ -1,4 +1,4 @@
 #!/bin/sh
 . ardev_common.sh
 export ARDOUR_RUNNING_UNDER_VALGRIND=TRUE
-exec valgrind  --num-callers=50 --tool=memcheck gtk2_ardour/ardour.bin --novst $*
+exec valgrind  --num-callers=50 --tool=memcheck $EXECUTABLE --novst $*
index 4ec8c1b89f99881a61db96f8235a8d5817fc2437..7ad7e4df65956ab6bfb31e6607f6ae8f92ab07f3 100644 (file)
@@ -22,6 +22,7 @@
 #include <cmath>
 
 #include <pbd/convert.h>
+#include <pbd/enumwriter.h>
 
 #include <gtkmm2ext/utils.h>
 
@@ -40,10 +41,14 @@ using namespace ARDOUR;
 using namespace PBD;
 using namespace sigc;
 using namespace Gtk;
+using namespace std;
 
 using PBD::atoi;
 using PBD::atof;
 
+sigc::signal<void> AudioClock::ModeChanged;
+vector<AudioClock*> AudioClock::clocks;
+
 const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
        2,   /* SMPTE_Hours */
        2,   /* SMPTE_Minutes */
@@ -58,8 +63,10 @@ const uint32_t AudioClock::field_length[(int) AudioClock::AudioFrames+1] = {
        10   /* Audio Frame */
 };
 
-AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool with_tempo_and_meter) 
-       : is_duration (duration),
+AudioClock::AudioClock (std::string clock_name, bool transient, std::string widget_name, bool allow_edit, bool duration, bool with_info) 
+       : _name (clock_name),
+         is_transient (transient),
+         is_duration (duration),
          editable (allow_edit),
          colon1 (":"),
          colon2 (":"),
@@ -75,9 +82,51 @@ AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool
        ops_menu = 0;
        dragging = false;
        
+       if (with_info) {
+               frames_upper_info_label = manage (new Label);
+               frames_lower_info_label = manage (new Label);
+               smpte_upper_info_label = manage (new Label);
+               smpte_lower_info_label = manage (new Label);
+               bbt_upper_info_label = manage (new Label);
+               bbt_lower_info_label = manage (new Label);
+               
+               frames_upper_info_label->set_name ("AudioClockFramesUpperInfo");
+               frames_lower_info_label->set_name ("AudioClockFramesLowerInfo");
+               smpte_upper_info_label->set_name ("AudioClockSMPTEUpperInfo");
+               smpte_lower_info_label->set_name ("AudioClockSMPTELowerInfo");
+               bbt_upper_info_label->set_name ("AudioClockBBTUpperInfo");
+               bbt_lower_info_label->set_name ("AudioClockBBTLowerInfo");
+
+               Gtkmm2ext::set_size_request_to_display_given_text(*smpte_upper_info_label, "23.98",0,0);
+               Gtkmm2ext::set_size_request_to_display_given_text(*smpte_lower_info_label, "NDF",0,0);
+
+               frames_info_box.pack_start (*frames_upper_info_label, true, true);
+               frames_info_box.pack_start (*frames_lower_info_label, true, true);
+               smpte_info_box.pack_start (*smpte_upper_info_label, true, true);
+               smpte_info_box.pack_start (*smpte_lower_info_label, true, true);
+               bbt_info_box.pack_start (*bbt_upper_info_label, true, true);
+               bbt_info_box.pack_start (*bbt_lower_info_label, true, true);
+               
+       } else {
+               frames_upper_info_label = 0;
+               frames_lower_info_label = 0;
+               smpte_upper_info_label = 0;
+               smpte_lower_info_label = 0;
+               bbt_upper_info_label = 0;
+               bbt_lower_info_label = 0;
+       }       
+       
        audio_frames_ebox.add (audio_frames_label);
-       frames_packer_hbox.set_border_width (2);
-       frames_packer_hbox.pack_start (audio_frames_ebox, false, false);
+       
+       frames_packer.set_homogeneous (false);
+       frames_packer.set_border_width (2);
+       frames_packer.pack_start (audio_frames_ebox, false, false);
+       
+       if (with_info) {
+               frames_packer.pack_start (frames_info_box, false, false, 5);
+       }
+       
+       frames_packer_hbox.pack_start (frames_packer, true, false);
 
        hours_ebox.add (hours_label);
        minutes_ebox.add (minutes_label);
@@ -100,6 +149,10 @@ AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool
        smpte_packer.pack_start (colon3, false, false);
        smpte_packer.pack_start (frames_ebox, false, false);
 
+       if (with_info) {
+               smpte_packer.pack_start (smpte_info_box, false, false, 5);
+       }
+
        smpte_packer_hbox.pack_start (smpte_packer, true, false);
 
        bbt_packer.set_homogeneous (false);
@@ -110,20 +163,8 @@ AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool
        bbt_packer.pack_start (b2, false, false);
        bbt_packer.pack_start (ticks_ebox, false, false);
 
-       if (with_tempo_and_meter) {
-               meter_label = manage (new Label);
-               tempo_label = manage (new Label);
-
-               meter_label->set_name ("BBTMeterLabel");
-               tempo_label->set_name ("BBTTempoLabel");
-
-               tempo_meter_box.pack_start (*meter_label, true, true);
-               tempo_meter_box.pack_start (*tempo_label, true, true);
-
-               bbt_packer.pack_start (tempo_meter_box, false, false, 5);
-       } else {
-               meter_label = 0;
-               tempo_label = 0;
+       if (with_info) {
+               bbt_packer.pack_start (bbt_info_box, false, false, 5);
        }
 
        bbt_packer_hbox.pack_start (bbt_packer, true, false);
@@ -138,7 +179,50 @@ AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool
 
        minsec_packer_hbox.pack_start (minsec_packer, true, false);
 
-       set_name (name);
+       clock_frame.set_shadow_type (Gtk::SHADOW_IN);
+       clock_frame.set_name ("BaseFrame");
+
+       clock_frame.add (clock_base);
+
+       set_widget_name (widget_name);
+
+       _mode = BBT; /* lie to force mode switch */
+       set_mode (SMPTE);
+
+       pack_start (clock_frame, true, true);
+
+       /* the clock base handles button releases for menu popup regardless of
+          editable status. if the clock is editable, the clock base is where
+          we pass focus to after leaving the last editable "field", which
+          will then shutdown editing till the user starts it up again.
+
+          it does this because the focus out event on the field disables
+          keyboard event handling, and we don't connect anything up to
+          notice focus in on the clock base. hence, keyboard event handling
+          stays disabled.
+       */
+
+       clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
+       clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
+
+       Session::SMPTEOffsetChanged.connect (mem_fun (*this, &AudioClock::smpte_offset_changed));
+
+       if (editable) {
+               setup_events ();
+       }
+
+       set (last_when, true);
+
+       if (!is_transient) {
+               clocks.push_back (this);
+       }
+}
+
+void
+AudioClock::set_widget_name (string name)
+{
+       Widget::set_name (name);
+
        clock_base.set_name (name);
 
        audio_frames_label.set_name (name);
@@ -172,37 +256,7 @@ AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool
        b1.set_name (name);
        b2.set_name (name);
 
-       clock_frame.set_shadow_type (Gtk::SHADOW_IN);
-       clock_frame.set_name ("BaseFrame");
-
-       clock_frame.add (clock_base);
-
-       _mode = BBT; /* lie to force mode switch */
-       set_mode (SMPTE);
-
-       pack_start (clock_frame, true, true);
-
-       /* the clock base handles button releases for menu popup regardless of
-          editable status. if the clock is editable, the clock base is where
-          we pass focus to after leaving the last editable "field", which
-          will then shutdown editing till the user starts it up again.
-
-          it does this because the focus out event on the field disables
-          keyboard event handling, and we don't connect anything up to
-          notice focus in on the clock base. hence, keyboard event handling
-          stays disabled.
-       */
-
-       clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
-       clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
-
-       Session::SMPTEOffsetChanged.connect (mem_fun (*this, &AudioClock::smpte_offset_changed));
-
-       if (editable) {
-               setup_events ();
-       }
-
-       set (last_when, true);
+       queue_draw ();
 }
 
 void
@@ -390,6 +444,27 @@ AudioClock::set_frames (nframes_t when, bool force)
        char buf[32];
        snprintf (buf, sizeof (buf), "%u", when);
        audio_frames_label.set_text (buf);
+       
+       if (frames_upper_info_label) {
+               nframes_t rate = session->frame_rate();
+               
+               if (fmod (rate, 1000.0) == 0.000) {
+                       sprintf (buf, "%uK", rate/1000);
+               } else {
+                       sprintf (buf, "%.3fK", rate/1000.0f);
+               }
+               
+               frames_upper_info_label->set_text (buf);
+               
+               float vid_pullup = Config->get_video_pullup();
+               
+               if (vid_pullup == 0.0) {
+                       frames_lower_info_label->set_text(_("none"));
+               } else {
+                       sprintf (buf, "%-6.4f", vid_pullup);
+                       frames_lower_info_label->set_text (buf);
+               }
+       }
 }      
 
 void
@@ -467,6 +542,26 @@ AudioClock::set_smpte (nframes_t when, bool force)
                frames_label.set_text (buf);
                last_frames = smpte.frames;
        }
+       
+       if (smpte_upper_info_label) {
+               double smpte_frames = session->smpte_frames_per_second();
+               
+               if ( fmod(smpte_frames, 1.0) == 0.0) {
+                       sprintf (buf, "%u", int (smpte_frames)); 
+               } else {
+                       sprintf (buf, "%.2f", smpte_frames);
+               }
+               
+               smpte_upper_info_label->set_text (buf);
+               
+               if (session->smpte_drop_frames()) {
+                       sprintf (buf, "DF");
+               } else {
+                       sprintf (buf, "NDF");
+               }
+               
+               smpte_lower_info_label->set_text (buf);
+       }
 }
 
 void
@@ -483,12 +578,12 @@ AudioClock::set_bbt (nframes_t when, bool force)
        sprintf (buf, "%04" PRIu32, bbt.ticks);
        ticks_label.set_text (buf);
        
-       if (meter_label) {
+       if (bbt_upper_info_label) {
                TempoMap::Metric m (session->tempo_map().metric_at (when));
                sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
-               tempo_label->set_text (buf);
+               bbt_lower_info_label->set_text (buf);
                sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
-               meter_label->set_text (buf);
+               bbt_upper_info_label->set_text (buf);
        }
 }
 
@@ -498,6 +593,18 @@ AudioClock::set_session (Session *s)
        session = s;
 
        if (s) {
+
+               XMLProperty* prop;
+               XMLNode* node = session->extra_xml (X_("ClockModes"));
+               AudioClock::Mode amode;
+               
+               if (node) {
+                       if ((prop = node->property (_name.c_str())) != 0) {
+                               amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
+                               set_mode (amode);
+                       }
+               }
+
                set (last_when, true);
        }
 }
@@ -1113,7 +1220,7 @@ AudioClock::get_frames (Field field,nframes_t pos,int dir)
                frames = session->frame_rate();
                break;
        case SMPTE_Frames:
-               frames = (nframes_t) floor (session->frame_rate() / Config->get_smpte_frames_per_second());
+               frames = (nframes_t) floor (session->frame_rate() / session->smpte_frames_per_second());
                break;
 
        case AudioFrames:
@@ -1221,7 +1328,7 @@ AudioClock::smpte_sanitize_display()
                seconds_label.set_text("59");
        }
        
-       switch ((long)rint(Config->get_smpte_frames_per_second())) {
+       switch ((long)rint(session->smpte_frames_per_second())) {
        case 24:
                if (atoi(frames_label.get_text()) > 23) {
                        frames_label.set_text("23");
@@ -1241,7 +1348,7 @@ AudioClock::smpte_sanitize_display()
                break;
        }
        
-       if (Config->get_smpte_drop_frames()) {
+       if (session->smpte_drop_frames()) {
                if ((atoi(minutes_label.get_text()) % 10) && (atoi(seconds_label.get_text()) == 0) && (atoi(frames_label.get_text()) < 2)) {
                        frames_label.set_text("02");
                }
@@ -1262,6 +1369,8 @@ AudioClock::smpte_frame_from_display () const
        smpte.minutes = atoi (minutes_label.get_text());
        smpte.seconds = atoi (seconds_label.get_text());
        smpte.frames = atoi (frames_label.get_text());
+       smpte.rate = session->smpte_frames_per_second();
+       smpte.drop= session->smpte_drop_frames();
 
        session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
        
@@ -1775,6 +1884,10 @@ AudioClock::set_mode (Mode m)
        set (last_when, true);
        clock_base.show_all ();
        key_entry_state = 0;
+
+       if (!is_transient) {
+               ModeChanged (); /* EMIT SIGNAL */
+       }
 }
 
 void
@@ -1784,26 +1897,26 @@ AudioClock::set_size_requests ()
 
        switch (_mode) {
        case SMPTE:
-               Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 2, 2);
-               Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 2, 2);
-               Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 2, 2);
-               Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 2, 2);
+               Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
                break;
 
        case BBT:
-               Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 2, 2);
-               Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 2, 2);
-               Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 2, 2);
+               Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
                break;
 
        case MinSec:
-               Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "99", 2, 2);
-               Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "99", 2, 2);
-               Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "99.999", 2, 2);
+               Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
                break;
 
        case Frames:
-               Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "4294967296", 2, 2);
+               Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
                break;
 
        case Off:
index e0431ba16ed55ecc591cc2764368e1c4e5871241..662cb949e64deeb5880176ee32fcc147c8e01b93 100644 (file)
@@ -43,12 +43,16 @@ class AudioClock : public Gtk::HBox
                Off
        };
        
-       AudioClock (const string& name, bool editable, bool is_duration = false, bool with_tempo_meter = false);
+       AudioClock (std::string clock_name, bool transient, std::string widget_name, bool editable, bool is_duration = false, bool with_info = false);
 
        Mode mode() const { return _mode; }
        
        void set (nframes_t, bool force = false);
        void set_mode (Mode);
+       
+       void set_widget_name (std::string);
+
+       std::string name() const { return _name; }
 
        nframes_t current_time (nframes_t position = 0) const;
        nframes_t current_duration (nframes_t position = 0) const;
@@ -56,10 +60,15 @@ class AudioClock : public Gtk::HBox
 
        sigc::signal<void> ValueChanged;
 
+       static sigc::signal<void> ModeChanged;
+       static std::vector<AudioClock*> clocks;
+
   private:
        ARDOUR::Session  *session;
        Mode             _mode;
-       uint32_t      key_entry_state;
+       uint32_t          key_entry_state;
+       std::string      _name;
+       bool              is_transient;
        bool              is_duration;
        bool              editable;
 
@@ -75,6 +84,7 @@ class AudioClock : public Gtk::HBox
        Gtk::HBox   bbt_packer;
 
        Gtk::HBox   frames_packer_hbox;
+       Gtk::HBox   frames_packer;
        
        enum Field {
                SMPTE_Hours,
@@ -123,10 +133,18 @@ class AudioClock : public Gtk::HBox
        Gtk::Label  b1;
        Gtk::Label  b2;
 
-       Gtk::Label*  tempo_label;
-       Gtk::Label*  meter_label;
+       Gtk::Label*  frames_upper_info_label;
+       Gtk::Label*  frames_lower_info_label;
+
+       Gtk::Label*  smpte_upper_info_label;
+       Gtk::Label*  smpte_lower_info_label;
+       
+       Gtk::Label*  bbt_upper_info_label;
+       Gtk::Label*  bbt_lower_info_label;
 
-       Gtk::VBox   tempo_meter_box;
+       Gtk::VBox   frames_info_box;
+       Gtk::VBox   smpte_info_box;
+       Gtk::VBox   bbt_info_box;
 
        Gtk::EventBox  clock_base;
        Gtk::Frame     clock_frame;
index c5645d479cabb1e5b799a4045c620bc653da8353..b7106a079660ec16bd3eeafdd68a9b48317e2f7b 100644 (file)
@@ -47,10 +47,10 @@ AudioRegionEditor::AudioRegionEditor (Session& s, boost::shared_ptr<AudioRegion>
          name_label (_("NAME:")),
          audition_button (_("play")),
          time_table (3, 2),
-         start_clock ("AudioRegionEditorClock", true),
-         end_clock ("AudioRegionEditorClock", true),
-         length_clock ("AudioRegionEditorClock", true, true),
-         sync_offset_clock ("AudioRegionEditorClock", true, true)
+         start_clock (X_("regionstart"), true, X_("AudioRegionEditorClock"), true),
+         end_clock (X_("regionend"), true, X_("AudioRegionEditorClock"), true),
+         length_clock (X_("regionlength"), true, X_("AudioRegionEditorClock"), true, true),
+         sync_offset_clock (X_("regionsyncoffset"), true, X_("AudioRegionEditorClock"), true, true)
 
 {
        start_clock.set_session (&_session);
@@ -128,8 +128,6 @@ AudioRegionEditor::AudioRegionEditor (Session& s, boost::shared_ptr<AudioRegion>
        name_changed ();
        bounds_changed (Change (StartChanged|LengthChanged|PositionChanged));
 
-       //XMLNode *node  = _region->extra_xml ("GUI");
-
        _region->StateChanged.connect (mem_fun(*this, &AudioRegionEditor::region_changed));
        
        spin_arrow_grab = false;
@@ -203,7 +201,7 @@ AudioRegionEditor::start_clock_changed ()
 {
        _session.begin_reversible_command (_("change region start position"));
 
-       Playlist* const pl = _region->playlist();
+       boost::shared_ptr<Playlist> pl = _region->playlist();
 
        if (pl) {
                XMLNode &before = pl->get_state();
@@ -220,8 +218,8 @@ AudioRegionEditor::end_clock_changed ()
 {
        _session.begin_reversible_command (_("change region end position"));
 
-       Playlist* const pl = _region->playlist();
-
+       boost::shared_ptr<Playlist> pl = _region->playlist();
+       
        if (pl) {
                XMLNode &before = pl->get_state();
                _region->trim_end (end_clock.current_time(), this);
@@ -241,7 +239,7 @@ AudioRegionEditor::length_clock_changed ()
        
        _session.begin_reversible_command (_("change region length"));
        
-       Playlist* const pl = _region->playlist();
+       boost::shared_ptr<Playlist> pl = _region->playlist();
 
        if (pl) {
                XMLNode &before = pl->get_state();
index 6543907bc8eb4b771d190ad8577ddccb57f88c29..e91dd529e3a0de171fbab4d74d0bf591ec6c6f83 100644 (file)
@@ -737,8 +737,8 @@ AudioRegionView::show_region_editor ()
                // trackview.editor.ensure_float (*editor);
        } 
 
-       editor->show_all ();
-       editor->get_window()->raise();
+       editor->present ();
+       editor->show_all();
 }
 
 void
@@ -873,6 +873,8 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
        wave->property_amplitude_above_axis() =  _amplitude_above_axis;
        wave->property_wave_color() = _region->muted() ? color_map[cMutedWaveForm] : color_map[cWaveForm];
        wave->property_region_start() = _region->start();
+       wave->property_rectified() = (bool) (_flags & WaveformRectified);
+       wave->property_logscaled() = (bool) (_flags & WaveformLogScaled);
 
        if (!(_flags & WaveformVisible)) {
                wave->hide();
@@ -987,6 +989,8 @@ AudioRegionView::store_flags()
 
        node->add_property ("waveform-visible", (_flags & WaveformVisible) ? "yes" : "no");
        node->add_property ("envelope-visible", (_flags & EnvelopeVisible) ? "yes" : "no");
+       node->add_property ("waveform-rectified", (_flags & WaveformRectified) ? "yes" : "no");
+       node->add_property ("waveform-logscaled", (_flags & WaveformLogScaled) ? "yes" : "no");
 
        _region->add_extra_xml (*node);
 }
@@ -1007,6 +1011,18 @@ AudioRegionView::set_flags (XMLNode* node)
                        _flags |= EnvelopeVisible;
                }
        }
+
+       if ((prop = node->property ("waveform-rectified")) != 0) {
+               if (prop->value() == "yes") {
+                       _flags |= WaveformRectified;
+               }
+       }
+
+       if ((prop = node->property ("waveform-logscaled")) != 0) {
+               if (prop->value() == "yes") {
+                       _flags |= WaveformLogScaled;
+               }
+       }
 }
        
 void
@@ -1046,9 +1062,30 @@ AudioRegionView::set_waveform_shape (WaveformShape shape)
                } else {
                        _flags &= ~WaveformRectified;
                }
+               store_flags ();
+       }
+}
+
+void
+AudioRegionView::set_waveform_scale (WaveformScale scale)
+{
+       bool yn = (scale == LogWaveform);
+
+       if (yn != (bool) (_flags & WaveformLogScaled)) {
+               for (vector<WaveView *>::iterator wave = waves.begin(); wave != waves.end() ; ++wave) {
+                       (*wave)->property_logscaled() = yn;
+               }
+
+               if (yn) {
+                       _flags |= WaveformLogScaled;
+               } else {
+                       _flags &= ~WaveformLogScaled;
+               }
+               store_flags ();
        }
 }
 
+
 GhostRegion*
 AudioRegionView::add_ghost (AutomationTimeAxisView& atv)
 {
index 977c0e3aae61311a097a1b312647706968980f6a..1d51cb7172b852ab94926574aa387e2ba6aa6cfb 100644 (file)
@@ -72,8 +72,10 @@ class AudioRegionView : public RegionView
        void set_envelope_visible (bool);
        void set_waveform_visible (bool yn);
        void set_waveform_shape (WaveformShape);
+       void set_waveform_scale (WaveformScale);
        
        bool waveform_rectified() const { return _flags & WaveformRectified; }
+       bool waveform_logscaled() const { return _flags & WaveformLogScaled; }
        bool waveform_visible()   const { return _flags & WaveformVisible; }
        bool envelope_visible()   const { return _flags & EnvelopeVisible; }
        
@@ -116,7 +118,8 @@ class AudioRegionView : public RegionView
     enum Flags {
            EnvelopeVisible = 0x1,
            WaveformVisible = 0x4,
-           WaveformRectified = 0x8
+           WaveformRectified = 0x8,
+           WaveformLogScaled = 0x10,
     };
 
     vector<ArdourCanvas::WaveView *> waves;
index bef35c572c002350d241b2ed0440e6f1d0b1f2b5..14b93c71829e74ea48f4a814edb7abf31e585874 100644 (file)
@@ -56,7 +56,9 @@ AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
        : StreamView (tv)
 {
        crossfades_visible = true;
-
+       _waveform_scale = LinearWaveform;
+       _waveform_shape = Traditional;
+       
        if (tv.is_track())
                stream_base_color = color_map[cAudioTrackBase];
        else
@@ -143,6 +145,14 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
                        /* great. we already have a AudioRegionView for this Region. use it again. */
                        
                        (*i)->set_valid (true);
+
+                       // this might not be necessary
+                       AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+                       if (arv) {
+                               arv->set_waveform_scale (_waveform_scale);
+                               arv->set_waveform_shape (_waveform_shape);
+                       }
+                               
                        return;
                }
        }
@@ -161,6 +171,27 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
        region_view->init (region_color, wait_for_waves);
        region_view->set_amplitude_above_axis(_amplitude_above_axis);
        region_views.push_front (region_view);
+
+       /* if this was the first one, then lets query the waveform scale and shape.
+          otherwise, we set it to the current value */
+          
+       if (region_views.size() == 1) {
+               if (region_view->waveform_logscaled()) {
+                       _waveform_scale = LogWaveform;
+               } else {
+                       _waveform_scale = LinearWaveform;
+               }
+
+               if (region_view->waveform_rectified()) {
+                       _waveform_shape = Rectified;
+               } else {
+                       _waveform_shape = Traditional;
+               }
+       }
+       else {
+               region_view->set_waveform_scale(_waveform_scale);
+               region_view->set_waveform_shape(_waveform_shape);
+       }
        
        /* follow global waveform setting */
 
@@ -237,7 +268,7 @@ AudioStreamView::playlist_changed (boost::shared_ptr<Diskstream> ds)
 
        StreamView::playlist_changed(ds);
 
-       AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(ds->playlist());
+       boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(ds->playlist());
        if (apl)
                playlist_connections.push_back (apl->NewCrossfade.connect (mem_fun (*this, &AudioStreamView::add_crossfade)));
 }
@@ -326,7 +357,7 @@ AudioStreamView::redisplay_diskstream ()
        if (_trackview.is_audio_track()) {
                _trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view);
 
-               AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(_trackview.get_diskstream()->playlist());
+               boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_trackview.get_diskstream()->playlist());
                if (apl)
                        apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
        }
@@ -380,8 +411,20 @@ AudioStreamView::set_waveform_shape (WaveformShape shape)
                if (arv)
                        arv->set_waveform_shape (shape);
        }
+       _waveform_shape = shape;
 }              
-               
+
+void
+AudioStreamView::set_waveform_scale (WaveformScale scale)
+{
+       for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+               AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+               if (arv) 
+                       arv->set_waveform_scale (scale);
+       }
+       _waveform_scale = scale;
+}              
+
 void
 AudioStreamView::setup_rec_box ()
 {
index 79aef2c042902565ef82d788ecebc7b3fe6d2461..ba0767a5e40e0ec3b208cac6cb04ece47454c81e 100644 (file)
@@ -59,6 +59,9 @@ class AudioStreamView : public StreamView
        ~AudioStreamView ();
 
        void set_waveform_shape (WaveformShape);
+       WaveformShape get_waveform_shape () const { return _waveform_shape; }
+       void set_waveform_scale (WaveformScale);
+       WaveformScale get_waveform_scale () const { return _waveform_scale; }
 
        int set_height (gdouble h);
        int set_samples_per_unit (gdouble spp);
@@ -100,6 +103,9 @@ class AudioStreamView : public StreamView
        typedef list<CrossfadeView*> CrossfadeViewList;
        CrossfadeViewList crossfade_views;
        bool              crossfades_visible;
+
+       WaveformShape     _waveform_shape;
+       WaveformScale     _waveform_scale;
 };
 
 #endif /* __ardour_audio_streamview_h__ */
index 7f6bc50222800028a6a672f424704fd7c695fae0..11d151fb914a49c5843d7260b48af558c7e5ab71 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <pbd/error.h>
 #include <pbd/stl_delete.h>
-#include <pbd/whitespace.h>
 #include <pbd/memento_command.h>
 
 #include <gtkmm2ext/gtk_ui.h>
@@ -133,6 +132,8 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
                controls_base_selected_name = "AudioBusControlsBaseSelected";
                controls_base_unselected_name = "AudioBusControlsBaseUnselected";
        }
+
+       post_construct ();
 }
 
 AudioTimeAxisView::~AudioTimeAxisView ()
@@ -260,14 +261,40 @@ AudioTimeAxisView::append_extra_display_menu_items ()
        waveform_item->set_active (editor.show_waveforms());
        ignore_toggle = false;
 
+       waveform_items.push_back (SeparatorElem());
+       
        RadioMenuItem::Group group;
-
+       
        waveform_items.push_back (RadioMenuElem (group, _("Traditional"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Traditional)));
        traditional_item = static_cast<RadioMenuItem *> (&waveform_items.back());
 
        waveform_items.push_back (RadioMenuElem (group, _("Rectified"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Rectified)));
        rectified_item = static_cast<RadioMenuItem *> (&waveform_items.back());
 
+       waveform_items.push_back (SeparatorElem());
+       
+       RadioMenuItem::Group group2;
+
+       waveform_items.push_back (RadioMenuElem (group2, _("Linear"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_scale), LinearWaveform)));
+       linearscale_item = static_cast<RadioMenuItem *> (&waveform_items.back());
+
+       waveform_items.push_back (RadioMenuElem (group2, _("Logarithmic"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_scale), LogWaveform)));
+       logscale_item = static_cast<RadioMenuItem *> (&waveform_items.back());
+
+       // setting initial item state
+       AudioStreamView* asv = audio_view();
+       if (asv) {
+               ignore_toggle = true;
+               if (asv->get_waveform_shape() == Rectified) 
+                       rectified_item->set_active(true);
+               else traditional_item->set_active(true);
+
+               if (asv->get_waveform_scale() == LogWaveform) 
+                       logscale_item->set_active(true);
+               else linearscale_item->set_active(true);
+               ignore_toggle = false;
+       }
+
        items.push_back (MenuElem (_("Waveform"), *waveform_menu));
 }
 
@@ -310,13 +337,25 @@ AudioTimeAxisView::set_waveform_shape (WaveformShape shape)
 {
        AudioStreamView* asv = audio_view();
 
-       if (asv) {
+       if (asv && !ignore_toggle) {
                asv->set_waveform_shape (shape);
        }
 
        map_frozen ();
 }      
 
+void
+AudioTimeAxisView::set_waveform_scale (WaveformScale scale)
+{
+       AudioStreamView* asv = audio_view();
+
+       if (asv && !ignore_toggle) {
+               asv->set_waveform_scale (scale);
+       }
+
+       map_frozen ();
+}      
+
 void
 AudioTimeAxisView::add_gain_automation_child ()
 {
index 2162771285c32f915c2a45baedcaa2cfdd9884a1..95bd8c0955f86d268060d3545b6f7c2f0b1e21a7 100644 (file)
@@ -98,6 +98,7 @@ class AudioTimeAxisView : public RouteTimeAxisView
        void toggle_show_waveforms ();
        void set_waveform_shape (WaveformShape);
        void toggle_waveforms ();
+       void set_waveform_scale (WaveformScale);
 
        void show_all_automation ();
        void show_existing_automation ();
@@ -125,6 +126,8 @@ class AudioTimeAxisView : public RouteTimeAxisView
        Gtk::CheckMenuItem* waveform_item;
        Gtk::RadioMenuItem* traditional_item;
        Gtk::RadioMenuItem* rectified_item;
+       Gtk::RadioMenuItem* linearscale_item;
+       Gtk::RadioMenuItem* logscale_item;
        Gtk::CheckMenuItem* gain_automation_item;
        Gtk::CheckMenuItem* pan_automation_item;
 };
index 44c100fd3760aac4c0eb7c37f341f8bc3105b45e..1dc62f1f42682eabf3240a31c1cfd00f1ab4b4fe 100644 (file)
@@ -21,6 +21,7 @@
 #include <cmath>
 #include <climits>
 #include <vector>
+#include <fstream>
 
 #include <pbd/stl_delete.h>
 #include <pbd/memento_command.h>
@@ -347,13 +348,6 @@ AutomationLine::nth (uint32_t n)
        }
 }
 
-void
-AutomationLine::modify_view (ControlPoint& cp, double x, double y, bool with_push)
-{
-       modify_view_point (cp, x, y, with_push);
-       update_line ();
-}
-
 void
 AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool with_push)
 {
@@ -416,7 +410,7 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi
                        ControlPoint* after;
                        
                        /* find the first point that can't move */
-                       
+
                        for (uint32_t n = cp.view_index + 1; (after = nth (n)) != 0; ++n) {
                                if (!after->can_slide) {
                                        x_limit = after->get_x() - 1.0;
@@ -471,14 +465,10 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi
 void
 AutomationLine::reset_line_coords (ControlPoint& cp)
 {      
-       line_points[cp.view_index].set_x (cp.get_x());
-       line_points[cp.view_index].set_y (cp.get_y());
-}
-
-void
-AutomationLine::update_line ()
-{
-       line->property_points() = line_points;
+       if (cp.view_index < line_points.size()) {
+               line_points[cp.view_index].set_x (cp.get_x());
+               line_points[cp.view_index].set_y (cp.get_y());
+       }
 }
 
 void
@@ -491,10 +481,8 @@ AutomationLine::sync_model_with_view_line (uint32_t start, uint32_t end)
 
        for (uint32_t i = start; i <= end; ++i) {
                p = nth(i);
-               sync_model_with_view_point(*p);
+               sync_model_with_view_point (*p, false, 0);
        }
-       
-       
 }
 
 void
@@ -508,7 +496,6 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr)
        mr.xval = (nframes_t) floor (cp.get_x());
        mr.yval = 1.0 - (cp.get_y() / _height);
 
-
         /* if xval has not changed, set it directly from the model to avoid rounding errors */
 
        if (mr.xval == trackview.editor.frame_to_unit((*cp.model)->when)) {
@@ -517,7 +504,6 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr)
                mr.xval = trackview.editor.unit_to_frame (mr.xval);
        }
 
-
        /* virtual call: this will do the right thing
           for whatever particular type of line we are.
        */
@@ -566,98 +552,6 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr)
        }
 }
 
-void
-AutomationLine::sync_model_from (ControlPoint& cp)
-{
-       ControlPoint* p;
-       uint32_t lasti;
-
-       sync_model_with_view_point (cp);
-
-       /* we might have moved all points after `cp' by some amount
-          if we pressed the with_push modifyer some of the time during the drag
-          so all subsequent points have to be resynced
-       */
-
-       lasti = control_points.size() - 1;
-       p = nth (lasti);
-
-       update_pending = true;
-
-       while (p != &cp && lasti) {
-               sync_model_with_view_point (*p);
-               --lasti;
-               p = nth (lasti);
-       }
-}
-
-void
-AutomationLine::sync_model_with_view_point (ControlPoint& cp)
-{
-       ModelRepresentation mr;
-       double ydelta;
-
-       model_representation (cp, mr);
-
-       /* part 4: how much are we changing the central point by */ 
-
-       ydelta = mr.yval - mr.ypos;
-
-       /* IMPORTANT: changing the model when the x-coordinate changes
-          may invalidate the iterators that we are using. this means that we have
-          to change the points before+after the one corresponding to the visual CP
-          first (their x-coordinate doesn't change). then we change the
-          "main" point.
-
-          apply the full change to the central point, and interpolate
-          in each direction to cover all model points represented
-          by the control point.
-       */
-
-       /* part 5: change all points before the primary point */
-
-       for (AutomationList::iterator i = mr.start; i != cp.model; ++i) {
-
-               double delta;
-
-               delta = ydelta * ((*i)->when - mr.xmin) / (mr.xpos - mr.xmin);
-
-               /* x-coordinate (generally time) stays where it is,
-                  y-coordinate moves by a certain amount.
-               */
-               
-               update_pending = true;
-               change_model (i, (*i)->when, mr.yval + delta);
-       }
-
-       /* part 6: change later points */
-
-       AutomationList::iterator i = cp.model;
-
-       ++i;
-
-       while (i != mr.end) {
-
-               double delta;
-               
-               delta = ydelta * (mr.xmax - (*i)->when) / (mr.xmax - mr.xpos);
-
-               /* x-coordinate (generally time) stays where it is,
-                  y-coordinate moves by a certain amount.
-               */
-               
-               update_pending = true;
-               change_model (i, (*i)->when, (*i)->value + delta);
-               
-               ++i;
-       }
-
-       /* part 7: change the primary point */
-
-       update_pending = true;
-       change_model (cp.model, mr.xval, mr.yval);
-}
-
 void
 AutomationLine::determine_visible_control_points (ALPoints& points)
 {
@@ -748,7 +642,8 @@ AutomationLine::determine_visible_control_points (ALPoints& points)
  
                if (view_index && pi != npoints && /* not the first, not the last */
                    (((this_rx == prev_rx) && (this_ry == prev_ry)) || /* same point */
-                    (((this_rx - prev_rx) < (box_size + 2)) &&  /* too close horizontally */
+                    (this_rx == prev_rx) || /* identical x coordinate */
+                    (((this_rx - prev_rx) < (box_size + 2)) &&  /* not identical, but still too close horizontally */
                      ((abs ((int)(this_ry - prev_ry)) < (int) (box_size + 2)))))) { /* too close vertically */
                        continue;
                }
@@ -810,7 +705,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points)
 
                view_index++;
        }
-
+       
        /* discard extra CP's to avoid confusing ourselves */
 
        while (control_points.size() > view_index) {
@@ -849,9 +744,11 @@ AutomationLine::determine_visible_control_points (ALPoints& points)
                if (_visible) {
                        line->show ();
                }
+
        } 
 
        set_selected_points (trackview.editor.get_selection().points);
+
 }
 
 string
@@ -886,7 +783,7 @@ AutomationLine::invalidate_point (ALPoints& p, uint32_t index)
 }
 
 void
-AutomationLine::start_drag (ControlPoint* cp, float fraction) 
+AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) 
 {
        if (trackview.editor.current_session() == 0) { /* how? */
                return;
@@ -901,24 +798,43 @@ AutomationLine::start_drag (ControlPoint* cp, float fraction)
        }
 
        trackview.editor.current_session()->begin_reversible_command (str);
-       trackview.editor.current_session()->add_command (new MementoCommand<AutomationLine>(*this, &get_state(), 0));
+       trackview.editor.current_session()->add_command (new MementoCommand<AutomationList>(alist, &get_state(), 0));
        
+       drag_x = x;
+       drag_distance = 0;
        first_drag_fraction = fraction;
        last_drag_fraction = fraction;
        drags = 0;
+       did_push = false;
 }
 
 void
 AutomationLine::point_drag (ControlPoint& cp, nframes_t x, float fraction, bool with_push) 
 {
-       modify_view (cp, x, fraction, with_push);
+       if (x > drag_x) {
+               drag_distance += (x - drag_x);
+       } else {
+               drag_distance -= (drag_x - x);
+       }
+
+       drag_x = x;
+
+       modify_view_point (cp, x, fraction, with_push);
+
+       if (line_points.size() > 1) {
+               line->property_points() = line_points;
+       }
+
        drags++;
+       did_push = with_push;
 }
 
 void
 AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_push) 
 {
        double ydelta = fraction - last_drag_fraction;
+
+       did_push = with_push;
        
        last_drag_fraction = fraction;
 
@@ -932,7 +848,9 @@ AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_p
                modify_view_point (*cp, trackview.editor.unit_to_frame (cp->get_x()), ((_height - cp->get_y()) /_height) + ydelta, with_push);
        }
 
-       update_line ();
+       if (line_points.size() > 1) {
+               line->property_points() = line_points;
+       }
 
        drags++;
 }
@@ -940,20 +858,95 @@ AutomationLine::line_drag (uint32_t i1, uint32_t i2, float fraction, bool with_p
 void
 AutomationLine::end_drag (ControlPoint* cp) 
 {
-       if (drags) {
+       if (!drags) {
+               return;
+       }
 
-               if (cp) {
-                       sync_model_from (*cp);
-               } else {
-                       sync_model_with_view_line (line_drag_cp1, line_drag_cp2);
+       alist.freeze ();
+
+       if (cp) {
+               sync_model_with_view_point (*cp, did_push, drag_distance);
+       } else {
+               sync_model_with_view_line (line_drag_cp1, line_drag_cp2);
+       }
+       
+       alist.thaw ();
+
+       update_pending = false;
+
+       trackview.editor.current_session()->add_command (new MementoCommand<AutomationList>(alist, 0, &alist.get_state()));
+       trackview.editor.current_session()->commit_reversible_command ();
+       trackview.editor.current_session()->set_dirty ();
+}
+
+
+void
+AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int64_t distance)
+{
+       ModelRepresentation mr;
+       double ydelta;
+
+       model_representation (cp, mr);
+
+       /* how much are we changing the central point by */ 
+
+       ydelta = mr.yval - mr.ypos;
+
+       /*
+          apply the full change to the central point, and interpolate
+          on both axes to cover all model points represented
+          by the control point.
+       */
+
+       /* change all points before the primary point */
+
+       for (AutomationList::iterator i = mr.start; i != cp.model; ++i) {
+               
+               double fract = ((*i)->when - mr.xmin) / (mr.xpos - mr.xmin);
+               double y_delta = ydelta * fract;
+               double x_delta = distance * fract;
+
+               /* interpolate */
+               
+               if (y_delta || x_delta) {
+                       alist.modify (i, (*i)->when + x_delta, mr.ymin + y_delta);
+               }
+       }
+
+       /* change the primary point */
+
+       update_pending = true;
+       alist.modify (cp.model, mr.xval, mr.yval);
+
+
+       /* change later points */
+       
+       AutomationList::iterator i = cp.model;
+       
+       ++i;
+       
+       while (i != mr.end) {
+               
+               double delta = ydelta * (mr.xmax - (*i)->when) / (mr.xmax - mr.xpos);
+
+               /* all later points move by the same distance along the x-axis as the main point */
+               
+               if (delta) {
+                       alist.modify (i, (*i)->when + distance, (*i)->value + delta);
                }
+               
+               ++i;
+       }
+               
+       if (did_push) {
 
-               update_pending = false;
+               /* move all points after the range represented by the view by the same distance
+                  as the main point moved.
+               */
 
-               trackview.editor.current_session()->add_command (new MementoCommand<AutomationLine>(*this, 0, &get_state()));
-               trackview.editor.current_session()->commit_reversible_command ();
-               trackview.editor.current_session()->set_dirty ();
+               alist.slide (mr.end, drag_distance);
        }
+
 }
 
 bool 
@@ -1027,11 +1020,11 @@ AutomationLine::remove_point (ControlPoint& cp)
        model_representation (cp, mr);
 
        trackview.editor.current_session()->begin_reversible_command (_("remove control point"));
-        XMLNode &before = get_state();
+        XMLNode &before = alist.get_state();
 
        alist.erase (mr.start, mr.end);
 
-       trackview.editor.current_session()->add_command(new MementoCommand<AutomationLine>(*this, &before, &get_state()));
+       trackview.editor.current_session()->add_command(new MementoCommand<AutomationList>(alist, &before, &alist.get_state()));
        trackview.editor.current_session()->commit_reversible_command ();
        trackview.editor.current_session()->set_dirty ();
 }
@@ -1149,8 +1142,6 @@ AutomationLine::show_selection ()
 {
        TimeSelection& time (trackview.editor.get_selection().time);
 
-       // cerr << "show selection\n";
-
        for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
                
                (*i)->selected = false;
@@ -1174,7 +1165,6 @@ AutomationLine::show_selection ()
 void
 AutomationLine::hide_selection ()
 {
-       // cerr << "hide selection\n";
 //     show_selection ();
 }
 
@@ -1239,7 +1229,6 @@ AutomationLine::clear ()
 void
 AutomationLine::change_model (AutomationList::iterator i, double x, double y)
 {
-       alist.modify (i, (nframes_t) x, y);
 }
 
 void
index b73a1c548ab840f3787a5080cb62a1e052fd80ef..1349efac4bd4ff8f9faf5ecb934b4bfefd3b058f 100644 (file)
@@ -117,7 +117,7 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoin
        
        /* dragging API */
 
-       virtual void start_drag (ControlPoint*, float fraction);
+       virtual void start_drag (ControlPoint*, nframes_t x, float fraction);
        virtual void point_drag(ControlPoint&, nframes_t x, float, bool with_push);
        virtual void end_drag (ControlPoint*);
        virtual void line_drag(uint32_t i1, uint32_t i2, float, bool with_push);
@@ -174,7 +174,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoin
        bool    update_pending : 1;
        bool    no_draw : 1;
        bool    points_visible : 1;
-       
+       bool    did_push;
+
        ArdourCanvas::Group&  _parent_group;
        ArdourCanvas::Group*   group;
        ArdourCanvas::Line*   line; /* line */
@@ -193,10 +194,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoin
        static bool invalid_point (ALPoints&, uint32_t index);
        
        void determine_visible_control_points (ALPoints&);
-       void sync_model_from (ControlPoint&);
-       void sync_model_with_view_point (ControlPoint&);
+       void sync_model_with_view_point (ControlPoint&, bool did_push, int64_t distance);
        void sync_model_with_view_line (uint32_t, uint32_t);
-       void modify_view (ControlPoint&, double, double, bool with_push);
        
        virtual void change_model (ARDOUR::AutomationList::iterator, double x, double y);
        virtual void change_model_range (ARDOUR::AutomationList::iterator,ARDOUR::AutomationList::iterator, double delta, float ydelta);
@@ -212,10 +211,11 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulThingWithGoin
        double   last_drag_fraction;
        uint32_t line_drag_cp1;
        uint32_t line_drag_cp2;
+       int64_t  drag_x;
+       int64_t  drag_distance;
 
        void modify_view_point(ControlPoint&, double, double, bool with_push);
        void reset_line_coords (ControlPoint&);
-       void update_line ();
 
        double control_point_box_size ();
 
index 2efb621b37c9e8c53ac5617938439e4d4d206a81..776dff37f21c8e49b815342e96b8ff2708ac2fa3 100644 (file)
@@ -21,6 +21,9 @@ using namespace PBD;
 using namespace Gtk;
 using namespace Editing;
 
+Pango::FontDescription AutomationTimeAxisView::name_font;
+bool AutomationTimeAxisView::have_name_font = false;
+
 AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, PublicEditor& e, TimeAxisView& rent, 
                                                ArdourCanvas::Canvas& canvas, const string & nom, 
                                                const string & state_name, const string & nomparent)
@@ -34,6 +37,11 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
          clear_button (_("clear")),
          auto_button (X_("")) /* force addition of a label */
 {
+       if (!have_name_font) {
+               name_font = get_font_for_style (X_("AutomationTrackName"));
+               have_name_font = true;
+       }
+
        automation_menu = 0;
        in_destructor = false;
        auto_off_item = 0;
@@ -84,14 +92,14 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
 
        string shortpname = _name;
        bool shortened = false;
-       
-       if (_name.length()) {
-               if (shortpname.length() > 18) {
-                       shortpname = shortpname.substr (0, 16);
-                       shortpname += "...";
-                       shortened = true;
-               }
+
+       int ignore_width;
+       shortpname = fit_to_pixels (_name, 60, name_font, ignore_width, true);
+
+       if (shortpname != _name ){
+               shortened = true;
        }
+
        name_label.set_text (shortpname);
        name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
 
@@ -99,11 +107,8 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
 
                /* limit the plug name string */
 
-               string pname = nomparent;
-
-               if (pname.length() > 14) {
-                       pname = pname.substr (0, 11);
-                       pname += "...";
+               string pname = fit_to_pixels (nomparent, 60, name_font, ignore_width, true);
+               if (pname != nomparent) {
                        shortened = true;
                }
 
@@ -150,7 +155,10 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
        controls_frame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT);
 
        XMLNode* xml_node = get_parent_with_state()->get_child_xml_node (_state_name);
-       set_state (*xml_node);
+
+       if (xml_node) {
+               set_state (*xml_node);
+       } 
 
        /* make sure labels etc. are correct */
 
@@ -186,7 +194,7 @@ AutomationTimeAxisView::auto_clicked ()
                                           bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Touch)));
        }
 
-       automation_menu->popup (1, 0);
+       automation_menu->popup (1, gtk_get_current_event_time());
 }
 
 
index 30fa71bea973608bff90dfc4f10b2c29508ce0f5..0eb525f6c1805c2d083e8b100b19687b016779aa 100644 (file)
@@ -121,6 +121,9 @@ class AutomationTimeAxisView : public TimeAxisView {
 
        void entered ();
        void exited ();
+
+       static Pango::FontDescription name_font;
+       static bool have_name_font;
 };
 
 #endif /* __ardour_gtk_automation_time_axis_h__ */
index 080f6871fa1705bb6f1d9231a17fb8881365400c..747761ea9ae887e6fb1dfb5425580f5aa535ce3d 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <ardour/dB.h>
 
+#include "logmeter.h"
 #include "canvas-waveview.h"
 #include "rgb_macros.h"
 
@@ -49,7 +50,8 @@ enum {
         PROP_HEIGHT,
         PROP_WAVE_COLOR,
         PROP_RECTIFIED,
-        PROP_REGION_START
+        PROP_REGION_START,
+        PROP_LOGSCALED,
 };
 
 static void gnome_canvas_waveview_class_init     (GnomeCanvasWaveViewClass *class);
@@ -253,6 +255,13 @@ gnome_canvas_waveview_class_init (GnomeCanvasWaveViewClass *class)
                  g_param_spec_boolean ("rectified", NULL, NULL,
                                        FALSE,
                                        (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_LOGSCALED,
+                 g_param_spec_boolean ("logscaled", NULL, NULL,
+                                       FALSE,
+                                       (G_PARAM_READABLE | G_PARAM_WRITABLE)));
         
         g_object_class_install_property
                 (gobject_class,
@@ -308,6 +317,7 @@ gnome_canvas_waveview_init (GnomeCanvasWaveView *waveview)
        waveview->gain_curve_function = NULL;
        waveview->gain_src = NULL;
        waveview->rectified = FALSE;
+       waveview->logscaled = FALSE;
        waveview->region_start = 0;
        waveview->samples_per_unit = 1.0;
        waveview->amplitude_above_axis = 1.0;
@@ -577,7 +587,29 @@ gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_
                free (gain);
        
        }
+
+       /* do optional log scaling.  this implementation is not particularly efficient */
        
+       if (waveview->logscaled) {
+               guint32 n;
+               GnomeCanvasWaveViewCacheEntry* buf = cache->data;
+               
+               for (n = 0; n < cache->data_size; ++n) {
+
+                       if (buf[n].max > 0.0f) {
+                               buf[n].max = alt_log_meter(coefficient_to_dB(buf[n].max));
+                       } else if (buf[n].max < 0.0f) {
+                               buf[n].max = -alt_log_meter(coefficient_to_dB(-buf[n].max));
+                       }
+                       
+                       if (buf[n].min > 0.0f) {
+                               buf[n].min = alt_log_meter(coefficient_to_dB(buf[n].min));
+                       } else if (buf[n].min < 0.0f) {
+                               buf[n].min = -alt_log_meter(coefficient_to_dB(-buf[n].min));
+                       }
+               }
+       }
+
        cache->start = ostart;
        cache->end = new_cache_end;
 
@@ -770,6 +802,17 @@ gnome_canvas_waveview_set_property (GObject      *object,
                        redraw = TRUE;
                }
                break;
+       case PROP_LOGSCALED:
+               if (waveview->logscaled != g_value_get_boolean(value)) {
+                       waveview->logscaled = g_value_get_boolean(value);
+                       if (waveview->cache_updater) {
+                               waveview->cache->start = 0;
+                               waveview->cache->end = 0;
+                       }
+                       redraw = TRUE;
+                       calc_bounds = TRUE;
+               }
+               break;
        case PROP_REGION_START:
                waveview->region_start = g_value_get_uint(value);
                redraw = TRUE;
@@ -869,6 +912,10 @@ gnome_canvas_waveview_get_property (GObject      *object,
                g_value_set_boolean (value, waveview->rectified);
                break;
 
+       case PROP_LOGSCALED:
+               g_value_set_boolean (value, waveview->logscaled);
+               break;
+
        case PROP_REGION_START:
                g_value_set_uint (value, waveview->region_start);
                break;
index 75281f69ebb5d80752e000361e0e445c29dc388d..81cf35910ee72ed6b04bdfbb6e85dab2eb03187d 100644 (file)
@@ -101,7 +101,8 @@ struct _GnomeCanvasWaveView
     uint32_t wave_color;
 
     char rectified;
-
+    char logscaled; 
+       
     /* These are updated by the update() routine
        to optimize the render() routine, which may
        be called several times after a single update().
index 6032bfa56125bdb7e62ed5eb7939049c8f422464..cf1994eb06a0162896fd88a33ab48ca3ab565a38 100644 (file)
@@ -96,7 +96,7 @@ CrossfadeEditor::CrossfadeEditor (Session& s, Crossfade& xf, double my, double m
          select_in_button (_("Fade In")),
          select_out_button (_("Fade Out"))
 {
-       set_wmclass ("ardour_automationedit", "Ardour");
+       set_wmclass (X_("ardour_automationedit"), "Ardour");
        set_name ("CrossfadeEditWindow");
        set_position (Gtk::WIN_POS_MOUSE);
 
@@ -698,8 +698,6 @@ CrossfadeEditor::redraw ()
 
        }
 
-       // GTK2FIX some odd math to fix up here
-
        size_t last_spt = (npoints + 3) - 1;
 
        for (size_t i = 0; i < npoints; ++i) {
index 42a1a47227b4c0b6049b9d9c421e9c8bb12367a1..7567b04282ebe25be732734411540e19d91b1f7a 100644 (file)
@@ -52,7 +52,7 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
                              
 
        : TimeAxisViewItem ("xfade" /*xf.name()*/, *parent, tv, spu, basic_color, xf.position(), 
-                           xf.overlap_length(), TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
+                           xf.length(), TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
          crossfade (xf),
          left_view (lview),
          right_view (rview)
@@ -124,7 +124,7 @@ CrossfadeView::crossfade_changed (Change what_changed)
 
        if (what_changed & BoundsChanged) {
                set_position (crossfade.position(), this);
-               set_duration (crossfade.overlap_length(), this);
+               set_duration (crossfade.length(), this);
                need_redraw_curves = true;
        }
 
index bb872049163cc6d4dedb62cbbca51f5c069306bf..3c1c89f9271549e0eb00f9a710e557777530ac92 100644 (file)
@@ -197,8 +197,8 @@ Editor::Editor (AudioEngine& eng)
 
          /* tool bar related */
 
-         edit_cursor_clock (X_("EditCursorClock"), true),
-         zoom_range_clock (X_("ZoomRangeClock"), true, true),
+         edit_cursor_clock (X_("editcursor"), false, X_("EditCursorClock"), true),
+         zoom_range_clock (X_("zoomrange"), false, X_("ZoomRangeClock"), true, true),
          
          toolbar_selection_clock_table (2,3),
          
@@ -211,7 +211,7 @@ Editor::Editor (AudioEngine& eng)
 
          /* nudge */
 
-         nudge_clock (X_("NudgeClock"), true, true)
+         nudge_clock (X_("nudge"), false, X_("NudgeClock"), true, true)
 
 {
        constructed = false;
@@ -284,6 +284,7 @@ Editor::Editor (AudioEngine& eng)
        route_list_menu = 0;
        region_list_menu = 0;
        marker_menu = 0;
+       start_end_marker_menu = 0;
        range_marker_menu = 0;
        marker_menu_item = 0;
        tm_marker_menu = 0;
@@ -309,6 +310,7 @@ Editor::Editor (AudioEngine& eng)
        playhead_cursor = 0;
        button_release_can_deselect = true;
        canvas_idle_queued = false;
+       _dragging_playhead = false;
 
        location_marker_color = color_map[cLocationMarker];
        location_range_color = color_map[cLocationRange];
@@ -444,6 +446,7 @@ Editor::Editor (AudioEngine& eng)
        edit_packer.attach (controls_layout,         1, 2, 1, 2,    FILL,        FILL|EXPAND, 0, 0);
        edit_packer.attach (track_canvas_event_box,  2, 3, 1, 2,    FILL|EXPAND, FILL|EXPAND, 0, 0);
 
+       edit_packer.attach (zoom_box,                1, 2, 2, 3,    FILL,         FILL, 0, 0);
        edit_packer.attach (edit_hscrollbar,         2, 3, 2, 3,    FILL|EXPAND,  FILL, 0, 0);
 
        bottom_hbox.set_border_width (2);
@@ -451,7 +454,7 @@ Editor::Editor (AudioEngine& eng)
 
        route_display_model = ListStore::create(route_display_columns);
        route_list_display.set_model (route_display_model);
-       route_list_display.append_column (_("Visible"), route_display_columns.visible);
+       route_list_display.append_column (_("Show"), route_display_columns.visible);
        route_list_display.append_column (_("Name"), route_display_columns.text);
        route_list_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
        route_list_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
@@ -477,7 +480,7 @@ Editor::Editor (AudioEngine& eng)
        edit_group_display.set_model (group_model);
        edit_group_display.append_column (_("Name"), group_columns.text);
        edit_group_display.append_column (_("Active"), group_columns.is_active);
-       edit_group_display.append_column (_("Visible"), group_columns.is_visible);
+       edit_group_display.append_column (_("Show"), group_columns.is_visible);
        edit_group_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
        edit_group_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
        edit_group_display.get_column (2)->set_data (X_("colnum"), GUINT_TO_POINTER(2));
@@ -597,7 +600,7 @@ Editor::Editor (AudioEngine& eng)
        
        named_selection_display.get_selection()->set_mode (SELECTION_SINGLE);
        named_selection_display.set_size_request (100, -1);
-       named_selection_display.signal_button_press_event().connect (mem_fun(*this, &Editor::named_selection_display_button_press), false);
+       named_selection_display.signal_button_release_event().connect (mem_fun(*this, &Editor::named_selection_display_button_press), false);
        named_selection_display.get_selection()->signal_changed().connect (mem_fun (*this, &Editor::named_selection_display_selection_changed));
 
        /* SNAPSHOTS */
@@ -685,8 +688,29 @@ Editor::Editor (AudioEngine& eng)
 
        fade_context_menu.set_name ("ArdourContextMenu");
 
+       /* icons, titles, WM stuff */
+
+       list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
+       Glib::RefPtr<Gdk::Pixbuf> icon;
+
+       if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
+               window_icons.push_back (icon);
+       }
+       if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
+               window_icons.push_back (icon);
+       }
+       if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
+               window_icons.push_back (icon);
+       }
+       if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
+               window_icons.push_back (icon);
+       }
+       if (!window_icons.empty()) {
+               set_icon_list (window_icons);
+               set_default_icon_list (window_icons);
+       }
        set_title (_("ardour: editor"));
-       set_wmclass (_("ardour_editor"), "Ardour");
+       set_wmclass (X_("ardour_editor"), "Ardour");
 
        add (vpacker);
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
@@ -1516,7 +1540,7 @@ Editor::build_track_region_context_menu (nframes_t frame)
 
        if (atv) {
                boost::shared_ptr<Diskstream> ds;
-               Playlist* pl;
+               boost::shared_ptr<Playlist> pl;
                
                if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
                        Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)frame * ds->speed()));
@@ -1543,10 +1567,10 @@ Editor::build_track_crossfade_context_menu (nframes_t frame)
 
        if (atv) {
                boost::shared_ptr<Diskstream> ds;
-               Playlist* pl;
-               AudioPlaylist* apl;
+               boost::shared_ptr<Playlist> pl;
+               boost::shared_ptr<AudioPlaylist> apl;
 
-               if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()) != 0) && ((apl = dynamic_cast<AudioPlaylist*> (pl)) != 0)) {
+               if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()) != 0) && ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) != 0)) {
 
                        Playlist::RegionList* regions = pl->regions_at (frame);
                        AudioPlaylist::Crossfades xfades;
@@ -1860,6 +1884,7 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items)
        items.push_back (SeparatorElem());
        items.push_back (MenuElem (_("Select all in range"), mem_fun(*this, &Editor::select_all_selectables_using_time_selection)));
        items.push_back (SeparatorElem());
+       items.push_back (MenuElem (_("Add Range Markers"), mem_fun (*this, &Editor::add_location_from_selection)));
        items.push_back (MenuElem (_("Set range to loop range"), mem_fun(*this, &Editor::set_selection_from_loop)));
        items.push_back (MenuElem (_("Set range to punch range"), mem_fun(*this, &Editor::set_selection_from_punch)));
        items.push_back (SeparatorElem());
@@ -2261,18 +2286,11 @@ Editor::get_state ()
 TimeAxisView *
 Editor::trackview_by_y_position (double y)
 {
-       TrackViewList::iterator iter;
-       TimeAxisView *tv;
-
-       for (iter = track_views.begin(); iter != track_views.end(); ++iter) {
-
-               tv = *iter;
+       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
 
-               if (tv->hidden()) {
-                       continue;
-               }
+               TimeAxisView *tv;
 
-               if (tv->y_position <= y && y < ((tv->y_position + tv->height + track_spacing))) {
+               if ((tv = (*iter)->covers_y_position (y)) != 0) {
                        return tv;
                }
        }
@@ -2292,7 +2310,8 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark)
 
        const nframes_t one_second = session->frame_rate();
        const nframes_t one_minute = session->frame_rate() * 60;
-
+       const nframes_t one_smpte_second = (nframes_t)(rint(session->smpte_frames_per_second()) * session->frames_per_smpte_frame());
+       nframes_t one_smpte_minute = (nframes_t)(rint(session->smpte_frames_per_second()) * session->frames_per_smpte_frame() * 60);
        nframes_t presnap = start;
 
        switch (snap_type) {
@@ -2306,8 +2325,9 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark)
                        start = (nframes_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
                }
                break;
+
        case SnapToSMPTEFrame:
-               if (direction) {
+               if (fmod((double)start, (double)session->frames_per_smpte_frame()) > (session->frames_per_smpte_frame() / 2)) {
                        start = (nframes_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());
@@ -2321,10 +2341,10 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark)
                } else {
                        start -= session->smpte_offset ();
                }    
-               if (direction > 0) {
-                       start = (nframes_t) ceil ((double) start / one_second) * one_second;
+               if (start % one_smpte_second > one_smpte_second / 2) {
+                       start = (nframes_t) ceil ((double) start / one_smpte_second) * one_smpte_second;
                } else {
-                       start = (nframes_t) floor ((double) start / one_second) * one_second;
+                       start = (nframes_t) floor ((double) start / one_smpte_second) * one_smpte_second;
                }
                
                if (session->smpte_offset_negative())
@@ -2342,10 +2362,10 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark)
                } else {
                        start -= session->smpte_offset ();
                }
-               if (direction) {
-                       start = (nframes_t) ceil ((double) start / one_minute) * one_minute;
+               if (start % one_smpte_minute > one_smpte_minute / 2) {
+                       start = (nframes_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute;
                } else {
-                       start = (nframes_t) floor ((double) start / one_minute) * one_minute;
+                       start = (nframes_t) floor ((double) start / one_smpte_minute) * one_smpte_minute;
                }
                if (session->smpte_offset_negative())
                {
@@ -2356,7 +2376,7 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark)
                break;
                
        case SnapToSeconds:
-               if (direction) {
+               if (start % one_second > one_second / 2) {
                        start = (nframes_t) ceil ((double) start / one_second) * one_second;
                } else {
                        start = (nframes_t) floor ((double) start / one_second) * one_second;
@@ -2364,7 +2384,7 @@ Editor::snap_to (nframes_t& start, int32_t direction, bool for_mark)
                break;
                
        case SnapToMinutes:
-               if (direction) {
+               if (start % one_minute > one_minute / 2) {
                        start = (nframes_t) ceil ((double) start / one_minute) * one_minute;
                } else {
                        start = (nframes_t) floor ((double) start / one_minute) * one_minute;
@@ -2596,35 +2616,33 @@ Editor::setup_toolbar ()
        zoom_box.set_border_width (2);
 
        zoom_in_button.set_name ("EditorTimeButton");
+       zoom_in_button.set_size_request(-1,16);
        zoom_in_button.add (*(manage (new Image (::get_icon("zoom_in")))));
        zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false));
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom In"));
        
        zoom_out_button.set_name ("EditorTimeButton");
+       zoom_out_button.set_size_request(-1,16);
        zoom_out_button.add (*(manage (new Image (::get_icon("zoom_out")))));
        zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true));
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom Out"));
 
        zoom_out_full_button.set_name ("EditorTimeButton");
+       zoom_out_full_button.set_size_request(-1,16);
        zoom_out_full_button.add (*(manage (new Image (::get_icon("zoom_full")))));
        zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session));
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session"));
        
-       zoom_box.pack_start (zoom_out_button, false, false);
-       zoom_box.pack_start (zoom_in_button, false, false);
-       zoom_box.pack_start (zoom_range_clock, false, false);   
-       zoom_box.pack_start (zoom_out_full_button, false, false);
-       
-       ARDOUR_UI::instance()->tooltips().set_tip (zoom_range_clock, _("Current Zoom Range\n(Width of visible area)"));
-
        zoom_focus_selector.set_name ("ZoomFocusSelector");
-       Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Focus Center", 2+FUDGE, 0);
+       Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Edit Cursor", FUDGE, 0);
        set_popdown_strings (zoom_focus_selector, zoom_focus_strings);
        zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done));
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_focus_selector, _("Zoom focus"));
 
-       zoom_box.pack_start (zoom_focus_selector, false, false);
-
+       zoom_box.pack_start (zoom_focus_selector, true, true);
+       zoom_box.pack_start (zoom_out_button, false, false);
+       zoom_box.pack_start (zoom_in_button, false, false);
+       zoom_box.pack_start (zoom_out_full_button, false, false);
 
        /* Edit Cursor / Snap */
 
@@ -2686,7 +2704,7 @@ Editor::setup_toolbar ()
 
        
        hbox->pack_start (snap_box, false, false);
-       hbox->pack_start (zoom_box, false, false); 
+       // hbox->pack_start (zoom_box, false, false); 
        hbox->pack_start (*nudge_box, false, false);
 
        hbox->show_all ();
@@ -2850,6 +2868,119 @@ Editor::commit_reversible_command ()
        }
 }
 
+struct TrackViewByPositionSorter
+{
+    bool operator() (const TimeAxisView* a, const TimeAxisView *b) {
+           return a->y_position < b->y_position;
+    }
+};
+
+bool
+Editor::extend_selection_to_track (TimeAxisView& view)
+{
+       if (selection->selected (&view)) {
+               /* already selected, do nothing */
+               return false;
+       }
+
+       if (selection->tracks.empty()) {
+
+               if (!selection->selected (&view)) {
+                       selection->set (&view);
+                       return true;
+               } else {
+                       return false;
+               }
+       } 
+
+       /* something is already selected, so figure out which range of things to add */
+       
+       TrackViewList to_be_added;
+       TrackViewList sorted = track_views;
+       TrackViewByPositionSorter cmp;
+       bool passed_clicked = false;
+       bool forwards;
+
+       sorted.sort (cmp);
+
+       if (!selection->selected (&view)) {
+               to_be_added.push_back (&view);
+       }
+
+       /* figure out if we should go forward or backwards */
+
+       for (TrackViewList::iterator i = sorted.begin(); i != sorted.end(); ++i) {
+
+               if ((*i) == &view) {
+                       passed_clicked = true;
+               }
+
+               if (selection->selected (*i)) {
+                       if (passed_clicked) {
+                               forwards = true;
+                       } else {
+                               forwards = false;
+                       }
+                       break;
+               }
+       }
+                       
+       passed_clicked = false;
+
+       if (forwards) {
+
+               for (TrackViewList::iterator i = sorted.begin(); i != sorted.end(); ++i) {
+                                       
+                       if ((*i) == &view) {
+                               passed_clicked = true;
+                               continue;
+                       }
+                                       
+                       if (passed_clicked) {
+                               if ((*i)->hidden()) {
+                                       continue;
+                               }
+                               if (selection->selected (*i)) {
+                                       break;
+                               } else if (!(*i)->hidden()) {
+                                       to_be_added.push_back (*i);
+                               }
+                       }
+               }
+
+       } else {
+
+               for (TrackViewList::reverse_iterator r = sorted.rbegin(); r != sorted.rend(); ++r) {
+                                       
+                       if ((*r) == &view) {
+                               passed_clicked = true;
+                               continue;
+                       }
+                                       
+                       if (passed_clicked) {
+                                               
+                               if ((*r)->hidden()) {
+                                       continue;
+                               }
+                                               
+                               if (selection->selected (*r)) {
+                                       break;
+                               } else if (!(*r)->hidden()) {
+                                       to_be_added.push_back (*r);
+                               }
+                       }
+               }
+       }
+                       
+       if (!to_be_added.empty()) {
+               selection->add (to_be_added);
+               return true;
+       }
+       
+       return false;
+}
+
+
 bool
 Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no_remove)
 {
@@ -2878,13 +3009,14 @@ Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no
        case Selection::Set:
                if (selection->selected (&view) && selection->tracks.size() == 1) {
                        /* no commit necessary */
-               } 
-
-               selection->set (&view);
+               } else {
+                       selection->set (&view);
+                       commit = true;
+               }
                break;
                
        case Selection::Extend:
-               /* not defined yet */
+               commit = extend_selection_to_track (view);
                break;
        }
 
@@ -2975,7 +3107,7 @@ void
 Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored, 
                                                   RegionView* basis, vector<RegionView*>* all_equivs)
 {
-       Playlist* pl;
+       boost::shared_ptr<Playlist> pl;
        vector<boost::shared_ptr<Region> > results;
        RegionView* marv;
        boost::shared_ptr<Diskstream> ds;
@@ -2991,7 +3123,7 @@ Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32
        }
 
        
-       if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) {
+       if ((pl = ds->playlist()) != 0) {
                pl->get_equivalent_regions (basis->region(), results);
        }
        
@@ -3192,7 +3324,7 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
                
                if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
                        
-                       Playlist* pl;
+                       boost::shared_ptr<Playlist> pl;
                        vector<boost::shared_ptr<Region> > results;
                        RegionView* marv;
                        boost::shared_ptr<Diskstream> ds;
@@ -3201,8 +3333,8 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
                                /* bus */
                                continue;
                        }
-
-                       if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) {
+                       
+                       if ((pl = (ds->playlist())) != 0) {
                                pl->get_region_list_equivalent_regions (region, results);
                        }
                        
@@ -3347,7 +3479,7 @@ Editor::duplicate_dialog (bool dup_region)
 
        entry.set_text ("1");
        set_size_request_to_display_given_text (entry, X_("12345678"), 20, 15);
-       entry.select_region (0, entry.get_text_length());
+       entry.select_region (0, -1);
        entry.grab_focus ();
 
 
@@ -3823,17 +3955,19 @@ Editor::end_location_changed (Location* location)
 }
 
 int
-Editor::playlist_deletion_dialog (Playlist* pl)
+Editor::playlist_deletion_dialog (boost::shared_ptr<Playlist> pl)
 {
        ArdourDialog dialog ("playlist deletion dialog");
        Label  label (string_compose (_("Playlist %1 is currently unused.\n"
-                                "If left alone, no audio files used by it will be cleaned.\n"
-                                "If deleted, audio files used by it alone by will cleaned."),
-                              pl->name()));
-
+                                       "If left alone, no audio files used by it will be cleaned.\n"
+                                       "If deleted, audio files used by it alone by will cleaned."),
+                                     pl->name()));
+       
        dialog.set_position (WIN_POS_CENTER);
        dialog.get_vbox()->pack_start (label);
 
+       label.show ();
+
        dialog.add_button (_("Delete playlist"), RESPONSE_ACCEPT);
        dialog.add_button (_("Keep playlist"), RESPONSE_CANCEL);
        dialog.add_button (_("Cancel"), RESPONSE_CANCEL);
index 9a18516588d32f29661dc628df2b3ab76770be20..63f8adaf48d40baf2186801fb66a9c92532392d6 100644 (file)
@@ -217,6 +217,8 @@ class Editor : public PublicEditor
        Selection& get_selection() const { return *selection; }
        Selection& get_cut_buffer() const { return *cut_buffer; }
 
+       bool extend_selection_to_track (TimeAxisView&);
+
        void play_selection ();
        void select_all_in_track (Selection::Operation op);
        void select_all (Selection::Operation op);
@@ -257,7 +259,7 @@ class Editor : public PublicEditor
        void route_name_changed (TimeAxisView *);
        gdouble        frames_per_unit;
        nframes_t leftmost_frame;
-       void clear_playlist (ARDOUR::Playlist&);
+       void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>);
 
        void new_playlists ();
        void copy_playlists ();
@@ -286,6 +288,7 @@ class Editor : public PublicEditor
        void set_follow_playhead (bool yn);
        void toggle_follow_playhead ();
        bool follow_playhead() const { return _follow_playhead; }
+       bool dragging_playhead () const { return _dragging_playhead; }
 
        void toggle_waveform_visibility ();
        void toggle_waveforms_while_recording ();
@@ -293,12 +296,13 @@ class Editor : public PublicEditor
 
        /* SMPTE timecode & video sync */
 
-       void smpte_fps_chosen (ARDOUR::Session::SmpteFormat format);
+       void smpte_fps_chosen (ARDOUR::SmpteFormat format);
        void video_pullup_chosen (ARDOUR::Session::PullupFormat pullup);
+       void subframes_per_frame_chosen (uint32_t);
 
        void update_smpte_mode();
        void update_video_pullup();
-
+       void update_subframes_per_frame ();
        /* xfades */
 
        void toggle_auto_xfade ();
@@ -652,6 +656,7 @@ class Editor : public PublicEditor
 
        double canvas_width;
        double canvas_height;
+       double full_canvas_height;
        nframes_t last_canvas_frame;
 
        bool track_canvas_map_handler (GdkEventAny*);
@@ -921,8 +926,8 @@ class Editor : public PublicEditor
        void bring_in_external_audio (Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t& pos, bool prompt);
        void do_import (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool);
        void do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool);
-       int  import_sndfile (Glib::ustring path, Editing::ImportMode mode, ARDOUR::AudioTrack* track, nframes_t& pos);
-       int  embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode, 
+       int  import_sndfile (vector<Glib::ustring> paths, Editing::ImportMode mode, ARDOUR::AudioTrack* track, nframes_t& pos);
+       int  embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode, 
                            ARDOUR::AudioTrack* track, nframes_t& pos, bool prompt);
        int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, ARDOUR::AudioTrack* track, nframes_t& pos, Editing::ImportMode mode);
 
@@ -953,7 +958,7 @@ class Editor : public PublicEditor
        /* to support this ... */
 
        void import_audio (bool as_tracks);
-       void do_import (vector<string> paths, bool split, bool as_tracks);
+       void do_import (vector<Glib::ustring> paths, bool split, bool as_tracks);
 
        void move_to_start ();
        void move_to_end ();
@@ -977,6 +982,8 @@ class Editor : public PublicEditor
        void clear_markers ();
        void clear_ranges ();
        void clear_locations ();
+       void unhide_markers ();
+       void unhide_ranges ();
        void jump_forward_to_mark ();
        void jump_backward_to_mark ();
        void cursor_align (bool playhead_to_edit);
@@ -1036,10 +1043,12 @@ class Editor : public PublicEditor
        void fade_in_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
        void fade_out_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
        
-       std::set<ARDOUR::Playlist*> motion_frozen_playlists;
+       std::set<boost::shared_ptr<ARDOUR::Playlist> > motion_frozen_playlists;
        void region_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*);
        void region_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
 
+       bool _dragging_playhead;
+
        void cursor_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*);
        void cursor_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
        void marker_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*);
@@ -1198,6 +1207,7 @@ class Editor : public PublicEditor
        void marker_menu_select_all_selectables_using_range ();
        void marker_menu_separate_regions_using_location ();
        void marker_menu_play_from ();
+       void marker_menu_play_range ();
        void marker_menu_set_playhead ();
        void marker_menu_set_from_playhead ();
        void marker_menu_set_from_selection ();
@@ -1210,14 +1220,14 @@ class Editor : public PublicEditor
        void tm_marker_context_menu (GdkEventButton*, ArdourCanvas::Item*);
        void transport_marker_context_menu (GdkEventButton*, ArdourCanvas::Item*);
        void new_transport_marker_context_menu (GdkEventButton*, ArdourCanvas::Item*);
-       void build_range_marker_menu ();
-       void build_marker_menu ();
+       void build_range_marker_menu (bool loop_or_punch);
+       void build_marker_menu (bool start_or_end);
        void build_tm_marker_menu ();
-       void build_transport_marker_menu ();
        void build_new_transport_marker_menu ();
 
        Gtk::Menu* tm_marker_menu;
        Gtk::Menu* marker_menu;
+       Gtk::Menu* start_end_marker_menu;
        Gtk::Menu* range_marker_menu;
        Gtk::Menu* transport_marker_menu;
        Gtk::Menu* new_transport_marker_menu;
@@ -1750,7 +1760,7 @@ class Editor : public PublicEditor
 
        /* handling cleanup */
 
-       int playlist_deletion_dialog (ARDOUR::Playlist*);
+       int playlist_deletion_dialog (boost::shared_ptr<ARDOUR::Playlist>);
 
        vector<sigc::connection> session_connections;
 
index a55aee62327b11442d130837454291cb84ab28bb..f99a828203bfe5b20c5a111902e3969dd5aa915a 100644 (file)
@@ -42,6 +42,7 @@ Editor::register_actions ()
        ActionManager::register_action (editor_actions, X_("Layering"), _("Layering"));
        ActionManager::register_action (editor_actions, X_("Timecode"), _("Timecode fps"));
        ActionManager::register_action (editor_actions, X_("Pullup"), _("Pullup / Pulldown"));
+       ActionManager::register_action (editor_actions, X_("Subframes"), _("Subframes"));
        ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Add Existing Audio"));
 
        /* add named actions for the editor */
@@ -59,7 +60,7 @@ Editor::register_actions ()
 
        act = ActionManager::register_toggle_action (editor_actions, "toggle-xfades-active", _("Active"), mem_fun(*this, &Editor::toggle_xfades_active));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_toggle_action (editor_actions, "toggle-xfades-visible", _("Visible"), mem_fun(*this, &Editor::toggle_xfade_visibility));
+       act = ActionManager::register_toggle_action (editor_actions, "toggle-xfades-visible", _("Show"), mem_fun(*this, &Editor::toggle_xfade_visibility));
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_toggle_action (editor_actions, "toggle-auto-xfades", _("Created Automatically"), mem_fun(*this, &Editor::toggle_auto_xfade));
        ActionManager::session_sensitive_actions.push_back (act);
@@ -379,16 +380,16 @@ Editor::register_actions ()
 
        RadioAction::Group smpte_group;
 
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte23976"), _("23.976"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_23976));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte24"), _("24"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_24));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte24976"), _("24.976"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_24976));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte25"), _("25"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_25));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte2997"), _("29.97"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_2997));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte2997drop"), _("29.97 drop"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_2997drop));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte30"), _("30"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_30));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte30drop"), _("30 drop"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_30drop));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte5994"), _("59.94"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_5994));
-       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte60"), _("60"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), Session::smpte_60));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte23976"), _("23.976"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_23976));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte24"), _("24"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_24));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte24976"), _("24.976"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_24976));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte25"), _("25"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_25));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte2997"), _("29.97"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_2997));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte2997drop"), _("29.97 drop"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_2997drop));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte30"), _("30"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_30));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte30drop"), _("30 drop"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_30drop));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte5994"), _("59.94"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_5994));
+       ActionManager::register_radio_action (editor_actions, smpte_group,  X_("Smpte60"), _("60"), bind (mem_fun (*this, &Editor::smpte_fps_chosen), smpte_60));
 
        RadioAction::Group pullup_group;
 
@@ -402,6 +403,11 @@ Editor::register_actions ()
        ActionManager::register_radio_action (editor_actions, pullup_group,  X_("PullupMinus4"), _("-4.1667%"), bind (mem_fun (*this, &Editor::video_pullup_chosen), Session::pullup_Minus4));
        ActionManager::register_radio_action (editor_actions, pullup_group,  X_("PullupMinus4Minus1"), _("-4.1667% - 0.1%"), bind (mem_fun (*this, &Editor::video_pullup_chosen), Session::pullup_Minus4Minus1));
 
+       RadioAction::Group subframe_group;
+
+       ActionManager::register_radio_action (editor_actions, pullup_group,  X_("Subframes80"), _("80 per frame"), bind (mem_fun (*this, &Editor::subframes_per_frame_chosen), 80));
+       ActionManager::register_radio_action (editor_actions, pullup_group,  X_("Subframes100"), _("100 per frame"), bind (mem_fun (*this, &Editor::subframes_per_frame_chosen), 100));
+
        ActionManager::add_action_group (rl_actions);
        ActionManager::add_action_group (zoom_actions);
        ActionManager::add_action_group (mouse_mode_actions);
@@ -496,33 +502,37 @@ Editor::update_smpte_mode ()
        RefPtr<Action> act;
        const char* action = 0;
 
-       float frames = Config->get_smpte_frames_per_second();
-       bool drop = Config->get_smpte_drop_frames();
-
-       if ((frames < 23.976 * 1.0005) && !drop)
+       switch (Config->get_smpte_format()) {
+       case smpte_23976:
                action = X_("Smpte23976");
-       else if ((frames < 24 * 1.0005) && !drop)
+               break;
+       case smpte_24:
                action = X_("Smpte24");
-       else if ((frames < 24.976 * 1.0005) && !drop)
+               break;
+       case smpte_24976:
                action = X_("Smpte24976");
-       else if ((frames < 25 * 1.0005) && !drop)
+               break;
+       case smpte_25:
                action = X_("Smpte25");
-       else if ((frames < 29.97 * 1.0005) && !drop)
+               break;
+       case smpte_2997:
                action = X_("Smpte2997");
-       else if ((frames < 29.97 * 1.0005) && drop)
+               break;
+       case smpte_2997drop:
                action = X_("Smpte2997drop");
-       else if ((frames < 30 * 1.0005) && !drop)
+               break;
+       case smpte_30:
                action = X_("Smpte30");
-       else if ((frames < 30 * 1.0005) && drop)
+               break;
+       case smpte_30drop:
                action = X_("Smpte30drop");
-       else if ((frames < 59.94 * 1.0005) && !drop)
+               break;
+       case smpte_5994:
                action = X_("Smpte5994");
-       else if ((frames < 60 * 1.0005) && !drop)
+               break;
+       case smpte_60:
                action = X_("Smpte60");
-       else {
-               fatal << string_compose (_("programming error: Unexpected SMPTE value (%1, drop = %2) in update_smpte_mode.  Menu is probably wrong."),
-                                        frames, drop) << endmsg;
-               /*NOTREACHED*/
+               break;
        }
 
        act = ActionManager::get_action (X_("Editor"), action);
@@ -831,7 +841,7 @@ Editor::zoom_focus_chosen (ZoomFocus focus)
 }
 
 void
-Editor::smpte_fps_chosen (Session::SmpteFormat format)
+Editor::smpte_fps_chosen (SmpteFormat format)
 {
        /* this is driven by a toggle on a radio group, and so is invoked twice,
           once for the item that became inactive and once for the one that became
@@ -840,62 +850,39 @@ Editor::smpte_fps_chosen (Session::SmpteFormat format)
 
        if (session) {
 
-               float fps = 10;
-               bool drop = false;
-
                RefPtr<Action> act;
 
                switch (format) {
-                       case Session::smpte_23976: {
-                               fps=23.976;
-                               drop = false;
+                       case smpte_23976: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte23976"));
-                       } break;
-                       case Session::smpte_24: {
-                               fps=24;
-                               drop = false;
+                        break;
+                       case smpte_24: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte24"));
-                       } break;
-                       case Session::smpte_24976: {
-                               fps=24.976;
-                               drop = false;
+                        break;
+                       case smpte_24976: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte24976"));
-                       } break;
-                       case Session::smpte_25: {
-                               fps=25;
-                               drop = false;
+                        break;
+                       case smpte_25: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte25"));
-                       } break;
-                       case Session::smpte_2997: {
-                               fps=29.97;
-                               drop = false;
+                        break;
+                       case smpte_2997: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte2997"));
-                       } break;
-                       case Session::smpte_2997drop: {
-                               fps=29.97;
-                               drop = true;
+                        break;
+                       case smpte_2997drop: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte2997drop"));
-                       } break;
-                       case Session::smpte_30: {
-                               fps=30;
-                               drop = false;
+                        break;
+                       case smpte_30: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte30"));
-                       } break;
-                       case Session::smpte_30drop: {
-                               fps=30;
-                               drop = true;
+                        break;
+                       case smpte_30drop: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte30drop"));
-                       } break;
-                       case Session::smpte_5994: {
-                               fps=59.94;
-                               drop = false;
+                        break;
+                       case smpte_5994: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte5994"));
-                       } break;
-                       case Session::smpte_60: {
-                               fps=60;
-                               drop = false;
+                        break;
+                       case smpte_60: 
                                act = ActionManager::get_action (X_("Editor"), X_("Smpte60"));
-                       } break;
+                        break;
                        default:
                                cerr << "Editor received unexpected smpte type" << endl;
                }
@@ -903,7 +890,7 @@ Editor::smpte_fps_chosen (Session::SmpteFormat format)
                if (act) {
                        RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
                        if (ract && ract->get_active()) {
-                               session->set_smpte_type (fps, drop);
+                               session->set_smpte_format (format);
                        }
                }
        }
@@ -978,6 +965,70 @@ Editor::video_pullup_chosen (Session::PullupFormat pullup)
        }
 }
 
+void
+Editor::update_subframes_per_frame ()
+{
+       ENSURE_GUI_THREAD (mem_fun(*this, &Editor::update_subframes_per_frame));
+
+       RefPtr<Action> act;
+       const char* action = 0;
+
+       uint32_t sfpf = Config->get_subframes_per_frame();
+
+       if (sfpf == 80) {
+               action = X_("Subframes80");
+       } else if (sfpf == 100) {
+               action = X_("Subframes100");
+       } else {
+               warning << string_compose (_("Configuraton is using unhandled subframes per frame value: %1"), sfpf) << endmsg;
+               /*NOTREACHED*/
+               return;
+       }
+
+       act = ActionManager::get_action (X_("Editor"), action);
+
+       if (act) {
+               RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+               if (ract && !ract->get_active()) {
+                       ract->set_active (true);
+               }
+       }
+}
+
+void
+Editor::subframes_per_frame_chosen (uint32_t sfpf)
+{
+       /* this is driven by a toggle on a radio group, and so is invoked twice,
+          once for the item that became inactive and once for the one that became
+          active.
+       */
+
+       const char* action = 0;
+
+       RefPtr<Action> act;
+       
+       if (sfpf == 80) {
+               action = X_("Subframes80");
+       } else if (sfpf == 100) {       
+               action = X_("Subframes100");
+       } else {
+               fatal << string_compose (_("programming error: %1 %2"), "Session received unexpected subframes per frame value: ", sfpf) << endmsg;
+               /*NOTREACHED*/
+       }
+       
+       act = ActionManager::get_action (X_("Editor"), action);
+       
+       if (act) {
+               RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+               if (ract && ract->get_active()) {
+                       Config->set_subframes_per_frame ((uint32_t) rint (sfpf));
+               }
+               
+       } else  {
+               error << string_compose (_("programming error: %1"), "Editor::subframes_per_frame_chosen could not find action to match value.") << endmsg;
+       }
+}
+
 void
 Editor::toggle_auto_xfade ()
 {
@@ -1011,8 +1062,8 @@ Editor::parameter_changed (const char* parameter_name)
                update_punch_range_view (true);
        } else if (PARAM_IS ("layer-model")) {
                update_layering_model ();
-       } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
-               update_smpte_mode ();
+       } else if (PARAM_IS ("smpte-format")) {
+               update_smpte_mode ();
                update_just_smpte ();
        } else if (PARAM_IS ("video-pullup")) {
                update_video_pullup ();
@@ -1026,6 +1077,9 @@ Editor::parameter_changed (const char* parameter_name)
                update_crossfade_model ();
        } else if (PARAM_IS ("edit-mode")) {
                edit_mode_selector.set_active_text (edit_mode_to_string (Config->get_edit_mode()));
+       } else if (PARAM_IS ("subframes-per-frame")) {
+               update_subframes_per_frame ();
+               update_just_smpte ();
        }
 
 #undef PARAM_IS
index 426ff57a2a42d15d6977631ff428500c4e4d00aa..48edb52756d8d8626a241bbf79c79b1221ae3c74 100644 (file)
@@ -49,6 +49,7 @@ using namespace PBD;
 using namespace sigc;
 using namespace Gtk;
 using namespace Editing;
+using Glib::ustring;
 
 /* Functions supporting the incorporation of external (non-captured) audio material into ardour */
 
@@ -95,7 +96,7 @@ Editor::bring_in_external_audio (ImportMode mode, AudioTrack* track, nframes_t&
 }
 
 void
-Editor::do_import (vector<Glib::ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt)
+Editor::do_import (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt)
 {
        /* SFDB sets "multichan" to true to indicate "split channels"
           so reverse the setting to match the way libardour
@@ -107,49 +108,119 @@ Editor::do_import (vector<Glib::ustring> paths, bool split, ImportMode mode, Aud
        if (interthread_progress_window == 0) {
                build_interthread_progress_window ();
        }
-       
-       /* for each path that was selected, import it and then potentially create a new track
-          containing the new region as the sole contents.
-       */
 
-       for (vector<Glib::ustring>::iterator i = paths.begin(); i != paths.end(); ++i ) {
-               import_sndfile (*i, mode, track, pos);
+       vector<ustring> to_import;
+
+       for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
+
+               to_import.clear ();
+               to_import.push_back (*a);
+
+               import_sndfile (to_import, mode, track, pos);
        }
 
        interthread_progress_window->hide_all ();
 }
 
 void
-Editor::do_embed (vector<Glib::ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt)
+Editor::do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt)
 {
        bool multiple_files = paths.size() > 1;
        bool check_sample_rate = true;
-       vector<Glib::ustring>::iterator i;
+       vector<ustring>::iterator a;
+
+       for (a = paths.begin(); a != paths.end(); ) {
        
-       for (i = paths.begin(); i != paths.end(); ++i) {
-               int ret = embed_sndfile (*i, split, multiple_files, check_sample_rate, mode, track, pos, prompt);
+               Glib::ustring path = *a;
+               Glib::ustring pair_base;
+               vector<ustring> to_embed;
+
+               to_embed.push_back (path);
+               a = paths.erase (a);
+
+               if (path_is_paired (path, pair_base)) {
+
+                       ustring::size_type len = pair_base.length();
 
-               if (ret < -1) {
-                       break;
+                       for (vector<Glib::ustring>::iterator b = paths.begin(); b != paths.end(); ) {
+
+                               if (((*b).substr (0, len) == pair_base) && ((*b).length() == path.length())) {
+
+                                       to_embed.push_back (*b);
+                                               
+                                       /* don't process this one again */
+
+                                       b = paths.erase (b);
+                                       break;
+
+                               } else {
+                                       ++b;
+                               }
+                       }
                }
-       }
 
-       if (i == paths.end()) {
+               if (to_embed.size() > 1) {
+
+                       vector<string> choices;
+
+                       choices.push_back (string_compose (_("Import as a %1 region"),
+                                                          to_embed.size() > 2 ? _("multichannel") : _("stereo")));
+                       choices.push_back (_("Import as multiple regions"));
+                       
+                       Gtkmm2ext::Choice chooser (string_compose (_("Paired files detected (%1, %2 ...).\nDo you want to:"),
+                                                                  to_embed[0],
+                                                                  to_embed[1]),
+                                                  choices);
+                       
+                       if (chooser.run () == 0) {
+                               
+                               /* keep them paired */
+
+                               if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) {
+                                       break;
+                               }
+
+                       } else {
+
+                               /* one thing per file */
+
+                               vector<ustring> foo;
+
+                               for (vector<ustring>::iterator x = to_embed.begin(); x != to_embed.end(); ++x) {
+
+                                       foo.clear ();
+                                       foo.push_back (*x);
+
+                                       if (embed_sndfile (foo, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) {
+                                               break;
+                                       }
+                               }
+                       }
+
+               } else {
+                       
+                       if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) {
+                               break;
+                       }
+               }
+       }
+       
+       if (a == paths.end()) {
                session->save_state ("");
        }
 }
 
 int
-Editor::import_sndfile (Glib::ustring path, ImportMode mode, AudioTrack* track, nframes_t& pos)
+Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* track, nframes_t& pos)
 {
-       interthread_progress_window->set_title (string_compose (_("ardour: importing %1"), path));
+       interthread_progress_window->set_title (string_compose (_("ardour: importing %1"), paths.front()));
        interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
        interthread_progress_window->show_all ();
        interthread_progress_bar.set_fraction (0.0f);
        interthread_cancel_label.set_text (_("Cancel Import"));
        current_interthread_info = &import_status;
 
-       import_status.pathname = path;
+       import_status.paths = paths;
        import_status.done = false;
        import_status.cancel = false;
        import_status.freeze = false;
@@ -161,8 +232,8 @@ Editor::import_sndfile (Glib::ustring path, ImportMode mode, AudioTrack* track,
        track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
        ARDOUR_UI::instance()->flush_pending ();
 
-       /* start import thread for this path. this will ultimately call Session::import_audiofile()
-          and if successful will add the file as a region to the session region list.
+       /* start import thread for this spec. this will ultimately call Session::import_audiofile()
+          and if successful will add the file(s) as a region to the session region list.
        */
        
        pthread_create_and_store ("import", &import_status.thread, 0, _import_thread, this);
@@ -187,7 +258,7 @@ Editor::import_sndfile (Glib::ustring path, ImportMode mode, AudioTrack* track,
 }
 
 int
-Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode, 
+Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode, 
                       AudioTrack* track, nframes_t& pos, bool prompt)
 {
        boost::shared_ptr<AudioFileSource> source;
@@ -196,96 +267,104 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
        string idspec;
        string linked_path;
        SoundFileInfo finfo;
-       string region_name;
-       uint32_t input_chan;
-       uint32_t output_chan;
+       ustring region_name;
+       uint32_t input_chan = 0;
+       uint32_t output_chan = 0;
 
        track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
        ARDOUR_UI::instance()->flush_pending ();
 
-       /* lets see if we can link it into the session */
-       
-       linked_path = session->sound_dir();
-       linked_path += Glib::path_get_basename (path);
-
-       if (link (path.c_str(), linked_path.c_str()) == 0) {
+       for (vector<Glib::ustring>::iterator p = paths.begin(); p != paths.end(); ++p) {
 
-               /* there are many reasons why link(2) might have failed.
-                  but if it succeeds, we now have a link in the
-                  session sound dir that will protect against
-                  unlinking of the original path. nice.
-               */
-
-               path = linked_path;
-       }
+               ustring path = *p;
 
-       /* note that we temporarily truncated _id at the colon */
-
-       string error_msg;
-
-       if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
-               error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), selection, error_msg ) << endmsg;
-               return 0;
-       }
-       
-       if (check_sample_rate  && (finfo.samplerate != (int) session->frame_rate())) {
-               vector<string> choices;
+               /* lets see if we can link it into the session */
                
-               if (multiple_files) {
-                       choices.push_back (_("Cancel entire import"));
-                       choices.push_back (_("Don't embed it"));
-                       choices.push_back (_("Embed all without questions"));
-               } else {
-                       choices.push_back (_("Cancel"));
+               linked_path = session->sound_dir();
+               linked_path += '/';
+               linked_path += Glib::path_get_basename (path);
+               
+               if (link (path.c_str(), linked_path.c_str()) == 0) {
+                       
+                       /* there are many reasons why link(2) might have failed.
+                          but if it succeeds, we now have a link in the
+                          session sound dir that will protect against
+                          unlinking of the original path. nice.
+                       */
+                       
+                       path = linked_path;
                }
-
-               choices.push_back (_("Embed it anyway"));
                
-               Gtkmm2ext::Choice rate_choice (
-                       string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
-                       choices, false);
+               /* note that we temporarily truncated _id at the colon */
                
-               switch (rate_choice.run()) {
-               case 0: /* stop a multi-file import */
-               case 1: /* don't import this one */
-                       return -1;
-               case 2: /* do it, and the rest without asking */
-                       check_sample_rate = false;
-                       break;
-               case 3: /* do it */
-                       break;
-               default:
-                       return -2;
-               }
-       }
-       
-       track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
-       ARDOUR_UI::instance()->flush_pending ();
-       
-       /* make the proper number of channels in the region */
-
-       for (int n = 0; n < finfo.channels; ++n)
-       {
-               idspec = path;
-               idspec += string_compose(":%1", n);
+               string error_msg;
                
-               try {
-                       source = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable 
-                                                                              (DataType::AUDIO, *session, idspec, 
-                                                                               (mode == ImportAsTapeTrack ? 
-                                                                                AudioFileSource::Destructive : 
-                                                                                AudioFileSource::Flag (0))));
-                       sources.push_back(source);
-               } 
+               if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
+                       error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), selection, error_msg ) << endmsg;
+                       return 0;
+               }
                
-               catch (failed_constructor& err) {
-                       error << string_compose(_("could not open %1"), path) << endmsg;
-                       goto out;
+               if (check_sample_rate  && (finfo.samplerate != (int) session->frame_rate())) {
+                       vector<string> choices;
+                       
+                       if (multiple_files) {
+                               choices.push_back (_("Cancel entire import"));
+                               choices.push_back (_("Don't embed it"));
+                               choices.push_back (_("Embed all without questions"));
+                       } else {
+                               choices.push_back (_("Cancel"));
+                       }
+                       
+                       choices.push_back (_("Embed it anyway"));
+                       
+                       Gtkmm2ext::Choice rate_choice (
+                               string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
+                               choices, false);
+                       
+                       switch (rate_choice.run()) {
+                       case 0: /* stop a multi-file import */
+                       case 1: /* don't import this one */
+                               return -1;
+                       case 2: /* do it, and the rest without asking */
+                               check_sample_rate = false;
+                               break;
+                       case 3: /* do it */
+                               break;
+                       default:
+                               return -2;
+                       }
                }
                
+               track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
                ARDOUR_UI::instance()->flush_pending ();
-       }
        
+               /* make the proper number of channels in the region */
+               
+               input_chan += finfo.channels;
+       
+               for (int n = 0; n < finfo.channels; ++n)
+               {
+                       idspec = path;
+                       idspec += string_compose(":%1", n);
+                       
+                       try {
+                               source = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable 
+                                                                                      (DataType::AUDIO, *session, idspec, 
+                                                                                       (mode == ImportAsTapeTrack ? 
+                                                                                        AudioFileSource::Destructive : 
+                                                                                        AudioFileSource::Flag (0))));
+                               sources.push_back(source);
+                       } 
+                       
+                       catch (failed_constructor& err) {
+                               error << string_compose(_("could not open %1"), path) << endmsg;
+                               goto out;
+                       }
+                       
+                       ARDOUR_UI::instance()->flush_pending ();
+               }
+       }
+
        if (sources.empty()) {
                goto out;
        }
@@ -294,20 +373,17 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
                pos = sources[0]->natural_position();
        } 
 
-       region_name = PBD::basename_nosuffix (path);
-       region_name += "-0";
+       region_name = region_name_from_path (paths.front(), (sources.size() > 1));
        
        region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
                                                                                  Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
        
-       input_chan = finfo.channels;
-       
        if (Config->get_output_auto_connect() & AutoConnectMaster) {
                output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
        } else {
                output_chan = input_chan;
        }
-       
+
        finish_bringing_in_audio (region, input_chan, output_chan, track, pos, mode);
        
   out:
@@ -325,7 +401,7 @@ Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_
                
        case ImportToTrack:
                if (track) {
-                       Playlist* playlist  = track->diskstream()->playlist();
+                       boost::shared_ptr<Playlist> playlist = track->diskstream()->playlist();
                        
                        boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
                        begin_reversible_command (_("insert sndfile"));
index 07fe56573d149a59d9ed3637bc4d659d06e0d05b..973598561ac183ba288ea099cf488a028459b9cc 100644 (file)
@@ -294,7 +294,6 @@ Editor::track_canvas_allocate (Gtk::Allocation alloc)
 bool
 Editor::track_canvas_idle ()
 {
-
        if (canvas_idle_queued) {
                canvas_idle_queued = false;
        }
@@ -302,6 +301,27 @@ Editor::track_canvas_idle ()
        canvas_width = canvas_allocation.get_width();
        canvas_height = canvas_allocation.get_height();
 
+       full_canvas_height = canvas_height;
+
+       if (session) {
+               TrackViewList::iterator i;
+               double height = 0;
+
+               for (i = track_views.begin(); i != track_views.end(); ++i) {
+                       if ((*i)->control_parent) {
+                               height += (*i)->effective_height;
+                               height += track_spacing;
+                       }
+               }
+               
+               if (height) {
+                       height -= track_spacing;
+               }
+
+               full_canvas_height = height;
+       }
+
+
        zoom_range_clock.set ((nframes_t) floor ((canvas_width * frames_per_unit)));
        edit_cursor->set_position (edit_cursor->current_frame);
        playhead_cursor->set_position (playhead_cursor->current_frame);
@@ -313,7 +333,7 @@ Editor::track_canvas_idle ()
        if (playhead_cursor) playhead_cursor->set_length (canvas_height);
 
        if (marker_drag_line) {
-               marker_drag_line_points.back().set_x(canvas_height);
+               marker_drag_line_points.back().set_y(canvas_height);
                marker_drag_line->property_points() = marker_drag_line_points;
        }
 
@@ -434,8 +454,6 @@ Editor::track_canvas_drag_data_received (const RefPtr<Gdk::DragContext>& context
                                         const SelectionData& data,
                                         guint info, guint time)
 {
-       cerr << "dropping, target = " << data.get_target() << endl;
-
        if (data.get_target() == "regions") {
                drop_regions (context, x, y, data, info, time);
        } else {
index 249a65ae0180a3aeba040b78ba85ef886156cc42..4e0d6d5fe3ecde3f6f9a0ac3599e6503c4c8a38c 100644 (file)
@@ -76,7 +76,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
                        if (!current_stepping_trackview) {
                                step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
-                               if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
+                               if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) {
                                        return false;
                                }
                        }
@@ -107,7 +107,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
                        if (!current_stepping_trackview) {
                                step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
-                               if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
+                               if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) {
                                        return false;
                                }
                        }
@@ -513,8 +513,8 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item,
 
                if (atv->is_audio_track()) {
 
-                       AudioPlaylist* pl;
-                       if ((pl = dynamic_cast<AudioPlaylist*> (atv->get_diskstream()->playlist())) != 0) {
+                       boost::shared_ptr<AudioPlaylist> pl;
+                       if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->get_diskstream()->playlist())) != 0) {
 
                                Playlist::RegionList* rl = pl->regions_at (event_frame (event));
 
index 8df76fef258ca5c18c592a01efa1603e4d50a163..2ee1773646b78327812f95a0f0c4c900fa6a57a9 100644 (file)
@@ -119,7 +119,7 @@ Editor::edit_group_list_button_press_event (GdkEventButton* ev)
                if (edit_group_list_menu == 0) {
                        build_edit_group_list_menu ();
                }
-               edit_group_list_menu->popup (1, 0);
+               edit_group_list_menu->popup (1, ev->time);
                return true;
        }
 
index 4526862f7952cf2db86eb63fb67a9cd039f0b819..43977f157770f6b3f1ac3c08226c7b15bd2fb2fd 100644 (file)
@@ -290,7 +290,7 @@ Editor::write_audio_selection (TimeSelection& ts)
 
                if (atv->is_audio_track()) {
 
-                       AudioPlaylist* playlist = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
+                       boost::shared_ptr<AudioPlaylist> playlist = boost::dynamic_pointer_cast<AudioPlaylist>(atv->get_diskstream()->playlist());
                        
                        if (playlist && write_audio_range (*playlist, atv->get_diskstream()->n_channels(), ts) == 0) {
                                ret = -1;
index adb64125fc4533112d41948e43675d7d4fb851b2..a2606175dfb7b0e76a196e0ee6773830890fbc2b 100644 (file)
@@ -100,16 +100,14 @@ Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
        nframes_t offset = 0;
 
        nframes_t x_pos = 0 ;
-       if(item->get_position() < offset)
-       {
+
+       if (item->get_position() < offset) {
                x_pos = 0 ;
-       }
-       else
-       {
-               x_pos = item->get_position() - offset + (item->get_duration() / 2) ;
+       } else {
+               x_pos = item->get_position() - offset + (item->get_duration() / 2);
        }
        
-       reposition_x_origin(x_pos) ;
+       reposition_x_origin (x_pos);
 }
 
 void
index 6da479bafef17cfba34a9766ed3404bba3d2167f..238a45c4d13b05d253e37c04186d11f2ccd82090 100644 (file)
@@ -288,8 +288,10 @@ Editor::LocationMarkers::set_color_rgba (uint32_t rgba)
 void
 Editor::mouse_add_new_marker (nframes_t where)
 {
+       string markername;
        if (session) {
-               Location *location = new Location (where, where, "mark", Location::IsMark);
+               session->locations()->next_available_name(markername,"mark");
+               Location *location = new Location (where, where, markername, Location::IsMark);
                session->begin_reversible_command (_("add marker"));
                 XMLNode &before = session->locations()->get_state();
                session->locations()->add (location, true);
@@ -313,17 +315,7 @@ Editor::remove_marker (ArdourCanvas::Item& item, GdkEvent* event)
        Location* loc = find_location_from_marker (marker, is_start);
 
        if (session && loc) {
-               if (loc->is_end()) {
-                       /* you can't hide or delete this marker */
-                       return;
-               }
-               if (loc->is_auto_loop() || loc->is_auto_punch()) {
-                       // just hide them
-                       loc->set_hidden (true, this);
-               }
-               else {
-                       Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::really_remove_marker), loc));
-               }
+               Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::really_remove_marker), loc));
        }
 }
 
@@ -388,16 +380,24 @@ Editor::marker_context_menu (GdkEventButton* ev, ArdourCanvas::Item* item)
        Location * loc = find_location_from_marker (marker, is_start);
        if (loc == transport_loop_location() || loc == transport_punch_location()) {
                if (transport_marker_menu == 0) {
-                       build_transport_marker_menu ();
+                       build_range_marker_menu (true);
                }
                marker_menu_item = item;
                transport_marker_menu->popup (1, ev->time);
        } else {
 
                if (loc->is_mark()) {
-                      if (marker_menu == 0) {
-                             build_marker_menu ();
-                      }
+                       bool start_or_end = loc->is_start() || loc->is_end();
+                       Menu *markerMenu;
+                       if (start_or_end) {
+                               if (start_end_marker_menu == 0)
+                                       build_marker_menu (true);
+                               markerMenu = start_end_marker_menu;
+                       } else {
+                               if (marker_menu == 0)
+                                       build_marker_menu (false);
+                               markerMenu = marker_menu;
+                       }
 
 
                // GTK2FIX use action group sensitivity
@@ -415,12 +415,12 @@ Editor::marker_context_menu (GdkEventButton* ev, ArdourCanvas::Item* item)
                }
 #endif         
                marker_menu_item = item;
-               marker_menu->popup (1, ev->time);
+               markerMenu->popup (1, ev->time);
                }
 
                if (loc->is_range_marker()) {
                       if (range_marker_menu == 0){
-                             build_range_marker_menu ();
+                             build_range_marker_menu (false);
                       }
                       marker_menu_item = item;
                       range_marker_menu->popup (1, ev->time);
@@ -443,20 +443,25 @@ void
 Editor::transport_marker_context_menu (GdkEventButton* ev, ArdourCanvas::Item* item)
 {
        if (transport_marker_menu == 0) {
-               build_transport_marker_menu ();
+               build_range_marker_menu (true);
        }
 
        transport_marker_menu->popup (1, ev->time);
 }
 
 void
-Editor::build_marker_menu ()
+Editor::build_marker_menu (bool start_or_end)
 {
        using namespace Menu_Helpers;
 
-       marker_menu = new Menu;
-       MenuList& items = marker_menu->items();
-       marker_menu->set_name ("ArdourContextMenu");
+       Menu *markerMenu = new Menu;
+       if (start_or_end) {
+               start_end_marker_menu = markerMenu;
+       } else {
+               marker_menu = markerMenu;
+       }
+       MenuList& items = markerMenu->items();
+       markerMenu->set_name ("ArdourContextMenu");
 
        items.push_back (MenuElem (_("Locate to Mark"), mem_fun(*this, &Editor::marker_menu_set_playhead)));
        items.push_back (MenuElem (_("Play from Mark"), mem_fun(*this, &Editor::marker_menu_play_from)));
@@ -464,32 +469,43 @@ Editor::build_marker_menu ()
 
        items.push_back (SeparatorElem());
 
-       items.push_back (MenuElem (_("Rename Mark"), mem_fun(*this, &Editor::marker_menu_rename)));
        items.push_back (MenuElem (_("Hide Mark"), mem_fun(*this, &Editor::marker_menu_hide)));
+       if (start_or_end) return;
+       items.push_back (MenuElem (_("Rename Mark"), mem_fun(*this, &Editor::marker_menu_rename)));
        items.push_back (MenuElem (_("Remove Mark"), mem_fun(*this, &Editor::marker_menu_remove)));
 
 }
 
 void
-Editor::build_range_marker_menu ()
+Editor::build_range_marker_menu (bool loop_or_punch)
 {
        using namespace Menu_Helpers;
 
-       range_marker_menu = new Menu;
-       MenuList& items = range_marker_menu->items();
-       range_marker_menu->set_name ("ArdourContextMenu");
+       Menu *markerMenu = new Menu;
+       if (loop_or_punch) {
+               transport_marker_menu = markerMenu;
+       } else {
+               range_marker_menu = markerMenu;
+       }
+       MenuList& items = markerMenu->items();
+       markerMenu->set_name ("ArdourContextMenu");
 
        items.push_back (MenuElem (_("Locate to Range Mark"), mem_fun(*this, &Editor::marker_menu_set_playhead)));
        items.push_back (MenuElem (_("Play from Range Mark"), mem_fun(*this, &Editor::marker_menu_play_from)));
-       items.push_back (MenuElem (_("Loop Range"), mem_fun(*this, &Editor::marker_menu_loop_range)));
+       if (! loop_or_punch) {
+               items.push_back (MenuElem (_("Play Range"), mem_fun(*this, &Editor::marker_menu_play_range)));
+               items.push_back (MenuElem (_("Loop Range"), mem_fun(*this, &Editor::marker_menu_loop_range)));
+       }
        items.push_back (MenuElem (_("Set Range Mark from Playhead"), mem_fun(*this, &Editor::marker_menu_set_from_playhead)));
        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 (_("Rename Range"), mem_fun(*this, &Editor::marker_menu_rename)));
        items.push_back (MenuElem (_("Hide Range"), mem_fun(*this, &Editor::marker_menu_hide)));
-       items.push_back (MenuElem (_("Remove Range"), mem_fun(*this, &Editor::marker_menu_remove)));
+       if (! loop_or_punch) {
+               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)));
+       }
 
        items.push_back (SeparatorElem());
 
@@ -526,26 +542,6 @@ Editor::build_new_transport_marker_menu ()
        new_transport_marker_menu->signal_unmap_event().connect ( mem_fun(*this, &Editor::new_transport_marker_menu_popdown)); 
 }
 
-void
-Editor::build_transport_marker_menu ()
-{
-       using namespace Menu_Helpers;
-
-       transport_marker_menu = new Menu;
-       MenuList& items = transport_marker_menu->items();
-       transport_marker_menu->set_name ("ArdourContextMenu");
-
-       items.push_back (MenuElem (_("Locate to Range Mark"), mem_fun(*this, &Editor::marker_menu_set_playhead)));
-       items.push_back (MenuElem (_("Play from Range Mark"), mem_fun(*this, &Editor::marker_menu_play_from)));
-       items.push_back (MenuElem (_("Set Range Mark from Playhead"), mem_fun(*this, &Editor::marker_menu_set_from_playhead)));
-       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 (_("Hide Range"), mem_fun(*this, &Editor::marker_menu_hide)));
-       items.push_back (SeparatorElem());
-       items.push_back (MenuElem (_("Separate Regions in Range"), mem_fun(*this, &Editor::marker_menu_separate_regions_using_location)));
-       items.push_back (MenuElem (_("Select All in Range"), mem_fun(*this, &Editor::marker_menu_select_all_selectables_using_range)));
-}
-
 void
 Editor::marker_menu_hide ()
 {
@@ -726,6 +722,32 @@ Editor::marker_menu_set_from_selection ()
        }
 }
 
+
+void
+Editor::marker_menu_play_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_mark()) {
+                       session->request_locate (l->start(), true);
+               }
+               else {
+                       session->request_bounded_roll (l->start(), l->end());
+                       
+               }
+       }
+}
+
 void
 Editor::marker_menu_loop_range ()
 {
index 8b100afae59988a6a6b3b2bf6ab29d84fadb4fd3..8139e91ca701578b79d23ac55d2635fb3babf422 100644 (file)
@@ -164,12 +164,16 @@ Editor::update_current_screen ()
 
                frame = session->audible_frame();
 
+               if (_dragging_playhead) {
+                       goto almost_done;
+               }
+
                /* only update if the playhead is on screen or we are following it */
 
                if (_follow_playhead) {
 
-
                        playhead_cursor->canvas_item.show();
+
                        if (frame != last_update_frame) {
                                const jack_nframes_t page_width = current_page_frames();
 
@@ -209,6 +213,7 @@ Editor::update_current_screen ()
                        }
                }
 
+         almost_done:
                last_update_frame = frame;
 
                if (current_mixer_strip) {
index 76357070a747df08f66b63404f6329f0944322ab..fc76c6a43c18c158c0858970ce50e95c525705ee 100644 (file)
@@ -317,6 +317,7 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
 
        switch (item_type) {
        case RegionItem:
+               /* XXX make tying track/region selection optional */
                c1 = set_selected_track_from_click (op, true);
                c2 = set_selected_regionview_from_click (press, op, true);
                commit = (c1 || c2);
@@ -324,6 +325,7 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
                
        case RegionViewNameHighlight:
        case RegionViewName:
+               /* XXX make tying track/region selection optional */
                c1 = set_selected_track_from_click (op, true);
                c2 = set_selected_regionview_from_click (press, op, true);
                commit = (c1 || c2);
@@ -332,6 +334,7 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
        case GainAutomationControlPointItem:
        case PanAutomationControlPointItem:
        case RedirectAutomationControlPointItem:
+               /* XXX make tying track/region selection optional */
                c1 = set_selected_track_from_click (op, true);
                c2 = set_selected_control_point_from_click (op, false);
                commit = (c1 || c2);
@@ -1943,8 +1946,10 @@ Editor::start_cursor_grab (ArdourCanvas::Item* item, GdkEvent* event)
 
        Cursor* cursor = (Cursor *) drag_info.data;
 
-       if (session && cursor == playhead_cursor) {
-               if (drag_info.was_rolling) {
+       if (cursor == playhead_cursor) {
+               _dragging_playhead = true;
+               
+               if (session && drag_info.was_rolling) {
                        session->request_stop ();
                } 
        }
@@ -1979,6 +1984,8 @@ Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        
        if (cursor == edit_cursor) {
                edit_cursor_clock.set (cursor->current_frame);
+       } else {
+               UpdateAllTransportClocks (cursor->current_frame);
        }
 
        show_verbose_time_cursor (cursor->current_frame, 10);
@@ -1993,6 +2000,8 @@ Editor::cursor_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
        if (drag_info.first_move) return;
        
        cursor_drag_motion_callback (item, event);
+
+       _dragging_playhead = false;
        
        if (item == &playhead_cursor->canvas_item) {
                if (session) {
@@ -2490,7 +2499,7 @@ Editor::start_control_point_grab (ArdourCanvas::Item* item, GdkEvent* event)
 
        start_grab (event, fader_cursor);
 
-       control_point->line.start_drag (control_point, 0);
+       control_point->line.start_drag (control_point, drag_info.grab_frame, 0);
 
        float fraction = 1.0 - (control_point->get_y() / control_point->line.height());
        set_verbose_canvas_cursor (control_point->line.get_verbose_cursor_string (fraction), 
@@ -2623,7 +2632,7 @@ Editor::start_line_grab (AutomationLine* line, GdkEvent* event)
 
        double fraction = 1.0 - (cy / line->height());
 
-       line->start_drag (0, fraction);
+       line->start_drag (0, drag_info.grab_frame, fraction);
        
        set_verbose_canvas_cursor (line->get_verbose_cursor_string (fraction),
                                   drag_info.current_pointer_x + 20, drag_info.current_pointer_y + 20);
@@ -2700,6 +2709,8 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
 void
 Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
 {
+       cerr << "start region copy grab, selected regions = " << selection->regions.size() << endl;
+
        if (selection->regions.empty() || clicked_regionview == 0) {
                return;
        }
@@ -2725,6 +2736,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
        drag_info.want_move_threshold = true;
        drag_info.motion_callback = &Editor::region_drag_motion_callback;
        drag_info.finished_callback = &Editor::region_drag_finished_callback;
+       show_verbose_time_cursor (drag_info.last_frame_position, 10);
 }
 
 void
@@ -2773,8 +2785,6 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        vector<int32_t>  height_list(512) ;
        vector<int32_t>::iterator j;
 
-       show_verbose_time_cursor (drag_info.last_frame_position, 10);
-
        if (drag_info.copy && drag_info.move_threshold_passed && drag_info.want_move_threshold) {
 
                drag_info.want_move_threshold = false; // don't copy again
@@ -2787,15 +2797,16 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                
                vector<RegionView*> new_regionviews;
                
-               set<Playlist*> affected_playlists;
-               pair<set<Playlist*>::iterator,bool> insert_result;
+               set<boost::shared_ptr<Playlist> > affected_playlists;
+               pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
                
+               // TODO: Crossfades need to be copied!
                for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
                        RegionView* rv;
                        
                        rv = (*i);
                        
-                       Playlist* to_playlist = rv->region()->playlist();
+                       boost::shared_ptr<Playlist> to_playlist = rv->region()->playlist();
                        RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view());
                        
                        insert_result = affected_playlists.insert (to_playlist);
@@ -2826,6 +2837,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                                new_regionviews.push_back (latest_regionview);
                        }
                }
+
+               
                
                if (new_regionviews.empty()) {
                        return;
@@ -3116,7 +3129,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                         MOTION                                                               
        ************************************************************/
 
-       pair<set<Playlist*>::iterator,bool> insert_result;
+       pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
        const list<RegionView*>& layered_regions = selection->regions.by_layer();
 
        for (list<RegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) {
@@ -3227,8 +3240,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                        */
 
                        RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view());
-                       if (rtv && rtv->is_track()) {
-                               Playlist* pl = dynamic_cast<Playlist*>(rtv->get_diskstream()->playlist());
+                       if (rtv && rtv->is_audio_track()) {
+                               boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>(rtv->get_diskstream()->playlist());
                                if (pl) {
                                        /* only freeze and capture state once */
 
@@ -3239,6 +3252,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                                        }
                                }
                        }
+                       rv->region()->set_opaque(false);
                }
 
                if (drag_info.brushing) {
@@ -3265,7 +3279,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
 {
        nframes_t where;
        RegionView* rv = reinterpret_cast<RegionView *> (drag_info.data);
-       pair<set<Playlist*>::iterator,bool> insert_result;
+       pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
        bool nocommit = true;
        double speed;
        RouteTimeAxisView* atv;
@@ -3337,8 +3351,8 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
 
                for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
 
-                       Playlist* from_playlist;
-                       Playlist* to_playlist;
+                       boost::shared_ptr<Playlist> from_playlist;
+                       boost::shared_ptr<Playlist> to_playlist;
                                
                        double ix1, ix2, iy1, iy2;
            
@@ -3346,6 +3360,8 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                        (*i)->get_canvas_group()->i2w (ix1, iy1);
                        TimeAxisView* tvp2 = trackview_by_y_position (iy1);
                        RouteTimeAxisView* atv2 = dynamic_cast<RouteTimeAxisView*>(tvp2);
+
+                       (*i)->region()->set_opaque (true);
            
                        from_playlist = (*i)->region()->playlist();
                        to_playlist = atv2->playlist();
@@ -3372,8 +3388,8 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
 
                for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
 
-                       Playlist* from_playlist;
-                       Playlist* to_playlist;
+                       boost::shared_ptr<Playlist> from_playlist;
+                       boost::shared_ptr<Playlist> to_playlist;
                                
                        double ix1, ix2, iy1, iy2;
            
@@ -3439,13 +3455,14 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                        /* no need to add an undo here, we did that when we added this playlist to motion_frozen playlists */
                        
                        rv->region()->set_position (where, (void *) this);
+                       rv->region()->set_opaque (true);
                }
        }
 
   out:
-       for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
+       for (set<boost::shared_ptr<Playlist> >::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
                (*p)->thaw ();
-               session->add_command (new MementoCommand<Playlist>(*(*p), 0, & (*p)->get_state()));
+               session->add_command (new MementoCommand<Playlist>(*((*p).get()), 0, & (*p)->get_state()));
        }
 
        motion_frozen_playlists.clear ();
@@ -3491,6 +3508,8 @@ Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, d
        char buf[128];
        SMPTE::Time smpte;
        BBT_Time bbt;
+       int hours, mins;
+       nframes_t frame_rate;
        float secs;
 
        if (session == 0) {
@@ -3509,10 +3528,14 @@ Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, d
                break;
 
        case AudioClock::MinSec:
-               /* XXX fix this to compute min/sec properly */
-               session->smpte_time (frame, smpte);
-               secs = smpte.seconds + ((float) smpte.frames / Config->get_smpte_frames_per_second());
-               snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", smpte.hours, smpte.minutes, secs);
+               /* XXX this is copied from show_verbose_duration_cursor() */
+               frame_rate = session->frame_rate();
+               hours = frame / (frame_rate * 3600);
+               frame = frame % (frame_rate * 3600);
+               mins = frame / (frame_rate * 60);
+               frame = frame % (frame_rate * 60);
+               secs = (float) frame / (float) frame_rate;
+               snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", hours, mins, secs);
                break;
 
        default:
@@ -3536,6 +3559,8 @@ Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double off
        SMPTE::Time smpte;
        BBT_Time sbbt;
        BBT_Time ebbt;
+       int hours, mins;
+       nframes_t distance, frame_rate;
        float secs;
        Meter meter_at_start(session->tempo_map().meter_at(start));
 
@@ -3576,10 +3601,15 @@ Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double off
                break;
 
        case AudioClock::MinSec:
-               /* XXX fix this to compute min/sec properly */
-               session->smpte_duration (end - start, smpte);
-               secs = smpte.seconds + ((float) smpte.frames / Config->get_smpte_frames_per_second());
-               snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", smpte.hours, smpte.minutes, secs);
+               /* XXX this stuff should be elsewhere.. */
+               distance = end - start;
+               frame_rate = session->frame_rate();
+               hours = distance / (frame_rate * 3600);
+               distance = distance % (frame_rate * 3600);
+               mins = distance / (frame_rate * 60);
+               distance = distance % (frame_rate * 60);
+               secs = (float) distance / (float) frame_rate;
+               snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", hours, mins, secs);
                break;
 
        default:
@@ -3638,7 +3668,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
 
        begin_reversible_command (_("selection grab"));
 
-       Playlist* playlist = clicked_axisview->playlist();
+       boost::shared_ptr<Playlist> playlist = clicked_axisview->playlist();
 
        XMLNode *before = &(playlist->get_state());
        clicked_routeview->playlist()->add_region (region, selection->time[clicked_selection].start);
@@ -3962,7 +3992,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        double speed = 1.0;
        TimeAxisView* tvp = clicked_axisview;
        RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
-       pair<set<Playlist*>::iterator,bool> insert_result;
+       pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
 
        if (tv && tv->is_track()) {
                speed = tv->get_diskstream()->speed();
@@ -4001,13 +4031,14 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                begin_reversible_command (trim_type);
 
                for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
+                       (*i)->region()->set_opaque(false);
                        (*i)->region()->freeze ();
                
                        AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
                        if (arv)
                                arv->temporarily_hide_envelope ();
 
-                       Playlist * pl = (*i)->region()->playlist();
+                       boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
                        insert_result = motion_frozen_playlists.insert (pl);
                        if (insert_result.second) {
                                 session->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
@@ -4195,12 +4226,13 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
                             i != selection->regions.by_layer().end(); ++i)
                        {
                                thaw_region_after_trim (**i);
+                               (*i)->region()->set_opaque(true);
                        }
                }
                
-               for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
+               for (set<boost::shared_ptr<Playlist> >::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
                        //(*p)->thaw ();
-                        session->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));
+                        session->add_command (new MementoCommand<Playlist>(*(*p).get(), 0, &(*p)->get_state()));
                 }
                
                motion_frozen_playlists.clear ();
@@ -4234,22 +4266,22 @@ Editor::point_trim (GdkEvent* event)
                             i != selection->regions.by_layer().end(); ++i)
                        {
                                if (!(*i)->region()->locked()) {
-                                        Playlist *pl = (*i)->region()->playlist();
+                                       boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
                                         XMLNode &before = pl->get_state();
                                        (*i)->region()->trim_front (new_bound, this);   
                                         XMLNode &after = pl->get_state();
-                                        session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+                                        session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
                                }
                        }
 
                } else {
 
                        if (!rv->region()->locked()) {
-                                Playlist *pl = rv->region()->playlist();
+                               boost::shared_ptr<Playlist> pl = rv->region()->playlist();
                                XMLNode &before = pl->get_state();
                                rv->region()->trim_front (new_bound, this);     
                                 XMLNode &after = pl->get_state();
-                               session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+                               session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
                        }
                }
 
@@ -4265,22 +4297,22 @@ Editor::point_trim (GdkEvent* event)
                        for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
                        {
                                if (!(*i)->region()->locked()) {
-                                        Playlist *pl = (*i)->region()->playlist();
+                                       boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
                                        XMLNode &before = pl->get_state();
                                        (*i)->region()->trim_end (new_bound, this);
                                        XMLNode &after = pl->get_state();
-                                       session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+                                       session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
                                }
                        }
 
                } else {
 
                        if (!rv->region()->locked()) {
-                                Playlist *pl = rv->region()->playlist();
+                               boost::shared_ptr<Playlist> pl = rv->region()->playlist();
                                XMLNode &before = pl->get_state();
                                rv->region()->trim_end (new_bound, this);
                                 XMLNode &after = pl->get_state();
-                               session->add_command (new MementoCommand<Playlist>(*pl, &before, &after));
+                               session->add_command (new MementoCommand<Playlist>(*pl.get(), &before, &after));
                        }
                }
 
@@ -4436,6 +4468,7 @@ void
 Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
 {
        Location * newloc = 0;
+       string rangename;
        
        if (!drag_info.first_move) {
                drag_range_markerbar_op (item, event);
@@ -4445,7 +4478,8 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
                    {
                        begin_reversible_command (_("new range marker"));
                         XMLNode &before = session->locations()->get_state();
-                       newloc = new Location(temp_location->start(), temp_location->end(), "unnamed", Location::IsRangeMarker);
+                       session->locations()->next_available_name(rangename,"unnamed");
+                       newloc = new Location(temp_location->start(), temp_location->end(), rangename, Location::IsRangeMarker);
                        session->locations()->add (newloc, true);
                         XMLNode &after = session->locations()->get_state();
                        session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
@@ -4584,7 +4618,7 @@ Editor::reposition_zoom_rect (nframes_t start, nframes_t end)
 {
        double x1 = frame_to_pixel (start);
        double x2 = frame_to_pixel (end);
-       double y2 = canvas_height - 2;
+       double y2 = full_canvas_height - 1.0;
 
        zoom_rect->property_x1() = x1;
        zoom_rect->property_y1() = 1.0;
@@ -4825,13 +4859,13 @@ Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos)
                return;
        }
 
-       Playlist* playlist = atv->playlist();
+       boost::shared_ptr<Playlist> playlist = atv->playlist();
        double speed = atv->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));
         XMLNode &after = playlist->get_state();
-       session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
+       session->add_command(new MementoCommand<Playlist>(*playlist.get(), &before, &after));
        
        // playlist is frozen, so we have to update manually
        
index 93e90f4c2cf5beda99c91bb6aa603987e886512c..ea4848b88238516eb86b706733c189444554c9b6 100644 (file)
@@ -44,6 +44,7 @@
 #include <ardour/audio_track.h>
 #include <ardour/audioplaylist.h>
 #include <ardour/region_factory.h>
+#include <ardour/playlist_factory.h>
 #include <ardour/reverse.h>
 
 #include "ardour_ui.h"
@@ -56,7 +57,6 @@
 #include "rgb_macros.h"
 #include "selection_templates.h"
 #include "selection.h"
-#include "sfdb_ui.h"
 #include "editing.h"
 #include "gtk-custom-hruler.h"
 #include "gui_thread.h"
@@ -122,7 +122,7 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
                tmp = a;
                ++tmp;
 
-               Playlist* pl = (*a)->region()->playlist();
+               boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
 
                AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a);
                if (arv)
@@ -149,7 +149,7 @@ Editor::remove_clicked_region ()
                return;
        }
 
-       Playlist* playlist = clicked_routeview->playlist();
+       boost::shared_ptr<Playlist> playlist = clicked_routeview->playlist();
        
        begin_reversible_command (_("remove region"));
         XMLNode &before = playlist->get_state();
@@ -232,7 +232,7 @@ Editor::select_region_for_operation (int dir, TimeAxisView **tv)
                RouteTimeAxisView* rtv;
 
                if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) {
-                       Playlist *pl;
+                       boost::shared_ptr<Playlist> pl;
                        
                        if ((pl = rtv->playlist()) == 0) {
                                return region;
@@ -1197,6 +1197,8 @@ Editor::temporal_zoom_to_frame (bool coarser, nframes_t frame)
 void
 Editor::add_location_from_selection ()
 {
+       string rangename;
+
        if (selection->time.empty()) {
                return;
        }
@@ -1208,7 +1210,8 @@ Editor::add_location_from_selection ()
        nframes_t start = selection->time[clicked_selection].start;
        nframes_t end = selection->time[clicked_selection].end;
 
-       Location *location = new Location (start, end, "selection");
+       session->locations()->next_available_name(rangename,"selection");
+       Location *location = new Location (start, end, rangename, Location::IsRangeMarker);
 
        session->begin_reversible_command (_("add marker"));
         XMLNode &before = session->locations()->get_state();
@@ -1221,9 +1224,12 @@ Editor::add_location_from_selection ()
 void
 Editor::add_location_from_playhead_cursor ()
 {
+       string markername;
+
        nframes_t where = session->audible_frame();
        
-       Location *location = new Location (where, where, "mark", Location::IsMark);
+       session->locations()->next_available_name(markername,"mark");
+       Location *location = new Location (where, where, markername, Location::IsMark);
        session->begin_reversible_command (_("add marker"));
         XMLNode &before = session->locations()->get_state();
        session->locations()->add (location, true);
@@ -1242,7 +1248,7 @@ Editor::add_location_from_audio_region ()
        RegionView* rv = *(selection->regions.begin());
        boost::shared_ptr<Region> region = rv->region();
        
-       Location *location = new Location (region->position(), region->last_frame(), region->name());
+       Location *location = new Location (region->position(), region->last_frame(), region->name(), Location::IsRangeMarker);
        session->begin_reversible_command (_("add marker"));
         XMLNode &before = session->locations()->get_state();
        session->locations()->add (location, true);
@@ -1649,6 +1655,7 @@ Editor::set_mark ()
        nframes_t pos;
        float prefix;
        bool was_floating;
+       string markername;
 
        if (get_prefix (prefix, was_floating)) {
                pos = session->audible_frame ();
@@ -1660,7 +1667,8 @@ Editor::set_mark ()
                }
        }
 
-       session->locations()->add (new Location (pos, 0, "mark", Location::IsMark), true);
+       session->locations()->next_available_name(markername,"mark");
+       session->locations()->add (new Location (pos, 0, markername, Location::IsMark), true);
 }
 
 void
@@ -1709,6 +1717,28 @@ Editor::clear_locations ()
        session->locations()->clear ();
 }
 
+void
+Editor::unhide_markers ()
+{
+       for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) {
+               Location *l = (*i).first;
+               if (l->is_hidden() && l->is_mark()) {
+                       l->set_hidden(false, this);
+               }
+       }
+}
+
+void
+Editor::unhide_ranges ()
+{
+       for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) {
+               Location *l = (*i).first;
+               if (l->is_hidden() && l->is_range_marker()) { 
+                       l->set_hidden(false, this);
+               }
+       }
+}
+
 /* INSERT/REPLACE */
 
 void
@@ -1719,7 +1749,7 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
        TimeAxisView *tv;
        nframes_t where;
        AudioTimeAxisView *atv = 0;
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
        
        track_canvas.window_to_world (x, y, wx, wy);
        wx += horizontal_adjustment.get_value();
@@ -1749,20 +1779,26 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
                return;
        }
        
+       cerr << "drop target playlist, UC  = " << playlist.use_count() << endl;
+
        snap_to (where);
        
        begin_reversible_command (_("insert dragged region"));
         XMLNode &before = playlist->get_state();
+       cerr << "pre add target playlist, UC  = " << playlist.use_count() << endl;
        playlist->add_region (RegionFactory::create (region), where, 1.0);
+       cerr << "post add target playlist, UC  = " << playlist.use_count() << endl;
        session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
        commit_reversible_command ();
+
+       cerr << "post drop target playlist, UC  = " << playlist.use_count() << endl;
 }
 
 void
 Editor::insert_region_list_selection (float times)
 {
        RouteTimeAxisView *tv = 0;
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
 
        if (clicked_routeview != 0) {
                tv = clicked_routeview;
@@ -2097,7 +2133,7 @@ Editor::region_from_selection ()
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
                boost::shared_ptr<AudioRegion> current;
                boost::shared_ptr<Region> current_r;
-               Playlist *pl;
+               boost::shared_ptr<Playlist> pl;
 
                nframes_t internal_start;
                string new_name;
@@ -2134,7 +2170,7 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n
 
                boost::shared_ptr<AudioRegion> current;
                boost::shared_ptr<Region> current_r;
-               Playlist* playlist;
+               boost::shared_ptr<Playlist> playlist;
                nframes_t internal_start;
                string new_name;
 
@@ -2191,7 +2227,7 @@ Editor::separate_region_from_selection ()
                return;
        }
 
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
                
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
 
@@ -2239,7 +2275,7 @@ Editor::separate_regions_using_location (Location& loc)
                return;
        }
 
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
 
        /* XXX i'm unsure as to whether this should operate on selected tracks only 
           or the entire enchillada. uncomment the below line to correct the behaviour 
@@ -2288,8 +2324,8 @@ Editor::crop_region_to_selection ()
                return;
        }
 
-       vector<Playlist*> playlists;
-       Playlist *playlist;
+       vector<boost::shared_ptr<Playlist> > playlists;
+       boost::shared_ptr<Playlist> playlist;
 
        if (clicked_axisview != 0) {
 
@@ -2322,7 +2358,7 @@ Editor::crop_region_to_selection ()
 
                begin_reversible_command (_("trim to selection"));
 
-               for (vector<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
                        
                        boost::shared_ptr<Region> region;
                        
@@ -2371,7 +2407,7 @@ Editor::region_fill_track ()
                boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(region);
                assert(ar);
 
-               Playlist* pl = region->playlist();
+               boost::shared_ptr<Playlist> pl = region->playlist();
 
                if (end <= region->last_frame()) {
                        return;
@@ -2415,7 +2451,7 @@ Editor::region_fill_selection ()
        nframes_t start = selection->time[clicked_selection].start;
        nframes_t end = selection->time[clicked_selection].end;
 
-       Playlist *playlist; 
+       boost::shared_ptr<Playlist> playlist; 
 
        if (selection->tracks.empty()) {
                return;
@@ -2781,7 +2817,7 @@ Editor::bounce_range_selection ()
                        continue;
                }
                
-               Playlist* playlist;
+               boost::shared_ptr<Playlist> playlist;
                
                if ((playlist = atv->playlist()) == 0) {
                        return;
@@ -2897,7 +2933,7 @@ Editor::cut_copy_points (CutCopyOp op)
 }
 
 struct PlaylistState {
-    Playlist* playlist;
+    boost::shared_ptr<Playlist> playlist;
     XMLNode*  before;
 };
 
@@ -2910,7 +2946,7 @@ struct lt_playlist {
 void
 Editor::cut_copy_regions (CutCopyOp op)
 {
-        typedef std::map<AudioPlaylist*,AudioPlaylist*> PlaylistMapping;
+        typedef std::map<boost::shared_ptr<AudioPlaylist>,boost::shared_ptr<AudioPlaylist> > PlaylistMapping;
        PlaylistMapping pmap;
        nframes_t first_position = max_frames;
 
@@ -2921,7 +2957,8 @@ Editor::cut_copy_regions (CutCopyOp op)
                first_position = min ((*x)->region()->position(), first_position);
 
                if (op == Cut || op == Clear) {
-                       AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region()->playlist());
+                       boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
+
                        if (pl) {
 
                                PlaylistState before;
@@ -2939,8 +2976,8 @@ Editor::cut_copy_regions (CutCopyOp op)
 
        for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) {
 
-               AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region()->playlist());
-               AudioPlaylist* npl;
+               boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
+               boost::shared_ptr<AudioPlaylist> npl;
                RegionSelection::iterator tmp;
                
                tmp = x;
@@ -2951,7 +2988,8 @@ Editor::cut_copy_regions (CutCopyOp op)
                        PlaylistMapping::iterator pi = pmap.find (pl);
                        
                        if (pi == pmap.end()) {
-                               npl = new AudioPlaylist (*session, "cutlist", true);
+                               // FIXME
+                               npl = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, *session, "cutlist", true));
                                npl->freeze();
                                pmap[pl] = npl;
                        } else {
@@ -2983,7 +3021,7 @@ Editor::cut_copy_regions (CutCopyOp op)
                x = tmp;
        }
 
-       list<Playlist*> foo;
+       list<boost::shared_ptr<Playlist> > foo;
 
        for (PlaylistMapping::iterator i = pmap.begin(); i != pmap.end(); ++i) {
                foo.push_back (i->second);
@@ -3080,8 +3118,8 @@ Editor::paste_named_selection (float times)
        TreeModel::iterator i = selected->get_selected();
        NamedSelection* ns = (*i)[named_selection_columns.selection];
 
-       list<Playlist*>::iterator chunk;
-       list<Playlist*>::iterator tmp;
+       list<boost::shared_ptr<Playlist> >::iterator chunk;
+       list<boost::shared_ptr<Playlist> >::iterator tmp;
 
        chunk = ns->playlists.begin();
                
@@ -3090,8 +3128,8 @@ Editor::paste_named_selection (float times)
        for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
                
                AudioTimeAxisView* atv;
-               Playlist* pl;
-               AudioPlaylist* apl;
+               boost::shared_ptr<Playlist> pl;
+               boost::shared_ptr<AudioPlaylist> apl;
 
                if ((atv = dynamic_cast<AudioTimeAxisView*> (*t)) == 0) {
                        continue;
@@ -3100,8 +3138,8 @@ Editor::paste_named_selection (float times)
                if ((pl = atv->playlist()) == 0) {
                        continue;
                }
-
-               if ((apl = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
+               
+               if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
                        continue;
                }
 
@@ -3109,7 +3147,7 @@ Editor::paste_named_selection (float times)
                ++tmp;
 
                 XMLNode &before = apl->get_state();
-               apl->paste (**chunk, edit_cursor->current_frame, times);
+               apl->paste (*chunk, edit_cursor->current_frame, times);
                session->add_command(new MementoCommand<AudioPlaylist>(*apl, &before, &apl->get_state()));
 
                if (tmp != ns->playlists.end()) {
@@ -3123,7 +3161,7 @@ Editor::paste_named_selection (float times)
 void
 Editor::duplicate_some_regions (RegionSelection& regions, float times)
 {
-       Playlist *playlist; 
+       boost::shared_ptr<Playlist> playlist; 
        RegionSelection sel = regions; // clear (below) will clear the argument list
                
        begin_reversible_command (_("duplicate region"));
@@ -3161,7 +3199,7 @@ Editor::duplicate_selection (float times)
                return;
        }
 
-       Playlist *playlist; 
+       boost::shared_ptr<Playlist> playlist; 
        vector<boost::shared_ptr<AudioRegion> > new_regions;
        vector<boost::shared_ptr<AudioRegion> >::iterator ri;
                
@@ -3227,20 +3265,20 @@ Editor::center_edit_cursor ()
 }
 
 void
-Editor::clear_playlist (Playlist& playlist)
+Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
 {
        begin_reversible_command (_("clear playlist"));
-        XMLNode &before = playlist.get_state();
-       playlist.clear ();
-        XMLNode &after = playlist.get_state();
-       session->add_command (new MementoCommand<Playlist>(playlist, &before, &after));
+        XMLNode &before = playlist->get_state();
+       playlist->clear ();
+        XMLNode &after = playlist->get_state();
+       session->add_command (new MementoCommand<Playlist>(*playlist.get(), &before, &after));
        commit_reversible_command ();
 }
 
 void
 Editor::nudge_track (bool use_edit_cursor, bool forwards)
 {
-       Playlist *playlist; 
+       boost::shared_ptr<Playlist> playlist; 
        nframes_t distance;
        nframes_t next_distance;
        nframes_t start;
@@ -3388,7 +3426,7 @@ Editor::apply_filter (AudioFilter& filter, string command)
                if (!arv)
                        continue;
 
-               Playlist* playlist = arv->region()->playlist();
+               boost::shared_ptr<Playlist> playlist = arv->region()->playlist();
 
                RegionSelection::iterator tmp;
                
index b30a3092ecaf4451e4866fefdbfd332417bb3c86..bc95cb0d14c2335be256987af50bbd5217635613 100644 (file)
@@ -26,7 +26,7 @@
 #include <pbd/basename.h>
 
 #include <ardour/audioregion.h>
-#include <ardour/audiosource.h>
+#include <ardour/audiofilesource.h>
 #include <ardour/session_region.h>
 
 #include <gtkmm2ext/stop_signal.h>
@@ -101,7 +101,8 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
                        parent = *(region_list_model->append());
                        
                        parent[region_list_columns.name] = _("Hidden");
-                       /// XXX FIX ME parent[region_list_columns.region]->reset ();
+                       boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
+                       proxy.reset ();
 
                } else {
 
@@ -109,7 +110,8 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
 
                                parent = *(region_list_model->insert(iter));
                                parent[region_list_columns.name] = _("Hidden");
-                               /// XXX FIX ME parent[region_list_columns.region]->reset ();
+                               boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
+                               proxy.reset ();
 
                        } else {
                                parent = *iter;
@@ -129,8 +131,15 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
 
                        if (region->whole_file()) {
                                str = ".../";
-                               str += PBD::basename_nosuffix (region->source()->name());
-                               
+
+                               boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(region->source());
+
+                               if (afs) {
+                                       str += region_name_from_path (afs->path(), region->n_channels() > 1);
+                               } else {
+                                       str += region->source()->name();
+                               }
+
                        } else {
                                str = region->name();
                        }
@@ -342,20 +351,15 @@ Editor::region_list_display_button_press (GdkEventButton *ev)
                }
        }
 
-       if (region == 0) {
-               return false;
-       }
-
-       if (Keyboard::is_delete_event (ev)) {
-               session->remove_region_from_region_list (region);
-               return true;
-       }
-
        if (Keyboard::is_context_menu_event (ev)) {
                show_region_list_display_context_menu (ev->button, ev->time);
                return true;
        }
 
+       if (region == 0) {
+               return false;
+       }
+
        switch (ev->button) {
        case 1:
                /* audition on double click */
index 06bf7da625782f7abbe47a8d028497798c660478..216e3a8e1be3c01c13b554d602e31f59fc8c9340 100644 (file)
@@ -479,7 +479,7 @@ Editor::show_route_list_menu()
                build_route_list_menu ();
        }
 
-       route_list_menu->popup (1, 0);
+       route_list_menu->popup (1, gtk_get_current_event_time());
 }
 
 bool
index 9834ce16db401fad4d7cc330813954ec71d1fc5a..bc2328b52411039270093a045c5065c40336bf0a 100644 (file)
@@ -338,11 +338,13 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t)
        case MarkerBarItem:
                ruler_items.push_back (MenuElem (_("New location marker"), bind ( mem_fun(*this, &Editor::mouse_add_new_marker), where)));
                ruler_items.push_back (MenuElem (_("Clear all locations"), mem_fun(*this, &Editor::clear_markers)));
+               ruler_items.push_back (MenuElem (_("Unhide locations"), mem_fun(*this, &Editor::unhide_markers)));
                ruler_items.push_back (SeparatorElem ());
                break;
        case RangeMarkerBarItem:
                //ruler_items.push_back (MenuElem (_("New Range")));
                ruler_items.push_back (MenuElem (_("Clear all ranges"), mem_fun(*this, &Editor::clear_ranges)));
+               ruler_items.push_back (MenuElem (_("Unhide ranges"), mem_fun(*this, &Editor::unhide_ranges)));
                ruler_items.push_back (SeparatorElem ());
 
                break;
@@ -422,7 +424,7 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t)
                mitem->set_active(true);
        }
        
-        editor_ruler_menu->popup (1, 0);
+        editor_ruler_menu->popup (1, gtk_get_current_event_time());
 
        no_ruler_shown_update = false;
 }
@@ -468,7 +470,7 @@ Editor::store_ruler_visibility ()
        session->add_extra_xml (*node);
        session->set_dirty ();
 }
+
 void 
 Editor::restore_ruler_visibility ()
 {
@@ -854,7 +856,7 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
        if (range < (2 * session->frames_per_smpte_frame())) { /* 0 - 2 frames */
                show_bits = true;
                mark_modulo = 20;
-               nmarks = 1 + 160;
+               nmarks = 1 + (2 * Config->get_subframes_per_frame());
        } else if (range <= (fr / 4)) { /* 2 frames - 0.250 second */
                show_frames = true;
                mark_modulo = 1;
index 959da1ad2d740e4a335d60d7a5290d45d978b05e..8e88ee497bbb9a74bd7fb8dbd878b101b0e5cf64 100644 (file)
@@ -79,7 +79,7 @@ Editor::named_selection_display_button_press (GdkEventButton *ev)
                        case 1:
                                if (Keyboard::is_delete_event (ev)) {
                                        session->remove_named_selection ((*i)[named_selection_columns.selection]);
-                                       return stop_signal (named_selection_display, "button_press_event");
+                                       return true;
                                }
                                break;
                        case 2:
@@ -150,12 +150,12 @@ Editor::create_named_selection (const string & name)
                return;
        }
 
-       Playlist*       what_we_found;
-       list<Playlist*> thelist;
+       boost::shared_ptr<Playlist>        what_we_found;
+       list<boost::shared_ptr<Playlist> > thelist;
 
        for (TrackViewList::iterator i = views->begin(); i != views->end(); ++i) {
                
-               Playlist *pl = (*i)->playlist();
+               boost::shared_ptr<Playlist> pl = (*i)->playlist();
                
                if (pl) {
                        
index 188960c9624fc8276d984693c6a1ddd01e5a0711..bfc5ee85cdd1479cfe763236f23b17b51254e6ef 100644 (file)
@@ -159,7 +159,7 @@ void
 Editor::do_timestretch (TimeStretchDialog& dialog)
 {
        Track*    t;
-       Playlist* playlist;
+       boost::shared_ptr<Playlist> playlist;
        boost::shared_ptr<Region>   new_region;
 
        for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) {
index cb63e2403a0b38fec0fc81ae34ee8d78f6d59b71..95a51a82137f7004de4825dd894cda255566b72c 100644 (file)
@@ -63,3 +63,55 @@ static const gchar speaker_cursor_mask_bits[] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x3f, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xf0,
    0x00, 0xc0, 0x00, 0xc0 };
+
+#define cursor_audition_width 13
+#define cursor_audition_height 16
+#define cursor_audition_x_hot 0
+#define cursor_audition_y_hot 7
+static const short cursor_audition_bits[] = {
+   0x1000, 0x1800, 0x1400, 0x1200, 0x11f0, 0x1110, 0x111f, 0x1111, 0x1112,
+   0x111e, 0x1110, 0x11f0, 0x1200, 0x1400, 0x1800, 0x1000 };
+
+#define cursor_audition_mask_width 13
+#define cursor_audition_mask_height 16
+#define cursor_audition_mask_x_hot 0
+#define cursor_audition_mask_y_hot 7
+static const short cursor_audition_mask_bits[] = {
+   0x1000, 0x1800, 0x1c00, 0x1e00, 0x1ff0, 0x1ff0, 0x1fff, 0x1fff, 0x1ffe,
+   0x1ffe, 0x1ff0, 0x1ff0, 0x1e00, 0x1c00, 0x1800, 0x1000 };
+
+#define cursor_timestretch_width 15
+#define cursor_timestretch_height 16
+#define cursor_timestretch_x_hot 7
+#define cursor_timestretch_y_hot 8
+static const short cursor_timestretch_bits[] = {
+   0x01c0, 0x0140, 0x0140, 0x0140, 0x0540, 0x0d40, 0x1548, 0x274c, 0x417e,
+   0x274c, 0x1548, 0x0d40, 0x0540, 0x0140, 0x0140, 0x01c0 };
+
+#define cursor_timestretch_mask_width 15
+#define cursor_timestretch_mask_height 16
+#define cursor_timestretch_mask_x_hot 7
+#define cursor_timestretch_mask_y_hot 8
+static const short cursor_timestretch_mask_bits[] = {
+   0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x05d0, 0x0dd8, 0x1ddc, 0x3ffe, 0x7fff,
+   0x3ffe, 0x1ddc, 0x0dd8, 0x05d0, 0x01c0, 0x01c0, 0x01c0 };
+
+#define cursor_zoom_width 17
+#define cursor_zoom_height 16
+#define cursor_zoom_x_hot 6
+#define cursor_zoom_y_hot 6
+static const short cursor_zoom_bits[] = {
+   0x00e0, 0x0000, 0x03b8, 0x0000, 0x0604, 0x0000, 0x0806, 0x0000, 0x0842,
+   0x0000, 0x1843, 0x0000, 0x11f1, 0x0000, 0x1843, 0x0000, 0x0842, 0x0000,
+   0x1806, 0x0000, 0x2604, 0x0000, 0x4758, 0x0000, 0x88e0, 0x0000, 0x1000,
+   0x0001, 0x2000, 0x0001, 0xc000, 0x0000 };
+
+#define cursor_zoom_mask_width 17
+#define cursor_zoom_mask_height 16
+#define cursor_zoom_mask_x_hot 6
+#define cursor_zoom_mask_y_hot 6
+static const short cursor_zoom_mask_bits[] = {
+   0x00e0, 0x0000, 0x03f8, 0x0000, 0x07fc, 0x0000, 0x0ffe, 0x0000, 0x0ffe,
+   0x0000, 0x1fff, 0x0000, 0x1fff, 0x0000, 0x1fff, 0x0000, 0x0ffe, 0x0000,
+   0x1ffe, 0x0000, 0x3ffc, 0x0000, 0x7ff8, 0x0000, 0xf8e0, 0x0000, 0xf000,
+   0x0001, 0xe000, 0x0001, 0xc000, 0x0000 };
diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc
new file mode 100644 (file)
index 0000000..68b2751
--- /dev/null
@@ -0,0 +1,29 @@
+#include <pbd/enumwriter.h>
+
+#include "audio_clock.h"
+
+using namespace std;
+using namespace PBD;
+using namespace ARDOUR;
+
+void
+setup_gtk_ardour_enums ()
+{
+       EnumWriter& enum_writer (EnumWriter::instance());
+       vector<int> i;
+       vector<string> s;
+
+       AudioClock::Mode clock_mode;
+
+#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
+#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
+#define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e)
+#define REGISTER_CLASS_ENUM(t,e) i.push_back (t::e); s.push_back (#e)
+
+       REGISTER_CLASS_ENUM (AudioClock, SMPTE);
+       REGISTER_CLASS_ENUM (AudioClock, BBT);
+       REGISTER_CLASS_ENUM (AudioClock, MinSec);
+       REGISTER_CLASS_ENUM (AudioClock, Frames);
+       REGISTER_CLASS_ENUM (AudioClock, Off);
+       REGISTER (clock_mode);
+}
index 15ba8743664c398a927a74eb71dc8ce4e97698e9..987c49fe06a1c42c6173f3a199d4e96364a0f2a9 100644 (file)
@@ -8,6 +8,11 @@ enum WaveformShape {
        Rectified
 };
 
+enum WaveformScale {
+       LinearWaveform=0,
+       LogWaveform,
+};
+
 
 enum Width {
        Wide,
@@ -27,4 +32,6 @@ struct SelectionRect {
     uint32_t id;
 };
 
+extern void setup_gtk_ardour_enums ();
+
 #endif /* __ardour_gtk_enums_h__ */
index 5a269ffbefe9c7ef1aa09ac600e628b2ff7c7a64..921e6776aacbc6f981b36fc8b3e54f0edb63b208 100644 (file)
@@ -123,7 +123,7 @@ ExportDialog::ExportDialog(PublicEditor& e)
        export_cd_markers_allowed = true;
        
        set_title (_("ardour: export"));
-       set_wmclass (_("ardour_export"), "Ardour");
+       set_wmclass (X_("ardour_export"), "Ardour");
        set_name ("ExportWindow");
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
 
index 5d2f383a806d733154030c844b1a09b961c8a796..e7a0fd75b6ffadb8904307c04f72f99e32c18b4b 100644 (file)
@@ -123,7 +123,7 @@ FFTGraph::setWindowSize_internal(int windowSize)
        }
        
        _logScale = (int *) malloc(sizeof(int) * _dataSize);
-       float count = 0;
+       //float count = 0;
        for (int i = 0; i < _dataSize; i++) {
                _logScale[i] = 0;
        }
@@ -389,7 +389,7 @@ FFTGraph::on_size_request(Gtk::Requisition* requisition)
                        pixel++;
                        freq_at_pixel = FFT_START * exp( FFT_RANGE * pixel / (double)scaleWidth );
                }
-               _logScale[i] = floor(pixel);
+               _logScale[i] = (int)floor(pixel);
 //printf("logscale at %d = %3.3f, freq_at_pixel %3.3f, freq_at_bin %3.3f, scaleWidth %d\n", i, pixel, freq_at_pixel, freq_at_bin, scaleWidth);
        }
 
index fc8e183d96656d13b16327bda4b523ecf68b88b7..cedded1d9b16ca3e4d6585548fcdd3263d75980e 100644 (file)
@@ -63,20 +63,7 @@ map<string,Glib::RefPtr<Gdk::Pixmap> > GainMeter::metric_pixmaps;
 int
 GainMeter::setup_slider_pix ()
 {
-       string path = ARDOUR::find_data_file("vslider02_slider.xpm", "pixmaps");
-       if (path.empty()) {
-               error << _("cannot find images for fader slider") << endmsg;
-               return -1;
-       }
-       slider = Gdk::Pixbuf::create_from_file (path);
-
-       path = ARDOUR::find_data_file("vslider02_rail.xpm", "pixmaps");
-       if (path.empty()) {
-               error << _("cannot find images for fader rail") << endmsg;
-               return -1;
-       }
-       rail = Gdk::Pixbuf::create_from_file (path);
-
+       slider = ::get_icon ("fader_belt");
        return 0;
 }
 
@@ -86,7 +73,6 @@ GainMeter::GainMeter (boost::shared_ptr<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_display (&gain_adjustment, "MixerStripGainDisplay"),
          gain_automation_style_button (""),
          gain_automation_state_button ("")
        
@@ -97,36 +83,38 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
 
        ignore_toggle = false;
        meter_menu = 0;
-       
-       gain_slider = manage (new VSliderController (slider, rail,
+       next_release_selects = false;
+
+       gain_slider = manage (new VSliderController (slider,
                                                     &gain_adjustment,
                                                     _io->gain_control(),
                                                     false));
 
        gain_slider->signal_button_press_event().connect (mem_fun(*this, &GainMeter::start_gain_touch));
        gain_slider->signal_button_release_event().connect (mem_fun(*this, &GainMeter::end_gain_touch));
-       gain_slider->set_name ("MixerGainMeter");
+       gain_slider->set_name ("GainFader");
 
-       gain_display.set_print_func (_gain_printer, this);
+       gain_display.set_name ("MixerStripGainDisplay");
+       gain_display.set_has_frame (false);
+       set_size_request_to_display_given_text (gain_display, "-80.g", 2, 6); /* note the descender */
+       gain_display.signal_activate().connect (mem_fun (*this, &GainMeter::gain_activated));
+       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_homogeneous (true);
        gain_display_box.set_spacing (2);
-       set_size_request_to_display_given_text (gain_display_frame, "-86.g", 2, 6); /* note the descender */
-       gain_display_frame.set_shadow_type (Gtk::SHADOW_IN);
-       gain_display_frame.set_name ("BaseFrame");
-       gain_display_frame.add (gain_display);
-       gain_display_box.pack_start (gain_display_frame,  Gtk::PACK_SHRINK);
+       gain_display_box.pack_start (gain_display, true, true);
 
        peak_display.set_name ("MixerStripPeakDisplay");
-       peak_display.add (peak_display_label);
-       set_size_request_to_display_given_text (peak_display_frame, "-86.g", 2, 6); /* note the descender */
-       peak_display_frame.set_shadow_type (Gtk::SHADOW_IN);
-       peak_display_frame.set_name ("BaseFrame");
-       peak_display_frame.add (peak_display);
+       peak_display.set_has_frame (false);
+       peak_display.set_editable (false);
+       set_size_request_to_display_given_text  (peak_display, "-80.g", 2, 6); /* note the descender */
        max_peak = minus_infinity();
-       peak_display_label.set_text (_("-inf"));
+       peak_display.set_text (_("-inf"));
+       peak_display.unset_flags (Gtk::CAN_FOCUS);
 
-       meter_metric_area.set_size_request (25, -1);
        meter_metric_area.set_name ("MeterMetricsStrip");
+       set_size_request_to_display_given_text (meter_metric_area, "-50", 0, 0);
 
        meter_packer.set_spacing (2);
 
@@ -142,12 +130,15 @@ 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 (*gain_slider, false, false, 0);
+       fader_vbox->pack_start (*fader_centering_box, false, false, 0);
 
-       hbox.set_spacing (0);
+       hbox.set_spacing (2);
+       hbox.pack_start (*fader_vbox, true, true);
 
        if (_io->default_type() == ARDOUR::DataType::AUDIO)
                hbox.pack_start (*fader_vbox, false, false, 2);
@@ -157,14 +148,15 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
        Route* r;
 
        if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+
                /* 
-                  if we don't have a route (if we're the click), 
+                  if we have a route (ie. we're not the click), 
                   pack some route-dependent stuff.
                */
 
-               gain_display_box.pack_end (peak_display_frame,  Gtk::PACK_SHRINK);
+               gain_display_box.pack_end (peak_display, true, true);
 
-               hbox.pack_start (meter_packer, true, false);
+               hbox.pack_end (meter_packer, true, true);
 
                using namespace Menu_Helpers;
        
@@ -193,23 +185,25 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
                gain_automation_state_changed ();
        }
 
+       set_spacing (2);
 
-       set_spacing (4);
-
-       pack_start (gain_display_box,  Gtk::PACK_SHRINK);
-       pack_start (hbox,  Gtk::PACK_SHRINK);
+       pack_start (gain_display_box, Gtk::PACK_SHRINK);
+       pack_start (hbox, Gtk::PACK_SHRINK);
 
        _io->gain_changed.connect (mem_fun(*this, &GainMeter::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));
+       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);
 
        Config->ParameterChanged.connect (mem_fun (*this, &GainMeter::parameter_changed));
 
        gain_changed (0);
-       update_gain_sensitive ();
+       show_gain ();
 
+       update_gain_sensitive ();
+       
        ResetAllPeakDisplays.connect (mem_fun(*this, &GainMeter::reset_peak_display));
        ResetGroupPeakDisplays.connect (mem_fun(*this, &GainMeter::reset_group_peak_display));
 }
@@ -219,10 +213,10 @@ GainMeter::set_width (Width w)
 {
        switch (w) {
        case Wide:
-               peak_display_frame.show_all();
+               peak_display.show();
                break;
        case Narrow:
-               peak_display_frame.hide_all();
+               peak_display.hide();
                break;
        }
 
@@ -322,7 +316,7 @@ GainMeter::update_meters ()
 {
        vector<MeterInfo>::iterator i;
        uint32_t n;
-       float peak;
+       float peak, mpeak;
        char buf[32];
        
        for (n = 0, i = meters.begin(); i != meters.end(); ++i, ++n) {
@@ -330,15 +324,17 @@ GainMeter::update_meters ()
                        peak = _io->peak_meter().peak_power (n);
 
                        (*i).meter->set (log_meter (peak), peak);
-                                               
-                       if (peak > max_peak) {
-               max_peak = peak;
-                /* set peak display */
+
+                       mpeak = _io->peak_meter().max_peak_power(n);
+                       
+                       if (mpeak > max_peak) {
+                               max_peak = mpeak;
+                               /* set peak display */
                                if (max_peak <= -200.0f) {
-                                       peak_display_label.set_text (_("-inf"));
+                                       peak_display.set_text (_("-inf"));
                                } else {
                                        snprintf (buf, sizeof(buf), "%.1f", max_peak);
-                                       peak_display_label.set_text (buf);
+                                       peak_display.set_text (buf);
                                }
 
                                if (max_peak >= 0.0f) {
@@ -432,7 +428,14 @@ GainMeter::setup_meters ()
                meters.push_back (MeterInfo());
        }
 
-       for (uint32_t n = 0; n < nmeters; ++n) {
+       /* pack them backwards */
+
+       if (_width == Wide) {
+               meter_packer.pack_end (meter_metric_area, false, false);
+               meter_metric_area.show_all ();
+       }
+
+       for (int32_t n = nmeters-1; nmeters && n >= 0 ; --n) {
                if (meters[n].width != width) {
                        delete meters[n].meter;
                        meters[n].meter = new FastMeter ((uint32_t) floor (Config->get_meter_hold()), width, FastMeter::Vertical);
@@ -442,18 +445,24 @@ GainMeter::setup_meters ()
                        meters[n].meter->signal_button_release_event().connect (bind (mem_fun(*this, &GainMeter::meter_button_release), n));
                }
 
-               meter_packer.pack_start (*meters[n].meter, Gtk::PACK_SHRINK);
+               meter_packer.pack_end (*meters[n].meter, false, false);
                meters[n].meter->show_all ();
                meters[n].packed = true;
        }
+}      
 
-       if (_width == Wide) {
-               meter_packer.pack_start (meter_metric_area, Gtk::PACK_SHRINK);
-               meter_metric_area.show_all ();
+bool
+GainMeter::gain_key_press (GdkEventKey* ev)
+{
+       if (key_is_legal_for_numeric_entry (ev->keyval)) {
+               /* drop through to normal handling */
+               return false;
        }
-}      
+       /* illegal key for gain entry */
+       return true;
+}
 
-gint
+bool
 GainMeter::peak_button_release (GdkEventButton* ev)
 {
        /* reset peak label */
@@ -468,14 +477,20 @@ GainMeter::peak_button_release (GdkEventButton* ev)
        } else {
                reset_peak_display ();
        }
-       return TRUE;
+
+       return true;
 }
 
 void
 GainMeter::reset_peak_display ()
 {
-       max_peak = minus_infinity();
-       peak_display_label.set_text (_("-Inf"));
+       Route * r;
+       if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+               r->peak_meter().reset_max();
+       }
+
+       max_peak = -INFINITY;
+       peak_display.set_text (_("-Inf"));
        peak_display.set_name ("MixerStripPeakDisplay");
 }
 
@@ -497,7 +512,7 @@ GainMeter::meter_button_release (GdkEventButton* ev, uint32_t which)
        case 1:
                meters[which].meter->clear();
                max_peak = minus_infinity();
-               peak_display_label.set_text (_("-inf"));
+               peak_display.set_text (_("-inf"));
                peak_display.set_name ("MixerStripPeakDisplay");
                break;
 
@@ -530,22 +545,46 @@ GainMeter::popup_meter_menu (GdkEventButton *ev)
        meter_menu->popup (1, ev->time);
 }
 
+bool
+GainMeter::gain_focused (GdkEventFocus* ev)
+{
+       if (ev->in) {
+               gain_display.select_region (0, -1);
+       } else {
+               gain_display.select_region (0, 0);
+       }
+       return false;
+}
+
 void
-GainMeter::_gain_printer (char buf[32], Gtk::Adjustment& adj, void *arg)
+GainMeter::gain_activated ()
 {
-       static_cast<GainMeter *>(arg)->gain_printer (buf, adj);
+       float f;
+
+       if (sscanf (gain_display.get_text().c_str(), "%f", &f) == 1) {
+
+               /* clamp to displayable values */
+
+               f = min (f, 6.0f);
+
+               _io->set_gain (dB_to_coefficient (f), this);
+       }
 }
 
 void
-GainMeter::gain_printer (char buf[32], Gtk::Adjustment& adj)
+GainMeter::show_gain ()
 {
-       float v = adj.get_value();
+       char buf[32];
 
+       float v = gain_adjustment.get_value();
+       
        if (v == 0.0) {
                strcpy (buf, _("-inf"));
        } else {
                snprintf (buf, 32, "%.1f", coefficient_to_dB (slider_position_to_gain (v)));
        }
+       
+       gain_display.set_text (buf);
 }
 
 void
@@ -554,6 +593,7 @@ GainMeter::gain_adjusted ()
        if (!ignore_toggle) {
                _io->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this);
        }
+       show_gain ();
 }
 
 void
@@ -562,7 +602,7 @@ GainMeter::effective_gain_display ()
        gfloat value = gain_to_slider_position (_io->effective_gain());
        
        if (gain_adjustment.get_value() != value) {
-               ignore_toggle = true;
+               ignore_toggle = true; 
                gain_adjustment.set_value (value);
                ignore_toggle = false;
        }
@@ -649,7 +689,13 @@ GainMeter::meter_press(GdkEventButton* ev)
 
                                        /* ctrl-shift-click applies change to all routes */
 
+                                       _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()));
+                                        cmd->mark();
+                                       _session.add_command (cmd);
+                                       _session.commit_reversible_command ();
+                                       
                                        
                                } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
 
@@ -658,12 +704,19 @@ GainMeter::meter_press(GdkEventButton* ev)
                                        */
                                        
                                        if (ev->button == 1) {
+                                               _session.begin_reversible_command (_("meter point change"));
+                                               Session::GlobalMeteringStateCommand *cmd = new Session::GlobalMeteringStateCommand (_session, this);
                                                set_mix_group_meter_point (*_route, next_meter_point (_route->meter_point()));
+                                               cmd->mark();
+                                               _session.add_command (cmd);
+                                               _session.commit_reversible_command ();
                                        }
                                        
                                } else {
                                        
-                                       /* click: solo this route */
+                                       /* click: change just this route */
+
+                                       // XXX no undo yet
                                        
                                        _route->set_meter_point (next_meter_point (_route->meter_point()), this);
                                }
index bbc12ccb6ce37567c906f2cb3747c8da14e003ef..88105ce846afdd99ede76101053e4523c93d52b3 100644 (file)
@@ -35,6 +35,7 @@
 #include <ardour/types.h>
 
 #include <gtkmm2ext/click_box.h>
+#include <gtkmm2ext/focus_entry.h>
 #include <gtkmm2ext/slider_controller.h>
 
 #include "enums.h"
@@ -79,14 +80,12 @@ class GainMeter : public Gtk::VBox
        ARDOUR::Session& _session;
 
        bool ignore_toggle;
+       bool next_release_selects;
 
        Gtkmm2ext::VSliderController *gain_slider;
        Gtk::Adjustment              gain_adjustment;
-       Gtk::Frame                   gain_display_frame;
-       Gtkmm2ext::ClickBox           gain_display;
-       Gtk::Frame                   peak_display_frame;
-       Gtk::EventBox                peak_display;
-       Gtk::Label                   peak_display_label;
+       Gtkmm2ext::FocusEntry        gain_display;
+       Gtk::Entry                   peak_display;
        Gtk::HBox                    gain_display_box;
        Gtk::HBox                    fader_box;
        Gtk::DrawingArea             meter_metric_area;
@@ -122,9 +121,10 @@ class GainMeter : public Gtk::VBox
 
        gint meter_metrics_expose (GdkEventExpose *);
 
-       static void _gain_printer (char buf[32], Gtk::Adjustment&, void *);
-       void gain_printer (char buf[32], Gtk::Adjustment&);
-       
+       void show_gain ();
+       void gain_activated ();
+       bool gain_focused (GdkEventFocus*);
+
        struct MeterInfo {
            Gtkmm2ext::FastMeter *meter;
            gint16          width;   
@@ -157,7 +157,8 @@ class GainMeter : public Gtk::VBox
        gint meter_button_press (GdkEventButton*, uint32_t);
        gint meter_button_release (GdkEventButton*, uint32_t);
 
-       gint peak_button_release (GdkEventButton*);
+       bool peak_button_release (GdkEventButton*);
+       bool gain_key_press (GdkEventKey*);
        
        Gtk::Menu* meter_menu;
        void popup_meter_menu (GdkEventButton*);
diff --git a/gtk2_ardour/icons/ardour_icon_16px.png b/gtk2_ardour/icons/ardour_icon_16px.png
new file mode 100644 (file)
index 0000000..7f21711
Binary files /dev/null and b/gtk2_ardour/icons/ardour_icon_16px.png differ
diff --git a/gtk2_ardour/icons/ardour_icon_22px.png b/gtk2_ardour/icons/ardour_icon_22px.png
new file mode 100644 (file)
index 0000000..bdf723e
Binary files /dev/null and b/gtk2_ardour/icons/ardour_icon_22px.png differ
diff --git a/gtk2_ardour/icons/ardour_icon_32px.png b/gtk2_ardour/icons/ardour_icon_32px.png
new file mode 100644 (file)
index 0000000..d906f35
Binary files /dev/null and b/gtk2_ardour/icons/ardour_icon_32px.png differ
diff --git a/gtk2_ardour/icons/ardour_icon_48px.png b/gtk2_ardour/icons/ardour_icon_48px.png
new file mode 100644 (file)
index 0000000..298a565
Binary files /dev/null and b/gtk2_ardour/icons/ardour_icon_48px.png differ
diff --git a/gtk2_ardour/icons/fader_belt.png b/gtk2_ardour/icons/fader_belt.png
new file mode 100644 (file)
index 0000000..eefed15
Binary files /dev/null and b/gtk2_ardour/icons/fader_belt.png differ
index 366e2c2769d708cc5ee882caca156e4bfd5c2873..00d24287ed193b0846963d37cf4266123f56bd9c 100644 (file)
@@ -458,7 +458,7 @@ IOSelector::display_ports ()
                        
                        really_short_name = port->short_name();
                        really_short_name = really_short_name.substr (really_short_name.find ('/') + 1);
-                       
+
                        tview = manage (new TreeView());
                        RefPtr<ListStore> port_model = ListStore::create (port_display_columns);
                        
@@ -478,7 +478,6 @@ IOSelector::display_ports ()
                        
                        /* now fill the clist with the current connections */
                        
-                       
                        const char **connections = port->get_connections ();
                        
                        if (connections) {
@@ -487,7 +486,7 @@ IOSelector::display_ports ()
                                        row[port_display_columns.displayed_name] = connections[c];
                                        row[port_display_columns.full_name] = connections[c];
                                }
-                       }
+                       } 
                        
                        if (for_input) {
                                
index 9465b12c23c34e4d3f1317905737df72f6314e8f..51fc20c457b85ac8f23a0be68382d2fc032f6cf7 100644 (file)
@@ -575,7 +575,7 @@ LadspaPluginUI::astate_clicked (ControlUI* cui, uint32_t port)
        items.push_back (MenuElem (_("Touch"),
                                   bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Touch, cui)));
 
-       automation_menu->popup (1, 0);
+       automation_menu->popup (1, gtk_get_current_event_time());
 }
 
 void
index 13dd95b47d4a74c4195383a1db00577c7fb70090..b77c3a55615447bc0aa30807b86fe906620c7d36 100644 (file)
@@ -48,11 +48,11 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
          item_table (1, 7, false),
          start_set_button (_("Set")),
          start_go_button (_("Go")),
-         start_clock (X_("LocationEditRowClock"), true),
+         start_clock (X_("locationstart"), true, X_("LocationEditRowClock"), true),
          end_set_button (_("Set")),
          end_go_button (_("Go")),
-         end_clock (X_("LocationEditRowClock"), true),
-         length_clock (X_("LocationEditRowClock"), true, true),
+         end_clock (X_("locationend"), true, X_("LocationEditRowClock"), true),
+         length_clock (X_("locationlength"), true, X_("LocationEditRowClock"), true, true),
          cd_check_button (_("CD")),
          hide_check_button (_("Hidden")),
          remove_button (_("Remove")),
@@ -215,7 +215,7 @@ LocationEditRow::set_location (Location *loc)
        }
        hide_check_button.set_active (location->is_hidden());
        
-       if (location->is_auto_loop() || location->is_auto_punch()) {
+       if (location->is_auto_loop() || location-> is_auto_punch()) {
                // use label instead of entry
 
                name_label.set_text (location->name());
@@ -574,7 +574,7 @@ LocationUI::LocationUI ()
        i_am_the_modifier = 0;
 
        set_title(_("ardour: locations"));
-       set_wmclass(_("ardour_locations"), "Ardour");
+       set_wmclass(X_("ardour_locations"), "Ardour");
 
        set_name ("LocationWindow");
 
@@ -770,9 +770,12 @@ LocationUI::map_locations (Locations::LocationList& locations)
 void
 LocationUI::add_new_location()
 {
+       string markername;
+
        if (session) {
                nframes_t where = session->audible_frame();
-               Location *location = new Location (where, where, "mark", Location::IsMark);
+               session->locations()->next_available_name(markername,"mark");
+               Location *location = new Location (where, where, markername, Location::IsMark);
                session->begin_reversible_command (_("add marker"));
                XMLNode &before = session->locations()->get_state();
                session->locations()->add (location, true);
@@ -786,10 +789,12 @@ LocationUI::add_new_location()
 void
 LocationUI::add_new_range()
 {
+       string rangename;
+
        if (session) {
                nframes_t where = session->audible_frame();
-               Location *location = new Location (where, where, "unnamed", 
-                                                                                       Location::IsRangeMarker);
+               session->locations()->next_available_name(rangename,"unnamed");
+               Location *location = new Location (where, where, rangename, Location::IsRangeMarker);
                session->begin_reversible_command (_("add range marker"));
                XMLNode &before = session->locations()->get_state();
                session->locations()->add (location, true);
index f7ed1dd2be2fc3f2580f34af9395712dd59fbee8..8d9f0b9d8278701ad86d9662efbbe23350a92a26 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __ardour_gtk_log_meter_h__
 #define __ardour_gtk_log_meter_h__
 
-#if 0
+#if 1
 inline float
 _log_meter (float power, double lower_db, double upper_db, double non_linearity)
 {
@@ -9,7 +9,7 @@ _log_meter (float power, double lower_db, double upper_db, double non_linearity)
 }
 
 inline float
-log_meter (float power)
+alt_log_meter (float power)
 {
        return _log_meter (power, -192.0, 0.0, 8.0);
 }
index a1d85cdb6976ed136c6126f82ba5c35d4d759f25..51a29bbb1727fddf6d963926793cbc90c6cd7689 100644 (file)
@@ -48,6 +48,7 @@
 #include "version.h"
 #include "ardour_ui.h"
 #include "opts.h"
+#include "enums.h"
 
 #include "i18n.h"
 
@@ -79,8 +80,6 @@ shutdown (int status)
        } else {
 
                if (ui) {
-                       msg = _("stopping user interface\n");
-                       write (1, msg, strlen (msg));
                        ui->kill();
                }
                
@@ -301,7 +300,7 @@ maybe_load_session ()
        if (!session_name.length()) {
                ui->hide_splash ();
                if (!Config->get_no_new_session_dialog()) {
-                      ui->new_session (true);
+                      ui->new_session ();
                }
 
                return true;
@@ -321,12 +320,16 @@ maybe_load_session ()
                        
                /* Loading a session, but the session doesn't exist */
                if (isnew) {
-                       error << string_compose (_("\n\nNo session named \"%1\" exists.\n\
-To create it from the command line, start ardour as \"ardour --new %1"), path) << endmsg;
+                       error << string_compose (_("\n\nNo session named \"%1\" exists.\n"
+                                                  "To create it from the command line, start ardour as \"ardour --new %1"), path) 
+                             << endmsg;
                        return false;
                }
 
-               ui->load_session (path, name);
+               if (ui->load_session (path, name)) {
+                       /* it failed */
+                       return false;
+               }
 
        } else {
 
@@ -338,7 +341,7 @@ To create it from the command line, start ardour as \"ardour --new %1"), path) <
                /* Show the NSD */
                ui->hide_splash ();
                if (!Config->get_no_new_session_dialog()) {
-                      ui->new_session (true);
+                      ui->new_session ();
                }
        }
 
@@ -360,14 +363,15 @@ int main (int argc, char *argv[])
        ARDOUR::AudioEngine *engine;
        vector<Glib::ustring> null_file_list;
 
+        Glib::thread_init();
        gtk_set_locale ();
 
-       (void)   bindtextdomain (PACKAGE, LOCALEDIR);
+       (void) bindtextdomain (PACKAGE, LOCALEDIR);
        (void) textdomain (PACKAGE);
 
        pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
 
-       // catch_signals ();
+       // catch error message system signals ();
 
        text_receiver.listen_to (error);
        text_receiver.listen_to (info);
@@ -407,9 +411,6 @@ int main (int argc, char *argv[])
                     << endl;
        }
 
-       // needs a better home.
-        Glib::thread_init();
-
         try { 
                ui = new ARDOUR_UI (&argc, &argv, which_ui_rcfile());
        } catch (failed_constructor& err) {
@@ -417,6 +418,9 @@ int main (int argc, char *argv[])
                exit (1);
        }
 
+       if (!keybindings_path.empty()) {
+               ui->set_keybindings_path (keybindings_path);
+       }
 
        if (!no_splash) {
                ui->show_splash ();
@@ -425,25 +429,27 @@ int main (int argc, char *argv[])
                }
        }
 
-
-    try { 
-               engine = new ARDOUR::AudioEngine (jack_client_name);
-       } catch (AudioEngine::NoBackendAvailable& err) {
-               gui_jack_error ();
-               error << string_compose (_("Could not connect to JACK server as  \"%1\""), jack_client_name) <<  endmsg;
-               return -1;
-       }
-
     try {
                ARDOUR::init (*engine, use_vst, try_hw_optimization);
+               setup_gtk_ardour_enums ();
                Config->set_current_owner (ConfigVariableBase::Interface);
+
+               try { 
+                       engine = new ARDOUR::AudioEngine (jack_client_name);
+               } catch (AudioEngine::NoBackendAvailable& err) {
+                       gui_jack_error ();
+                       error << string_compose (_("Could not connect to JACK server as  \"%1\""), jack_client_name) <<  endmsg;
+                       return -1;
+               }
+               
                ui->set_engine (*engine);
+
        } catch (failed_constructor& err) {
                error << _("could not initialize Ardour.") << endmsg;
                return -1;
        } 
 
+       ui->start_engine ();
 
        if (maybe_load_session ()) {
                ui->run (text_receiver);
index b871561563209a19bc93c7e9046c72fd3e7ed58c..0e88eff5e06ed660aa6833a1f6e274b4af3b1998 100644 (file)
@@ -76,7 +76,7 @@ MeterBridge::MeterBridge ()
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
        set_name ("MeterBridgeWindow");
        set_title (_("ardour: meter bridge"));
-       set_wmclass (_("ardour_meter_bridge"), "Ardour");
+       set_wmclass (X_("ardour_meter_bridge"), "Ardour");
        // set_policy (false, false, false); // no user resizing of any kind
 
        signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), static_cast<Gtk::Window*>(this)));
index 289fb4553678e30f51a5575674111a6e7862a83c..edc66c92bbf677e5299ea21bd5c8be53e5732884 100644 (file)
@@ -233,15 +233,17 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt
        global_vpacker.set_border_width (0);
        global_vpacker.set_spacing (0);
 
-       Gtk::VBox *whvbox = manage (new Gtk::VBox);
+       VBox *whvbox = manage (new VBox);
 
        width_button.set_name ("MixerWidthButton");
        hide_button.set_name ("MixerHideButton");
+       top_event_box.set_name ("MixerTopEventBox");
 
        width_button.signal_clicked().connect (mem_fun(*this, &MixerStrip::width_clicked));
        hide_button.signal_clicked().connect (mem_fun(*this, &MixerStrip::hide_clicked));
 
        width_hide_box.pack_start (width_button, false, true);
+       width_hide_box.pack_start (top_event_box, true, true);
        width_hide_box.pack_end (hide_button, false, true);
        Gtk::Alignment *gain_meter_alignment = Gtk::manage(new Gtk::Alignment());
        gain_meter_alignment->set_padding(0, 4, 0, 0);
@@ -425,8 +427,8 @@ MixerStrip::set_width (Width w)
                if (rec_enable_button) {
                        rec_enable_button->set_label (_("record"));
                }
-               mute_button->set_label  (_("mute"));
-               solo_button->set_label (_("solo"));
+               mute_button->set_label  (_("Mute"));
+               solo_button->set_label (_("Solo"));
 
                if (_route->comment() == "") {
                       comment_button.unset_bg (STATE_NORMAL);
@@ -962,6 +964,7 @@ void
 MixerStrip::show_route_color ()
 {
        name_button.modify_bg (STATE_NORMAL, color());
+       top_event_box.modify_bg (STATE_NORMAL, color());
        route_active_changed ();
 }
 
index 92da4c13fe74aa39054e4c0d7ea0bc91ab1865fd..430f774eb6f68abe1845c53dd98748e3abd18ef1 100644 (file)
@@ -111,6 +111,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
        Gtk::Button         hide_button;
        Gtk::Button         width_button;
        Gtk::HBox           width_hide_box;
+       Gtk::EventBox       top_event_box;
 
        void hide_clicked();
        void width_clicked ();
index d8e5fc6988857999661458601d282ee2e1ba48bc..f20171f9fba1553a55712dab0f841ad65dd464e5 100644 (file)
@@ -81,7 +81,7 @@ Mixer_UI::Mixer_UI (AudioEngine& eng)
        track_model = ListStore::create (track_columns);
        track_display.set_model (track_model);
        track_display.append_column (_("Strips"), track_columns.text);
-       track_display.append_column (_("Visible"), track_columns.visible);
+       track_display.append_column (_("Show"), track_columns.visible);
        track_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
        track_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
        track_display.get_column (0)->set_expand(true);
@@ -107,7 +107,7 @@ Mixer_UI::Mixer_UI (AudioEngine& eng)
        group_display.set_model (group_model);
        group_display.append_column (_("Group"), group_columns.text);
        group_display.append_column (_("Active"), group_columns.active);
-       group_display.append_column (_("Visible"), group_columns.visible);
+       group_display.append_column (_("Show"), group_columns.visible);
        group_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
        group_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
        group_display.get_column (2)->set_data (X_("colnum"), GUINT_TO_POINTER(2));
@@ -199,15 +199,12 @@ Mixer_UI::Mixer_UI (AudioEngine& eng)
        rhs_pane1.set_data ("collapse-direction", (gpointer) 0);
        list_hpane.set_data ("collapse-direction", (gpointer) 1);
 
-       rhs_pane1.signal_button_release_event().connect (bind (sigc::ptr_fun (pane_handler), static_cast<Paned*>(&rhs_pane1)));
-       list_hpane.signal_button_release_event().connect (bind (sigc::ptr_fun (pane_handler), static_cast<Paned*>(&list_hpane)));
-       
        global_vpacker.pack_start (list_hpane, true, true);
 
        add (global_vpacker);
        set_name ("MixerWindow");
        set_title (_("ardour: mixer"));
-       set_wmclass (_("ardour_mixer"), "Ardour");
+       set_wmclass (X_("ardour_mixer"), "Ardour");
 
        add_accel_group (ActionManager::ui_manager->get_accel_group());
 
@@ -656,7 +653,7 @@ Mixer_UI::show_track_list_menu ()
                build_track_menu ();
        }
 
-       track_menu->popup (1, 0);
+       track_menu->popup (1, gtk_get_current_event_time());
 }
 
 bool
@@ -765,7 +762,7 @@ Mixer_UI::group_display_button_press (GdkEventButton* ev)
                if (mix_group_context_menu == 0) {
                        build_mix_group_context_menu ();
                }
-               mix_group_context_menu->popup (1, 0);
+               mix_group_context_menu->popup (1, ev->time);
                return true;
        }
 
index 4c486eaaf818c37253f1fb35dbd469f1edceba0c..9e094c9ad041d08019a511cd80d4ad07412539ef 100644 (file)
@@ -357,17 +357,29 @@ NewSessionDialog::NewSessionDialog()
        m_treeview->get_selection()->set_mode (Gtk::SELECTION_SINGLE);
 
        std::string path = ARDOUR::get_user_ardour_path();
+       
        if (path.empty()) {
                path = ARDOUR::get_system_data_path();
        }
+
+       const char * const template_dir_name = X_("templates");
+
        if (!path.empty()) {
-               m_template->set_current_folder (path + X_("templates/"));
+               string user_template_path = path + template_dir_name;
+
+               if (Glib::file_test(user_template_path, Glib::FILE_TEST_IS_DIR))
+               {
+                       m_template->set_current_folder (user_template_path);
+               }
        }
 
-       const std::string sys_templates_dir = ARDOUR::get_system_data_path() + X_("templates");
+       const std::string sys_templates_dir = ARDOUR::get_system_data_path() + template_dir_name;
+       
        if (Glib::file_test(sys_templates_dir, Glib::FILE_TEST_IS_DIR))
+       {
                m_template->add_shortcut_folder(sys_templates_dir);
-       
+       }
+
        m_template->set_title(_("select template"));
        Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
        session_filter->add_pattern(X_("*.ardour"));
index 3e461a85d7b475cad4ecaa169801d5c3cc8abff9..1c76f8079b5193496b15b751374c7a05191acea2 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <pbd/whitespace.h>
 
-#include <ardour/audio_library.h>
 #include <ardour/session.h>
 #include <ardour/audioengine.h>
 #include <ardour/configuration.h>
@@ -60,7 +59,6 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
 
          /* Paths */
          path_table (11, 2),
-         sfdb_path_view(),
 
          /* Fades */
 
@@ -71,7 +69,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
 
          /* Sync */
 
-         smpte_offset_clock (X_("SMPTEOffsetClock"), true, true),
+         smpte_offset_clock (X_("smpteoffset"), false, X_("SMPTEOffsetClock"), true, true),
          smpte_offset_negative_button (_("SMPTE offset is negative")),
 
          /* MIDI */
@@ -99,7 +97,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
 
        set_default_size (300, 300);
        set_title (_("ardour: options editor"));
-       set_wmclass (_("ardour_option_editor"), "Ardour");
+       set_wmclass (X_("ardour_option_editor"), "Ardour");
 
        set_name ("OptionsWindow");
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
@@ -224,23 +222,9 @@ OptionEditor::setup_path_options()
        path_table.attach (*label, 0, 1, 0, 1, FILL|EXPAND, FILL);
        path_table.attach (session_raid_entry, 1, 3, 0, 1, Gtk::FILL|Gtk::EXPAND, FILL);
 
-       label = manage(new Label(_("Soundfile Search Paths")));
-       label->set_name("OptionsLabel");
-       path_table.attach(*label, 0, 1, 2, 3, FILL|EXPAND, FILL);
-       path_table.attach(sfdb_path_view, 1, 3, 2, 3, Gtk::FILL|Gtk::EXPAND, FILL);
-
-       sfdb_path_view.set_paths(Library->get_paths());
-       sfdb_path_view.PathsUpdated.connect (mem_fun(*this, &OptionEditor::sfdb_paths_changed));
-
        path_table.show_all();
 }
 
-void
-OptionEditor::sfdb_paths_changed ()
-{
-       Library->set_paths (sfdb_path_view.get_paths());
-}
-
 void
 OptionEditor::add_session_paths ()
 {
@@ -549,7 +533,7 @@ void
 OptionEditor::port_online_toggled (MIDI::Port* port, ToggleButton* tb)
 {
        bool wanted = tb->get_active();
-       
+
        if (wanted != port->input()->offline()) {
                port->input()->set_offline (wanted);
        } 
@@ -558,12 +542,16 @@ OptionEditor::port_online_toggled (MIDI::Port* port, ToggleButton* tb)
 void
 OptionEditor::map_port_online (MIDI::Port* port, ToggleButton* tb)
 {
-       if (port->input()->offline()) {
-               tb->set_label (_("offline"));
-               tb->set_active (false);
-       } else {
-               tb->set_label (_("online"));
-               tb->set_active (true);
+       bool bstate = tb->get_active ();
+
+       if (bstate != port->input()->offline()) {
+               if (port->input()->offline()) {
+                       tb->set_label (_("offline"));
+                       tb->set_active (false);
+               } else {
+                       tb->set_label (_("online"));
+                       tb->set_active (true);
+               }
        }
 }
 
@@ -659,19 +647,12 @@ OptionEditor::click_sound_changed ()
                        return;
                }
 
-               if (path.empty()) {
+               strip_whitespace_edges (path);
 
+               if (path == _("internal")) {
                        Config->set_click_sound ("");
-
                } else {
-
-                       strip_whitespace_edges (path);
-                       
-                       if (path == _("internal")) {
-                               Config->set_click_sound ("");
-                       } else {
-                               Config->set_click_sound (path);
-                       }
+                       Config->set_click_sound (path);
                }
        }
 }
@@ -686,19 +667,12 @@ OptionEditor::click_emphasis_sound_changed ()
                        return;
                }
 
-               if (path.empty()) {
+               strip_whitespace_edges (path);
 
+               if (path == _("internal")) {
                        Config->set_click_emphasis_sound ("");
-
                } else {
-
-                       strip_whitespace_edges (path);
-
-                       if (path == _("internal")) {
-                               Config->set_click_emphasis_sound ("");
-                       } else {
-                               Config->set_click_emphasis_sound (path);
-                       }
+                       Config->set_click_emphasis_sound (path);
                }
        }
 }
index 2076da3935b737db2e8d96b759876ddab1b84482..cc28a74e603620e5e0b292b2e91338ab8a8726f7 100644 (file)
@@ -33,8 +33,6 @@
 #include <gtkmm/radiobutton.h>
 #include <gtkmm/comboboxtext.h>
 
-#include <gtkmm2ext/pathlist.h>
-
 #include <ardour/session.h>
 
 #include "ardour_dialog.h"
@@ -75,13 +73,10 @@ class OptionEditor : public Gtk::Dialog
        Gtk::Table      path_table;
        Gtk::Entry      session_raid_entry;
 
-       Gtkmm2ext::PathList sfdb_path_view;
-
        void setup_path_options();
        void add_session_paths ();
        void remove_session_paths ();
        void raid_path_changed ();
-       void sfdb_paths_changed ();
 
        /* fades */
 
index fcd62de51280404b6b76e03cdd99f472d24202f1..792fde3a10a6df60edddc3ae21d7783f88c09042 100644 (file)
@@ -37,6 +37,7 @@ bool GTK_ARDOUR::use_vst = true;
 bool GTK_ARDOUR::new_session = false;
 char* GTK_ARDOUR::curvetest_file = 0;
 bool GTK_ARDOUR::try_hw_optimization = true;
+string GTK_ARDOUR::keybindings_path = ""; /* empty means use builtin default */
 
 using namespace GTK_ARDOUR;
 
@@ -50,13 +51,13 @@ print_help (const char *execname)
             << _("  -n, --show-splash                Show splash screen\n")
             << _("  -c, --name  name                 Use a specific jack client name, default is ardour\n")
             << _("  -N, --new session-name           Create a new session from the command line\n")                       
-            << _("  -o, --use-hw-optimizations        Try to use h/w specific optimizations\n")
+            << _("  -O, --no-hw-optimizations        Disable h/w specific optimizations\n")
 #ifdef VST_SUPPORT
             << _("  -V, --novst                      Do not use VST support\n")
 #endif
             << _("  [session-name]                   Name of session to load\n")
             << _("  -C, --curvetest filename         Curve algorithm debugger\n")
-            << _("  -g, --gtktheme                   Allow GTK to load a theme\n")
+            << _("  -k, --keybindings filename       Name of key bindings to load (default is ~/.ardour2/ardour.bindings)\n")
                ;
        return 1;
 
@@ -66,7 +67,7 @@ int
 GTK_ARDOUR::parse_opts (int argc, char *argv[])
 
 {
-       const char *optstring = "U:hbvVnoc:C:N:g";
+       const char *optstring = "U:hbvVnOc:C:N:k:";
        const char *execname = strrchr (argv[0], '/');
 
        if (execname == 0) {
@@ -85,7 +86,6 @@ GTK_ARDOUR::parse_opts (int argc, char *argv[])
                { "new", 1, 0, 'N' },
                { "no-hw-optimizations", 0, 0, 'O' },
                { "curvetest", 1, 0, 'C' },
-               { "gtktheme", 0, 0, 'g' },
                { 0, 0, 0, 0 }
        };
 
@@ -142,6 +142,10 @@ GTK_ARDOUR::parse_opts (int argc, char *argv[])
                        curvetest_file = optarg;
                        break;
 
+               case 'k':
+                       keybindings_path = optarg;
+                       break;
+
                default:
                        return print_help(execname);
                }
index 0516c3aa98c11543b292ee23523dbe1ca589243d..710621ac6526d4888ac5b5eb4a064a43fc097fc8 100644 (file)
@@ -37,6 +37,7 @@ extern bool   new_session;
 extern char*  curvetest_file;
 extern bool   try_hw_optimization;
 extern bool   use_gtk_theme;
+extern string keybindings_path;
 
 extern int32_t parse_opts (int argc, char *argv[]);
 
diff --git a/gtk2_ardour/panner.cc b/gtk2_ardour/panner.cc
new file mode 100644 (file)
index 0000000..bb9b432
--- /dev/null
@@ -0,0 +1,104 @@
+#include <iostream>
+
+#include "panner.h"
+
+using namespace std;
+
+static const int triangle_size = 5;
+
+static void
+null_label_callback (char* buf, unsigned int bufsize)
+{
+       /* no label */
+
+       buf[0] = '\0';
+}
+
+
+PannerBar::PannerBar (Gtk::Adjustment& adj, PBD::Controllable& c)
+       : BarController (adj, c, sigc::ptr_fun (null_label_callback))
+{
+       set_style (BarController::Line);
+}
+
+PannerBar::~PannerBar ()
+{
+}
+
+bool
+PannerBar::expose (GdkEventExpose* ev)
+{
+       Glib::RefPtr<Gdk::Window> win (darea.get_window());
+       Glib::RefPtr<Gdk::GC> gc (get_style()->get_base_gc (get_state()));
+
+       BarController::expose (ev);
+
+       /* now draw triangles for left, right and center */
+
+       GdkPoint points[3];
+
+       // left
+       
+       points[0].x = 0;
+       points[0].y = 0;
+
+       points[1].x = triangle_size;
+       points[1].y = 0;
+       
+       points[2].x = 0;
+       points[2].y = triangle_size;
+
+       gdk_draw_polygon (win->gobj(), gc->gobj(), true, points, 3);
+
+       // center
+
+       points[0].x = (darea.get_width()/2 - triangle_size);
+       points[0].y = 0;
+
+       points[1].x = (darea.get_width()/2 + triangle_size) - 1;
+       points[1].y = 0;
+       
+       points[2].x = darea.get_width()/2 - 1;
+       points[2].y = triangle_size - 1;
+
+       gdk_draw_polygon (win->gobj(), gc->gobj(), true, points, 3); 
+
+       // right
+
+       points[0].x = (darea.get_width() - triangle_size) - 1;
+       points[0].y = 0;
+
+       points[1].x = darea.get_width() - 1;
+       points[1].y = 0;
+       
+       points[2].x = darea.get_width() - 1;
+       points[2].y = triangle_size;
+
+       gdk_draw_polygon (win->gobj(), gc->gobj(), true, points, 3);
+
+       return true;
+}
+
+bool
+PannerBar::button_press (GdkEventButton* ev)
+{
+       if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS && ev->y < 10) {
+               if (ev->x < triangle_size) {
+                       adjustment.set_value (adjustment.get_lower());
+               } else if (ev->x > (darea.get_width() - triangle_size)) {
+                       adjustment.set_value (adjustment.get_upper());
+               } else if (ev->x > (darea.get_width()/2 - triangle_size) &&
+                          ev->x < (darea.get_width()/2 + triangle_size)) {
+                       adjustment.set_value (adjustment.get_lower() + ((adjustment.get_upper() - adjustment.get_lower()) / 2.0));
+               }
+       }
+
+       return BarController::button_press (ev);
+}
+
+bool
+PannerBar::button_release (GdkEventButton* ev)
+{
+       return BarController::button_release (ev);
+}
+
diff --git a/gtk2_ardour/panner.h b/gtk2_ardour/panner.h
new file mode 100644 (file)
index 0000000..d06a4c2
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __gtk_ardour_panner_h__
+#define __gtk_ardour_panner_h__
+
+#include <gtkmm2ext/barcontroller.h>
+
+class PannerBar : public Gtkmm2ext::BarController
+{
+  public:
+       PannerBar (Gtk::Adjustment& adj, PBD::Controllable&);
+       ~PannerBar ();
+
+  protected:
+       bool expose (GdkEventExpose*);
+       bool button_press (GdkEventButton*);
+       bool button_release (GdkEventButton*);
+};
+
+#endif /* __gtk_ardour_panner_h__ */
index 1fb94a1321130a292b9af83766052eedf3c6111b..1e6e4c16c943497925d5c2a9b047a6b745c25b99 100644 (file)
@@ -593,7 +593,7 @@ Panner2d::show_context_menu ()
        } 
 
        bypass_menu_item->set_active (panner.bypassed());
-       context_menu->popup (1, 0);
+       context_menu->popup (1, gtk_get_current_event_time());
 }
 
 void
index 250f1e146e894e58ca618aabf7bccd319c64d1d3..af5379b40f9cf35f0498e3c8e0ec8dfd6b66118c 100644 (file)
@@ -30,6 +30,7 @@
 #include "panner_ui.h"
 #include "panner2d.h"
 #include "utils.h"
+#include "panner.h"
 #include "gui_thread.h"
 
 #include <ardour/session.h>
@@ -44,6 +45,7 @@ using namespace Gtkmm2ext;
 using namespace Gtk;
 using namespace sigc;
 
+const int PannerUI::pan_bar_height = 30;
 
 PannerUI::PannerUI (boost::shared_ptr<IO> io, Session& s)
        : _io (io),
@@ -71,7 +73,7 @@ PannerUI::PannerUI (boost::shared_ptr<IO> io, Session& s)
        //set_size_request_to_display_given_text (pan_automation_style_button, X_("0"), 2, 2);
 
        pan_bar_packer.set_size_request (-1, 61);
-       panning_viewport.set_size_request (61, 61);
+       panning_viewport.set_size_request (64, 61);
 
        panning_viewport.set_name (X_("BaseFrame"));
 
@@ -131,7 +133,7 @@ PannerUI::PannerUI (boost::shared_ptr<IO> io, Session& s)
        panning_up_arrow.set_name (X_("PanScrollerArrow"));
        panning_down_arrow.set_name (X_("PanScrollerArrow"));
 
-       pan_vbox.set_spacing (4);
+       pan_vbox.set_spacing (2);
        pan_vbox.pack_start (panning_viewport, Gtk::PACK_SHRINK);
        pan_vbox.pack_start (panning_link_box, Gtk::PACK_SHRINK);
 
@@ -213,22 +215,22 @@ PannerUI::set_width (Width w)
 {
        switch (w) {
        case Wide:
-               panning_viewport.set_size_request (61, 61);
+               panning_viewport.set_size_request (64, 61);
                if (panner) {
-                       panner->set_size_request (61, 61);
+                       panner->set_size_request (63, 61);
                }
-               for (vector<BarController*>::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) {
-                               (*i)->set_size_request (61, 15);
+               for (vector<PannerBar*>::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) {
+                       (*i)->set_size_request (63, pan_bar_height);
                }
                panning_link_button.set_label (_("link"));
                break;
        case Narrow:
-               panning_viewport.set_size_request (31, 61);
+               panning_viewport.set_size_request (34, 61);
                if (panner) {
-                       panner->set_size_request (31, 61);
+                       panner->set_size_request (33, 61);
                }
-               for (vector<BarController*>::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) {
-                               (*i)->set_size_request (31, 15);
+               for (vector<PannerBar*>::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) {
+                       (*i)->set_size_request (33, pan_bar_height);
                }
                panning_link_button.set_label (_("L"));
                break;
@@ -244,7 +246,7 @@ PannerUI::~PannerUI ()
                delete (*i);
        }
        
-       for (vector<BarController*>::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) {
+       for (vector<PannerBar*>::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) {
                delete (*i);
        }
 
@@ -301,25 +303,36 @@ PannerUI::setup_pan ()
 
                while ((asz = pan_adjustments.size()) < npans) {
 
-                       float x;
-                       BarController* bc;
+                       float x, rx;
+                       PannerBar* bc;
 
-                       /* initialize adjustment with current value of panner */
+                       /* initialize adjustment with 0.0 (L) or 1.0 (R) for the first and second panners,
+                          which serves as a default, otherwise use current value */
 
-                       _io->panner()[asz]->get_position (x);
+                       _io->panner()[asz]->get_position (rx);
+
+                       if (npans == 1) {
+                               x = 0.5;
+                       } else if (asz == 0) {
+                               x = 0.0;
+                       } else if (asz == 1) {
+                               x = 1.0;
+                       } else {
+                               x = rx;
+                       }
 
                        pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.05, 0.1));
+                       bc = new PannerBar (*pan_adjustments[asz], _io->panner()[asz]->control());
+
+                       /* now set adjustment with current value of panner, then connect the signals */
+                       pan_adjustments.back()->set_value(rx);
                        pan_adjustments.back()->signal_value_changed().connect (bind (mem_fun(*this, &PannerUI::pan_adjustment_changed), (uint32_t) asz));
 
                        _io->panner()[asz]->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz));
 
-                       bc = new BarController (*pan_adjustments[asz], 
-                                               _io->panner()[asz]->control(),
-                                               bind (mem_fun(*this, &PannerUI::pan_printer), pan_adjustments[asz]));
                        
                        bc->set_name ("PanSlider");
                        bc->set_shadow_type (Gtk::SHADOW_NONE);
-                       bc->set_style (BarController::Line);
 
                        bc->StartGesture.connect (bind (mem_fun (*_io, &IO::start_pan_touch), (uint32_t) asz));
                        bc->StopGesture.connect (bind (mem_fun (*_io, &IO::end_pan_touch), (uint32_t) asz));
@@ -334,14 +347,14 @@ PannerUI::setup_pan ()
                        pan_bars.push_back (bc);
                        switch (_width) {
                        case Wide:
-                               pan_bars.back()->set_size_request (61, 15);
+                               bc->set_size_request (63, pan_bar_height);
                                break;
                        case Narrow:
-                               pan_bars.back()->set_size_request (31, 15);
+                               bc->set_size_request (33, pan_bar_height);
                                break;
                        }
 
-                       pan_bar_packer.pack_start (*pan_bars.back(), false, false);
+                       pan_bar_packer.pack_start (*bc, false, false);
                }
 
                /* now that we actually have the pan bars,
@@ -361,10 +374,10 @@ PannerUI::setup_pan ()
 
                switch (_width) {
                case Wide:
-                       w = 61;
+                       w = 63;
                        break;
                case Narrow:
-                       w = 31;
+                       w = 33;
                        break;
                }
 
@@ -631,7 +644,7 @@ PannerUI::update_pan_sensitive ()
        case 1:
                break;
        case 2:
-               for (vector<BarController*>::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) {
+               for (vector<PannerBar*>::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) {
                        (*i)->set_sensitive (sensitive);
                }
                break;
index 76589782331ea7e4f53ff063291ae765e2117f93..79a8085488da10231c0a0322073588ca4e3da1fa 100644 (file)
@@ -37,6 +37,7 @@
 #include "enums.h"
 
 class Panner2d;
+class PannerBar;
 
 namespace ARDOUR {
        class IO;
@@ -44,7 +45,6 @@ namespace ARDOUR {
 }
 namespace Gtkmm2ext {
        class FastMeter;
-       class BarController;
 }
 
 namespace Gtk {
@@ -78,6 +78,8 @@ class PannerUI : public Gtk::HBox
        bool ignore_toggle;
        bool in_pan_update;
 
+       static const int pan_bar_height;
+
        Panner2d*   panner;
 
        Gtk::VBox           pan_bar_packer;
@@ -107,7 +109,7 @@ class PannerUI : public Gtk::HBox
        void panning_link_direction_clicked ();
 
        vector<Gtk::Adjustment*> pan_adjustments;
-       vector<Gtkmm2ext::BarController*> pan_bars;
+       vector<PannerBar*> pan_bars;
 
        void pan_adjustment_changed (uint32_t which);
        void pan_value_changed (uint32_t which);
index c532d3551afc96c02bc8163adaa81cd90a5c7fd4..194031c44f23e284b51c4f1ebba504b30902ae46 100644 (file)
@@ -5,6 +5,6 @@ import glob
 pixmap_files = glob.glob('*.xpm')
 
 Import('env install_prefix')
-env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour/pixmaps'), pixmap_files))
+env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour', 'pixmaps'), pixmap_files))
 
 env.Alias('tarball', env.Distribute(env['DISTTREE'], [ 'SConscript' ] + pixmap_files))
index af0031fec9520def84559496ee491770dc1c60bc..813f8a92111a5484ba7220d19e388d297b50ffe5 100644 (file)
@@ -2,11 +2,12 @@
 #define __ardour_gtk_playlist_selection_h__
 
 #include <list>
+#include <boost/shared_ptr.hpp>
 
 namespace ARDOUR {
        class Playlist;
 }
 
-struct PlaylistSelection : list<ARDOUR::Playlist*> {};
+struct PlaylistSelection : list<boost::shared_ptr<ARDOUR::Playlist> > {};
 
 #endif /* __ardour_gtk_playlist_selection_h__ */
index ffeaf8f5e9b8e227e5a32d71c5e61baa1af1c84d..d02c5a88de7d941f57634e38927e136004e0504e 100644 (file)
@@ -61,9 +61,8 @@ PlaylistSelector::PlaylistSelector ()
        scroller.add (tree);
        scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
 
-       // GTK2FIX do we need this stuff or is GTK applying some policy now?
-       //set_border_width (6);
-       // set_spacing (12);
+       get_vbox()->set_border_width (6);
+       get_vbox()->set_spacing (12);
 
        get_vbox()->pack_start (scroller);
 
@@ -86,6 +85,17 @@ PlaylistSelector::clear_map ()
        dspl_map.clear ();
 }
 
+bool
+PlaylistSelector::on_unmap_event (GdkEventAny* ev)
+{
+       cerr << "PLselector unmapped\n";
+       clear_map ();
+       if (model) {
+               model->clear ();
+       }
+       return Dialog::on_unmap_event (ev);
+}
+
 void
 PlaylistSelector::show_for (RouteUI* ruix)
 {
@@ -112,7 +122,8 @@ PlaylistSelector::show_for (RouteUI* ruix)
        TreeModel::Row others = *(model->append ());
 
        others[columns.text] = _("Other tracks");
-       others[columns.playlist] = 0;
+       boost::shared_ptr<Playlist> proxy = others[columns.playlist];
+       proxy.reset ();
        
        for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
 
@@ -139,18 +150,20 @@ PlaylistSelector::show_for (RouteUI* ruix)
                if (ds == this_ds) {
                        row = *(model->prepend());
                        row[columns.text] = nodename;
-                       row[columns.playlist] = 0;
+                       boost::shared_ptr<Playlist> proxy = row[columns.playlist];
+                       proxy.reset ();
                } else {
                        row = *(model->append (others.children()));
                        row[columns.text] = nodename;
-                       row[columns.playlist] = 0;
+                       boost::shared_ptr<Playlist> proxy = row[columns.playlist];
+                       proxy.reset ();
                }
 
                /* Now insert all the playlists for this diskstream/track in a subtree */
                
-               list<Playlist*> *pls = x->second;
+               list<boost::shared_ptr<Playlist> > *pls = x->second;
                
-               for (list<Playlist*>::iterator p = pls->begin(); p != pls->end(); ++p) {
+               for (list<boost::shared_ptr<Playlist> >::iterator p = pls->begin(); p != pls->end(); ++p) {
 
                        TreeModel::Row child_row;
 
@@ -173,15 +186,15 @@ PlaylistSelector::show_for (RouteUI* ruix)
 }
 
 void
-PlaylistSelector::add_playlist_to_map (Playlist *pl)
+PlaylistSelector::add_playlist_to_map (boost::shared_ptr<Playlist> pl)
 {
-       AudioPlaylist* apl;
+       boost::shared_ptr<AudioPlaylist> apl;
 
        if (pl->frozen()) {
                return;
        }
-
-       if ((apl = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
+       
+       if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
                return;
        }
 
@@ -189,7 +202,7 @@ PlaylistSelector::add_playlist_to_map (Playlist *pl)
 
        if ((x = dspl_map.find (apl->get_orig_diskstream_id())) == dspl_map.end()) {
 
-               pair<PBD::ID,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>);
+               pair<PBD::ID,list<boost::shared_ptr<Playlist> >*> newp (apl->get_orig_diskstream_id(), new list<boost::shared_ptr<Playlist> >);
                
                x = dspl_map.insert (dspl_map.end(), newp);
        }
@@ -219,7 +232,7 @@ PlaylistSelector::close_button_click ()
 void
 PlaylistSelector::selection_changed ()
 {
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
 
        TreeModel::iterator iter = tree.get_selection()->get_selected();
 
@@ -231,14 +244,14 @@ PlaylistSelector::selection_changed ()
        if ((playlist = ((*iter)[columns.playlist])) != 0) {
                
                AudioTrack* at;
-               AudioPlaylist* apl;
+               boost::shared_ptr<AudioPlaylist> apl;
                
                if ((at = rui->audio_track()) == 0) {
                        /* eh? */
                        return;
                }
                
-               if ((apl = dynamic_cast<AudioPlaylist*> (playlist)) == 0) {
+               if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (playlist)) == 0) {
                        /* eh? */
                        return;
                }
index 2829ba54bbc921550de08796cf67ad40e67e7e11..071f82c616b1906564f2e688f72314c218fc2d60 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __ardour_playlist_selector_h__
 #define __ardour_playlist_selector_h__
 
+#include <boost/shared_ptr.hpp>
+
 #include <gtkmm/box.h>
 #include <gtkmm/scrolledwindow.h>
 #include <gtkmm/button.h>
@@ -45,8 +47,11 @@ class PlaylistSelector : public ArdourDialog
        void set_session (ARDOUR::Session*);
        void show_for (RouteUI*);
 
+  protected:
+       bool on_unmap_event (GdkEventAny*);
+
   private:
-       typedef std::map<PBD::ID,std::list<ARDOUR::Playlist*>*> DSPL_Map;
+       typedef std::map<PBD::ID,std::list<boost::shared_ptr<ARDOUR::Playlist> >*> DSPL_Map;
 
        ARDOUR::Session* session;
        Gtk::ScrolledWindow scroller;
@@ -55,7 +60,7 @@ class PlaylistSelector : public ArdourDialog
 
        sigc::connection select_connection;
 
-       void add_playlist_to_map (ARDOUR::Playlist*);
+       void add_playlist_to_map (boost::shared_ptr<ARDOUR::Playlist>);
        void clear_map ();
        void close_button_click ();
        void selection_changed ();
@@ -66,7 +71,7 @@ class PlaylistSelector : public ArdourDialog
                    add (playlist);
            }
            Gtk::TreeModelColumn<std::string> text;
-           Gtk::TreeModelColumn<ARDOUR::Playlist*>   playlist;
+           Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Playlist> >   playlist;
        };
 
        ModelColumns columns;
index 56b9e34d35b5b19e48e9ecd575851369b51fb93b..26f38250a530a70cf64ee8b72e2441508e9d20e1 100644 (file)
@@ -102,6 +102,7 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr<PluginInsert> insert, bool scr
 
        set_position (Gtk::WIN_POS_MOUSE);
        set_name ("PluginEditor");
+       set_wmclass (X_("ardour_plugin_editor"), "Ardour");
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
 
        signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this)));
index edd8394611aaea5f234c9eafbfccde0d87c99341..f8ac19f833b6d92b970bc4b98d2cb6d29c3e392d 100644 (file)
@@ -7,289 +7,352 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gtk-ardour 0.347.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-06-27 13:00-0400\n"
-"PO-Revision-Date: 2003-05-11 17:36+0200\n"
-"Last-Translator: Karsten Petersen <kapet@kapet.de>\n"
+"POT-Creation-Date: 2006-11-24 00:48+0100\n"
+"PO-Revision-Date: 2006-12-04 13:34+0100\n"
+"Last-Translator: Sebastian Arnold <mail@sebastian-arnold.net>\n"
 "Language-Team: Deutsch <de@li.org>\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Generator: KBabel 0.9.6\n"
 
-#: about.cc:120
+#: gtk2_ardour/about.cc:121
 msgid "Paul Davis"
 msgstr ""
 
-#: about.cc:121
-#, fuzzy
+#: gtk2_ardour/about.cc:122
 msgid "Jesse Chappell"
-msgstr "bestmöglich"
+msgstr ""
 
-#: about.cc:122
+#: gtk2_ardour/about.cc:123
 msgid "Taybin Rutkin"
 msgstr ""
 
-#: about.cc:123
+#: gtk2_ardour/about.cc:124
 msgid "Marcus Andersson"
 msgstr ""
 
-#: about.cc:124
+#: gtk2_ardour/about.cc:125
 msgid "Jeremy Hall"
 msgstr ""
 
-#: about.cc:125
+#: gtk2_ardour/about.cc:126
 msgid "Steve Harris"
 msgstr ""
 
-#: about.cc:126
+#: gtk2_ardour/about.cc:127
 msgid "Tim Mayberry"
 msgstr ""
 
-#: about.cc:127
+#: gtk2_ardour/about.cc:128
 msgid "Mark Stewart"
 msgstr ""
 
-#: about.cc:128
+#: gtk2_ardour/about.cc:129
 msgid "Sam Chessman"
 msgstr ""
 
-#: about.cc:129
+#: gtk2_ardour/about.cc:130
 msgid "Jack O'Quin"
 msgstr ""
 
-#: about.cc:130
+#: gtk2_ardour/about.cc:131
 msgid "Matt Krai"
 msgstr ""
 
-#: about.cc:131
+#: gtk2_ardour/about.cc:132
 msgid "Ben Bell"
 msgstr ""
 
-#: about.cc:132
+#: gtk2_ardour/about.cc:133
 msgid "Gerard van Dongen"
 msgstr ""
 
-#: about.cc:133
+#: gtk2_ardour/about.cc:134
 msgid "Thomas Charbonnel"
 msgstr ""
 
-#: about.cc:134
+#: gtk2_ardour/about.cc:135
 msgid "Nick Mainsbridge"
 msgstr ""
 
-#: about.cc:135
+#: gtk2_ardour/about.cc:136
 msgid "Colin Law"
 msgstr ""
 
-#: about.cc:136
+#: gtk2_ardour/about.cc:137
 msgid "Sampo Savolainen"
 msgstr ""
 
-#: about.cc:137
+#: gtk2_ardour/about.cc:138
 msgid "Joshua Leach"
 msgstr ""
 
-#: about.cc:138
+#: gtk2_ardour/about.cc:139
 msgid "Rob Holland"
 msgstr ""
 
-#: about.cc:139
+#: gtk2_ardour/about.cc:140
 msgid "Per Sigmond"
 msgstr ""
 
-#: about.cc:140
+#: gtk2_ardour/about.cc:141
 msgid "Doug Mclain"
 msgstr ""
 
-#: about.cc:141
+#: gtk2_ardour/about.cc:142
 msgid "Petter Sundlöf"
 msgstr ""
 
-#: about.cc:146
+#: gtk2_ardour/about.cc:143
+msgid "Thorsten Wilms"
+msgstr ""
+
+#: gtk2_ardour/about.cc:144
+msgid "Ben Loftis"
+msgstr ""
+
+#: gtk2_ardour/about.cc:145
+msgid "Stefan Kersten"
+msgstr ""
+
+#: gtk2_ardour/about.cc:146
+msgid "Christopher George"
+msgstr ""
+
+#: gtk2_ardour/about.cc:147
+msgid "Robert Jordens"
+msgstr ""
+
+#: gtk2_ardour/about.cc:152
 msgid ""
 "French:\n"
 "\tAlain Fréhel <alain.frehel@free.fr>\n"
+"\tChristophe Combelles <ccomb@free.fr>\n"
 msgstr ""
 
-#: about.cc:147
+#: gtk2_ardour/about.cc:153
 msgid ""
 "German:\n"
 "\tKarsten Petersen <kapet@kapet.de>\n"
 msgstr ""
+"German:\n"
+"\tKarsten Petersen <kapet@kapet.de>\n"
+"\tSebastian Arnold <linux@sebastian-arnold.net>\n"
 
-#: about.cc:148
+#: gtk2_ardour/about.cc:154
 msgid ""
 "Italian:\n"
 "\tFilippo Pappalardo <filippo@email.it>\n"
 msgstr ""
 
-#: about.cc:149
+#: gtk2_ardour/about.cc:155
 msgid ""
 "Portuguese:\n"
 "\tRui Nuno Capela <rncbc@rncbc.org>\n"
 msgstr ""
 
-#: about.cc:150
+#: gtk2_ardour/about.cc:156
 msgid ""
 "Brazilian Portuguese:\n"
 "\tAlexander da Franca Fernandes <alexander@nautae.eti.br>\n"
 "\tChris Ross <chris@tebibyte.org>\n"
 msgstr ""
 
-#: about.cc:152
+#: gtk2_ardour/about.cc:158
 msgid ""
 "Spanish:\n"
 "\t Alex Krohn <alexkrohn@fastmail.fm>\n"
 msgstr ""
 
-#: about.cc:153
+#: gtk2_ardour/about.cc:159
 msgid ""
 "Russian:\n"
 "\t Igor Blinov <pitstop@nm.ru>\n"
 msgstr ""
 
-#: about.cc:181
-msgid "Copyright (C) 1999-2005 Paul Davis\n"
+#: gtk2_ardour/about.cc:187
+msgid "Copyright (C) 1999-2006 Paul Davis\n"
 msgstr ""
 
-#: about.cc:182
+#: gtk2_ardour/about.cc:188
 msgid ""
 "Ardour comes with ABSOLUTELY NO WARRANTY\n"
 "This is free software, and you are welcome to redistribute it\n"
 "under certain conditions; see the file COPYING for details.\n"
 msgstr ""
 
-#: about.cc:188
+#: gtk2_ardour/about.cc:193
+msgid "visit http://www.ardour.org/"
+msgstr ""
+
+#: gtk2_ardour/about.cc:194
 msgid ""
 "%1\n"
-"(built with ardour/gtk %2.%3.%4 libardour: %5.%6.%7)"
+"(built from revision %2)"
 msgstr ""
+"%1\n"
+"(built from revision %2)"
+
+#: gtk2_ardour/actions.cc:77
+msgid "badly formatted UI definition file"
+msgstr "die UI Definitionsdatei ist falsch formatiert"
+
+#: gtk2_ardour/actions.cc:79
+msgid "Ardour menu definition file not found"
+msgstr "Konnte die Ardour Menü-Definition nicht finden"
 
-#: actions.cc:261
+#: gtk2_ardour/actions.cc:83
+msgid "ardour will not work without a valid ardour.menus file"
+msgstr "Ardour benötigt eine gültige ardour.menus Datei"
+
+#: gtk2_ardour/actions.cc:235
 msgid "programmer error: %1 %2"
+msgstr "Programmierfehler: %1 %2"
+
+#: gtk2_ardour/actions.cc:254
+msgid "Unknown action name: %1"
+msgstr "Unbekannte Aktionsbezeichnung: %1"
+
+#: gtk2_ardour/add_route_dialog.cc:41
+#: gtk2_ardour/add_route_dialog.cc:196
+msgid "Mono"
+msgstr "Mono"
+
+#: gtk2_ardour/add_route_dialog.cc:42
+#: gtk2_ardour/add_route_dialog.cc:198
+msgid "Stereo"
+msgstr "Stereo"
+
+#: gtk2_ardour/add_route_dialog.cc:43
+msgid "3 Channels"
+msgstr "3 Kanäle"
+
+#: gtk2_ardour/add_route_dialog.cc:44
+msgid "4 Channels"
+msgstr "4 Kanäle"
+
+#: gtk2_ardour/add_route_dialog.cc:45
+msgid "6 Channels"
+msgstr "6 Kanäle"
+
+#: gtk2_ardour/add_route_dialog.cc:46
+msgid "8 Channels"
+msgstr "8 Kanäle"
+
+#: gtk2_ardour/add_route_dialog.cc:47
+msgid "Manual Setup"
+msgstr "Manuell"
+
+#: gtk2_ardour/add_route_dialog.cc:52
+#: gtk2_ardour/add_route_dialog.cc:177
+#: gtk2_ardour/editor.cc:126
+#: gtk2_ardour/editor.cc:3485
+#: gtk2_ardour/editor_actions.cc:286
+#: gtk2_ardour/time_axis_view.cc:586
+msgid "Normal"
+msgstr "Normal"
+
+#: gtk2_ardour/add_route_dialog.cc:53
+#: gtk2_ardour/add_route_dialog.cc:179
+msgid "Tape"
 msgstr ""
 
-#: add_route_dialog.cc:62
-#, fuzzy
+#: gtk2_ardour/add_route_dialog.cc:62
 msgid "ardour: add track/bus"
-msgstr "Ardour: Editor"
+msgstr "Ardour: Füge Spur/Bus hinzu"
 
-#. path = "1"
-#: add_route_dialog.cc:63 editor_route_list.cc:73
+#: gtk2_ardour/add_route_dialog.cc:63
+#: gtk2_ardour/editor_route_list.cc:71
 msgid "Tracks"
 msgstr "Spuren"
 
-#. path = "0"
-#: add_route_dialog.cc:64 editor_route_list.cc:70
+#: gtk2_ardour/add_route_dialog.cc:64
+#: gtk2_ardour/editor_route_list.cc:68
 msgid "Busses"
-msgstr ""
+msgstr "Busse"
 
-#: add_route_dialog.cc:96 plugin_ui.cc:833
+#: gtk2_ardour/add_route_dialog.cc:96
+#: gtk2_ardour/plugin_ui.cc:150
 msgid "Add"
 msgstr "Hinzufügen"
 
-#: add_route_dialog.cc:114
-#, fuzzy
+#: gtk2_ardour/add_route_dialog.cc:114
 msgid "Name (template)"
-msgstr "Name für Mixer-Voreinstellung"
+msgstr "Name für Mixer-Vorlage"
 
-#: add_route_dialog.cc:120
-#, fuzzy
+#: gtk2_ardour/add_route_dialog.cc:120
 msgid "Channel Configuration"
-msgstr "Importieren Abbrechen"
-
-#: add_route_dialog.cc:177 editor.cc:134 editor.cc:3688 time_axis_view.cc:552
-msgid "Normal"
-msgstr ""
-
-#: add_route_dialog.cc:179
-#, fuzzy
-msgid "Tape"
-msgstr "Anfang"
-
-#: add_route_dialog.cc:196
-msgid "Mono"
-msgstr ""
-
-#: add_route_dialog.cc:198
-#, fuzzy
-msgid "Stereo"
-msgstr "Stop"
+msgstr "Kanaleinstellungen"
 
-#. preroll stuff
-#: ardour_ui.cc:106
+#: gtk2_ardour/ardour_ui.cc:106
 msgid ""
 "pre\n"
 "roll"
 msgstr ""
 
-#: ardour_ui.cc:107
+#: gtk2_ardour/ardour_ui.cc:107
 msgid ""
 "post\n"
 "roll"
 msgstr ""
 
-#. transport
-#: ardour_ui.cc:115
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:115
 msgid ""
 "time\n"
 "master"
-msgstr "Ardour: Mixer"
+msgstr ""
+"Time\n"
+"Master"
 
-#: ardour_ui.cc:117
+#: gtk2_ardour/ardour_ui.cc:117
 msgid "% "
 msgstr ""
 
-#: ardour_ui.cc:119
-msgid ""
-"punch\n"
-"in"
-msgstr ""
+#: gtk2_ardour/ardour_ui.cc:119
+#: gtk2_ardour/ardour_ui_ed.cc:275
+msgid "Punch In"
+msgstr "Punch In"
 
-#: ardour_ui.cc:120
-msgid ""
-"punch\n"
-"out"
-msgstr ""
+#: gtk2_ardour/ardour_ui.cc:120
+#: gtk2_ardour/ardour_ui_ed.cc:278
+msgid "Punch Out"
+msgstr "Punch Out"
 
-#: ardour_ui.cc:121
-msgid ""
-"auto\n"
-"return"
-msgstr ""
+#: gtk2_ardour/ardour_ui.cc:121
+#: gtk2_ardour/ardour_ui_ed.cc:290
+msgid "Auto Return"
+msgstr "Auto Return"
 
-#: ardour_ui.cc:122
-msgid ""
-"auto\n"
-"play"
-msgstr ""
+#: gtk2_ardour/ardour_ui.cc:122
+msgid "Autuo Play"
+msgstr "Auto Play"
 
-#: ardour_ui.cc:123
-#, fuzzy
-msgid ""
-"auto\n"
-"input"
-msgstr "Port hinzufügen"
+#: gtk2_ardour/ardour_ui.cc:123
+#: gtk2_ardour/ardour_ui_ed.cc:284
+msgid "Auto Input"
+msgstr "Auto Input"
 
-#: ardour_ui.cc:124
-msgid "click"
-msgstr ""
+#: gtk2_ardour/ardour_ui.cc:124
+#: gtk2_ardour/ardour_ui_ed.cc:281
+#: gtk2_ardour/option_editor.cc:128
+msgid "Click"
+msgstr "Click"
 
-#: ardour_ui.cc:125
-msgid "AUDITIONING"
-msgstr ""
+#: gtk2_ardour/ardour_ui.cc:125
+msgid "AUDITION"
+msgstr "VORHÖREN"
 
-#: ardour_ui.cc:126
+#: gtk2_ardour/ardour_ui.cc:126
 msgid "SOLO"
-msgstr ""
+msgstr "SOLO"
 
-#: ardour_ui.cc:375
+#: gtk2_ardour/ardour_ui.cc:370
 msgid "quit"
-msgstr "Verlassen"
+msgstr "Beenden"
 
-#: ardour_ui.cc:384
+#: gtk2_ardour/ardour_ui.cc:379
 msgid ""
 "Ardour was unable to save your session.\n"
 "\n"
@@ -297,35 +360,37 @@ msgid ""
 "\n"
 "\"Just quit\" option."
 msgstr ""
+"Ardour konnte die Sitzung nicht speichern.\n"
+"\n"
+"Wenn Sie trotzdem beenden wollen, wählen Sie bitte\n"
+"\n"
+"\"Trotzdem beenden\"."
 
-#: ardour_ui.cc:403
+#: gtk2_ardour/ardour_ui.cc:398
 msgid "ardour: save session?"
 msgstr "Ardour: Sitzung speichern?"
 
-#: ardour_ui.cc:410
+#: gtk2_ardour/ardour_ui.cc:405
 msgid "Don't %1"
-msgstr "Ohne %1"
+msgstr "Nicht %1"
 
-#: ardour_ui.cc:412
+#: gtk2_ardour/ardour_ui.cc:407
 msgid "Just %1"
-msgstr "Nur %1"
+msgstr "%1 ohne zu Speichern"
 
-#: ardour_ui.cc:414
+#: gtk2_ardour/ardour_ui.cc:409
 msgid "Save and %1"
 msgstr "Speichern und %1"
 
-#: ardour_ui.cc:426
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:421
 msgid "session"
 msgstr "Sitzung"
 
-#: ardour_ui.cc:428
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:423
 msgid "snapshot"
-msgstr "Schnappschuß"
+msgstr "Schnappschuss..."
 
-#: ardour_ui.cc:430
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:425
 msgid ""
 "The %1\"%2\"\n"
 "has not been saved.\n"
@@ -335,7 +400,7 @@ msgid ""
 "\n"
 "What do you want to do?"
 msgstr ""
-"Die Sitzung \"%1\"\n"
+"Die Sitzung %1\"%2\"\n"
 "wurde nicht gespeichert.\n"
 "\n"
 "Alle Ã„nderungen werden verloren\n"
@@ -343,159 +408,179 @@ msgstr ""
 "\n"
 "Was wollen Sie machen?"
 
-#: ardour_ui.cc:444
+#: gtk2_ardour/ardour_ui.cc:439
 msgid "Prompter"
 msgstr ""
 
-#: ardour_ui.cc:503
-#, fuzzy, c-format
+#: gtk2_ardour/ardour_ui.cc:498
+#, c-format
 msgid "disconnected"
-msgstr "Trennen"
+msgstr "getrennt"
 
-#: ardour_ui.cc:510
+#: gtk2_ardour/ardour_ui.cc:505
 #, c-format
-msgid "SR: %.1f kHz / %4.1f msecs"
+msgid "%.1f kHz / %4.1f msecs"
 msgstr ""
 
-#: ardour_ui.cc:514
+#: gtk2_ardour/ardour_ui.cc:509
 #, c-format
-msgid "SR: %u kHz / %4.1f msecs"
+msgid "%u kHz / %4.1f msecs"
 msgstr ""
 
-#: ardour_ui.cc:527
-#, fuzzy, c-format
-msgid "DSP Load: %.1f%%"
-msgstr "Auslastung der CPU: %.1f%%"
+#: gtk2_ardour/ardour_ui.cc:522
+#, c-format
+msgid "DSP: %.1f%%"
+msgstr "CPU Auslastung: %.1f%%"
 
-#: ardour_ui.cc:537
+#: gtk2_ardour/ardour_ui.cc:532
 #, c-format
 msgid "Buffers p:%<PRIu32>%% c:%<PRIu32>%%"
-msgstr ""
+msgstr "Buffer p:%<PRIu32>%% c:%<PRIu32>%%"
 
-#: ardour_ui.cc:564
-msgid "space: 24hrs+"
+#: gtk2_ardour/ardour_ui.cc:560
+msgid "Disk: 24hrs+"
 msgstr "Platz: >24 Stunden"
 
-#: ardour_ui.cc:594
+#: gtk2_ardour/ardour_ui.cc:580
 #, c-format
-msgid "space: %02dh:%02dm:%02ds"
+msgid "Disk: %02dh:%02dm:%02ds"
 msgstr "Platz: %02dh:%02dm:%02ds"
 
-#: ardour_ui.cc:633
+#: gtk2_ardour/ardour_ui.cc:619
 msgid "programming error: impossible control method"
-msgstr ""
+msgstr "Programmierfehler: ungültige Kontrollmethode"
 
-#: ardour_ui.cc:741 new_session_dialog.cc:294
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:727
+#: gtk2_ardour/new_session_dialog.cc:355
 msgid "Recent Sessions"
-msgstr "Sitzung"
+msgstr "Zuletzt verwendete Sitzungen"
 
-#. ardour sessions are folders
-#: ardour_ui.cc:834
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:820
 msgid "open session"
-msgstr "Sitzung"
+msgstr "Sitzung Ã¶ffnen"
 
-#: ardour_ui.cc:840
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:826
 msgid "Ardour sessions"
-msgstr "Ardour: Neue Sitzung"
+msgstr "Ardour-Sitzungen"
 
-#: ardour_ui.cc:873
+#: gtk2_ardour/ardour_ui.cc:859
 msgid "Patience is a virtue.\n"
 msgstr "Geduld ist eine Tugend.\n"
 
-#: ardour_ui.cc:882
-msgid "You cannot add a track without a session already loaded."
-msgstr "Sie können erst eine Spur hinzufügen, wenn eine Sitzung geladen wurde."
+#: gtk2_ardour/ardour_ui.cc:869
+msgid "You cannot add a track or bus without a session already loaded."
+msgstr "Sie können erst Spuren oder Busse hinzufügen, wenn eine Sitzung geladen wurde."
 
-#: ardour_ui.cc:889
-msgid "could not create new audio track"
+#: gtk2_ardour/ardour_ui.cc:879
+#: gtk2_ardour/ardour_ui.cc:891
+msgid "could not create a new audio track"
 msgstr "Konnte neue Spur nicht erstellen."
 
-#: ardour_ui.cc:893
-msgid "could not create new audio bus"
-msgstr "Konnte neuen Audiokanal nicht erstellen."
+#: gtk2_ardour/ardour_ui.cc:881
+#: gtk2_ardour/ardour_ui.cc:893
+msgid "could not create %1 new audio tracks"
+msgstr "Konnte %1 neue Spuren nicht erstellen."
 
-#: ardour_ui.cc:912
+#: gtk2_ardour/ardour_ui.cc:913
 msgid ""
 "There are insufficient JACK ports available\n"
 "to create a new track or bus.\n"
 "You should save Ardour, exit and\n"
 "restart JACK with more ports."
 msgstr ""
+"Es sind nicht genügend JACK Ports verfügbar\n"
+"um neue Spuren oder Busse zu erstellen.\n"
+"Speichern Sie Ihre Sitzung und starten Sie\n"
+"Ardour sowie JACK mit einer größeren\n"
+"Anzahl Ports erneut."
 
-#: ardour_ui.cc:1036
+#: gtk2_ardour/ardour_ui.cc:1033
 msgid ""
 "Please create 1 or more track\n"
 "before trying to record.\n"
 "Check the Session menu."
 msgstr ""
+"Bitte fügen Sie mindestens eine weitere Spur hinzu,\n"
+"bevor Sie aufnehmen.\n"
+"Weitere Einstellungen finden Sie im Sitzungsmenü."
 
-#: ardour_ui.cc:1265
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:1253
 msgid ""
 "JACK has either been shutdown or it\n"
 "disconnected Ardour because Ardour\n"
 "was not fast enough. You can save the\n"
 "session and/or try to reconnect to JACK ."
 msgstr ""
-"JACK wurde entweder beendet oder es\n"
-"hat Ardour abgekoppelt weil Ardour nicht\n"
+"JACK wurde entweder beendet oder\n"
+"hat Ardour getrennt weil Ardour nicht\n"
 "schnell genug war. Sie sollten die Sitzung\n"
-"speichern und JACK sowie Ardour neu starten."
+"speichern versuchen, erneut zu JACK zu verbinden."
 
-#: ardour_ui.cc:1282
+#: gtk2_ardour/ardour_ui.cc:1270
 msgid "Unable to create all required ports"
-msgstr ""
+msgstr "Ardour konnte nicht alle benötigten Ports erstellen."
 
-#: ardour_ui.cc:1290
+#: gtk2_ardour/ardour_ui.cc:1278
 #, fuzzy
 msgid "Unable to start the session running"
-msgstr "An den Anfang der Sitzung springen"
-
-#: ardour_ui.cc:1426
-msgid "No Stream"
-msgstr "Kein Datenstrom"
+msgstr "Konnte die aktuelle Sitzung nicht starten"
 
-#: ardour_ui.cc:1453 ardour_ui.cc:1472
+#: gtk2_ardour/ardour_ui.cc:1384
+#: gtk2_ardour/ardour_ui.cc:1403
+#: gtk2_ardour/audio_clock.cc:448
 msgid "none"
 msgstr "keine"
 
-#: ardour_ui.cc:1462 ardour_ui.cc:1481
+#: gtk2_ardour/ardour_ui.cc:1393
+#: gtk2_ardour/ardour_ui.cc:1412
 msgid "off"
 msgstr "aus"
 
-#: ardour_ui.cc:1505
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:1435
 msgid "Name of New Snapshot"
-msgstr "Name für Schnappschuß"
+msgstr "Name für neuen Schnappschuss"
 
-#: ardour_ui.cc:1651
+#: gtk2_ardour/ardour_ui.cc:1581
 msgid "Name for mix template:"
-msgstr "Name für Mixer-Voreinstellung"
+msgstr "Name für Mixer-Vorlage"
 
-#: ardour_ui.cc:1652
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:1582
 msgid "-template"
-msgstr "Voreinstellung"
+msgstr "Vorlage"
+
+#: gtk2_ardour/ardour_ui.cc:1703
+msgid ""
+"This session\n"
+"%1\n"
+"already exists. Do you want to open it?"
+msgstr ""
+"Die Sitzung\n"
+"%1\n"
+"existiert bereits. Wollen Sie sie Ã¶ffnen?"
 
-#: ardour_ui.cc:1809
+#: gtk2_ardour/ardour_ui.cc:1713
+#, fuzzy
+msgid "existing_session"
+msgstr "Stellen"
+
+#: gtk2_ardour/ardour_ui.cc:1819
 msgid ""
 "You do not have write access to this session.\n"
 "This prevents the session from being loaded."
 msgstr ""
+"Sie haben keinen Schreibzugriff auf diese Sitzung.\n"
+"Dadurch kann die Sitzung nicht geladen werden."
 
-#: ardour_ui.cc:1822 ardour_ui.cc:1877
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:1832
+#: gtk2_ardour/ardour_ui.cc:1889
 msgid "Session \"%1 (snapshot %2)\" did not load successfully"
-msgstr "Sitzung \"%1\" konnte nicht geladen werden."
+msgstr "Sitzung  \"%1 (Schnappschuss %2)\" konnte nicht geladen werden."
 
-#: ardour_ui.cc:1933
+#: gtk2_ardour/ardour_ui.cc:1948
 msgid "No audio files were ready for cleanup"
-msgstr ""
+msgstr "Keine Audiodateien zum Aufräumen vorhanden"
 
-#: ardour_ui.cc:1937
+#: gtk2_ardour/ardour_ui.cc:1952
 msgid ""
 "If this seems suprising, \n"
 "check for any existing snapshots.\n"
@@ -503,51 +588,53 @@ msgid ""
 "require some unused files to continue to exist."
 msgstr ""
 
-#: ardour_ui.cc:1946
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:1961
 msgid "ardour: cleanup"
-msgstr "Ardour: Uhr"
+msgstr "Ardour: Aufräumen"
 
-#: ardour_ui.cc:1982 ardour_ui.cc:1988
+#: gtk2_ardour/ardour_ui.cc:1997
+#: gtk2_ardour/ardour_ui.cc:2003
 msgid "files were"
-msgstr ""
+msgstr "folgenden Dateien wurden"
 
-#: ardour_ui.cc:1984 ardour_ui.cc:1990
+#: gtk2_ardour/ardour_ui.cc:1999
+#: gtk2_ardour/ardour_ui.cc:2005
 msgid "file was"
-msgstr ""
+msgstr "folgende Datei wurde"
 
-#: ardour_ui.cc:2031
+#: gtk2_ardour/ardour_ui.cc:2046
 msgid "Are you sure you want to cleanup?"
-msgstr ""
+msgstr "Sind Sie sicher, dass Sie aufräumen wollen?"
 
-#: ardour_ui.cc:2036
+#: gtk2_ardour/ardour_ui.cc:2051
 msgid ""
 "Cleanup is a destructive operation.\n"
 "ALL undo/redo information will be lost if you cleanup.\n"
-"After cleanup, unused audio files will be moved to a \"dead sounds\" "
-"location."
+"After cleanup, unused audio files will be moved to a \"dead sounds\" location."
 msgstr ""
+"Das Aufräumen ist eine destruktive Operation.\n"
+"Sämtliche Wiederherstellungsinformationen gehen verloren, wenn Sie aufräumen.\n"
+"Nach dem Aufräumen werden alle nicht benötigten Audiodateien in einen \"dead sounds\" Ordner verschoben."
 
-#: ardour_ui.cc:2042
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:2057
 msgid "Clean Up"
-msgstr "leeren"
+msgstr "Aufräumen"
 
-#: ardour_ui.cc:2045
+#: gtk2_ardour/ardour_ui.cc:2060
 #, fuzzy
 msgid "CleanupDialog"
 msgstr "leeren"
 
-#: ardour_ui.cc:2046
+#: gtk2_ardour/ardour_ui.cc:2061
 #, fuzzy
 msgid "ardour_cleanup"
 msgstr "Ardour: Uhr"
 
-#: ardour_ui.cc:2065
+#: gtk2_ardour/ardour_ui.cc:2080
 msgid "cleaned files"
-msgstr ""
+msgstr "aufgeräumte Dateien"
 
-#: ardour_ui.cc:2066
+#: gtk2_ardour/ardour_ui.cc:2081
 msgid ""
 "The following %1 %2 not in use and \n"
 "have been moved to:\n"
@@ -557,24 +644,32 @@ msgid ""
 "release an additional\n"
 "%4 %5bytes of disk space.\n"
 msgstr ""
+"Die %1 %2 nicht benötigt und\n"
+"verschoben nach:\n"
+"%3. \n"
+"\n"
+"Wenn Sie den Müll leeren werden weitere\n"
+"%4 %5byte Speicherplatz frei.\n"
 
-#: ardour_ui.cc:2091
-#, fuzzy
+#: gtk2_ardour/ardour_ui.cc:2106
 msgid "deleted file"
-msgstr "entfernen"
+msgstr "gelöschte Datei"
 
-#: ardour_ui.cc:2092
+#: gtk2_ardour/ardour_ui.cc:2107
 msgid ""
 "The following %1 %2 deleted from\n"
 "%3,\n"
 "releasing %4 %5bytes of disk space"
 msgstr ""
+"Die %1 %2 gelöscht aus\n"
+"%3,\n"
+"und machten %4 %5byte Speicherplatz frei"
 
-#: ardour_ui.cc:2215
+#: gtk2_ardour/ardour_ui.cc:2223
 msgid "Recording was stopped because your system could not keep up."
 msgstr ""
 
-#: ardour_ui.cc:2238
+#: gtk2_ardour/ardour_ui.cc:2234
 msgid ""
 "The disk system on your computer\n"
 "was not able to keep up with Ardour.\n"
@@ -583,7 +678,7 @@ msgid ""
 "quickly enough to keep up with recording.\n"
 msgstr ""
 
-#: ardour_ui.cc:2257
+#: gtk2_ardour/ardour_ui.cc:2253
 msgid ""
 "The disk system on your computer\n"
 "was not able to keep up with Ardour.\n"
@@ -592,7 +687,7 @@ msgid ""
 "quickly enough to keep up with playback.\n"
 msgstr ""
 
-#: ardour_ui.cc:2283
+#: gtk2_ardour/ardour_ui.cc:2279
 msgid ""
 "This session appears to have been in\n"
 "middle of recording when ardour or\n"
@@ -603,3482 +698,3564 @@ msgid ""
 "what you would like to do.\n"
 msgstr ""
 
-#: ardour_ui.cc:2293
+#: gtk2_ardour/ardour_ui.cc:2289
 msgid "Recover from crash"
 msgstr ""
 
-#: ardour_ui.cc:2294
+#: gtk2_ardour/ardour_ui.cc:2290
 msgid "Ignore crash data"
 msgstr ""
 
-#: ardour_ui.cc:2312
+#: gtk2_ardour/ardour_ui.cc:2308
 msgid "Could not disconnect from JACK"
 msgstr ""
 
-#: ardour_ui.cc:2325
+#: gtk2_ardour/ardour_ui.cc:2321
 msgid "Could not reconnect to JACK"
 msgstr ""
 
-#: ardour_ui2.cc:60
+#: gtk2_ardour/ardour_ui2.cc:60
 msgid "UI: cannot setup editor"
 msgstr "Der Editor konnte nicht initialisiert werden."
 
-#: ardour_ui2.cc:65
+#: gtk2_ardour/ardour_ui2.cc:65
 msgid "UI: cannot setup mixer"
 msgstr "Der Mixer konnte nicht initialisiert werden."
 
-#: ardour_ui2.cc:91
+#: gtk2_ardour/ardour_ui2.cc:91
 msgid "MMC + Local"
 msgstr ""
 
-#: ardour_ui2.cc:92
+#: gtk2_ardour/ardour_ui2.cc:92
 msgid "MMC"
 msgstr ""
 
-#: ardour_ui2.cc:93
+#: gtk2_ardour/ardour_ui2.cc:93
 msgid "Local"
 msgstr ""
 
-#: ardour_ui2.cc:110
+#: gtk2_ardour/ardour_ui2.cc:110
 msgid "MMC ID"
 msgstr ""
 
-#: ardour_ui2.cc:291
+#: gtk2_ardour/ardour_ui2.cc:295
 msgid "Play from playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Wiedergabe ab Positionszeiger"
 
-#: ardour_ui2.cc:292
+#: gtk2_ardour/ardour_ui2.cc:296
 msgid "Stop playback"
 msgstr "Wiedergabe anhalten"
 
-#: ardour_ui2.cc:293
-#, fuzzy
+#: gtk2_ardour/ardour_ui2.cc:297
 msgid "Play range/selection"
-msgstr "Auswahl wiedergeben"
+msgstr "Bereich/Auswahl wiedergeben"
 
-#: ardour_ui2.cc:294
+#: gtk2_ardour/ardour_ui2.cc:298
 msgid "Go to start of session"
 msgstr "An den Anfang der Sitzung springen"
 
-#: ardour_ui2.cc:295
+#: gtk2_ardour/ardour_ui2.cc:299
 msgid "Go to end of session"
 msgstr "Ans Ende der Sitzung springen"
 
-#: ardour_ui2.cc:296
-#, fuzzy
+#: gtk2_ardour/ardour_ui2.cc:300
 msgid "Play loop range"
-msgstr "Bereich"
+msgstr "Schleife wiedergeben"
 
-#: ardour_ui2.cc:297
+#: gtk2_ardour/ardour_ui2.cc:301
 msgid "Return to last playback start when stopped"
-msgstr "Bei Stopp zum Wiedergabeanfang springen"
+msgstr "Bei Stop zum letzten Wiedergabeanfang springen"
 
-#: ardour_ui2.cc:298
+#: gtk2_ardour/ardour_ui2.cc:302
 msgid "Start playback after any locate"
-msgstr ""
+msgstr "Startet die Wiedergabe nach setzen des Positionszeigers"
 
-#: ardour_ui2.cc:299
+#: gtk2_ardour/ardour_ui2.cc:303
 msgid "Be sensible about input monitoring"
-msgstr ""
+msgstr "Automatisches Input Monitoring aktivieren"
 
-#: ardour_ui2.cc:300
+#: gtk2_ardour/ardour_ui2.cc:304
 msgid "Start recording at auto-punch start"
-msgstr ""
+msgstr "Beginnt die Aufnahme bei Auto-Punch Start"
 
-#: ardour_ui2.cc:301
+#: gtk2_ardour/ardour_ui2.cc:305
 msgid "Stop recording at auto-punch end"
-msgstr ""
+msgstr "Beginnt die Aufnahme bei Auto-Punch Ende"
 
-#: ardour_ui2.cc:302
+#: gtk2_ardour/ardour_ui2.cc:306
 msgid "Enable/Disable audio click"
-msgstr ""
+msgstr "Aktiviert/Deaktiviert Audio Click"
 
-#: ardour_ui2.cc:303
+#: gtk2_ardour/ardour_ui2.cc:307
 msgid "Positional sync source"
 msgstr ""
 
-#: ardour_ui2.cc:304
+#: gtk2_ardour/ardour_ui2.cc:308
 msgid "Does Ardour control the time?"
-msgstr ""
+msgstr "Bestimmt Ardour die Time?"
 
-#: ardour_ui2.cc:305
+#: gtk2_ardour/ardour_ui2.cc:309
 msgid "Shuttle speed control"
-msgstr ""
+msgstr "Shuttle-Geschwindigkeit"
 
-#: ardour_ui2.cc:306
+#: gtk2_ardour/ardour_ui2.cc:310
 #, c-format
 msgid "Select semitones or %%-age for speed display"
-msgstr ""
+msgstr "Geschwindigkeitsanzeige als Prozent oder Halbtöne einstellen"
 
-#: ardour_ui2.cc:307
+#: gtk2_ardour/ardour_ui2.cc:311
 msgid "Current transport speed"
-msgstr ""
+msgstr "Geschwindigkeitsanzeige"
 
-#: ardour_ui2.cc:330
-#, fuzzy
+#: gtk2_ardour/ardour_ui2.cc:334
 msgid "Primary clock"
-msgstr "Ardour: Uhr"
+msgstr ""
 
-#: ardour_ui2.cc:331
+#: gtk2_ardour/ardour_ui2.cc:335
 msgid "secondary clock"
 msgstr ""
 
-#. XXX: this should really be saved in instant.xml or something similar and restored from there
-#. Combo's are stupid - they steal space from the entry for the button
-#: ardour_ui2.cc:388 ardour_ui2.cc:833 ardour_ui2.cc:846 ardour_ui2.cc:909
-#: ardour_ui2.cc:911
-msgid "sprung"
+#: gtk2_ardour/ardour_ui2.cc:366
+msgid ""
+"When active, something is soloed.\n"
+"Click to de-solo everything"
 msgstr ""
+"Wird aktiv, wenn eine Spur Solo läuft.\n"
+"Schaltet bei Klick Solo aus."
 
-#: ardour_ui2.cc:389 ardour_ui2.cc:835 ardour_ui2.cc:857
-msgid "wheel"
+#: gtk2_ardour/ardour_ui2.cc:367
+msgid ""
+"When active, auditioning is taking place\n"
+"Click to stop the audition"
 msgstr ""
+"Wird beim Vorhören aktiv.\n"
+"Klicken stoppt das Vorhören."
 
-#: ardour_ui2.cc:451
-msgid "ardour: clock"
-msgstr "Ardour: Uhr"
+#: gtk2_ardour/ardour_ui2.cc:395
+#: gtk2_ardour/ardour_ui2.cc:826
+#: gtk2_ardour/ardour_ui2.cc:882
+#: gtk2_ardour/ardour_ui_options.cc:804
+msgid "sprung"
+msgstr "Feder"
 
-#: ardour_ui2.cc:596
+#: gtk2_ardour/ardour_ui2.cc:396
+#: gtk2_ardour/ardour_ui2.cc:828
+#: gtk2_ardour/ardour_ui_options.cc:815
+msgid "wheel"
+msgstr "Drehrad"
+
+#: gtk2_ardour/ardour_ui2.cc:602
 msgid "Maximum speed"
 msgstr ""
 
-#: ardour_ui2.cc:823
-#, fuzzy
-msgid "st"
-msgstr "bestmöglich"
+#: gtk2_ardour/ardour_ui2.cc:838
+#: gtk2_ardour/ardour_ui2.cc:861
+msgid "stop"
+msgstr "Stop"
 
-#: ardour_ui2.cc:867 ardour_ui2.cc:890 ardour_ui2.cc:907
-msgid "stopped"
+#: gtk2_ardour/ardour_ui2.cc:880
+msgid "-0.55"
 msgstr ""
 
-#: ardour_ui_dialogs.cc:153 playlist_selector.cc:70
-#, fuzzy
+#: gtk2_ardour/ardour_ui_dialogs.cc:146
+#: gtk2_ardour/playlist_selector.cc:70
 msgid "close"
 msgstr "Schließen"
 
-#: ardour_ui_dialogs.cc:360 ardour_ui_ed.cc:184
-#, fuzzy
+#: gtk2_ardour/ardour_ui_dialogs.cc:353
+#: gtk2_ardour/ardour_ui_ed.cc:192
 msgid "Sound File Browser"
-msgstr "Ardour: Audio Bibliothek"
+msgstr "Audio-Browser"
 
-#. menus + submenus that need action items
-#: ardour_ui_ed.cc:72
+#: gtk2_ardour/ardour_ui_ed.cc:77
 msgid "Session"
 msgstr "Sitzung"
 
-#: ardour_ui_ed.cc:73 ardour_ui_ed.cc:130 editor.cc:1836 export_dialog.cc:350
-#: export_dialog.cc:1059 export_dialog.cc:1063
+#: gtk2_ardour/ardour_ui_ed.cc:78
+#: gtk2_ardour/ardour_ui_ed.cc:138
+#: gtk2_ardour/editor.cc:1713
+#: gtk2_ardour/export_dialog.cc:348
+#: gtk2_ardour/export_dialog.cc:1057
+#: gtk2_ardour/export_dialog.cc:1061
 msgid "Export"
 msgstr "Exportieren"
 
-#: ardour_ui_ed.cc:74
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:79
 msgid "Cleanup"
-msgstr "leeren"
+msgstr "Aufräumen"
 
-#: ardour_ui_ed.cc:75 option_editor.cc:126
+#: gtk2_ardour/ardour_ui_ed.cc:80
+#: gtk2_ardour/option_editor.cc:125
 msgid "Sync"
 msgstr ""
 
-#: ardour_ui_ed.cc:76 ardour_ui_ed.cc:77
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:81
+#: gtk2_ardour/ardour_ui_ed.cc:82
 msgid "Options"
-msgstr "Geschwindigkeitseditor"
+msgstr "Optionen"
 
-#: ardour_ui_ed.cc:78
+#: gtk2_ardour/ardour_ui_ed.cc:83
 msgid "Help"
-msgstr ""
+msgstr "Hilfe"
 
-#: ardour_ui_ed.cc:79
+#: gtk2_ardour/ardour_ui_ed.cc:84
 msgid "KeyMouse Actions"
-msgstr ""
+msgstr "Tastatur/Maus-Befehle"
 
-#: ardour_ui_ed.cc:80
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:85
 msgid "Audio File Format"
-msgstr "Ardour: Audio Bibliothek"
+msgstr "Audio-Dateiformat"
 
-#: ardour_ui_ed.cc:81
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:86
 msgid "Header"
-msgstr "Verbergen"
+msgstr "Header"
 
-#: ardour_ui_ed.cc:82
+#: gtk2_ardour/ardour_ui_ed.cc:87
 msgid "Data"
-msgstr ""
+msgstr "Datenformat"
 
-#: ardour_ui_ed.cc:83
+#: gtk2_ardour/ardour_ui_ed.cc:88
 msgid "Control Surfaces"
-msgstr ""
+msgstr "Eingabegeräte"
 
-#. the real actions
-#: ardour_ui_ed.cc:87 audio_time_axis.cc:1854 new_session_dialog.cc:529
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:89
+msgid "Metering"
+msgstr "Pegelanzeige"
+
+#: gtk2_ardour/ardour_ui_ed.cc:90
+msgid "Fall off rate"
+msgstr "Abfall der Pegelanzeige"
+
+#: gtk2_ardour/ardour_ui_ed.cc:91
+msgid "Hold Time"
+msgstr "Pegelanzeige halten"
+
+#: gtk2_ardour/ardour_ui_ed.cc:95
+#: gtk2_ardour/route_time_axis.cc:1288
+#: gtk2_ardour/new_session_dialog.cc:600
 msgid "New"
 msgstr "Neu..."
 
-#: ardour_ui_ed.cc:89 new_session_dialog.cc:517
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:97
+#: gtk2_ardour/new_session_dialog.cc:587
 msgid "Open"
 msgstr "Öffnen..."
 
-#: ardour_ui_ed.cc:90
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:98
 msgid "Recent"
-msgstr "Zurücksetzen"
+msgstr "Zuletzt verwendet..."
 
-#: ardour_ui_ed.cc:91 io_selector.cc:58 io_selector.cc:792
+#: gtk2_ardour/ardour_ui_ed.cc:99
+#: gtk2_ardour/io_selector.cc:60
+#: gtk2_ardour/io_selector.cc:749
+#: gtk2_ardour/connection_editor.cc:59
 msgid "Close"
 msgstr "Schließen"
 
-#: ardour_ui_ed.cc:94 route_params_ui.cc:514
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:102
+#: gtk2_ardour/route_params_ui.cc:510
 msgid "Add Track/Bus"
-msgstr "MIDI Spur(en) hinzufügen"
+msgstr "Spur/Bus hinzufügen..."
 
-#: ardour_ui_ed.cc:105
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:113
 msgid "Connect"
-msgstr "Verbindungen"
+msgstr "Verbinden"
 
-#. </CMT Additions>
-#: ardour_ui_ed.cc:113
+#: gtk2_ardour/ardour_ui_ed.cc:121
 msgid "Snapshot"
-msgstr "Schnappschuß"
+msgstr "Schnappschuss"
 
-#: ardour_ui_ed.cc:116
+#: gtk2_ardour/ardour_ui_ed.cc:124
 msgid "Save Template..."
-msgstr "Speichern als Voreinstellung..."
+msgstr "Als Vorlage Speichern..."
 
-#: ardour_ui_ed.cc:119
+#: gtk2_ardour/ardour_ui_ed.cc:127
 msgid "Export session to audiofile..."
-msgstr "Export als Audio-Datei..."
+msgstr "Exportiere Sitzung als Audio-Datei..."
 
-#: ardour_ui_ed.cc:122
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:130
 msgid "Export selection to audiofile..."
-msgstr "Export als Audio-Datei..."
+msgstr "Exportiere Auswahl als Audio-Datei..."
 
-#: ardour_ui_ed.cc:126
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:134
 msgid "Export range markers to audiofile..."
-msgstr "Export als Audio-Datei..."
+msgstr "Exportiere Bereich als Audio-Datei..."
 
-#: ardour_ui_ed.cc:133
+#: gtk2_ardour/ardour_ui_ed.cc:141
 msgid "Cleanup unused sources"
-msgstr ""
+msgstr "Nicht benutzte Dateien entfernen"
 
-#: ardour_ui_ed.cc:135
+#: gtk2_ardour/ardour_ui_ed.cc:143
 msgid "Flush wastebasket"
-msgstr ""
+msgstr "Müll leeren"
 
-#: ardour_ui_ed.cc:141 ardour_ui_options.cc:408 ardour_ui_options.cc:417
-#: ardour_ui_options.cc:489
+#: gtk2_ardour/ardour_ui_ed.cc:149
 msgid "JACK"
 msgstr ""
 
-#: ardour_ui_ed.cc:142
+#: gtk2_ardour/ardour_ui_ed.cc:150
 msgid "Latency"
-msgstr ""
+msgstr "Latenz"
 
-#: ardour_ui_ed.cc:144
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:152
 msgid "Reconnect"
-msgstr "Verbindungen"
+msgstr "Neu Verbinden"
 
-#: ardour_ui_ed.cc:147 mixer_strip.cc:497 mixer_strip.cc:565
+#: gtk2_ardour/ardour_ui_ed.cc:155
+#: gtk2_ardour/mixer_strip.cc:517
+#: gtk2_ardour/mixer_strip.cc:579
 msgid "Disconnect"
 msgstr "Trennen"
 
-#: ardour_ui_ed.cc:174
+#: gtk2_ardour/ardour_ui_ed.cc:182
 msgid "Windows"
 msgstr "Fenster"
 
-#: ardour_ui_ed.cc:175
+#: gtk2_ardour/ardour_ui_ed.cc:183
 msgid "start prefix"
 msgstr ""
 
-#: ardour_ui_ed.cc:176
+#: gtk2_ardour/ardour_ui_ed.cc:184
 msgid "Quit"
 msgstr "Beenden"
 
-#. windows visibility actions
-#: ardour_ui_ed.cc:180
+#: gtk2_ardour/ardour_ui_ed.cc:188
 msgid "Maximise Editor Space"
-msgstr ""
+msgstr "Editor Maximieren"
 
-#: ardour_ui_ed.cc:182
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:190
 msgid "Show Editor"
-msgstr "Geschwindigkeitseditor"
+msgstr "Editor anzeigen"
 
-#: ardour_ui_ed.cc:183
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:191
 msgid "Show Mixer"
-msgstr "Mixer"
+msgstr "Mixer anzeigen"
 
-#: ardour_ui_ed.cc:185
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:193
 msgid "Options Editor"
-msgstr "Geschwindigkeitseditor"
+msgstr "Optionen"
 
-#: ardour_ui_ed.cc:186
+#: gtk2_ardour/ardour_ui_ed.cc:194
 msgid "Track/Bus Inspector"
-msgstr ""
+msgstr "Verbindungen"
 
-#: ardour_ui_ed.cc:188
+#: gtk2_ardour/ardour_ui_ed.cc:196
+#: gtk2_ardour/connection_editor.cc:147
+#: gtk2_ardour/connection_editor.cc:148
 msgid "Connections"
 msgstr "Verbindungen"
 
-#: ardour_ui_ed.cc:190
+#: gtk2_ardour/ardour_ui_ed.cc:198
 msgid "Locations"
-msgstr "Stellen"
+msgstr "Lokatoren"
 
-#: ardour_ui_ed.cc:192
+#: gtk2_ardour/ardour_ui_ed.cc:200
 msgid "Big Clock"
 msgstr "Große Uhr"
 
-#: ardour_ui_ed.cc:194
+#: gtk2_ardour/ardour_ui_ed.cc:202
 msgid "About"
-msgstr ""
+msgstr "Ãœber Ardour..."
 
-#: ardour_ui_ed.cc:195
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:203
 msgid "Colors"
-msgstr "solo"
+msgstr "Farben"
 
-#: ardour_ui_ed.cc:197
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:205
 msgid "Add Audio Track"
-msgstr "MIDI Spur(en) hinzufügen"
+msgstr "Audiospur hinzufügen"
 
-#: ardour_ui_ed.cc:199
+#: gtk2_ardour/ardour_ui_ed.cc:207
 msgid "Add Audio Bus"
 msgstr ""
 
-#: ardour_ui_ed.cc:201
+#: gtk2_ardour/ardour_ui_ed.cc:209
 msgid "Save"
 msgstr "Speichern"
 
-#: ardour_ui_ed.cc:203 editor_actions.cc:255
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:211
+#: gtk2_ardour/editor_actions.cc:256
 msgid "Remove Last Capture"
-msgstr "Synchronisationspunkt entfernen"
+msgstr "Letzte Aufnahme entfernen"
 
-#. do-nothing action for the "transport" menu bar item
-#: ardour_ui_ed.cc:210
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:218
 msgid "Transport"
-msgstr "dreieckig"
+msgstr "Transport"
 
-#. these two are not used by key bindings, instead use ToggleRoll for that. these two do show up in
-#. menus and via button proxies.
-#.
-#: ardour_ui_ed.cc:216 sfdb_ui.cc:57
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:224
+#: gtk2_ardour/sfdb_ui.cc:60
 msgid "Stop"
 msgstr "Stop"
 
-#: ardour_ui_ed.cc:219
+#: gtk2_ardour/ardour_ui_ed.cc:227
 msgid "Roll"
 msgstr ""
 
-#: ardour_ui_ed.cc:223
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:231
 msgid "Start/Stop"
-msgstr "Anfang:"
+msgstr "Start/Stop"
 
-#: ardour_ui_ed.cc:226
+#: gtk2_ardour/ardour_ui_ed.cc:234
 msgid "Stop + Forget Capture"
-msgstr ""
+msgstr "Stop + Aufnahme verwerfen"
 
-#: ardour_ui_ed.cc:229
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:237
 msgid "Play Loop Range"
-msgstr "Bereich"
+msgstr "Schleife wiedergeben"
 
-#: ardour_ui_ed.cc:232
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:240
 msgid "Play Selection"
-msgstr "Wiedergabe der ausgewählten Region"
+msgstr "Auswahl wiedergeben"
 
-#: ardour_ui_ed.cc:236
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:244
 msgid "Enable Record"
-msgstr "Wiederherstellen"
+msgstr "Aufnahme aktivieren"
 
-#: ardour_ui_ed.cc:239
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:247
 msgid "Rewind"
-msgstr "Suchen"
+msgstr "Rückwärts"
 
-#: ardour_ui_ed.cc:242
+#: gtk2_ardour/ardour_ui_ed.cc:250
 msgid "Rewind (Slow)"
 msgstr ""
 
-#: ardour_ui_ed.cc:245
+#: gtk2_ardour/ardour_ui_ed.cc:253
 msgid "Rewind (Fast)"
 msgstr ""
 
-#: ardour_ui_ed.cc:248
+#: gtk2_ardour/ardour_ui_ed.cc:256
 msgid "Forward"
-msgstr ""
+msgstr "Vorwärts"
 
-#: ardour_ui_ed.cc:251
+#: gtk2_ardour/ardour_ui_ed.cc:259
 msgid "Forward (Slow)"
 msgstr ""
 
-#: ardour_ui_ed.cc:254
+#: gtk2_ardour/ardour_ui_ed.cc:262
 msgid "Forward (Fast)"
 msgstr ""
 
-#: ardour_ui_ed.cc:257
+#: gtk2_ardour/ardour_ui_ed.cc:265
 msgid "Goto Zero"
-msgstr ""
+msgstr "Zum Nullpunkt springen"
 
-#: ardour_ui_ed.cc:260
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:268
 msgid "Goto Start"
-msgstr "Anfang:"
+msgstr "Zum Anfang springen"
 
-#: ardour_ui_ed.cc:263
+#: gtk2_ardour/ardour_ui_ed.cc:271
 msgid "Goto End"
-msgstr ""
-
-#. XXX the newline in the displayed names of these action is really wrong, but its because we want the button
-#. that proxies for these action to be more compact. It would be nice to find a way to override the action
-#. name appearance on the buttons.
-#.
-#: ardour_ui_ed.cc:272
-msgid ""
-"Punch\n"
-"in"
-msgstr ""
+msgstr "Zum Ende Springen"
 
-#: ardour_ui_ed.cc:275
-msgid ""
-"Punch\n"
-"out"
-msgstr ""
-
-#: ardour_ui_ed.cc:278 option_editor.cc:129
-msgid "Click"
-msgstr ""
-
-#: ardour_ui_ed.cc:281
-#, fuzzy
-msgid ""
-"Auto\n"
-"input"
-msgstr "Port hinzufügen"
-
-#: ardour_ui_ed.cc:284
-msgid ""
-"Auto\n"
-"play"
-msgstr ""
+#: gtk2_ardour/ardour_ui_ed.cc:287
+msgid "Auto Play"
+msgstr "Auto Play"
 
-#: ardour_ui_ed.cc:287
-msgid ""
-"Auto\n"
-"return"
-msgstr ""
+#: gtk2_ardour/ardour_ui_ed.cc:294
+msgid "Sync startup to video"
+msgstr "Mit Video synchronisieren"
 
-#: ardour_ui_ed.cc:291
-msgid ""
-"Time\n"
-"master"
-msgstr ""
+#: gtk2_ardour/ardour_ui_ed.cc:295
+msgid "Time master"
+msgstr "Time Master"
 
-#: ardour_ui_ed.cc:294
+#: gtk2_ardour/ardour_ui_ed.cc:298
 msgid "Toggle Record Enable Track1"
 msgstr ""
 
-#: ardour_ui_ed.cc:296
+#: gtk2_ardour/ardour_ui_ed.cc:300
 msgid "Toggle Record Enable Track2"
 msgstr ""
 
-#: ardour_ui_ed.cc:298
+#: gtk2_ardour/ardour_ui_ed.cc:302
 msgid "Toggle Record Enable Track3"
 msgstr ""
 
-#: ardour_ui_ed.cc:300
+#: gtk2_ardour/ardour_ui_ed.cc:304
 msgid "Toggle Record Enable Track4"
 msgstr ""
 
-#: ardour_ui_ed.cc:302
+#: gtk2_ardour/ardour_ui_ed.cc:306
 msgid "Toggle Record Enable Track5"
 msgstr ""
 
-#: ardour_ui_ed.cc:304
+#: gtk2_ardour/ardour_ui_ed.cc:308
 msgid "Toggle Record Enable Track6"
 msgstr ""
 
-#: ardour_ui_ed.cc:306
+#: gtk2_ardour/ardour_ui_ed.cc:310
 msgid "Toggle Record Enable Track7"
 msgstr ""
 
-#: ardour_ui_ed.cc:308
+#: gtk2_ardour/ardour_ui_ed.cc:312
 msgid "Toggle Record Enable Track8"
 msgstr ""
 
-#: ardour_ui_ed.cc:310
+#: gtk2_ardour/ardour_ui_ed.cc:314
 msgid "Toggle Record Enable Track9"
 msgstr ""
 
-#: ardour_ui_ed.cc:312
+#: gtk2_ardour/ardour_ui_ed.cc:316
 msgid "Toggle Record Enable Track10"
 msgstr ""
 
-#: ardour_ui_ed.cc:314
+#: gtk2_ardour/ardour_ui_ed.cc:318
 msgid "Toggle Record Enable Track11"
 msgstr ""
 
-#: ardour_ui_ed.cc:316
+#: gtk2_ardour/ardour_ui_ed.cc:320
 msgid "Toggle Record Enable Track12"
 msgstr ""
 
-#: ardour_ui_ed.cc:318
+#: gtk2_ardour/ardour_ui_ed.cc:322
 msgid "Toggle Record Enable Track13"
 msgstr ""
 
-#: ardour_ui_ed.cc:320
+#: gtk2_ardour/ardour_ui_ed.cc:324
 msgid "Toggle Record Enable Track14"
 msgstr ""
 
-#: ardour_ui_ed.cc:322
+#: gtk2_ardour/ardour_ui_ed.cc:326
 msgid "Toggle Record Enable Track15"
 msgstr ""
 
-#: ardour_ui_ed.cc:324
+#: gtk2_ardour/ardour_ui_ed.cc:328
 msgid "Toggle Record Enable Track16"
 msgstr ""
 
-#: ardour_ui_ed.cc:326
+#: gtk2_ardour/ardour_ui_ed.cc:330
 msgid "Toggle Record Enable Track17"
 msgstr ""
 
-#: ardour_ui_ed.cc:328
+#: gtk2_ardour/ardour_ui_ed.cc:332
 msgid "Toggle Record Enable Track18"
 msgstr ""
 
-#: ardour_ui_ed.cc:330
+#: gtk2_ardour/ardour_ui_ed.cc:334
 msgid "Toggle Record Enable Track19"
 msgstr ""
 
-#: ardour_ui_ed.cc:332
+#: gtk2_ardour/ardour_ui_ed.cc:336
 msgid "Toggle Record Enable Track20"
 msgstr ""
 
-#: ardour_ui_ed.cc:334
+#: gtk2_ardour/ardour_ui_ed.cc:338
 msgid "Toggle Record Enable Track21"
 msgstr ""
 
-#: ardour_ui_ed.cc:336
+#: gtk2_ardour/ardour_ui_ed.cc:340
 msgid "Toggle Record Enable Track22"
 msgstr ""
 
-#: ardour_ui_ed.cc:338
+#: gtk2_ardour/ardour_ui_ed.cc:342
 msgid "Toggle Record Enable Track23"
 msgstr ""
 
-#: ardour_ui_ed.cc:340
+#: gtk2_ardour/ardour_ui_ed.cc:344
 msgid "Toggle Record Enable Track24"
 msgstr ""
 
-#: ardour_ui_ed.cc:342
+#: gtk2_ardour/ardour_ui_ed.cc:346
 msgid "Toggle Record Enable Track25"
 msgstr ""
 
-#: ardour_ui_ed.cc:344
+#: gtk2_ardour/ardour_ui_ed.cc:348
 msgid "Toggle Record Enable Track26"
 msgstr ""
 
-#: ardour_ui_ed.cc:346
+#: gtk2_ardour/ardour_ui_ed.cc:350
 msgid "Toggle Record Enable Track27"
 msgstr ""
 
-#: ardour_ui_ed.cc:348
+#: gtk2_ardour/ardour_ui_ed.cc:352
 msgid "Toggle Record Enable Track28"
 msgstr ""
 
-#: ardour_ui_ed.cc:350
+#: gtk2_ardour/ardour_ui_ed.cc:354
 msgid "Toggle Record Enable Track29"
 msgstr ""
 
-#: ardour_ui_ed.cc:352
+#: gtk2_ardour/ardour_ui_ed.cc:356
 msgid "Toggle Record Enable Track30"
 msgstr ""
 
-#: ardour_ui_ed.cc:354
+#: gtk2_ardour/ardour_ui_ed.cc:358
 msgid "Toggle Record Enable Track31"
 msgstr ""
 
-#: ardour_ui_ed.cc:356
+#: gtk2_ardour/ardour_ui_ed.cc:360
 msgid "Toggle Record Enable Track32"
 msgstr ""
 
-#: ardour_ui_ed.cc:361
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:365
 msgid "Percentage"
-msgstr "Zurücksetzen"
+msgstr "Prozent"
 
-#: ardour_ui_ed.cc:362
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:366
 msgid "Semitones"
-msgstr "Sitzung"
+msgstr "Halbtöne"
 
-#: ardour_ui_ed.cc:366
+#: gtk2_ardour/ardour_ui_ed.cc:370
 msgid "Send MTC"
 msgstr "MTC senden"
 
-#: ardour_ui_ed.cc:368
+#: gtk2_ardour/ardour_ui_ed.cc:372
 msgid "Send MMC"
 msgstr "MMC senden"
 
-#: ardour_ui_ed.cc:370
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:374
 msgid "Use MMC"
-msgstr "MMC senden"
+msgstr "Benutze MMC"
 
-#: ardour_ui_ed.cc:372
+#: gtk2_ardour/ardour_ui_ed.cc:376
 msgid "Send MIDI feedback"
 msgstr ""
 
-#: ardour_ui_ed.cc:374
+#: gtk2_ardour/ardour_ui_ed.cc:378
 msgid "Use MIDI control"
 msgstr ""
 
-#: ardour_ui_ed.cc:377
-msgid "Connect new track inputs to hardware"
-msgstr ""
-
-#: ardour_ui_ed.cc:396
-msgid "Connect new track outputs to hardware"
-msgstr ""
-
-#: ardour_ui_ed.cc:398
-msgid "Connect new track outputs to master"
-msgstr ""
-
-#: ardour_ui_ed.cc:400
-msgid "Manually connect new track outputs"
-msgstr ""
-
-#: ardour_ui_ed.cc:405
-msgid "Hardware monitoring"
-msgstr ""
-
-#: ardour_ui_ed.cc:406
-msgid "Software monitoring"
-msgstr ""
-
-#: ardour_ui_ed.cc:407
-msgid "External monitoring"
-msgstr ""
-
-#. Configuration object options (i.e. not session specific)
-#: ardour_ui_ed.cc:411
+#: gtk2_ardour/ardour_ui_ed.cc:381
 msgid "Stop plugins with transport"
-msgstr ""
+msgstr "Plugins mit Transport stoppen"
 
-#: ardour_ui_ed.cc:412
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:382
 msgid "Verify remove last capture"
-msgstr "Synchronisationspunkt entfernen"
+msgstr "Verwerfen der letzten Aufnahme bestätigen"
 
-#: ardour_ui_ed.cc:413
+#: gtk2_ardour/ardour_ui_ed.cc:383
 msgid "Stop recording on xrun"
-msgstr ""
+msgstr "Aufnahme bei XRUN stoppen"
 
-#: ardour_ui_ed.cc:414
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:384
 msgid "Stop transport at session end"
-msgstr "Ans Ende der Sitzung springen"
+msgstr "Transport am Ende der Sitzung stoppen"
 
-#: ardour_ui_ed.cc:415
+#: gtk2_ardour/ardour_ui_ed.cc:385
 msgid "-12dB gain reduce ffwd/rewind"
-msgstr ""
+msgstr "Beim Spulen Pegel um -12dB absenken"
 
-#: ardour_ui_ed.cc:416
+#: gtk2_ardour/ardour_ui_ed.cc:386
 msgid "Rec-enable stays engaged at stop"
-msgstr ""
+msgstr "Aufnahmestatus bleibt nach Stop erhalten"
 
-#. session options
-#: ardour_ui_ed.cc:420
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:388
 msgid "Do not run plugins while recording"
-msgstr "Wellenform zeigen"
+msgstr "Plugins während der Aufnahme daktivieren"
 
-#: ardour_ui_ed.cc:423
+#: gtk2_ardour/ardour_ui_ed.cc:391
 msgid "Latched solo"
-msgstr ""
+msgstr "Latch Solo"
+
+#: gtk2_ardour/ardour_ui_ed.cc:399
+#: gtk2_ardour/ardour_ui_ed.cc:407
+#: gtk2_ardour/audio_clock.cc:1800
+#: gtk2_ardour/gain_meter.cc:159
+#: gtk2_ardour/ladspa_pluginui.cc:330
+#: gtk2_ardour/ladspa_pluginui.cc:573
+#: gtk2_ardour/panner_ui.cc:87
+msgid "Off"
+msgstr "Aus"
 
-#: ardour_ui_ed.cc:428
-#, fuzzy
+#: gtk2_ardour/ardour_ui_ed.cc:400
+#: gtk2_ardour/editor.cc:1334
+#: gtk2_ardour/editor.cc:1351
+msgid "Slowest"
+msgstr "Sehr langsam"
+
+#: gtk2_ardour/ardour_ui_ed.cc:401
+#: gtk2_ardour/editor.cc:1335
+#: gtk2_ardour/editor.cc:1352
+msgid "Slow"
+msgstr "Langsam"
+
+#: gtk2_ardour/ardour_ui_ed.cc:402
+#: gtk2_ardour/ardour_ui_ed.cc:409
+msgid "Medium"
+msgstr "Mittel"
+
+#: gtk2_ardour/ardour_ui_ed.cc:403
+#: gtk2_ardour/editor.cc:1336
+#: gtk2_ardour/editor.cc:1353
+msgid "Fast"
+msgstr "Schnell"
+
+#: gtk2_ardour/ardour_ui_ed.cc:404
+msgid "Faster"
+msgstr "Schneller"
+
+#: gtk2_ardour/ardour_ui_ed.cc:405
+#: gtk2_ardour/editor.cc:1337
+#: gtk2_ardour/editor.cc:1354
+msgid "Fastest"
+msgstr "Schnellstmöglich"
+
+#: gtk2_ardour/ardour_ui_ed.cc:408
+#: gtk2_ardour/editor_actions.cc:58
+msgid "Short"
+msgstr "Kurz"
+
+#: gtk2_ardour/ardour_ui_ed.cc:410
+msgid "Long"
+msgstr "Lange"
+
+#: gtk2_ardour/ardour_ui_ed.cc:428
+msgid "Hardware monitoring"
+msgstr "Hardware Monitoring"
+
+#: gtk2_ardour/ardour_ui_ed.cc:429
+msgid "Software monitoring"
+msgstr "Software Monitoring"
+
+#: gtk2_ardour/ardour_ui_ed.cc:430
+msgid "External monitoring"
+msgstr "Externes Monitoring"
+
+#: gtk2_ardour/ardour_ui_ed.cc:434
 msgid "Solo in-place"
-msgstr "solo"
+msgstr "Solo-In-Place"
 
-#: ardour_ui_ed.cc:430
+#: gtk2_ardour/ardour_ui_ed.cc:436
 msgid "Solo via bus"
+msgstr "Solo Ã¼ber Bus"
+
+#: gtk2_ardour/ardour_ui_ed.cc:441
+msgid "Auto-connect inputs to physical inputs"
+msgstr "Eingänge automatisch mit Soundkarteneingängen verbinden"
+
+#: gtk2_ardour/ardour_ui_ed.cc:443
+msgid "Manually connect inputs"
+msgstr "Eingänge manuell verbinden"
+
+#: gtk2_ardour/ardour_ui_ed.cc:448
+msgid "Auto-connect outputs to physical outs"
+msgstr "Ausgänge automatisch mit Soundkartenausgängen verbinden"
+
+#: gtk2_ardour/ardour_ui_ed.cc:450
+msgid "Auto-connect outputs to master bus"
+msgstr "Ausgänge automatisch mit Master-Bus verbinden"
+
+#: gtk2_ardour/ardour_ui_ed.cc:452
+msgid "Manually connect outputs"
+msgstr "Ausgänge manuell verbinden"
+
+#: gtk2_ardour/ardour_ui_ed.cc:547
+#: gtk2_ardour/ladspa_pluginui.cc:168
+msgid "Controls"
+msgstr "Steuerelemente"
+
+#: gtk2_ardour/ardour_ui_ed.cc:551
+msgid "Feedback"
 msgstr ""
 
-#: ardour_ui_ed.cc:433
-msgid "Automatically create crossfades"
+#: gtk2_ardour/ardour_ui_ed.cc:631
+msgid "ardour: clock"
+msgstr "Ardour: Uhr"
+
+#: gtk2_ardour/ardour_ui_options.cc:205
+msgid "programming error: unknown solo model in ARDOUR_UI::set_solo_model: %1"
 msgstr ""
 
-#: ardour_ui_ed.cc:435
-msgid "Unmute new full crossfades"
+#: gtk2_ardour/ardour_ui_options.cc:239
+msgid "programming error: unknown monitor model in ARDOUR_UI::set_monitor_model: %1"
 msgstr ""
 
-#: ardour_ui_options.cc:406 ardour_ui_options.cc:416 ardour_ui_options.cc:483
-#, fuzzy
-msgid "Internal"
-msgstr "mittelmäßig"
+#: gtk2_ardour/ardour_ui_options.cc:492
+msgid "programming error: unknown file header format passed to ARDOUR_UI::map_file_data_format: %1"
+msgstr ""
 
-#: ardour_ui_options.cc:407 ardour_ui_options.cc:486
-msgid "MTC"
+#: gtk2_ardour/ardour_ui_options.cc:524
+msgid "programming error: unknown file data format passed to ARDOUR_UI::map_file_data_format: %1"
 msgstr ""
 
-#: audio_clock.cc:1742 editor.cc:188
-msgid "SMPTE"
+#: gtk2_ardour/ardour_ui_options.cc:826
+msgid "ST"
 msgstr ""
 
-#: audio_clock.cc:1743 editor.cc:187 editor_rulers.cc:360
+#: gtk2_ardour/audio_clock.cc:1796
+#: gtk2_ardour/editor.cc:180
+msgid "Timecode"
+msgstr "Timecode"
+
+#: gtk2_ardour/audio_clock.cc:1797
+#: gtk2_ardour/editor.cc:179
+#: gtk2_ardour/editor_rulers.cc:386
 msgid "Bars:Beats"
-msgstr ""
+msgstr "Takte:Schläge"
 
-#: audio_clock.cc:1744
+#: gtk2_ardour/audio_clock.cc:1798
 msgid "Minutes:Seconds"
 msgstr "Minuten:Sekunden"
 
-#: audio_clock.cc:1745
+#: gtk2_ardour/audio_clock.cc:1799
 msgid "Audio Frames"
 msgstr ""
 
-#.
-#. Slowest = 6.6dB/sec falloff at update rate of 40ms
-#. Slow    = 6.8dB/sec falloff at update rate of 40ms
-#.
-#: audio_clock.cc:1746 editor_actions.cc:375 editor_actions.cc:383
-#: gain_meter.cc:172 panner_ui.cc:89 plugin_ui.cc:392 plugin_ui.cc:635
-msgid "Off"
-msgstr "Aus"
-
-#: audio_clock.cc:1748
+#: gtk2_ardour/audio_clock.cc:1802
 msgid "Mode"
 msgstr "Modus"
 
-#: audio_time_axis.cc:91
+#: gtk2_ardour/route_time_axis.cc:87
 msgid "m"
-msgstr ""
+msgstr "m"
 
-#: audio_time_axis.cc:91
+#: gtk2_ardour/route_time_axis.cc:87
 msgid "s"
-msgstr ""
+msgstr "s"
 
-#: audio_time_axis.cc:91
+#: gtk2_ardour/route_time_axis.cc:87
 msgid "r"
 msgstr ""
 
-#: audio_time_axis.cc:95
+#: gtk2_ardour/route_time_axis.cc:91
 msgid "g"
-msgstr ""
+msgstr "g"
 
-#. group
-#: audio_time_axis.cc:96
+#: gtk2_ardour/route_time_axis.cc:92
 msgid "p"
-msgstr ""
+msgstr "w"
 
-#: audio_time_axis.cc:97 automation_time_axis.cc:32 visual_time_axis.cc:74
+#: gtk2_ardour/route_time_axis.cc:93
+#: gtk2_ardour/automation_time_axis.cc:33
+#: gtk2_ardour/visual_time_axis.cc:74
 msgid "h"
-msgstr ""
+msgstr "h"
 
-#. height
-#: audio_time_axis.cc:98
+#: gtk2_ardour/route_time_axis.cc:94
 msgid "a"
-msgstr ""
+msgstr "a"
 
-#: audio_time_axis.cc:99 visual_time_axis.cc:73
+#: gtk2_ardour/route_time_axis.cc:95
+#: gtk2_ardour/visual_time_axis.cc:73
 msgid "v"
-msgstr ""
+msgstr "v"
 
-#: audio_time_axis.cc:168 mixer_strip.cc:86
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:150
+#: gtk2_ardour/mixer_strip.cc:85
 msgid "Record"
-msgstr "Wiederherstellen"
+msgstr "Aufnahme"
 
-#: audio_time_axis.cc:169 editor_actions.cc:37 mixer_strip.cc:86
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:158
+#: gtk2_ardour/editor_actions.cc:38
+#: gtk2_ardour/mixer_strip.cc:85
+#: gtk2_ardour/mixer_strip.cc:433
 msgid "Solo"
-msgstr "solo"
-
-#: audio_time_axis.cc:170 editor.cc:1760 editor.cc:1859 mixer_strip.cc:86
-#: panner_ui.cc:427
-#, fuzzy
+msgstr "Solo"
+
+#: gtk2_ardour/route_time_axis.cc:159
+#: gtk2_ardour/editor.cc:1637
+#: gtk2_ardour/editor.cc:1727
+#: gtk2_ardour/mixer_strip.cc:85
+#: gtk2_ardour/mixer_strip.cc:432
+#: gtk2_ardour/panner_ui.cc:417
 msgid "Mute"
-msgstr "mute"
+msgstr "Mute"
 
-#: audio_time_axis.cc:171
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:160
 msgid "Edit Group"
-msgstr "Mix Gruppen"
+msgstr "Bearbeitungsgruppe"
 
-#: audio_time_axis.cc:172 visual_time_axis.cc:92
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:161
+#: gtk2_ardour/visual_time_axis.cc:92
 msgid "Display Height"
-msgstr "Anzeige"
+msgstr "Anzeigehöhe"
 
-#: audio_time_axis.cc:173
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:162
 msgid "Playlist"
-msgstr "Wiedergabe"
+msgstr "Wiedergabeliste"
 
-#: audio_time_axis.cc:174 audio_time_axis.cc:741
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:163
+#: gtk2_ardour/route_time_axis.cc:425
 msgid "Automation"
-msgstr "Stellen"
+msgstr "Automationen"
 
-#: audio_time_axis.cc:175 visual_time_axis.cc:93
+#: gtk2_ardour/route_time_axis.cc:164
+#: gtk2_ardour/visual_time_axis.cc:93
 msgid "Visual options"
-msgstr ""
+msgstr "Visuelle optionen"
 
-#: audio_time_axis.cc:176 visual_time_axis.cc:94
+#: gtk2_ardour/route_time_axis.cc:165
+#: gtk2_ardour/visual_time_axis.cc:94
 msgid "Hide this track"
-msgstr ""
+msgstr "Diese Spur verbergen"
 
-#: audio_time_axis.cc:333 mixer_strip.cc:927
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:276
+#: gtk2_ardour/mixer_strip.cc:917
 msgid "No group"
 msgstr "keine Gruppe"
 
-#: audio_time_axis.cc:702 automation_time_axis.cc:450
-#: imageframe_time_axis.cc:255 marker_time_axis.cc:211
-#, fuzzy
-msgid "Height"
-msgstr "Rechts"
-
-#: audio_time_axis.cc:703 color_manager.cc:41 imageframe_time_axis.cc:256
-#: marker_time_axis.cc:212
-#, fuzzy
-msgid "Color"
-msgstr "solo"
-
-#: audio_time_axis.cc:707
-msgid "Hide all crossfades"
-msgstr ""
-
-#: audio_time_axis.cc:708
-msgid "Show all crossfades"
-msgstr ""
-
-#: audio_time_axis.cc:712 mixer_strip.cc:1011
-#, fuzzy
-msgid "Remote Control ID"
-msgstr "Synchronisationspunkt entfernen"
-
-#: audio_time_axis.cc:718
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:386
 msgid "Show all automation"
-msgstr "Stellen"
+msgstr "Alle Automationen zeigen"
 
-#: audio_time_axis.cc:721
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:389
 msgid "Show existing automation"
-msgstr "Stellen"
+msgstr "Verfügbare Automationen zeigen"
 
-#: audio_time_axis.cc:724
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:392
 msgid "Hide all automation"
-msgstr "Stellen"
-
-#: audio_time_axis.cc:729
-#, fuzzy
-msgid "Fader"
-msgstr "Verbergen"
-
-#: audio_time_axis.cc:734
-msgid "Pan"
-msgstr ""
+msgstr "Automationen verbergen"
 
-#: audio_time_axis.cc:739
+#: gtk2_ardour/route_time_axis.cc:395
 msgid "Plugins"
-msgstr ""
-
-#: audio_time_axis.cc:747
-#, fuzzy
-msgid "Show waveforms"
-msgstr "Wellenform zeigen"
+msgstr "Plugins"
 
-#: audio_time_axis.cc:755
-msgid "Traditional"
-msgstr ""
+#: gtk2_ardour/route_time_axis.cc:416
+#: gtk2_ardour/automation_time_axis.cc:425
+#: gtk2_ardour/imageframe_time_axis.cc:255
+#: gtk2_ardour/marker_time_axis.cc:211
+msgid "Height"
+msgstr "Höhe"
 
-#: audio_time_axis.cc:758
-msgid "Rectified"
-msgstr ""
+#: gtk2_ardour/route_time_axis.cc:417
+#: gtk2_ardour/color_manager.cc:41
+#: gtk2_ardour/imageframe_time_axis.cc:256
+#: gtk2_ardour/marker_time_axis.cc:212
+msgid "Color"
+msgstr "Farbe"
 
-#: audio_time_axis.cc:761
-#, fuzzy
-msgid "Waveform"
-msgstr "Wellenform zeigen"
+#: gtk2_ardour/route_time_axis.cc:422
+#: gtk2_ardour/mixer_strip.cc:1002
+msgid "Remote Control ID"
+msgstr "ID für Fernsteuerung"
 
-#: audio_time_axis.cc:771
+#: gtk2_ardour/route_time_axis.cc:440
 msgid "Align with existing material"
-msgstr ""
+msgstr "An vorhandenem Material ausrichten"
 
-#: audio_time_axis.cc:776
+#: gtk2_ardour/route_time_axis.cc:446
 msgid "Align with capture time"
-msgstr ""
+msgstr "An Aufnahmezeit ausrichten"
 
-#: audio_time_axis.cc:782
+#: gtk2_ardour/route_time_axis.cc:452
 msgid "Alignment"
-msgstr ""
+msgstr "Ausrichtung"
+
+#: gtk2_ardour/route_time_axis.cc:458
+msgid "Normal mode"
+msgstr "Normaler Modus"
 
-#: audio_time_axis.cc:788 editor.cc:527 editor_actions.cc:60
-#: mixer_strip.cc:1000 mixer_ui.cc:111
+#: gtk2_ardour/route_time_axis.cc:461
+msgid "Tape mode"
+msgstr "Tape-Modus"
+
+#: gtk2_ardour/route_time_axis.cc:477
+#: gtk2_ardour/editor.cc:478
+#: gtk2_ardour/editor_actions.cc:61
+#: gtk2_ardour/mixer_strip.cc:991
+#: gtk2_ardour/mixer_ui.cc:109
 msgid "Active"
 msgstr "Aktiv"
 
-#: audio_time_axis.cc:793 editor.cc:1922 editor_actions.cc:320
-#: editor_markers.cc:508 imageframe_time_axis.cc:259 location_ui.cc:57
-#: marker_time_axis.cc:215 mixer_strip.cc:1014
+#: gtk2_ardour/route_time_axis.cc:482
+#: gtk2_ardour/editor.cc:1817
+#: gtk2_ardour/editor_actions.cc:326
+#: gtk2_ardour/editor_markers.cc:511
+#: gtk2_ardour/imageframe_time_axis.cc:259
+#: gtk2_ardour/location_ui.cc:58
+#: gtk2_ardour/marker_time_axis.cc:215
+#: gtk2_ardour/mixer_strip.cc:1005
 msgid "Remove"
-msgstr "Entfernen"
+msgstr "Löschen"
 
-#: audio_time_axis.cc:833
-#, fuzzy
-msgid "Name for playlist"
-msgstr "Name für Schnappschuß"
+#: gtk2_ardour/route_time_axis.cc:508
+#: gtk2_ardour/route_time_axis.cc:563
+#: gtk2_ardour/route_time_axis.cc:826
+#: gtk2_ardour/editor_actions.cc:1034
+msgid "programming error: %1 %2"
+msgstr ""
 
-#: audio_time_axis.cc:835 audio_time_axis.cc:1851 editor_markers.cc:827
-#: editor_mouse.cc:4673 imageframe_time_axis.cc:248 marker_time_axis.cc:208
-#: meter_bridge_strip.cc:224 mixer_strip.cc:998 redirect_box.cc:751
-#: redirect_box.cc:1065 route_ui.cc:739 visual_time_axis.cc:326
+#: gtk2_ardour/route_time_axis.cc:850
+msgid "Name for playlist"
+msgstr "Name für Wiedergabeliste"
+
+#: gtk2_ardour/route_time_axis.cc:852
+#: gtk2_ardour/route_time_axis.cc:1285
+#: gtk2_ardour/editor_markers.cc:830
+#: gtk2_ardour/editor_mouse.cc:4732
+#: gtk2_ardour/imageframe_time_axis.cc:248
+#: gtk2_ardour/marker_time_axis.cc:208
+#: gtk2_ardour/mixer_strip.cc:989
+#: gtk2_ardour/redirect_box.cc:752
+#: gtk2_ardour/redirect_box.cc:1075
+#: gtk2_ardour/route_ui.cc:760
+#: gtk2_ardour/visual_time_axis.cc:331
 msgid "Rename"
 msgstr "Umbenennen"
 
-#: audio_time_axis.cc:868 audio_time_axis.cc:908
-#, fuzzy
+#: gtk2_ardour/route_time_axis.cc:894
+#: gtk2_ardour/route_time_axis.cc:935
 msgid "Name for Playlist"
-msgstr "Name für Schnappschuß"
+msgstr "Name für Playlist"
 
-#: audio_time_axis.cc:1126 visual_time_axis.cc:383
+#: gtk2_ardour/route_time_axis.cc:1118
+#: gtk2_ardour/visual_time_axis.cc:388
 msgid "a track already exists with that name"
 msgstr ""
 
-#: audio_time_axis.cc:1167 editor.cc:218
-msgid "gain"
+#: gtk2_ardour/route_time_axis.cc:1289
+msgid "New Copy"
+msgstr "Neue Kopie"
+
+#: gtk2_ardour/route_time_axis.cc:1291
+msgid "Clear Current"
 msgstr ""
 
-#: audio_time_axis.cc:1207
-msgid "pan"
+#: gtk2_ardour/route_time_axis.cc:1294
+msgid "Select from all ..."
 msgstr ""
 
-#: audio_time_axis.cc:1410 editor.cc:1483 selection.cc:634
+#: gtk2_ardour/route_time_axis.cc:1494
+#: gtk2_ardour/editor.cc:1359
+#: gtk2_ardour/selection.cc:642
 msgid "programming error: "
 msgstr ""
 
-#: audio_time_axis.cc:1848
-msgid "Current: %1"
+#: gtk2_ardour/audio_time_axis.cc:221
+msgid "Fader"
+msgstr "Fader"
+
+#: gtk2_ardour/audio_time_axis.cc:226
+msgid "Pan"
 msgstr ""
 
-#: audio_time_axis.cc:1855
-#, fuzzy
-msgid "New Copy"
-msgstr "Kopieren"
+#: gtk2_ardour/audio_time_axis.cc:241
+msgid "Hide all crossfades"
+msgstr "Alle Crossfades verbergen"
 
-#: audio_time_axis.cc:1857
-msgid "Clear Current"
+#: gtk2_ardour/audio_time_axis.cc:242
+msgid "Show all crossfades"
+msgstr "Alle Crossfades zeigen"
+
+#: gtk2_ardour/audio_time_axis.cc:249
+msgid "Show waveforms"
+msgstr "Wellenformen zeigen"
+
+#: gtk2_ardour/audio_time_axis.cc:257
+msgid "Traditional"
+msgstr "Traditionell"
+
+#: gtk2_ardour/audio_time_axis.cc:260
+msgid "Rectified"
+msgstr "Gleichgerichtet"
+
+#: gtk2_ardour/audio_time_axis.cc:263
+msgid "Waveform"
+msgstr "Wellenform"
+
+#: gtk2_ardour/audio_time_axis.cc:323
+msgid "gain"
 msgstr ""
 
-#: audio_time_axis.cc:1859 editor.cc:2024 editor.cc:2100
-msgid "Select"
-msgstr "Auswahl"
+#: gtk2_ardour/audio_time_axis.cc:363
+msgid "pan"
+msgstr ""
 
-#: automation_line.cc:884
+#: gtk2_ardour/automation_line.cc:801
 #, fuzzy
 msgid "automation event move"
 msgstr "Stellen"
 
-#: automation_line.cc:886
+#: gtk2_ardour/automation_line.cc:803
 #, fuzzy
 msgid "automation range drag"
 msgstr "Stellen"
 
-#: automation_line.cc:1015 region_gain_line.cc:62
+#: gtk2_ardour/automation_line.cc:1028
+#: gtk2_ardour/region_gain_line.cc:64
 #, fuzzy
 msgid "remove control point"
 msgstr "Synchronisationspunkt entfernen"
 
-#: automation_time_axis.cc:33 editor_ops.cc:2885
+#: gtk2_ardour/automation_time_axis.cc:34
+#: gtk2_ardour/editor_ops.cc:2834
 msgid "clear"
 msgstr "leeren"
 
-#: automation_time_axis.cc:75
+#: gtk2_ardour/automation_time_axis.cc:70
 msgid "track height"
-msgstr ""
+msgstr "Anzeigehöhe"
 
-#: automation_time_axis.cc:76
-#, fuzzy
+#: gtk2_ardour/automation_time_axis.cc:71
 msgid "automation state"
-msgstr "Stellen"
+msgstr "Automationsmodus"
 
-#: automation_time_axis.cc:77
-#, fuzzy
+#: gtk2_ardour/automation_time_axis.cc:72
 msgid "clear track"
-msgstr "Verbindungen löschen"
+msgstr "Verbindungen entfernen"
 
-#: automation_time_axis.cc:78
-#, fuzzy
+#: gtk2_ardour/automation_time_axis.cc:73
 msgid "hide track"
-msgstr "Stille einfügen"
+msgstr "Diese Spur verbergen"
 
-#: automation_time_axis.cc:184 automation_time_axis.cc:213
-#: automation_time_axis.cc:461
+#: gtk2_ardour/automation_time_axis.cc:182
+#: gtk2_ardour/automation_time_axis.cc:211
+#: gtk2_ardour/automation_time_axis.cc:436
 msgid "Manual"
-msgstr ""
-
-#: automation_time_axis.cc:186 automation_time_axis.cc:224
-#: automation_time_axis.cc:465 editor.cc:2001 editor.cc:2082 gain_meter.cc:174
-#: panner_ui.cc:91 plugin_ui.cc:395 plugin_ui.cc:637 sfdb_ui.cc:56
+msgstr "Manuell"
+
+#: gtk2_ardour/automation_time_axis.cc:184
+#: gtk2_ardour/automation_time_axis.cc:222
+#: gtk2_ardour/automation_time_axis.cc:440
+#: gtk2_ardour/editor.cc:1894
+#: gtk2_ardour/editor.cc:1975
+#: gtk2_ardour/gain_meter.cc:161
+#: gtk2_ardour/ladspa_pluginui.cc:333
+#: gtk2_ardour/ladspa_pluginui.cc:575
+#: gtk2_ardour/panner_ui.cc:89
+#: gtk2_ardour/sfdb_ui.cc:59
 msgid "Play"
 msgstr "Wiedergabe"
 
-#: automation_time_axis.cc:188 automation_time_axis.cc:235
-#: automation_time_axis.cc:469 gain_meter.cc:176 panner_ui.cc:93
-#: plugin_ui.cc:398 plugin_ui.cc:639
+#: gtk2_ardour/automation_time_axis.cc:186
+#: gtk2_ardour/automation_time_axis.cc:233
+#: gtk2_ardour/automation_time_axis.cc:444
+#: gtk2_ardour/gain_meter.cc:163
+#: gtk2_ardour/ladspa_pluginui.cc:336
+#: gtk2_ardour/ladspa_pluginui.cc:577
+#: gtk2_ardour/panner_ui.cc:91
 msgid "Write"
-msgstr ""
-
-#: automation_time_axis.cc:190 automation_time_axis.cc:246
-#: automation_time_axis.cc:473 gain_meter.cc:178 panner_ui.cc:95
-#: plugin_ui.cc:401 plugin_ui.cc:641
+msgstr "Schreiben"
+
+#: gtk2_ardour/automation_time_axis.cc:188
+#: gtk2_ardour/automation_time_axis.cc:244
+#: gtk2_ardour/automation_time_axis.cc:448
+#: gtk2_ardour/gain_meter.cc:165
+#: gtk2_ardour/ladspa_pluginui.cc:339
+#: gtk2_ardour/ladspa_pluginui.cc:579
+#: gtk2_ardour/panner_ui.cc:93
 msgid "Touch"
-msgstr ""
+msgstr "Berühren"
 
-#: automation_time_axis.cc:257 option_editor.cc:183 option_editor.cc:189
-#: plugin_ui.cc:404
+#: gtk2_ardour/automation_time_axis.cc:255
+#: gtk2_ardour/ladspa_pluginui.cc:342
 msgid "???"
 msgstr ""
 
-#: automation_time_axis.cc:271
-#, fuzzy
+#: gtk2_ardour/automation_time_axis.cc:269
 msgid "clear automation"
-msgstr "Verbindungen löschen"
+msgstr "Verbindungen entfernen"
 
-#: automation_time_axis.cc:452 editor_actions.cc:318
+#: gtk2_ardour/automation_time_axis.cc:427
+#: gtk2_ardour/editor_actions.cc:324
 msgid "Hide"
 msgstr "Verbergen"
 
-#: automation_time_axis.cc:454 crossfade_edit.cc:78 redirect_box.cc:1057
+#: gtk2_ardour/automation_time_axis.cc:429
+#: gtk2_ardour/crossfade_edit.cc:79
+#: gtk2_ardour/redirect_box.cc:1067
+#: gtk2_ardour/connection_editor.cc:57
 msgid "Clear"
 msgstr "leeren"
 
-#: automation_time_axis.cc:477
-#, fuzzy
+#: gtk2_ardour/automation_time_axis.cc:452
 msgid "State"
-msgstr "Anfang"
+msgstr "Automationssmodus"
 
-#: canvas-imageframe.c:104
+#: gtk2_ardour/canvas-imageframe.c:104
 msgid "pixbuf"
 msgstr ""
 
-#: canvas-imageframe.c:105
+#: gtk2_ardour/canvas-imageframe.c:105
 msgid "the pixbuf"
 msgstr ""
 
-#: canvas-imageframe.c:110
+#: gtk2_ardour/canvas-imageframe.c:110
 msgid "x"
 msgstr ""
 
-#: canvas-imageframe.c:111 canvas-simpleline.c:111 canvas-simplerect.c:107
+#: gtk2_ardour/canvas-imageframe.c:111
+#: gtk2_ardour/canvas-simpleline.c:111
+#: gtk2_ardour/canvas-simplerect.c:107
 msgid "x coordinate of upper left corner of rect"
 msgstr ""
 
-#: canvas-imageframe.c:120
+#: gtk2_ardour/canvas-imageframe.c:120
 msgid "y"
 msgstr ""
 
-#: canvas-imageframe.c:121 canvas-simpleline.c:121 canvas-simplerect.c:117
+#: gtk2_ardour/canvas-imageframe.c:121
+#: gtk2_ardour/canvas-simpleline.c:121
+#: gtk2_ardour/canvas-simplerect.c:117
 msgid "y coordinate of upper left corner of rect "
 msgstr ""
 
-#: canvas-imageframe.c:129
+#: gtk2_ardour/canvas-imageframe.c:129
 msgid "width"
 msgstr ""
 
-#: canvas-imageframe.c:130
+#: gtk2_ardour/canvas-imageframe.c:130
 msgid "the width"
 msgstr ""
 
-#: canvas-imageframe.c:139
+#: gtk2_ardour/canvas-imageframe.c:139
 msgid "drawwidth"
 msgstr ""
 
-#: canvas-imageframe.c:140
+#: gtk2_ardour/canvas-imageframe.c:140
 msgid "drawn width"
 msgstr ""
 
-#: canvas-imageframe.c:148
+#: gtk2_ardour/canvas-imageframe.c:148
 #, fuzzy
 msgid "height"
 msgstr "Rechts"
 
-#: canvas-imageframe.c:149
+#: gtk2_ardour/canvas-imageframe.c:149
 #, fuzzy
 msgid "the height"
 msgstr "Rechts"
 
-#: canvas-imageframe.c:157
+#: gtk2_ardour/canvas-imageframe.c:157
 msgid "anchor"
 msgstr ""
 
-#: canvas-imageframe.c:158
+#: gtk2_ardour/canvas-imageframe.c:158
 msgid "the anchor"
 msgstr ""
 
-#: canvas-simpleline.c:110 canvas-simplerect.c:106
+#: gtk2_ardour/canvas-simpleline.c:110
+#: gtk2_ardour/canvas-simplerect.c:106
 msgid "x1"
 msgstr ""
 
-#: canvas-simpleline.c:120 canvas-simplerect.c:116
+#: gtk2_ardour/canvas-simpleline.c:120
+#: gtk2_ardour/canvas-simplerect.c:116
 msgid "y1"
 msgstr ""
 
-#: canvas-simpleline.c:131 canvas-simplerect.c:127
+#: gtk2_ardour/canvas-simpleline.c:131
+#: gtk2_ardour/canvas-simplerect.c:127
 msgid "x2"
 msgstr ""
 
-#: canvas-simpleline.c:132 canvas-simplerect.c:128
+#: gtk2_ardour/canvas-simpleline.c:132
+#: gtk2_ardour/canvas-simplerect.c:128
 msgid "x coordinate of lower right corner of rect"
 msgstr ""
 
-#: canvas-simpleline.c:141 canvas-simplerect.c:137
+#: gtk2_ardour/canvas-simpleline.c:141
+#: gtk2_ardour/canvas-simplerect.c:137
 msgid "y2"
 msgstr ""
 
-#: canvas-simpleline.c:142 canvas-simplerect.c:138
+#: gtk2_ardour/canvas-simpleline.c:142
+#: gtk2_ardour/canvas-simplerect.c:138
 msgid "y coordinate of lower right corner of rect "
 msgstr ""
 
-#: canvas-simpleline.c:150
+#: gtk2_ardour/canvas-simpleline.c:150
 msgid "color rgba"
 msgstr ""
 
-#: canvas-simpleline.c:151
+#: gtk2_ardour/canvas-simpleline.c:151
 msgid "color of line"
 msgstr ""
 
-#: canvas-simplerect.c:148
+#: gtk2_ardour/canvas-simplerect.c:148
 msgid "outline pixels"
 msgstr ""
 
-#: canvas-simplerect.c:149
+#: gtk2_ardour/canvas-simplerect.c:149
 msgid "width in pixels of outline"
 msgstr ""
 
-#: canvas-simplerect.c:159
+#: gtk2_ardour/canvas-simplerect.c:159
 msgid "outline what"
 msgstr ""
 
-#: canvas-simplerect.c:160
+#: gtk2_ardour/canvas-simplerect.c:160
 msgid "which boundaries to outline (mask)"
 msgstr ""
 
-#: canvas-simplerect.c:171
+#: gtk2_ardour/canvas-simplerect.c:171
 msgid "fill"
 msgstr ""
 
-#: canvas-simplerect.c:172
+#: gtk2_ardour/canvas-simplerect.c:172
 #, fuzzy
 msgid "fill rectangle"
 msgstr "Auswahl zu Schleife machen"
 
-#: canvas-simplerect.c:179
+#: gtk2_ardour/canvas-simplerect.c:179
 msgid "draw"
 msgstr ""
 
-#: canvas-simplerect.c:180
+#: gtk2_ardour/canvas-simplerect.c:180
 #, fuzzy
 msgid "draw rectangle"
 msgstr "Bereich"
 
-#: canvas-simplerect.c:188
+#: gtk2_ardour/canvas-simplerect.c:188
 msgid "outline color rgba"
 msgstr ""
 
-#: canvas-simplerect.c:189
+#: gtk2_ardour/canvas-simplerect.c:189
 msgid "color of outline"
 msgstr ""
 
-#: canvas-simplerect.c:199
+#: gtk2_ardour/canvas-simplerect.c:199
 msgid "fill color rgba"
 msgstr ""
 
-#: canvas-simplerect.c:200
+#: gtk2_ardour/canvas-simplerect.c:200
 msgid "color of fill"
 msgstr ""
 
-#: color_manager.cc:40
+#: gtk2_ardour/color_manager.cc:40
 #, fuzzy
 msgid "Object"
 msgstr "Objekt"
 
-#: color_manager.cc:78
+#: gtk2_ardour/color_manager.cc:78
 msgid "cannot open color definition file %1: %2"
 msgstr ""
 
-#: crossfade_edit.cc:75
+#: gtk2_ardour/crossfade_edit.cc:76
 #, fuzzy
 msgid "ardour: x-fade edit"
 msgstr "Ardour: Editor"
 
-#: crossfade_edit.cc:79 panner_ui.cc:443
+#: gtk2_ardour/crossfade_edit.cc:80
+#: gtk2_ardour/panner_ui.cc:433
 #, fuzzy
 msgid "Reset"
 msgstr "bestmöglich"
 
-#: crossfade_edit.cc:80
+#: gtk2_ardour/crossfade_edit.cc:81
 msgid "Fade"
 msgstr ""
 
-#: crossfade_edit.cc:81
+#: gtk2_ardour/crossfade_edit.cc:82
 msgid "Out (dry)"
 msgstr ""
 
-#: crossfade_edit.cc:82
+#: gtk2_ardour/crossfade_edit.cc:83
 #, fuzzy
 msgid "Out"
 msgstr "Ausgänge"
 
-#: crossfade_edit.cc:83
+#: gtk2_ardour/crossfade_edit.cc:84
 msgid "In (dry)"
 msgstr ""
 
-#: crossfade_edit.cc:84
+#: gtk2_ardour/crossfade_edit.cc:85
 msgid "In"
 msgstr ""
 
-#: crossfade_edit.cc:86
+#: gtk2_ardour/crossfade_edit.cc:87
 msgid "With Pre-roll"
 msgstr ""
 
-#: crossfade_edit.cc:87
+#: gtk2_ardour/crossfade_edit.cc:88
 msgid "With Post-roll"
 msgstr ""
 
-#: crossfade_edit.cc:95
+#: gtk2_ardour/crossfade_edit.cc:96
 msgid "Fade In"
 msgstr ""
 
-#: crossfade_edit.cc:96
+#: gtk2_ardour/crossfade_edit.cc:97
 msgid "Fade Out"
 msgstr ""
 
-#: crossfade_edit.cc:172 editor.cc:1835 editor_actions.cc:316
-#: option_editor.cc:130
+#: gtk2_ardour/crossfade_edit.cc:173
+#: gtk2_ardour/editor.cc:1712
+#: gtk2_ardour/editor_actions.cc:322
+#: gtk2_ardour/option_editor.cc:129
 msgid "Audition"
-msgstr ""
-
-#: editor.cc:104 editor.cc:3616
-msgid "Slide"
-msgstr ""
-
-#: editor.cc:105 editor.cc:3614
-msgid "Splice"
-msgstr ""
-
-#. note that this menu list starts at zero, not 1, because zero
-#. is a valid, if useless, ID.
-#.
-#. leave some breathing room
-#: editor.cc:110 editor.cc:3671 export_dialog.cc:78 export_dialog.cc:92
-#: export_dialog.cc:893 export_dialog.cc:1225 route_ui.cc:437
+msgstr "Vorhören"
+
+#: gtk2_ardour/editor.cc:102
+#: gtk2_ardour/editor.cc:3469
+#: gtk2_ardour/editor_actions.cc:400
+#: gtk2_ardour/export_dialog.cc:76
+#: gtk2_ardour/export_dialog.cc:90
+#: gtk2_ardour/export_dialog.cc:891
+#: gtk2_ardour/export_dialog.cc:1223
+#: gtk2_ardour/route_ui.cc:459
 msgid "None"
-msgstr "Nichts"
+msgstr "Kein"
 
-#: editor.cc:111 editor.cc:3659
+#: gtk2_ardour/editor.cc:103
+#: gtk2_ardour/editor.cc:3457
 msgid "CD Frames"
-msgstr ""
+msgstr "CD-Frames"
 
-#: editor.cc:112 editor.cc:3661
+#: gtk2_ardour/editor.cc:104
+#: gtk2_ardour/editor.cc:3459
 msgid "SMPTE Frames"
-msgstr ""
+msgstr "SMPTE-Frames"
 
-#: editor.cc:113 editor.cc:3663
+#: gtk2_ardour/editor.cc:105
+#: gtk2_ardour/editor.cc:3461
 msgid "SMPTE Seconds"
-msgstr ""
+msgstr "SMPTE-Sekunden"
 
-#: editor.cc:114 editor.cc:3665
+#: gtk2_ardour/editor.cc:106
+#: gtk2_ardour/editor.cc:3463
 msgid "SMPTE Minutes"
-msgstr ""
+msgstr "SMPTE-Minuten"
 
-#: editor.cc:115 editor.cc:3667
-#, fuzzy
+#: gtk2_ardour/editor.cc:107
+#: gtk2_ardour/editor.cc:3465
 msgid "Seconds"
-msgstr "Minuten:Sekunden"
+msgstr "Sekunden"
 
-#: editor.cc:116 editor.cc:3669
-#, fuzzy
+#: gtk2_ardour/editor.cc:108
+#: gtk2_ardour/editor.cc:3467
 msgid "Minutes"
-msgstr "mute"
+msgstr "Minuten"
 
-#: editor.cc:117 editor.cc:3641
+#: gtk2_ardour/editor.cc:109
+#: gtk2_ardour/editor.cc:3439
 msgid "Beats/32"
-msgstr ""
+msgstr "Zweiunddreißigstel"
 
-#: editor.cc:118 editor.cc:3639
+#: gtk2_ardour/editor.cc:110
+#: gtk2_ardour/editor.cc:3437
 msgid "Beats/16"
-msgstr ""
+msgstr "Sechzehntel"
 
-#: editor.cc:119 editor.cc:3637
+#: gtk2_ardour/editor.cc:111
+#: gtk2_ardour/editor.cc:3435
 msgid "Beats/8"
-msgstr ""
+msgstr "Achtel"
 
-#: editor.cc:120 editor.cc:3635
+#: gtk2_ardour/editor.cc:112
+#: gtk2_ardour/editor.cc:3433
 msgid "Beats/4"
-msgstr ""
+msgstr "Viertel"
 
-#: editor.cc:121 editor.cc:3633
+#: gtk2_ardour/editor.cc:113
+#: gtk2_ardour/editor.cc:3431
 msgid "Beats/3"
-msgstr ""
+msgstr "Vierteltriolen"
 
-#: editor.cc:122 editor.cc:3643
+#: gtk2_ardour/editor.cc:114
+#: gtk2_ardour/editor.cc:3441
 msgid "Beats"
-msgstr ""
+msgstr "Schläge"
 
-#: editor.cc:123 editor.cc:3645
+#: gtk2_ardour/editor.cc:115
+#: gtk2_ardour/editor.cc:3443
 msgid "Bars"
-msgstr ""
+msgstr "Takte"
 
-#: editor.cc:124 editor.cc:3647
+#: gtk2_ardour/editor.cc:116
+#: gtk2_ardour/editor.cc:3445
 msgid "Marks"
-msgstr ""
+msgstr "Marker"
 
-#: editor.cc:125 editor.cc:144 editor.cc:3649 editor.cc:3715
+#: gtk2_ardour/editor.cc:117
+#: gtk2_ardour/editor.cc:136
+#: gtk2_ardour/editor.cc:3447
+#: gtk2_ardour/editor.cc:3512
 msgid "Edit Cursor"
-msgstr ""
+msgstr "Editierzeiger"
 
-#: editor.cc:126 editor.cc:3651
-#, fuzzy
+#: gtk2_ardour/editor.cc:118
+#: gtk2_ardour/editor.cc:3449
 msgid "Region starts"
-msgstr "Regionen"
+msgstr "Regionen-Anfang"
 
-#: editor.cc:127 editor.cc:3653
-#, fuzzy
+#: gtk2_ardour/editor.cc:119
+#: gtk2_ardour/editor.cc:3451
 msgid "Region ends"
-msgstr "Regionen"
+msgstr "Regionen-Ende"
 
-#: editor.cc:128 editor.cc:3657
-#, fuzzy
+#: gtk2_ardour/editor.cc:120
+#: gtk2_ardour/editor.cc:3455
 msgid "Region syncs"
-msgstr "Regionen"
+msgstr "Regionen-Sync"
 
-#: editor.cc:129 editor.cc:3655
-#, fuzzy
+#: gtk2_ardour/editor.cc:121
+#: gtk2_ardour/editor.cc:3453
 msgid "Region bounds"
-msgstr "Regionen"
+msgstr "Regionen-Grenzen"
 
-#: editor.cc:135 editor.cc:3690
-#, fuzzy
+#: gtk2_ardour/editor.cc:127
+#: gtk2_ardour/editor.cc:3487
+#: gtk2_ardour/editor_actions.cc:287
 msgid "Magnetic"
-msgstr "generisch"
-
-#: editor.cc:140 editor.cc:3707 export_dialog.cc:140 export_dialog.cc:156
-#: export_dialog.cc:1068 export_dialog.cc:1072
+msgstr "Magnetisch"
+
+#: gtk2_ardour/editor.cc:132
+#: gtk2_ardour/editor.cc:3504
+#: gtk2_ardour/export_dialog.cc:138
+#: gtk2_ardour/export_dialog.cc:154
+#: gtk2_ardour/export_dialog.cc:1066
+#: gtk2_ardour/export_dialog.cc:1070
 msgid "Left"
 msgstr "Links"
 
-#: editor.cc:141 editor.cc:3709 export_dialog.cc:141 export_dialog.cc:157
+#: gtk2_ardour/editor.cc:133
+#: gtk2_ardour/editor.cc:3506
+#: gtk2_ardour/export_dialog.cc:139
+#: gtk2_ardour/export_dialog.cc:155
 msgid "Right"
 msgstr "Rechts"
 
-#: editor.cc:142 editor.cc:3711
+#: gtk2_ardour/editor.cc:134
+#: gtk2_ardour/editor.cc:3508
 msgid "Center"
 msgstr "Mitte"
 
-#: editor.cc:143 editor.cc:3713
+#: gtk2_ardour/editor.cc:135
+#: gtk2_ardour/editor.cc:3510
 msgid "Playhead"
-msgstr ""
+msgstr "Positionszeiger"
 
-#. time display buttons
-#: editor.cc:186
+#: gtk2_ardour/editor.cc:178
 msgid "Mins:Secs"
 msgstr "Min:Sek"
 
-#: editor.cc:189 editor_rulers.cc:354
+#: gtk2_ardour/editor.cc:181
+#: gtk2_ardour/editor_rulers.cc:380
 msgid "Frames"
-msgstr ""
+msgstr "Frames"
 
-#: editor.cc:190 editor_rulers.cc:374
+#: gtk2_ardour/editor.cc:182
+#: gtk2_ardour/editor_rulers.cc:400
 msgid "Tempo"
-msgstr ""
+msgstr "Tempo"
 
-#: editor.cc:191 editor_rulers.cc:368
+#: gtk2_ardour/editor.cc:183
+#: gtk2_ardour/editor_rulers.cc:394
 msgid "Meter"
-msgstr ""
+msgstr "Taktart"
 
-#: editor.cc:192 editor_rulers.cc:380
-#, fuzzy
+#: gtk2_ardour/editor.cc:184
+#: gtk2_ardour/editor_rulers.cc:406
 msgid "Location Markers"
-msgstr "Stellen"
+msgstr "Positionsmarker"
 
-#: editor.cc:193 editor_rulers.cc:386
+#: gtk2_ardour/editor.cc:185
+#: gtk2_ardour/editor_rulers.cc:412
 msgid "Range Markers"
-msgstr ""
+msgstr "Bereiche"
 
-#: editor.cc:194 editor_rulers.cc:392
+#: gtk2_ardour/editor.cc:186
+#: gtk2_ardour/editor_rulers.cc:418
 msgid "Loop/Punch Ranges"
-msgstr ""
+msgstr "Schleifen/Punch-Bereiche"
 
-#: editor.cc:216
-msgid "range"
-msgstr "Bereich"
-
-#: editor.cc:217
-msgid "object"
-msgstr "Objekt"
-
-#: editor.cc:219
-msgid "zoom"
-msgstr ""
-
-#: editor.cc:220
-msgid "timefx"
-msgstr ""
-
-#: editor.cc:221
-msgid "listen"
-msgstr ""
-
-#: editor.cc:223
+#: gtk2_ardour/editor.cc:204
 msgid "mode"
 msgstr "Modus"
 
-#: editor.cc:224
+#: gtk2_ardour/editor.cc:205
 msgid "automation"
 msgstr ""
 
-#: editor.cc:226
-msgid "Edit Mode"
-msgstr "Bearbeitungs Modus"
-
-#: editor.cc:227 editor_actions.cc:284
-msgid "Snap To"
-msgstr ""
-
-#: editor.cc:228
-#, fuzzy
-msgid "Snap Mode"
-msgstr "Modus"
-
-#: editor.cc:229
-#, fuzzy
-msgid "Zoom Focus"
-msgstr "Verkleinern"
-
-#. </CMT Additions>
-#. nudge
-#: editor.cc:237 editor.cc:1900 editor.cc:2066 editor.cc:2122
-msgid "Nudge"
-msgstr ""
-
-#: editor.cc:470
-msgid "Zoom in"
-msgstr "Vergrößern"
-
-#: editor.cc:471
-msgid "Zoom out"
-msgstr "Verkleinern"
-
-#: editor.cc:474
-#, fuzzy
-msgid "Zoom to session"
-msgstr "Vergrößern auf Auswahl"
-
-#: editor.cc:489
-#, fuzzy
-msgid "Zoom Span"
-msgstr "Vergrößern"
-
-#: editor.cc:502 editor.cc:528 editor_actions.cc:62 mixer_ui.cc:86
-#: mixer_ui.cc:112
-msgid "Visible"
-msgstr ""
+#: gtk2_ardour/editor.cc:453
+#: gtk2_ardour/editor.cc:479
+#: gtk2_ardour/editor_actions.cc:63
+#: gtk2_ardour/mixer_ui.cc:84
+#: gtk2_ardour/mixer_ui.cc:110
+#: gtk2_ardour/analysis_window.cc:64
+msgid "Show"
+msgstr "Anzeigen"
 
-#: editor.cc:503 editor.cc:526
+#: gtk2_ardour/editor.cc:454
+#: gtk2_ardour/editor.cc:477
 #, fuzzy
 msgid "Name"
 msgstr "Umbenennen"
 
-#: editor.cc:602 editor.cc:669
-#, fuzzy
+#: gtk2_ardour/editor.cc:553
+#: gtk2_ardour/editor.cc:619
 msgid "Regions"
 msgstr "Regionen"
 
-#: editor.cc:642 editor.cc:681
+#: gtk2_ardour/editor.cc:592
+#: gtk2_ardour/editor.cc:631
 msgid "Chunks"
-msgstr "Stücke"
+msgstr "Teile"
 
-#: editor.cc:672
-#, fuzzy
+#: gtk2_ardour/editor.cc:622
 msgid "Tracks/Busses"
-msgstr "MIDI Spur(en) hinzufügen"
+msgstr "Spuren/Busse"
 
-#: editor.cc:675
+#: gtk2_ardour/editor.cc:625
 msgid "Snapshots"
 msgstr "Schnapschüsse"
 
-#: editor.cc:678
+#: gtk2_ardour/editor.cc:628
 msgid "Edit Groups"
-msgstr ""
+msgstr "Bearbeitungsgruppen"
 
-#: editor.cc:727
-msgid "Nudge region/selection forwards"
-msgstr ""
+#: gtk2_ardour/editor.cc:679
+msgid "Nudge Region/Selection Forwards"
+msgstr "Region/Auswahl schrittweise nach vorne"
 
-#: editor.cc:728
-msgid "Nudge region/selection backwards"
-msgstr ""
+#: gtk2_ardour/editor.cc:680
+msgid "Nudge Region/Selection Backwards"
+msgstr "Region/Auswahl schrittweise nach hinten"
 
-#: editor.cc:735 editor_mixer.cc:299
+#: gtk2_ardour/editor.cc:687
+#: gtk2_ardour/editor_mixer.cc:299
 msgid "ardour: editor"
 msgstr "Ardour: Editor"
 
-#: editor.cc:736
+#: gtk2_ardour/editor.cc:688
 #, fuzzy
 msgid "ardour_editor"
 msgstr "Ardour: Editor"
 
-#: editor.cc:1183
+#: gtk2_ardour/editor.cc:1093
 msgid "ardour: editor: "
 msgstr "Ardour: Editor: "
 
-#. force name
-#: editor.cc:1268 editor.cc:1277 editor_markers.cc:870
+#: gtk2_ardour/editor.cc:1166
+#: gtk2_ardour/editor.cc:1175
+#: gtk2_ardour/editor_markers.cc:874
 msgid "Loop"
 msgstr "Schleife"
 
-#. force name
-#: editor.cc:1282 editor.cc:1291 editor_markers.cc:896
+#: gtk2_ardour/editor.cc:1180
+#: gtk2_ardour/editor.cc:1189
+#: gtk2_ardour/editor_markers.cc:902
 msgid "Punch"
 msgstr ""
 
-#: editor.cc:1439 editor_mouse.cc:1742
+#: gtk2_ardour/editor.cc:1314
+#: gtk2_ardour/editor_mouse.cc:1748
 msgid "programming error: fade in canvas item has no regionview data pointer!"
 msgstr ""
 
-#: editor.cc:1451 editor.cc:1468 redirect_box.cc:1073
-#, fuzzy
+#: gtk2_ardour/editor.cc:1326
+#: gtk2_ardour/editor.cc:1343
+#: gtk2_ardour/redirect_box.cc:1083
 msgid "Deactivate"
-msgstr "Alles deaktivieren"
+msgstr "Deaktivieren"
 
-#. activation
-#: editor.cc:1453 editor.cc:1470 redirect_box.cc:1071
-#, fuzzy
+#: gtk2_ardour/editor.cc:1328
+#: gtk2_ardour/editor.cc:1345
+#: gtk2_ardour/redirect_box.cc:1081
 msgid "Activate"
-msgstr "Aktiv"
+msgstr "Aktivieren"
 
-#: editor.cc:1458 editor.cc:1475
+#: gtk2_ardour/editor.cc:1333
+#: gtk2_ardour/editor.cc:1350
 msgid "Linear"
 msgstr ""
 
-#: editor.cc:1459 editor.cc:1476 editor_actions.cc:376
-#, fuzzy
-msgid "Slowest"
-msgstr "Alle zeigen"
+#: gtk2_ardour/editor.cc:1466
+#: gtk2_ardour/editor.cc:1474
+msgid "Freeze"
+msgstr "Einfrieren"
 
-#: editor.cc:1460 editor.cc:1477 editor_actions.cc:377
-#, fuzzy
-msgid "Slow"
-msgstr "solo"
-
-#: editor.cc:1461 editor.cc:1478 editor_actions.cc:379
-#, fuzzy
-msgid "Fast"
-msgstr "Einfügen"
-
-#: editor.cc:1462 editor.cc:1479 editor_actions.cc:381
-#, fuzzy
-msgid "Fastest"
-msgstr "schnellstmöglich"
-
-#: editor.cc:1589 editor.cc:1597
-msgid "Freeze"
-msgstr ""
-
-#: editor.cc:1593
+#: gtk2_ardour/editor.cc:1470
 msgid "Unfreeze"
-msgstr ""
+msgstr "Auftauen"
 
-#: editor.cc:1762 editor.cc:1857
-#, fuzzy
+#: gtk2_ardour/editor.cc:1639
 msgid "Unmute"
-msgstr "mute"
-
-#. non-operative menu items for menu bar
-#. show editors
-#: editor.cc:1766 editor.cc:2046 editor.cc:2748 editor_actions.cc:27
-#: editor_markers.cc:507 mixer_strip.cc:495 mixer_strip.cc:563
-#: redirect_box.cc:1079
+msgstr "Unmute"
+
+#: gtk2_ardour/editor.cc:1643
+#: gtk2_ardour/editor.cc:1939
+#: gtk2_ardour/editor_actions.cc:28
+#: gtk2_ardour/editor_markers.cc:510
+#: gtk2_ardour/mixer_strip.cc:515
+#: gtk2_ardour/mixer_strip.cc:577
+#: gtk2_ardour/redirect_box.cc:1089
 msgid "Edit"
 msgstr "Bearbeiten"
 
-#: editor.cc:1771
+#: gtk2_ardour/editor.cc:1648
 msgid "Convert to short"
 msgstr ""
 
-#: editor.cc:1773
+#: gtk2_ardour/editor.cc:1650
 msgid "Convert to full"
 msgstr ""
 
-#: editor.cc:1784
-#, fuzzy
+#: gtk2_ardour/editor.cc:1661
 msgid "Crossfade"
-msgstr "Ardour: Editor"
+msgstr "Crossfade"
 
-#: editor.cc:1827
+#: gtk2_ardour/editor.cc:1704
 msgid "Popup region editor"
-msgstr "Regionen Editor Ã¶ffnen"
+msgstr "Regioneneditor Ã¶ffnen"
 
-#: editor.cc:1828
-#, fuzzy
+#: gtk2_ardour/editor.cc:1705
 msgid "Raise to top layer"
 msgstr "Region ganz nach oben"
 
-#: editor.cc:1829
-#, fuzzy
+#: gtk2_ardour/editor.cc:1706
 msgid "Lower to bottom layer"
 msgstr "Region ganz nach unten"
 
-#: editor.cc:1831
+#: gtk2_ardour/editor.cc:1708
 msgid "Define sync point"
 msgstr "Synchronisationspunkt definieren"
 
-#: editor.cc:1832
+#: gtk2_ardour/editor.cc:1709
 msgid "Remove sync point"
 msgstr "Synchronisationspunkt entfernen"
 
-#: editor.cc:1837
-#, fuzzy
+#: gtk2_ardour/editor.cc:1714
 msgid "Bounce"
-msgstr "Bereich"
+msgstr "Bounce"
 
-#: editor.cc:1840
-#, fuzzy
+#: gtk2_ardour/editor.cc:1717
 msgid "Analyze region"
-msgstr "Wiedergabe der Region"
+msgstr "Analysiere Region"
 
-#: editor.cc:1852
-#, fuzzy
+#: gtk2_ardour/editor.cc:1722
 msgid "Lock"
-msgstr "OK"
+msgstr "Sperren"
 
-#: editor.cc:1853
-#, fuzzy
-msgid "Unlock"
-msgstr "Rückgängig"
+#: gtk2_ardour/editor.cc:1732
+msgid "Opaque"
+msgstr "Deckend"
 
-#: editor.cc:1863
-#, fuzzy
+#: gtk2_ardour/editor.cc:1738
 msgid "Original position"
-msgstr "Regionen"
+msgstr "Ursprungsposition"
 
-#: editor.cc:1869
-msgid "Toggle envelope visibility"
-msgstr ""
+#: gtk2_ardour/editor.cc:1750
+msgid "Reset Envelope"
+msgstr "Lautstärkekurve zurücksetzen"
 
-#: editor.cc:1870
-msgid "Toggle envelope active"
-msgstr ""
+#: gtk2_ardour/editor.cc:1752
+msgid "Envelope Visible"
+msgstr "Lautstärkekurve sichtbar"
 
-#: editor.cc:1874
-#, fuzzy
+#: gtk2_ardour/editor.cc:1759
+msgid "Envelope Active"
+msgstr "Lautstärkekurve aktiv"
+
+#: gtk2_ardour/editor.cc:1769
 msgid "DeNormalize"
-msgstr "Ardour: Region"
+msgstr "Ardour: Region "
 
-#: editor.cc:1876
-#, fuzzy
+#: gtk2_ardour/editor.cc:1771
 msgid "Normalize"
-msgstr "Ardour: Region"
+msgstr "Normalisieren"
 
-#: editor.cc:1879
-#, fuzzy
+#: gtk2_ardour/editor.cc:1774
 msgid "Reverse"
-msgstr "Entfernen"
+msgstr "Rückwärts"
 
-#. range related stuff
-#: editor.cc:1885
-#, fuzzy
+#: gtk2_ardour/editor.cc:1780
 msgid "Add Range Markers"
-msgstr "Ardour: Region umbenennen"
+msgstr "Bereichsmarker einfügen"
 
-#: editor.cc:1886
-#, fuzzy
-msgid "Set Range"
-msgstr "Ausgewählten Bereich wiedergeben"
+#: gtk2_ardour/editor.cc:1781
+msgid "Set Range Selection"
+msgstr "Bereich auswählen"
 
-#: editor.cc:1895
+#: gtk2_ardour/editor.cc:1790
 msgid "Nudge fwd"
-msgstr ""
+msgstr "Schritt nach vorne"
 
-#: editor.cc:1896
+#: gtk2_ardour/editor.cc:1791
 msgid "Nudge bwd"
-msgstr ""
+msgstr "Schritt nach hinten"
 
-#: editor.cc:1897
+#: gtk2_ardour/editor.cc:1792
 msgid "Nudge fwd by capture offset"
-msgstr ""
+msgstr "Schritt nach vorne um Aufnahme-Offset"
 
-#: editor.cc:1898
+#: gtk2_ardour/editor.cc:1793
 msgid "Nudge bwd by capture offset"
-msgstr ""
+msgstr "Schritt nach hinten um Aufnahme-Offset"
+
+#: gtk2_ardour/editor.cc:1795
+#: gtk2_ardour/editor.cc:1959
+#: gtk2_ardour/editor.cc:2015
+msgid "Nudge"
+msgstr "Verschieben"
 
-#: editor.cc:1907
+#: gtk2_ardour/editor.cc:1802
 msgid "Start to edit cursor"
-msgstr ""
+msgstr "Von Anfang bis Editierzeiger"
 
-#: editor.cc:1908
+#: gtk2_ardour/editor.cc:1803
 msgid "Edit cursor to end"
-msgstr ""
+msgstr "Von Editierzeiger bis Ende"
 
-#: editor.cc:1910 gain_meter.cc:181 gain_meter.cc:813 panner_ui.cc:98
-#: panner_ui.cc:803
+#: gtk2_ardour/editor.cc:1805
+#: gtk2_ardour/gain_meter.cc:168
+#: gtk2_ardour/gain_meter.cc:848
+#: gtk2_ardour/panner_ui.cc:96
+#: gtk2_ardour/panner_ui.cc:793
 msgid "Trim"
-msgstr ""
+msgstr "Abschneiden"
 
-#: editor.cc:1913
+#: gtk2_ardour/editor.cc:1808
 msgid "Split"
 msgstr "Teilen"
 
-#: editor.cc:1916
-#, fuzzy
+#: gtk2_ardour/editor.cc:1811
 msgid "Make mono regions"
-msgstr "Name für Region:"
+msgstr "Zu Mono-Regionen umwandeln"
 
-#: editor.cc:1919
+#: gtk2_ardour/editor.cc:1814
 msgid "Duplicate"
 msgstr "Duplizieren"
 
-#: editor.cc:1920
-#, fuzzy
+#: gtk2_ardour/editor.cc:1815
 msgid "Fill Track"
-msgstr "Spur"
-
-#: editor.cc:1924
-msgid "Destroy"
-msgstr ""
+msgstr "Spur auffüllen"
 
-#: editor.cc:1954
+#: gtk2_ardour/editor.cc:1847
 #, fuzzy
 msgid "Play range"
 msgstr "Bereich"
 
-#: editor.cc:1955
+#: gtk2_ardour/editor.cc:1848
 #, fuzzy
 msgid "Loop range"
 msgstr "Bereich"
 
-#: editor.cc:1959
-#, fuzzy
+#: gtk2_ardour/editor.cc:1852
 msgid "Analyze range"
-msgstr "Bereich"
+msgstr "Bereich analysieren"
 
-#: editor.cc:1963
+#: gtk2_ardour/editor.cc:1856
 #, fuzzy
 msgid "Separate range to track"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: editor.cc:1964
+#: gtk2_ardour/editor.cc:1857
 #, fuzzy
 msgid "Separate range to region list"
 msgstr "Auswahl zu Schleife machen"
 
-#: editor.cc:1967
+#: gtk2_ardour/editor.cc:1860
 #, fuzzy
 msgid "Select all in range"
 msgstr "Auswahl"
 
-#: editor.cc:1969 editor.cc:2014
-#, fuzzy
+#: gtk2_ardour/editor.cc:1862
+#: gtk2_ardour/editor.cc:1907
 msgid "Set range to loop range"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Ausgewählten Bereich als Schleife"
 
-#: editor.cc:1970 editor.cc:2015
-#, fuzzy
+#: gtk2_ardour/editor.cc:1863
+#: gtk2_ardour/editor.cc:1908
 msgid "Set range to punch range"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Ausgewählten Bereich als Punch-Bereich"
 
-#: editor.cc:1972
-#, fuzzy
+#: gtk2_ardour/editor.cc:1865
 msgid "Crop region to range"
-msgstr "Regionen Editor Ã¶ffnen"
+msgstr "Regionen-Editor Ã¶ffnen"
 
-#: editor.cc:1973
+#: gtk2_ardour/editor.cc:1866
 #, fuzzy
 msgid "Fill range with region"
 msgstr "Region erstellen"
 
-#: editor.cc:1974
+#: gtk2_ardour/editor.cc:1867
 #, fuzzy
 msgid "Duplicate range"
 msgstr "Duplizieren"
 
-#: editor.cc:1975
+#: gtk2_ardour/editor.cc:1868
 #, fuzzy
 msgid "Create chunk from range"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: editor.cc:1977
+#: gtk2_ardour/editor.cc:1870
 #, fuzzy
 msgid "Bounce range"
 msgstr "Bereich"
 
-#: editor.cc:1978
+#: gtk2_ardour/editor.cc:1871
 #, fuzzy
 msgid "Export range"
 msgstr "Name für Region:"
 
-#: editor.cc:1980
+#: gtk2_ardour/editor.cc:1873
 #, fuzzy
 msgid "Range"
 msgstr "Bereich"
 
-#: editor.cc:1995 editor.cc:2080
-#, fuzzy
+#: gtk2_ardour/editor.cc:1888
+#: gtk2_ardour/editor.cc:1973
 msgid "Play from edit cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Wiedergabe ab Editierzeiger"
 
-#: editor.cc:1996 editor.cc:2081
+#: gtk2_ardour/editor.cc:1889
+#: gtk2_ardour/editor.cc:1974
 msgid "Play from start"
 msgstr "Wiedergabe ab Anfang"
 
-#: editor.cc:1997
-#, fuzzy
+#: gtk2_ardour/editor.cc:1890
 msgid "Play region"
-msgstr "Wiedergabe der Region"
+msgstr "Region wiedergeben"
 
-#: editor.cc:1999
-#, fuzzy
+#: gtk2_ardour/editor.cc:1892
 msgid "Loop Region"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Region in Schleife wiedergeben"
 
-#: editor.cc:2009 editor.cc:2090
-#, fuzzy
+#: gtk2_ardour/editor.cc:1902
+#: gtk2_ardour/editor.cc:1983
 msgid "Select All in track"
-msgstr "Auswahl"
+msgstr "Alles in Spur auswählen"
 
-#: editor.cc:2010 editor.cc:2091 redirect_box.cc:1067
-#, fuzzy
+#: gtk2_ardour/editor.cc:1903
+#: gtk2_ardour/editor.cc:1984
+#: gtk2_ardour/redirect_box.cc:1077
 msgid "Select All"
-msgstr "Auswahl"
+msgstr "Alles Auswählen"
 
-#: editor.cc:2011 editor.cc:2092
-#, fuzzy
+#: gtk2_ardour/editor.cc:1904
+#: gtk2_ardour/editor.cc:1985
 msgid "Invert selection in track"
-msgstr "Stille einfügen"
+msgstr "Auswahl in Spur umkehren"
 
-#: editor.cc:2012 editor.cc:2093
-#, fuzzy
+#: gtk2_ardour/editor.cc:1905
+#: gtk2_ardour/editor.cc:1986
 msgid "Invert selection"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Auswahl umkehren"
 
-#: editor.cc:2017 editor.cc:2095
-#, fuzzy
+#: gtk2_ardour/editor.cc:1910
+#: gtk2_ardour/editor.cc:1988
 msgid "Select all after edit cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Alles nach Editierzeiger auswählen"
 
-#: editor.cc:2018 editor.cc:2096
-#, fuzzy
+#: gtk2_ardour/editor.cc:1911
+#: gtk2_ardour/editor.cc:1989
 msgid "Select all before edit cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Alles vor Editierzeiger auswählen"
 
-#: editor.cc:2019 editor.cc:2097
-#, fuzzy
+#: gtk2_ardour/editor.cc:1912
+#: gtk2_ardour/editor.cc:1990
 msgid "Select all after playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Alles nach Positionszeiger auswählen"
 
-#: editor.cc:2020 editor.cc:2098
-#, fuzzy
+#: gtk2_ardour/editor.cc:1913
+#: gtk2_ardour/editor.cc:1991
 msgid "Select all before playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Alles vor Positionszeiger auswählen"
 
-#: editor.cc:2021
-#, fuzzy
+#: gtk2_ardour/editor.cc:1914
 msgid "Select all between cursors"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Alles zwischen Zeigern auswählen"
 
-#. standard editing stuff
-#: editor.cc:2032 editor.cc:2108 editor.cc:3483 editor_actions.cc:214
-#: redirect_box.cc:1060
+#: gtk2_ardour/editor.cc:1917
+#: gtk2_ardour/editor.cc:1993
+msgid "Select"
+msgstr "Auswahl"
+
+#: gtk2_ardour/editor.cc:1925
+#: gtk2_ardour/editor.cc:2001
+#: gtk2_ardour/editor_actions.cc:215
+#: gtk2_ardour/redirect_box.cc:1070
 msgid "Cut"
 msgstr "Ausschneiden"
 
-#: editor.cc:2033 editor.cc:2109 editor.cc:3485 editor_actions.cc:219
-#: redirect_box.cc:1062
+#: gtk2_ardour/editor.cc:1926
+#: gtk2_ardour/editor.cc:2002
+#: gtk2_ardour/editor_actions.cc:220
+#: gtk2_ardour/redirect_box.cc:1072
 msgid "Copy"
 msgstr "Kopieren"
 
-#: editor.cc:2034
-#, fuzzy
+#: gtk2_ardour/editor.cc:1927
 msgid "Paste at edit cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Am Editierzeiger einfügen"
 
-#: editor.cc:2035
+#: gtk2_ardour/editor.cc:1928
 msgid "Paste at mouse"
-msgstr ""
+msgstr "An Mausposition einfügen"
 
-#: editor.cc:2039 editor.cc:3490
+#: gtk2_ardour/editor.cc:1932
 msgid "Align"
-msgstr ""
+msgstr "Ausrichten"
 
-#: editor.cc:2040 editor.cc:3492
+#: gtk2_ardour/editor.cc:1933
 msgid "Align Relative"
-msgstr ""
+msgstr "Relativ ausrichten"
 
-#: editor.cc:2044
+#: gtk2_ardour/editor.cc:1937
 msgid "Insert chunk"
 msgstr "Abschnitt einfügen"
 
-#: editor.cc:2051
-#, fuzzy
+#: gtk2_ardour/editor.cc:1944
 msgid "Insert Selected Region"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Ausgewählte Region einfügen"
 
-#: editor.cc:2052
+#: gtk2_ardour/editor.cc:1945
 msgid "Insert Existing Audio"
-msgstr ""
+msgstr "Audio importieren..."
 
-#: editor.cc:2061 editor.cc:2117
+#: gtk2_ardour/editor.cc:1954
+#: gtk2_ardour/editor.cc:2010
 msgid "Nudge entire track fwd"
-msgstr ""
+msgstr "Gesamte Spur schrittweise nach vorne"
 
-#: editor.cc:2062 editor.cc:2118
+#: gtk2_ardour/editor.cc:1955
+#: gtk2_ardour/editor.cc:2011
 msgid "Nudge track after edit cursor fwd"
-msgstr ""
+msgstr "Spur nach Editierzeiger schrittweise nach vorne"
 
-#: editor.cc:2063 editor.cc:2119
+#: gtk2_ardour/editor.cc:1956
+#: gtk2_ardour/editor.cc:2012
 msgid "Nudge entire track bwd"
-msgstr ""
+msgstr "Gesamte Spur schrittweise nach hinten"
 
-#: editor.cc:2064 editor.cc:2120
+#: gtk2_ardour/editor.cc:1957
+#: gtk2_ardour/editor.cc:2013
 msgid "Nudge track after edit cursor bwd"
-msgstr ""
+msgstr "Spur nach Editierzeiger schrittweise nach hinten"
 
-#: editor.cc:2110 editor.cc:3487 editor_actions.cc:221 redirect_box.cc:1064
+#: gtk2_ardour/editor.cc:2003
+#: gtk2_ardour/editor_actions.cc:222
+#: gtk2_ardour/redirect_box.cc:1074
 msgid "Paste"
 msgstr "Einfügen"
 
-#: editor.cc:2630
-msgid "select/move objects"
-msgstr ""
+#: gtk2_ardour/editor.cc:2566
+msgid "Select/Move Objects"
+msgstr "Objekte auswählen/verschieben"
 
-#: editor.cc:2631
-#, fuzzy
-msgid "select/move ranges"
-msgstr "Ausgewählten Bereich wiedergeben"
+#: gtk2_ardour/editor.cc:2567
+msgid "Select/Move Ranges"
+msgstr "Bereiche auswählen/verschieben"
 
-#: editor.cc:2632
-msgid "draw gain automation"
-msgstr ""
+#: gtk2_ardour/editor.cc:2568
+msgid "Draw Gain Automation"
+msgstr "Lautstärkeautomation zeichnen"
 
-#: editor.cc:2633
-#, fuzzy
-msgid "select zoom range"
-msgstr "Ausgewählten Bereich wiedergeben"
+#: gtk2_ardour/editor.cc:2569
+msgid "Select Zoom Range"
+msgstr "Zoombereich auswählen"
 
-#: editor.cc:2634
-msgid "stretch/shrink regions"
-msgstr ""
+#: gtk2_ardour/editor.cc:2570
+msgid "Stretch/Shrink Regions"
+msgstr "Regionen vergrößern/verkleinern (Time-Stretch)"
 
-#: editor.cc:2635
-#, fuzzy
-msgid "listen to specific regions"
-msgstr "Auswahl zu Schleife machen"
+#: gtk2_ardour/editor.cc:2571
+msgid "Listen to Specific Regions"
+msgstr "Ausgewählte Regionen vorhören"
+
+#: gtk2_ardour/editor.cc:2600
+#: gtk2_ardour/editor_actions.cc:143
+msgid "Zoom In"
+msgstr "Vergrößern"
+
+#: gtk2_ardour/editor.cc:2605
+#: gtk2_ardour/editor_actions.cc:141
+msgid "Zoom Out"
+msgstr "Verkleinern"
+
+#: gtk2_ardour/editor.cc:2610
+#: gtk2_ardour/editor_actions.cc:145
+msgid "Zoom to Session"
+msgstr "Auf ganze Sitzung zoomen"
 
-#: editor.cc:2746
-msgid "Start:"
-msgstr "Anfang:"
+#: gtk2_ardour/editor.cc:2617
+msgid ""
+"Current Zoom Range\n"
+"(Width of visible area)"
+msgstr ""
 
-#: editor.cc:2747
-msgid "End:"
-msgstr "Ende:"
+#: gtk2_ardour/editor.cc:2623
+msgid "Zoom focus"
+msgstr "Zoom-Mittelpunkt"
+
+#: gtk2_ardour/editor.cc:2637
+msgid "Unit to snap cursors and ranges to"
+msgstr ""
 
-#: editor.cc:3362 editor.cc:3402
+#: gtk2_ardour/editor.cc:3217
+#: gtk2_ardour/editor.cc:3266
 #, fuzzy
 msgid "set selected regions"
 msgstr "Auswahl zu Schleife machen"
 
-#: editor.cc:3458 editor_actions.cc:204
+#: gtk2_ardour/editor.cc:3306
+#: gtk2_ardour/editor_actions.cc:205
 msgid "Undo"
 msgstr "Rückgängig"
 
-#: editor.cc:3460
+#: gtk2_ardour/editor.cc:3308
 msgid "Undo (%1)"
 msgstr "Rückgängig (%1)"
 
-#: editor.cc:3470 editor_actions.cc:206
+#: gtk2_ardour/editor.cc:3315
+#: gtk2_ardour/editor_actions.cc:207
 msgid "Redo"
 msgstr "Wiederherstellen"
 
-#: editor.cc:3472
+#: gtk2_ardour/editor.cc:3317
 msgid "Redo (%1)"
 msgstr "Wiederherstellen (%1)"
 
-#: editor.cc:3506
-msgid "... as new track"
-msgstr ""
-
-#: editor.cc:3507
-#, fuzzy
-msgid "... as new region"
-msgstr "Ardour: Region"
-
-#: editor.cc:3509
-#, fuzzy
-msgid "Import audio (copy)"
-msgstr "Audio Importieren"
+#: gtk2_ardour/editor.cc:3338
+msgid "Duplicate how many times?"
+msgstr "Wie häufig duplizieren?"
 
-#: editor.cc:3512
+#: gtk2_ardour/editor.cc:3416
 #, fuzzy
-msgid "Remove last capture"
-msgstr "Synchronisationspunkt entfernen"
+msgid "Splice Edit"
+msgstr "Teilen"
 
-#: editor.cc:3536
-msgid "Duplicate how many times?"
-msgstr "Wie häufig duplizieren?"
+#: gtk2_ardour/editor.cc:3418
+msgid "Slide Edit"
+msgstr ""
 
-#: editor.cc:4022
+#: gtk2_ardour/editor.cc:3828
 msgid ""
 "Playlist %1 is currently unused.\n"
 "If left alone, no audio files used by it will be cleaned.\n"
 "If deleted, audio files used by it alone by will cleaned."
 msgstr ""
 
-#: editor.cc:4030
-#, fuzzy
+#: gtk2_ardour/editor.cc:3836
 msgid "Delete playlist"
-msgstr "Name für Schnappschuß"
+msgstr "Wiedergabeliste löschen"
 
-#: editor.cc:4031
-#, fuzzy
+#: gtk2_ardour/editor.cc:3837
 msgid "Keep playlist"
-msgstr "Name für Schnappschuß"
-
-#: editor.cc:4032 editor_audio_import.cc:236 editor_ops.cc:2048
-#: editor_timefx.cc:71 export_dialog.cc:971 io_selector.cc:59
-#: io_selector.cc:793 redirect_box.cc:903 tempo_dialog.cc:20
-#: tempo_dialog.cc:37 tempo_dialog.cc:202 tempo_dialog.cc:220
+msgstr "Wiedergabeliste beibehalten"
+
+#: gtk2_ardour/editor.cc:3838
+#: gtk2_ardour/editor_audio_import.cc:239
+#: gtk2_ardour/editor_ops.cc:1973
+#: gtk2_ardour/editor_timefx.cc:72
+#: gtk2_ardour/export_dialog.cc:969
+#: gtk2_ardour/io_selector.cc:61
+#: gtk2_ardour/io_selector.cc:750
+#: gtk2_ardour/redirect_box.cc:901
+#: gtk2_ardour/tempo_dialog.cc:20
+#: gtk2_ardour/tempo_dialog.cc:37
+#: gtk2_ardour/tempo_dialog.cc:202
+#: gtk2_ardour/tempo_dialog.cc:220
+#: gtk2_ardour/connection_editor.cc:60
 msgid "Cancel"
 msgstr "Abbrechen"
 
-#: editor.cc:4199
-#, fuzzy
+#: gtk2_ardour/editor.cc:4041
 msgid "new playlists"
-msgstr "Name für Schnappschuß"
+msgstr "Neue Wiedergabelisten"
 
-#: editor.cc:4207
-#, fuzzy
+#: gtk2_ardour/editor.cc:4049
 msgid "copy playlists"
-msgstr "Name für Schnappschuß"
+msgstr "Wiedergabelisten kopieren"
 
-#: editor.cc:4215
-#, fuzzy
+#: gtk2_ardour/editor.cc:4057
 msgid "clear playlists"
-msgstr "Name für Schnappschuß"
+msgstr ""
 
-#: editor_actions.cc:28
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:29
 msgid "Select regions"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Region(en) auswählen"
 
-#: editor_actions.cc:29
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:30
 msgid "Select range operations"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Bereich"
 
-#: editor_actions.cc:30
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:31
 msgid "Move edit cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Editierzeiger bewegen"
 
-#: editor_actions.cc:31
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:32
 msgid "Region operations"
-msgstr "Regionen"
+msgstr "Region(en)"
 
-#: editor_actions.cc:32
+#: gtk2_ardour/editor_actions.cc:33
 msgid "Tools"
 msgstr ""
 
-#: editor_actions.cc:33
+#: gtk2_ardour/editor_actions.cc:34
 msgid "View"
-msgstr ""
+msgstr "Ansicht"
 
-#: editor_actions.cc:34
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:35
 msgid "ZoomFocus"
-msgstr "Verkleinern"
+msgstr "Zoom-Mittelpunkt"
 
-#: editor_actions.cc:35
+#: gtk2_ardour/editor_actions.cc:36
 msgid "Meter hold"
-msgstr ""
+msgstr "Pegelanzeige halten"
 
-#: editor_actions.cc:36
+#: gtk2_ardour/editor_actions.cc:37
 msgid "Meter falloff"
-msgstr ""
+msgstr "Abfall der Pegelanzeigen"
 
-#: editor_actions.cc:38
+#: gtk2_ardour/editor_actions.cc:39
 #, fuzzy
 msgid "Crossfades"
 msgstr "Ardour: Editor"
 
-#: editor_actions.cc:39
+#: gtk2_ardour/editor_actions.cc:40
 msgid "Monitoring"
-msgstr ""
+msgstr "Monitoring"
 
-#: editor_actions.cc:40
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:41
 msgid "Autoconnect"
-msgstr "Verbindungen"
+msgstr "Automatisch verbinden"
 
-#: editor_actions.cc:41
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:42
 msgid "Layering"
-msgstr "Schicht"
+msgstr "Layering"
 
-#: editor_actions.cc:42
-#, fuzzy
-msgid "Metering"
-msgstr "Schicht"
+#: gtk2_ardour/editor_actions.cc:43
+msgid "Timecode fps"
+msgstr ""
 
-#: editor_actions.cc:43
-msgid "Fall off rate"
+#: gtk2_ardour/editor_actions.cc:44
+msgid "Pullup / Pulldown"
 msgstr ""
 
-#: editor_actions.cc:44
-msgid "Hold Time"
+#: gtk2_ardour/editor_actions.cc:45
+msgid "Subframes"
 msgstr ""
 
-#: editor_actions.cc:45
+#: gtk2_ardour/editor_actions.cc:46
 msgid "Add Existing Audio"
-msgstr ""
+msgstr "Audio importieren"
 
-#. add named actions for the editor
-#: editor_actions.cc:50
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:51
 msgid "Show Editor Mixer"
-msgstr "Ardour: Mixer"
+msgstr "Mixer-Panel zeigen"
 
-#: editor_actions.cc:55
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:56
 msgid "Span Entire Overlap"
-msgstr "Region eine Ebene nach oben"
-
-#: editor_actions.cc:57 editor_actions.cc:384
-#, fuzzy
-msgid "Short"
-msgstr "Anschluß"
+msgstr "Gesamte Ãœberlappung"
 
-#: editor_actions.cc:64
+#: gtk2_ardour/editor_actions.cc:65
 msgid "Created Automatically"
-msgstr ""
+msgstr "Automatisch erzeugen"
 
-#: editor_actions.cc:67
+#: gtk2_ardour/editor_actions.cc:68
 msgid "Playhead to Next Region Start"
-msgstr ""
+msgstr "Positionszeiger zum Anfang der nächsten Region"
 
-#: editor_actions.cc:69
+#: gtk2_ardour/editor_actions.cc:70
 msgid "Playhead to Next Region End"
-msgstr ""
+msgstr "Positionszeiger zum Ende der nächsten Region"
 
-#: editor_actions.cc:71
+#: gtk2_ardour/editor_actions.cc:72
 msgid "Playhead to Next Region Sync"
-msgstr ""
+msgstr "Positionszeiger zum Sync der nächsten Region"
 
-#: editor_actions.cc:74
+#: gtk2_ardour/editor_actions.cc:75
 msgid "Playhead to Previous Region Start"
-msgstr ""
+msgstr "Positionszeiger zum Anfang der vorherigen Region"
 
-#: editor_actions.cc:76
+#: gtk2_ardour/editor_actions.cc:77
 msgid "Playhead to Previous Region End"
-msgstr ""
+msgstr "Positionszeiger zum Ende der vorherigen Region"
 
-#: editor_actions.cc:78
+#: gtk2_ardour/editor_actions.cc:79
 msgid "Playhead to Previous Region Sync"
-msgstr ""
+msgstr "Positionszeiger zum Sync der vorherigen Region"
 
-#: editor_actions.cc:81
+#: gtk2_ardour/editor_actions.cc:82
 msgid "Edit Cursor to Next Region Start"
-msgstr ""
+msgstr "Editierzeiger zum Anfang der nächsten Region"
 
-#: editor_actions.cc:83
+#: gtk2_ardour/editor_actions.cc:84
 msgid "Edit Cursor to Next Region End"
-msgstr ""
+msgstr "Editierzeiger zum Ende der nächsten Region"
 
-#: editor_actions.cc:85
+#: gtk2_ardour/editor_actions.cc:86
 msgid "Edit Cursor to Next Region Sync"
-msgstr ""
+msgstr "Editierzeiger zum Sync der nächsten Region"
 
-#: editor_actions.cc:88
+#: gtk2_ardour/editor_actions.cc:89
 msgid "Edit Cursor to Previous Region Start"
-msgstr ""
+msgstr "Editierzeiger zum Anfang der vorherigen Region"
 
-#: editor_actions.cc:90
+#: gtk2_ardour/editor_actions.cc:91
 msgid "Edit Cursor to Previous Region End"
-msgstr ""
+msgstr "Editierzeiger zum Ende der vorherigen Region"
 
-#: editor_actions.cc:92
+#: gtk2_ardour/editor_actions.cc:93
 msgid "Edit Cursor to Previous Region Sync"
-msgstr ""
+msgstr "Editierzeiger zum Sync der vorherigen Region"
 
-#: editor_actions.cc:95
+#: gtk2_ardour/editor_actions.cc:96
 msgid "Playhead to Range Start"
-msgstr ""
+msgstr "Positionszeiger zum Anfang der Auswahl"
 
-#: editor_actions.cc:97
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:98
 msgid "Playhead to Range End"
-msgstr "Bereich"
+msgstr "Positionszeiger zum Ende der Auswahl"
 
-#: editor_actions.cc:100
+#: gtk2_ardour/editor_actions.cc:101
 msgid "Edit Cursor to Range Start"
-msgstr ""
+msgstr "Editierzeiger zum Anfang der Auswahl"
 
-#: editor_actions.cc:102
+#: gtk2_ardour/editor_actions.cc:103
 msgid "Edit Cursor to Range End"
-msgstr ""
+msgstr "Editierzeiger zum Ende der Auswahl"
 
-#: editor_actions.cc:105 editor_ops.cc:1363
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:106
+#: gtk2_ardour/editor_ops.cc:1292
 msgid "select all"
-msgstr "Auswahl"
+msgstr "Alle Regionen auswählen"
 
-#: editor_actions.cc:107
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:108
 msgid "Select All After Edit Cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Alle Regionen nach dem Editierzeiger auswählen"
 
-#: editor_actions.cc:109
+#: gtk2_ardour/editor_actions.cc:110
 msgid "Select All Before Edit Cursor"
-msgstr ""
+msgstr "Alle Regionen vor dem Editierzeiger auswählen"
 
-#: editor_actions.cc:112
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:113
 msgid "Select All After Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Alle Regionen nach dem Positionszeiger auswählen"
 
-#: editor_actions.cc:114
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:115
 msgid "Select All Before Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Alle Regionen vor dem Positionszeiger auswählen"
 
-#: editor_actions.cc:116
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:117
 msgid "Select All Between Cursors"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Alle Regionen zwischen den Zeigern auswählen"
 
-#: editor_actions.cc:119
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:120
 msgid "Select All in Punch Range"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Alle Regionen im Punch-Bereich auswählen"
 
-#: editor_actions.cc:121
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:122
 msgid "Select All in Loop Range"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Alle Regionen innerhalb der Schleife auswählen"
 
-#: editor_actions.cc:124
+#: gtk2_ardour/editor_actions.cc:125
 msgid "Jump Forward to Mark"
-msgstr ""
+msgstr "Zum nächsten Marker springen"
 
-#: editor_actions.cc:126
+#: gtk2_ardour/editor_actions.cc:127
 msgid "Jump Backward to Mark"
-msgstr ""
+msgstr "Zum vorherigen Marker springen"
 
-#: editor_actions.cc:128
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:129
 msgid "Add Location from Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Marker am Positionszeiger setzen"
 
-#: editor_actions.cc:131
+#: gtk2_ardour/editor_actions.cc:132
 msgid "Nudge Forward"
-msgstr ""
+msgstr "Schritt nach vorne"
 
-#: editor_actions.cc:133
+#: gtk2_ardour/editor_actions.cc:134
 msgid "Nudge Next Forward"
 msgstr ""
 
-#: editor_actions.cc:135
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:136
 msgid "Nudge Backward"
-msgstr "Stille einfügen"
+msgstr "Schritt nach Hinten"
 
-#: editor_actions.cc:137
+#: gtk2_ardour/editor_actions.cc:138
 #, fuzzy
 msgid "Nudge Next Backward"
 msgstr "Stille einfügen"
 
-#: editor_actions.cc:140
-#, fuzzy
-msgid "Zoom Out"
-msgstr "Verkleinern"
-
-#: editor_actions.cc:142
-#, fuzzy
-msgid "Zoom In"
-msgstr "Vergrößern"
-
-#: editor_actions.cc:144
-#, fuzzy
-msgid "Zoom to Session"
-msgstr "Vergrößern auf Auswahl"
-
-#: editor_actions.cc:147
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:148
 msgid "Scroll Tracks Up"
-msgstr "Spur"
+msgstr "Spuren nach oben scrollen"
 
-#: editor_actions.cc:149
+#: gtk2_ardour/editor_actions.cc:150
 msgid "Scroll Tracks Down"
-msgstr ""
+msgstr "Spuren nach unten scrollen"
 
-#: editor_actions.cc:151
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:152
 msgid "Step Tracks Up"
-msgstr "Stille einfügen"
+msgstr "Spuren langsam nach oben scrollen"
 
-#: editor_actions.cc:153
+#: gtk2_ardour/editor_actions.cc:154
 msgid "Step Tracks Down"
-msgstr ""
+msgstr "Spuren langsam nach unten scrollen"
 
-#: editor_actions.cc:156
+#: gtk2_ardour/editor_actions.cc:157
 msgid "Scroll Backward"
-msgstr ""
+msgstr "Vorwärts scrollen"
 
-#: editor_actions.cc:158
+#: gtk2_ardour/editor_actions.cc:159
 msgid "Scroll Forward"
-msgstr ""
+msgstr "Rückwärts scrollen"
 
-#: editor_actions.cc:160
+#: gtk2_ardour/editor_actions.cc:161
 msgid "goto"
 msgstr ""
 
-#: editor_actions.cc:162
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:163
 msgid "Center Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Ansicht am Positionszeiger zentrieren"
 
-#: editor_actions.cc:164
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:165
 msgid "Center Edit Cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Editierzeiger zentrieren"
 
-#: editor_actions.cc:166
+#: gtk2_ardour/editor_actions.cc:167
 msgid "Playhead Forward"
-msgstr ""
+msgstr "Positionszeiger vorwärts"
 
-#: editor_actions.cc:168
+#: gtk2_ardour/editor_actions.cc:169
 msgid "Playhead Backward"
-msgstr ""
+msgstr "Positionszeiger rückwärts"
 
-#: editor_actions.cc:170
+#: gtk2_ardour/editor_actions.cc:171
 msgid "Playhead to Edit"
-msgstr ""
+msgstr "Positionszeiger zum Editierzeiger setzen"
 
-#: editor_actions.cc:172
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:173
 msgid "Edit to Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Editierzeiger zum Positionszeiger setzen"
 
-#: editor_actions.cc:175
+#: gtk2_ardour/editor_actions.cc:176
 #, fuzzy
 msgid "Align Regions Start"
 msgstr "Regionen"
 
-#: editor_actions.cc:177
+#: gtk2_ardour/editor_actions.cc:178
 #, fuzzy
 msgid "Align Regions Start Relative"
 msgstr "nach Anfang der Region in der Datei"
 
-#: editor_actions.cc:179
+#: gtk2_ardour/editor_actions.cc:180
 #, fuzzy
 msgid "Align Regions End"
 msgstr "Ardour: Region"
 
-#: editor_actions.cc:181
+#: gtk2_ardour/editor_actions.cc:182
 msgid "Align Regions End Relative"
 msgstr ""
 
-#: editor_actions.cc:184
+#: gtk2_ardour/editor_actions.cc:185
 #, fuzzy
 msgid "Align Regions Sync"
 msgstr "Ardour: Region"
 
-#: editor_actions.cc:186
+#: gtk2_ardour/editor_actions.cc:187
 msgid "Align Regions Sync Relative"
 msgstr ""
 
-#: editor_actions.cc:189
+#: gtk2_ardour/editor_actions.cc:190
 msgid "Audition at Mouse"
-msgstr ""
+msgstr "An Mauszeigerposition vorhören"
 
-#: editor_actions.cc:191
+#: gtk2_ardour/editor_actions.cc:192
 msgid "Brush at Mouse"
-msgstr ""
+msgstr "Pinsel an Mausposition (Brush)"
 
-#: editor_actions.cc:193
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:194
 msgid "Set Edit Cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Editierzeiger setzen"
 
-#: editor_actions.cc:195
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:196
 msgid "Mute/Unmute Region"
-msgstr "Region erstellen"
+msgstr "Region Mute/Unmute"
 
-#: editor_actions.cc:197
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:198
 msgid "Set Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Positionszeiger setzen"
 
-#: editor_actions.cc:199
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:200
 msgid "Split Region"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Region teilen (Split)"
 
-#: editor_actions.cc:201
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:202
 msgid "Set Region Sync Position"
-msgstr "nach Zeitstempel der Region"
+msgstr "Sync-Position der Region setzen"
 
-#: editor_actions.cc:209
+#: gtk2_ardour/editor_actions.cc:210
 #, fuzzy
 msgid "Export Session"
 msgstr "Name für Region:"
 
-#: editor_actions.cc:211
+#: gtk2_ardour/editor_actions.cc:212
 #, fuzzy
 msgid "Export Range"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#. Note: for now, editor-delete does the exact same thing as editor-cut
-#: editor_actions.cc:217
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:218
+#: gtk2_ardour/connection_editor.cc:56
 msgid "Delete"
-msgstr "entfernen"
+msgstr "Löschen"
 
-#: editor_actions.cc:223
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:224
 msgid "Duplicate Region"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Duplizieren"
 
-#: editor_actions.cc:225
+#: gtk2_ardour/editor_actions.cc:226
 #, fuzzy
 msgid "Duplicate Range"
 msgstr "Duplizieren"
 
-#: editor_actions.cc:227
+#: gtk2_ardour/editor_actions.cc:228
 msgid "Insert Region"
-msgstr ""
+msgstr "Einfügen"
 
-#: editor_actions.cc:229
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:230
 msgid "Reverse Region"
-msgstr "Name für Region:"
+msgstr "Rückwärts"
 
-#: editor_actions.cc:231
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:232
 msgid "Normalize Region"
-msgstr "Ardour: Region"
+msgstr "Normalisieren"
 
-#: editor_actions.cc:233
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:234
 msgid "crop"
-msgstr "Kopieren"
+msgstr "Abschneiden"
 
-#: editor_actions.cc:235
+#: gtk2_ardour/editor_actions.cc:236
 #, fuzzy
 msgid "Insert Chunk"
 msgstr "Abschnitt einfügen"
 
-#: editor_actions.cc:238
+#: gtk2_ardour/editor_actions.cc:239
 #, fuzzy
 msgid "Split at edit cursor"
 msgstr "Wiedergabe ab Cursor"
 
-#: editor_actions.cc:241
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:242
 msgid "Start Range"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Bereich anfangen"
 
-#: editor_actions.cc:243
+#: gtk2_ardour/editor_actions.cc:244
 msgid "Finish Range"
-msgstr ""
+msgstr "Bereich beenden"
 
-#: editor_actions.cc:245
+#: gtk2_ardour/editor_actions.cc:246
 msgid "Finish add Range"
 msgstr ""
 
-#: editor_actions.cc:248
+#: gtk2_ardour/editor_actions.cc:249
 msgid "Extend Range to End of Region"
-msgstr ""
+msgstr "Bereich vergrößern bis zum Ende der Region "
 
-#: editor_actions.cc:250
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:251
 msgid "Extend Range to Start of Region"
-msgstr "An den Anfang der Sitzung springen"
+msgstr "Bereich vergrößern bis zum Anfang der Region "
 
-#: editor_actions.cc:253
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:254
 msgid "Follow Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Positionszeiger folgen"
 
-#: editor_actions.cc:261
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:262
 msgid "Zoom Focus Left"
-msgstr "Verkleinern"
+msgstr "Am linken Rand ausrichten"
 
-#: editor_actions.cc:263
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:264
 msgid "Zoom Focus Right"
-msgstr "Verkleinern"
+msgstr "Am rechten Rand ausrichten"
 
-#: editor_actions.cc:265
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:266
 msgid "Zoom Focus Center"
-msgstr "Verkleinern"
+msgstr "Zentriert ausrichten"
 
-#: editor_actions.cc:267
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:268
 msgid "Zoom Focus Playhead"
-msgstr "Verkleinern"
+msgstr "Am Positionszeiger ausrichten"
 
-#: editor_actions.cc:269
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:270
 msgid "Zoom Focus Edit"
-msgstr "Verkleinern"
+msgstr "Am Editierzeiger ausrichten"
 
-#: editor_actions.cc:275
+#: gtk2_ardour/editor_actions.cc:276
 msgid "Object Tool"
-msgstr ""
+msgstr "Objektwerkzeug"
 
-#: editor_actions.cc:276
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:277
 msgid "Range Tool"
-msgstr "Bereich"
+msgstr "Bereich-Werkzeug (Range)"
 
-#: editor_actions.cc:277
+#: gtk2_ardour/editor_actions.cc:278
 msgid "Gain Tool"
-msgstr ""
+msgstr "Lautstärkewerkzeug (Gain)"
 
-#: editor_actions.cc:278
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:279
 msgid "Zoom Tool"
-msgstr "Verkleinern"
+msgstr "Zoom-Werkzeug"
 
-#: editor_actions.cc:279
+#: gtk2_ardour/editor_actions.cc:280
 msgid "Timefx Tool"
-msgstr ""
+msgstr "Zeit-Werkzeug (Time)"
 
-#: editor_actions.cc:286
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:282
+msgid "Snap To"
+msgstr "Raster"
+
+#: gtk2_ardour/editor_actions.cc:283
+msgid "Snap Mode"
+msgstr "Einrastmodus"
+
+#: gtk2_ardour/editor_actions.cc:292
 msgid "Snap to frame"
-msgstr "Modus"
+msgstr "An Frames einrasten"
 
-#: editor_actions.cc:287
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:293
 msgid "Snap to cd frame"
-msgstr "Modus"
+msgstr "An CD-Frames einrasten"
 
-#: editor_actions.cc:288
+#: gtk2_ardour/editor_actions.cc:294
 msgid "Snap to SMPTE frame"
-msgstr ""
+msgstr "An SMPTE-Frames einrasten"
 
-#: editor_actions.cc:289
+#: gtk2_ardour/editor_actions.cc:295
 msgid "Snap to SMPTE seconds"
-msgstr ""
+msgstr "An SMPTE-Sekunden einrasten"
 
-#: editor_actions.cc:290
+#: gtk2_ardour/editor_actions.cc:296
 msgid "Snap to SMPTE minutes"
-msgstr ""
+msgstr "An SMPTE-Minuten einrasten"
 
-#: editor_actions.cc:291
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:297
 msgid "Snap to seconds"
-msgstr "Minuten:Sekunden"
+msgstr "An Sekunden einrasten"
 
-#: editor_actions.cc:292
+#: gtk2_ardour/editor_actions.cc:298
 msgid "Snap to minutes"
-msgstr ""
+msgstr "An Minuten einrasten"
 
-#: editor_actions.cc:293
+#: gtk2_ardour/editor_actions.cc:299
 msgid "Snap to thirtyseconds"
-msgstr ""
+msgstr "An halben Minuten einrasten"
 
-#: editor_actions.cc:294
+#: gtk2_ardour/editor_actions.cc:300
 msgid "Snap to asixteenthbeat"
-msgstr ""
+msgstr "An Sechzehnteln einrasten"
 
-#: editor_actions.cc:295
+#: gtk2_ardour/editor_actions.cc:301
 msgid "Snap to eighths"
-msgstr ""
+msgstr "An Achteln einrasten"
 
-#: editor_actions.cc:296
+#: gtk2_ardour/editor_actions.cc:302
 msgid "Snap to quarters"
-msgstr ""
+msgstr "An Vierteln einrasten"
 
-#: editor_actions.cc:297
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:303
 msgid "Snap to thirds"
-msgstr "Modus"
+msgstr "An Triolen einrasten"
 
-#: editor_actions.cc:298
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:304
 msgid "Snap to beat"
-msgstr "Modus"
+msgstr "An Schlägen einrasten"
 
-#: editor_actions.cc:299
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:305
 msgid "Snap to bar"
-msgstr "Modus"
+msgstr "An Takten einrasten"
 
-#: editor_actions.cc:300
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:306
 msgid "Snap to mark"
-msgstr "Ardour: Region umbenennen"
+msgstr "An Markern einrasten"
 
-#: editor_actions.cc:301
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:307
 msgid "Snap to edit cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Am Editierzeiger einrasten"
 
-#: editor_actions.cc:302
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:308
 msgid "Snap to region start"
-msgstr "Regionen"
+msgstr "Am Anfang der Regionen einrasten"
 
-#: editor_actions.cc:303
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:309
 msgid "Snap to region end"
-msgstr "Regionen"
+msgstr "Am Ende der Regionen einrasten"
 
-#: editor_actions.cc:304
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:310
 msgid "Snap to region sync"
-msgstr "Regionen"
+msgstr "Am Sync der Regionen einrasten"
 
-#: editor_actions.cc:305
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:311
 msgid "Snap to region boundary"
-msgstr "Regionen"
+msgstr "An Grenzen der Regionen einrasten"
 
-#. the region list popup menu
-#: editor_actions.cc:314
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:320
 msgid "Sort"
-msgstr "Anschluß"
+msgstr "Sortieren"
 
-#: editor_actions.cc:322
+#: gtk2_ardour/editor_actions.cc:328
 msgid "Show all"
 msgstr "Alle zeigen"
 
-#: editor_actions.cc:323
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:329
 msgid "Show automatic regions"
-msgstr "Stellen"
+msgstr "Automatische Regionen zeigen"
 
-#: editor_actions.cc:325
+#: gtk2_ardour/editor_actions.cc:331
 msgid "Ascending"
 msgstr "aufsteigend"
 
-#: editor_actions.cc:327
+#: gtk2_ardour/editor_actions.cc:333
 msgid "Descending"
 msgstr "absteigend"
 
-#: editor_actions.cc:330
+#: gtk2_ardour/editor_actions.cc:336
 msgid "By Region Name"
 msgstr "nach Name der Region"
 
-#: editor_actions.cc:332
+#: gtk2_ardour/editor_actions.cc:338
 msgid "By Region Length"
 msgstr "nach Länge der Region"
 
-#: editor_actions.cc:334
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:340
 msgid "By Region Position"
-msgstr "nach Zeitstempel der Region"
+msgstr "nach Position der Region"
 
-#: editor_actions.cc:336
+#: gtk2_ardour/editor_actions.cc:342
 msgid "By Region Timestamp"
 msgstr "nach Zeitstempel der Region"
 
-#: editor_actions.cc:338
+#: gtk2_ardour/editor_actions.cc:344
 msgid "By Region Start in File"
 msgstr "nach Anfang der Region in der Datei"
 
-#: editor_actions.cc:340
+#: gtk2_ardour/editor_actions.cc:346
 msgid "By Region End in File"
 msgstr "nach Ende der Region in der Datei"
 
-#: editor_actions.cc:342
+#: gtk2_ardour/editor_actions.cc:348
 msgid "By Source File Name"
 msgstr "nach Namen der Quelldatei"
 
-#: editor_actions.cc:344
+#: gtk2_ardour/editor_actions.cc:350
 msgid "By Source File Length"
 msgstr "nach Länge der Quelldatei"
 
-#: editor_actions.cc:346
+#: gtk2_ardour/editor_actions.cc:352
 msgid "By Source File Creation Date"
 msgstr "nach Erstellungsdatum der Quelldatei"
 
-#: editor_actions.cc:348
+#: gtk2_ardour/editor_actions.cc:354
 msgid "By Source Filesystem"
 msgstr "nach Dateisystem der Quelle"
 
-#. the next two are duplicate items with different names for use in two different contexts
-#: editor_actions.cc:354
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:360
 msgid "Add External Audio"
-msgstr "Ardour: Region"
+msgstr "Audio importieren..."
 
-#: editor_actions.cc:356
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:362
 msgid "as Region(s)"
-msgstr "Ardour: Region"
+msgstr "als Region(en)..."
 
-#: editor_actions.cc:358
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:364
 msgid "as Tracks"
-msgstr "Spuren"
+msgstr "als neue Spur(en)..."
 
-#: editor_actions.cc:360
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:366
+msgid "as Tape Tracks"
+msgstr "als neue Tape-Spur(en)..."
+
+#: gtk2_ardour/editor_actions.cc:368
 msgid "to Tracks"
-msgstr "Spuren"
+msgstr "in vorhandene Spuren..."
 
-#: editor_actions.cc:363
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:371
 msgid "Show Waveforms"
-msgstr "Wellenform zeigen"
+msgstr "Wellenformen zeigen"
 
-#: editor_actions.cc:364
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:372
 msgid "Show Waveforms While Recording"
-msgstr "Wellenform zeigen"
+msgstr "Wellenformen beim Aufnehmen zeigen"
 
-#: editor_actions.cc:365
+#: gtk2_ardour/editor_actions.cc:373
 msgid "Show Measures"
+msgstr "Takte zeigen"
+
+#: gtk2_ardour/editor_actions.cc:377
+msgid "Later is Higher"
+msgstr "Neuste nach oben"
+
+#: gtk2_ardour/editor_actions.cc:378
+msgid "Most Recently Moved/Added is Higher"
+msgstr "Zuletzt bewegte/hinzugefügte nach oben"
+
+#: gtk2_ardour/editor_actions.cc:379
+msgid "Most Recently Added is Higher"
+msgstr "Zuletzt hinzugefügte nach oben"
+
+#: gtk2_ardour/editor_actions.cc:383
+msgid "23.976"
 msgstr ""
 
-#: editor_actions.cc:378 editor_actions.cc:385
-msgid "Medium"
+#: gtk2_ardour/editor_actions.cc:384
+msgid "24"
 msgstr ""
 
-#: editor_actions.cc:380
-#, fuzzy
-msgid "Faster"
-msgstr "Einfügen"
+#: gtk2_ardour/editor_actions.cc:385
+msgid "24.976"
+msgstr ""
 
-#: editor_actions.cc:386
-msgid "Long"
+#: gtk2_ardour/editor_actions.cc:386
+msgid "25"
 msgstr ""
 
-#: editor_actions.cc:390
-#, fuzzy
-msgid "Later is Higher"
-msgstr "Region eine Ebene nach unten"
+#: gtk2_ardour/editor_actions.cc:387
+msgid "29.97"
+msgstr ""
 
-#: editor_actions.cc:391
-#, fuzzy
-msgid "Most Recently Moved/Added is Higher"
-msgstr "Region eine Ebene nach unten"
+#: gtk2_ardour/editor_actions.cc:388
+msgid "29.97 drop"
+msgstr ""
 
-#: editor_actions.cc:392
-#, fuzzy
-msgid "Most Recently Added is Higher"
-msgstr "Region eine Ebene nach unten"
+#: gtk2_ardour/editor_actions.cc:389
+msgid "30"
+msgstr ""
 
-#: editor_audio_import.cc:72
-#, fuzzy
-msgid "You can't import or embed an audiofile until you have a session loaded."
+#: gtk2_ardour/editor_actions.cc:390
+msgid "30 drop"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:391
+msgid "59.94"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:392
+msgid "60"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:396
+msgid "+4.1667% + 0.1%"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:397
+msgid "+4.1667%"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:398
+msgid "+4.1667% - 0.1%"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:399
+msgid "+ 0.1%"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:401
+msgid "- 0.1%"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:402
+msgid "-4.1667% + 0.1%"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:403
+msgid "-4.1667%"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:404
+msgid "-4.1667% - 0.1%"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:408
+msgid "80 per frame"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:409
+msgid "100 per frame"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:529
+msgid "programming error: Unexpected SMPTE value (%1, drop = %2) in update_smpte_mode.  Menu is probably wrong."
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:708
+#: gtk2_ardour/editor_actions.cc:753
+#: gtk2_ardour/editor_actions.cc:764
+#: gtk2_ardour/editor_actions.cc:808
+#: gtk2_ardour/editor_actions.cc:818
+msgid "programming error: %1: %2"
+msgstr ""
+
+#: gtk2_ardour/editor_actions.cc:719
+#: gtk2_ardour/editor_actions.cc:970
+#: gtk2_ardour/editor_actions.cc:983
+#: gtk2_ardour/editor_actions.cc:1047
+#: gtk2_ardour/sfdb_ui.cc:454
+msgid "programming error: %1"
 msgstr ""
-"Sie können keine Audio-Daten importieren, solange keine Sitzung geladen ist."
 
-#: editor_audio_import.cc:77
+#: gtk2_ardour/editor_actions.cc:1002
+msgid "Configuraton is using unhandled subframes per frame value: %1"
+msgstr ""
+
+#: gtk2_ardour/editor_audio_import.cc:75
 #, fuzzy
+msgid "You can't import or embed an audiofile until you have a session loaded."
+msgstr "Sie können keine Audio-Daten importieren, solange keine Sitzung geladen ist."
+
+#: gtk2_ardour/editor_audio_import.cc:80
 msgid "Add existing audio to session"
-msgstr "Stellen"
+msgstr "Audio importieren"
 
-#: editor_audio_import.cc:142
+#: gtk2_ardour/editor_audio_import.cc:145
 #, fuzzy
 msgid "ardour: importing %1"
 msgstr "Ardour: Exportieren"
 
-#: editor_audio_import.cc:146
+#: gtk2_ardour/editor_audio_import.cc:149
 msgid "Cancel Import"
 msgstr "Importieren Abbrechen"
 
-#: editor_audio_import.cc:224
+#: gtk2_ardour/editor_audio_import.cc:227
 msgid "Editor: cannot open file \"%1\", (%2)"
 msgstr ""
 
-#: editor_audio_import.cc:232
+#: gtk2_ardour/editor_audio_import.cc:235
 #, fuzzy
 msgid "Cancel entire import"
 msgstr "Importieren Abbrechen"
 
-#: editor_audio_import.cc:233
+#: gtk2_ardour/editor_audio_import.cc:236
 #, fuzzy
 msgid "Don't embed it"
 msgstr "Ohne %1"
 
-#: editor_audio_import.cc:234
+#: gtk2_ardour/editor_audio_import.cc:237
 msgid "Embed all without questions"
 msgstr ""
 
-#: editor_audio_import.cc:239
+#: gtk2_ardour/editor_audio_import.cc:242
 msgid "Embed it anyway"
 msgstr ""
 
-#: editor_audio_import.cc:242
+#: gtk2_ardour/editor_audio_import.cc:245
 msgid ""
 "%1\n"
 "This audiofile's sample rate doesn't match the session sample rate!"
 msgstr ""
 
-#: editor_audio_import.cc:275
+#: gtk2_ardour/editor_audio_import.cc:282
 msgid "could not open %1"
 msgstr "Konnte \"%s\" nicht Ã¶ffnen."
 
-#: editor_audio_import.cc:320
+#: gtk2_ardour/editor_audio_import.cc:331
 #, fuzzy
 msgid "insert sndfile"
 msgstr "Stille einfügen"
 
-#. stuff for the verbose canvas cursor
-#: editor_canvas.cc:118
+#: gtk2_ardour/editor_canvas.cc:119
 msgid "VerboseCanvasCursor"
 msgstr ""
 
-#: editor_edit_groups.cc:53 mixer_ui.cc:736
-#, fuzzy
+#: gtk2_ardour/editor_edit_groups.cc:53
+#: gtk2_ardour/mixer_ui.cc:754
 msgid "Activate All"
-msgstr "Aktiv"
+msgstr "Alle aktivieren"
 
-#: editor_edit_groups.cc:54 mixer_ui.cc:737
-#, fuzzy
+#: gtk2_ardour/editor_edit_groups.cc:54
+#: gtk2_ardour/mixer_ui.cc:755
 msgid "Disable All"
-msgstr "Trennen"
+msgstr "Alle deaktivieren"
 
-#: editor_edit_groups.cc:56 mixer_ui.cc:739
-#, fuzzy
+#: gtk2_ardour/editor_edit_groups.cc:56
+#: gtk2_ardour/mixer_ui.cc:757
 msgid "Add group"
-msgstr "keine Gruppe"
+msgstr "Gruppe hinzufügen"
 
-#: editor_edit_groups.cc:229 mixer_ui.cc:970
+#: gtk2_ardour/editor_edit_groups.cc:229
+#: gtk2_ardour/mixer_ui.cc:988
 #, fuzzy
 msgid "unnamed"
 msgstr "Umbenennen"
 
-#: editor_edit_groups.cc:258 mixer_ui.cc:834
+#: gtk2_ardour/editor_edit_groups.cc:258
+#: gtk2_ardour/mixer_ui.cc:852
 msgid "-all-"
 msgstr "-alle-"
 
-#: editor_export_audio.cc:65
+#: gtk2_ardour/editor_export_audio.cc:67
 msgid ""
 "There is no selection to export.\n"
 "\n"
 "Select a selection using the range mouse mode"
 msgstr ""
 
-#: editor_export_audio.cc:110
+#: gtk2_ardour/editor_export_audio.cc:112
 msgid ""
 "There are no ranges to export.\n"
 "\n"
 "Create 1 or more ranges by dragging the mouse in the range bar"
 msgstr ""
 
-#: editor_imageframe.cc:625 editor_imageframe.cc:655
+#: gtk2_ardour/editor_imageframe.cc:625
+#: gtk2_ardour/editor_imageframe.cc:655
 msgid "programming error: no ImageFrameView selected"
 msgstr ""
 
-#: editor_imageframe.cc:848 editor_imageframe.cc:870
+#: gtk2_ardour/editor_imageframe.cc:848
+#: gtk2_ardour/editor_imageframe.cc:870
 msgid "programming error: no MarkerView selected"
 msgstr ""
 
-#: editor_keyboard.cc:104
+#: gtk2_ardour/editor_keyboard.cc:105
 #, fuzzy
 msgid "mute region"
 msgstr "Name für Region:"
 
-#: editor_keys.cc:46
+#: gtk2_ardour/editor_keys.cc:46
 #, fuzzy
 msgid "keyboard selection"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: editor_markers.cc:292 editor_ops.cc:1290 editor_ops.cc:1303
-#: editor_ops.cc:1321 location_ui.cc:774
+#: gtk2_ardour/editor_markers.cc:293
+#: gtk2_ardour/editor_ops.cc:1213
+#: gtk2_ardour/editor_ops.cc:1227
+#: gtk2_ardour/editor_ops.cc:1246
+#: gtk2_ardour/location_ui.cc:776
 msgid "add marker"
 msgstr ""
 
-#: editor_markers.cc:307 editor_markers.cc:380 editor_markers.cc:552
-#: editor_markers.cc:570 editor_markers.cc:589 editor_markers.cc:608
-#: editor_markers.cc:638 editor_markers.cc:666 editor_markers.cc:694
-#: editor_markers.cc:732 editor_markers.cc:759 editor_markers.cc:782
-#: editor_markers.cc:801 editor_mouse.cc:2015 editor_mouse.cc:4275
+#: gtk2_ardour/editor_markers.cc:309
+#: gtk2_ardour/editor_markers.cc:383
+#: gtk2_ardour/editor_markers.cc:555
+#: gtk2_ardour/editor_markers.cc:573
+#: gtk2_ardour/editor_markers.cc:592
+#: gtk2_ardour/editor_markers.cc:611
+#: gtk2_ardour/editor_markers.cc:641
+#: gtk2_ardour/editor_markers.cc:669
+#: gtk2_ardour/editor_markers.cc:697
+#: gtk2_ardour/editor_markers.cc:735
+#: gtk2_ardour/editor_markers.cc:762
+#: gtk2_ardour/editor_markers.cc:785
+#: gtk2_ardour/editor_markers.cc:804
+#: gtk2_ardour/editor_mouse.cc:2031
+#: gtk2_ardour/editor_mouse.cc:4331
 msgid "programming error: marker canvas item has no marker object pointer!"
 msgstr ""
 
-#: editor_markers.cc:331 location_ui.cc:656
+#: gtk2_ardour/editor_markers.cc:333
+#: gtk2_ardour/location_ui.cc:657
 msgid "remove marker"
-msgstr ""
+msgstr "Marker entfernen"
 
-#: editor_markers.cc:458
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:461
 msgid "Locate to Mark"
-msgstr "Stellen"
+msgstr "Positionszeiger zu Marker setzen"
 
-#: editor_markers.cc:459
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:462
 msgid "Play from Mark"
-msgstr "Wiedergabe ab Anfang"
+msgstr "Wiedergabe ab Marker"
 
-#: editor_markers.cc:460
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:463
 msgid "Set Mark from Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Marker am Positionszeiger setzen"
 
-#: editor_markers.cc:464
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:467
 msgid "Rename Mark"
-msgstr "Umbenennen"
+msgstr "Marker umbenennen"
 
-#: editor_markers.cc:465
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:468
 msgid "Hide Mark"
-msgstr "Stille einfügen"
+msgstr "Marker verbergen"
 
-#: editor_markers.cc:466
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:469
 msgid "Remove Mark"
-msgstr "Feld entfernen"
+msgstr "Marker entfernen"
 
-#: editor_markers.cc:479 editor_markers.cc:535
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:482
+#: gtk2_ardour/editor_markers.cc:538
 msgid "Locate to Range Mark"
-msgstr "Stellen"
+msgstr "Positionszeiger zu Bereichsmarker"
 
-#: editor_markers.cc:480 editor_markers.cc:536
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:483
+#: gtk2_ardour/editor_markers.cc:539
 msgid "Play from Range Mark"
-msgstr "Bereich"
+msgstr "Wiedergabe ab Bereichsmarker"
 
-#: editor_markers.cc:481
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:484
 msgid "Loop Range"
-msgstr "Bereich"
+msgstr "Bereich in Schleife wiedergeben"
 
-#: editor_markers.cc:482 editor_markers.cc:537
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:485
+#: gtk2_ardour/editor_markers.cc:540
 msgid "Set Range Mark from Playhead"
-msgstr "Wiedergabe ab Playhead"
+msgstr "Bereichsmarker zum Positionszeiger verschieben"
 
-#: editor_markers.cc:483 editor_markers.cc:538
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:486
+#: gtk2_ardour/editor_markers.cc:541
 msgid "Set Range from Range Selection"
-msgstr "Auswahl wiedergeben"
+msgstr "Bereichsmarker zum Auswahlbereich verschieben"
 
-#: editor_markers.cc:487
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:490
 msgid "Rename Range"
-msgstr "Umbenennen"
+msgstr "Bereich umbenennen"
 
-#: editor_markers.cc:488 editor_markers.cc:540
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:491
+#: gtk2_ardour/editor_markers.cc:543
 msgid "Hide Range"
-msgstr "Bereich"
+msgstr "Bereich verbergen"
 
-#: editor_markers.cc:489
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:492
 msgid "Remove Range"
-msgstr "Feld entfernen"
+msgstr "Bereich entfernen"
 
-#: editor_markers.cc:493 editor_markers.cc:542
+#: gtk2_ardour/editor_markers.cc:496
+#: gtk2_ardour/editor_markers.cc:545
 msgid "Separate Regions in Range"
-msgstr ""
+msgstr "Regionen an Bereichsgrenzen teilen"
 
-#: editor_markers.cc:494 editor_markers.cc:543
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:497
+#: gtk2_ardour/editor_markers.cc:546
 msgid "Select All in Range"
-msgstr "Auswahl"
+msgstr "Alles im Bereich auswählen"
 
-#: editor_markers.cc:520
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:523
 msgid "Set Loop Range"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Schleife erstellen"
 
-#: editor_markers.cc:521
+#: gtk2_ardour/editor_markers.cc:524
 msgid "Set Punch Range"
-msgstr ""
+msgstr "Punch-Bereich erstellen"
 
-#: editor_markers.cc:815
+#: gtk2_ardour/editor_markers.cc:818
 #, fuzzy
 msgid "New Name:"
 msgstr "Neuer Name: "
 
-#: editor_markers.cc:818
+#: gtk2_ardour/editor_markers.cc:821
 #, fuzzy
 msgid "ardour: rename mark"
 msgstr "Ardour: Region umbenennen"
 
-#: editor_markers.cc:820
+#: gtk2_ardour/editor_markers.cc:823
 #, fuzzy
 msgid "ardour: rename range"
 msgstr "Ardour: Region umbenennen"
 
-#: editor_markers.cc:840
+#: gtk2_ardour/editor_markers.cc:843
 #, fuzzy
 msgid "rename marker"
 msgstr "Feld entfernen"
 
-#: editor_markers.cc:865
+#: gtk2_ardour/editor_markers.cc:869
 #, fuzzy
 msgid "set loop range"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: editor_markers.cc:891
+#: gtk2_ardour/editor_markers.cc:897
 #, fuzzy
 msgid "set punch range"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: editor_mouse.cc:103
+#: gtk2_ardour/editor_mouse.cc:105
 msgid "Editor::event_frame() used on unhandled event type %1"
 msgstr ""
 
-#: editor_mouse.cc:313
+#: gtk2_ardour/editor_mouse.cc:315
 #, fuzzy
 msgid "select on click"
 msgstr "Auswahl"
 
-#: editor_mouse.cc:1590
+#: gtk2_ardour/editor_mouse.cc:1596
 msgid "programming error: start_grab called without drag item"
 msgstr ""
 
-#: editor_mouse.cc:1814
+#: gtk2_ardour/editor_mouse.cc:1820
 msgid "change fade in length"
 msgstr ""
 
-#: editor_mouse.cc:1832
+#: gtk2_ardour/editor_mouse.cc:1842
 msgid "programming error: fade out canvas item has no regionview data pointer!"
 msgstr ""
 
-#: editor_mouse.cc:1906
+#: gtk2_ardour/editor_mouse.cc:1916
 #, fuzzy
 msgid "change fade out length"
 msgstr "Ardour: Editor"
 
-#: editor_mouse.cc:1925
+#: gtk2_ardour/editor_mouse.cc:1939
 msgid "programming error: cursor canvas item has no cursor data pointer!"
 msgstr ""
 
-#: editor_mouse.cc:2142
-#, fuzzy
+#: gtk2_ardour/editor_mouse.cc:2166
 msgid "move marker"
-msgstr "Feld entfernen"
+msgstr "Marker bewegen"
 
-#: editor_mouse.cc:2165 editor_mouse.cc:2196 editor_tempodisplay.cc:459
-msgid ""
-"programming error: meter marker canvas item has no marker object pointer!"
+#: gtk2_ardour/editor_mouse.cc:2194
+#: gtk2_ardour/editor_mouse.cc:2225
+#: gtk2_ardour/editor_tempodisplay.cc:492
+msgid "programming error: meter marker canvas item has no marker object pointer!"
 msgstr ""
 
-#: editor_mouse.cc:2264
+#: gtk2_ardour/editor_mouse.cc:2293
 #, fuzzy
 msgid "copy meter mark"
 msgstr "Ardour: Region umbenennen"
 
-#: editor_mouse.cc:2274
+#: gtk2_ardour/editor_mouse.cc:2304
 msgid "move meter mark"
-msgstr ""
+msgstr "Taktwechsel bewegen"
 
-#: editor_mouse.cc:2289 editor_mouse.cc:2322 editor_tempodisplay.cc:331
-#: editor_tempodisplay.cc:409 editor_tempodisplay.cc:428
-msgid ""
-"programming error: tempo marker canvas item has no marker object pointer!"
+#: gtk2_ardour/editor_mouse.cc:2320
+#: gtk2_ardour/editor_mouse.cc:2353
+#: gtk2_ardour/editor_tempodisplay.cc:355
+#: gtk2_ardour/editor_tempodisplay.cc:439
+#: gtk2_ardour/editor_tempodisplay.cc:458
+msgid "programming error: tempo marker canvas item has no marker object pointer!"
 msgstr ""
 
-#: editor_mouse.cc:2294 editor_mouse.cc:2327 editor_tempodisplay.cc:336
-#: editor_tempodisplay.cc:414
+#: gtk2_ardour/editor_mouse.cc:2325
+#: gtk2_ardour/editor_mouse.cc:2358
+#: gtk2_ardour/editor_tempodisplay.cc:360
+#: gtk2_ardour/editor_tempodisplay.cc:444
 msgid "programming error: marker for tempo is not a tempo marker!"
 msgstr ""
 
-#: editor_mouse.cc:2394
+#: gtk2_ardour/editor_mouse.cc:2425
 #, fuzzy
 msgid "copy tempo mark"
 msgstr "Ardour: Region umbenennen"
 
-#: editor_mouse.cc:2404
+#: gtk2_ardour/editor_mouse.cc:2436
 msgid "move tempo mark"
-msgstr ""
+msgstr "Tempowechsel bewegen"
 
-#: editor_mouse.cc:2418 editor_mouse.cc:2437 editor_mouse.cc:2450
-msgid ""
-"programming error: control point canvas item has no control point object "
-"pointer!"
+#: gtk2_ardour/editor_mouse.cc:2451
+#: gtk2_ardour/editor_mouse.cc:2470
+#: gtk2_ardour/editor_mouse.cc:2483
+msgid "programming error: control point canvas item has no control point object pointer!"
 msgstr ""
 
-#: editor_mouse.cc:2555
+#: gtk2_ardour/editor_mouse.cc:2589
 msgid "programming error: line canvas item has no line pointer!"
 msgstr ""
 
-#: editor_mouse.cc:2664
-#, fuzzy
+#: gtk2_ardour/editor_mouse.cc:2698
 msgid "move region(s)"
-msgstr "Name für Region:"
+msgstr "Region(en) bewegen"
 
-#: editor_mouse.cc:2727
+#: gtk2_ardour/editor_mouse.cc:2762
 #, fuzzy
 msgid "Drag region brush"
 msgstr "Ardour: Region"
 
-#. don't copy again
-#. this is committed in the grab finished callback.
-#: editor_mouse.cc:2751
+#: gtk2_ardour/editor_mouse.cc:2784
 msgid "Drag region copy"
 msgstr ""
 
-#. A selection grab currently creates two undo/redo operations, one for
-#. creating the new region and another for moving it.
-#.
-#: editor_mouse.cc:3609
+#: gtk2_ardour/editor_mouse.cc:3648
 #, fuzzy
 msgid "selection grab"
 msgstr "Auswahl"
 
-#: editor_mouse.cc:3650
+#: gtk2_ardour/editor_mouse.cc:3690
 #, fuzzy
 msgid "cancel selection"
 msgstr "Auswahl wiedergeben"
 
-#: editor_mouse.cc:3760
+#: gtk2_ardour/editor_mouse.cc:3800
 #, fuzzy
 msgid "range selection"
 msgstr "Auswahl wiedergeben"
 
-#: editor_mouse.cc:3776
+#: gtk2_ardour/editor_mouse.cc:3816
 #, fuzzy
 msgid "trim selection start"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: editor_mouse.cc:3792
+#: gtk2_ardour/editor_mouse.cc:3832
 #, fuzzy
 msgid "trim selection end"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: editor_mouse.cc:3809
-#, fuzzy
+#: gtk2_ardour/editor_mouse.cc:3849
 msgid "move selection"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Auswahl bewegen"
 
-#: editor_mouse.cc:4195
+#: gtk2_ardour/editor_mouse.cc:4240
 msgid "Start point trim"
 msgstr ""
 
-#: editor_mouse.cc:4223
+#: gtk2_ardour/editor_mouse.cc:4272
 msgid "End point trim"
 msgstr ""
 
-#: editor_mouse.cc:4262
+#: gtk2_ardour/editor_mouse.cc:4315
 #, fuzzy
 msgid "trimmed region"
 msgstr "Ardour: Region"
 
-#: editor_mouse.cc:4400
+#: gtk2_ardour/editor_mouse.cc:4457
 #, fuzzy
 msgid "new range marker"
 msgstr "Ardour: Region umbenennen"
 
-#: editor_mouse.cc:4642
+#: gtk2_ardour/editor_mouse.cc:4701
 #, fuzzy
 msgid "select regions"
 msgstr "Auswahl zu Schleife machen"
 
-#: editor_mouse.cc:4671
+#: gtk2_ardour/editor_mouse.cc:4730
 msgid "Name for region:"
 msgstr "Name für Region:"
 
-#: editor_mouse.cc:4735
+#: gtk2_ardour/editor_mouse.cc:4794
 #, fuzzy
 msgid "timestretch"
 msgstr "Ardour: Mixer"
 
-#: editor_ops.cc:195
+#: gtk2_ardour/editor_ops.cc:115
 #, fuzzy
 msgid "split"
 msgstr "Teilen"
 
-#: editor_ops.cc:231
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:154
 msgid "remove region"
-msgstr "Name für Region:"
+msgstr "Region(en) löschen"
 
-#: editor_ops.cc:250
+#: gtk2_ardour/editor_ops.cc:174
 msgid ""
 " This is destructive, will possibly delete audio files\n"
 "It cannot be undone\n"
 "Do you really want to destroy %1 ?"
 msgstr ""
 
-#: editor_ops.cc:254
+#: gtk2_ardour/editor_ops.cc:178
 #, fuzzy
 msgid "these regions"
 msgstr "Name für Region:"
 
-#: editor_ops.cc:254
+#: gtk2_ardour/editor_ops.cc:178
 #, fuzzy
 msgid "this region"
 msgstr "Name für Region:"
 
-#: editor_ops.cc:256 editor_ops.cc:3318 route_ui.cc:707
-#: visual_time_axis.cc:278
+#: gtk2_ardour/editor_ops.cc:180
+#: gtk2_ardour/editor_ops.cc:3293
+#: gtk2_ardour/route_ui.cc:736
+#: gtk2_ardour/visual_time_axis.cc:283
 msgid "No, do nothing."
 msgstr "Nein, nichts machen."
 
-#: editor_ops.cc:259
+#: gtk2_ardour/editor_ops.cc:183
 #, fuzzy
 msgid "Yes, destroy them."
 msgstr "Ja, entfernen."
 
-#: editor_ops.cc:261 editor_ops.cc:3319
+#: gtk2_ardour/editor_ops.cc:185
+#: gtk2_ardour/editor_ops.cc:3294
 #, fuzzy
 msgid "Yes, destroy it."
 msgstr "Ja, entfernen."
 
-#: editor_ops.cc:352 editor_ops.cc:380
+#: gtk2_ardour/editor_ops.cc:271
+#: gtk2_ardour/editor_ops.cc:299
 #, fuzzy
 msgid "extend selection"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: editor_ops.cc:396 editor_ops.cc:430 editor_ops.cc:474 editor_ops.cc:500
+#: gtk2_ardour/editor_ops.cc:315
+#: gtk2_ardour/editor_ops.cc:350
+#: gtk2_ardour/editor_ops.cc:395
+#: gtk2_ardour/editor_ops.cc:422
 msgid "nudge forward"
 msgstr ""
 
-#: editor_ops.cc:564
+#: gtk2_ardour/editor_ops.cc:487
 msgid "build_region_boundary_cache called with snap_type = %1"
 msgstr ""
 
-#: editor_ops.cc:1420
+#: gtk2_ardour/editor_ops.cc:1350
 #, fuzzy
 msgid "select all within"
 msgstr "Auswahl"
 
-#: editor_ops.cc:1452
+#: gtk2_ardour/editor_ops.cc:1383
 #, fuzzy
 msgid "set selection from region"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: editor_ops.cc:1485
+#: gtk2_ardour/editor_ops.cc:1416
 #, fuzzy
 msgid "set selection from range"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: editor_ops.cc:1515
+#: gtk2_ardour/editor_ops.cc:1446
 #, fuzzy
 msgid "select all from range"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: editor_ops.cc:1537
+#: gtk2_ardour/editor_ops.cc:1468
 #, fuzzy
 msgid "select all from punch"
 msgstr "Auswahl"
 
-#: editor_ops.cc:1559
+#: gtk2_ardour/editor_ops.cc:1490
 #, fuzzy
 msgid "select all from loop"
 msgstr "Auswahl"
 
-#: editor_ops.cc:1573
+#: gtk2_ardour/editor_ops.cc:1504
 #, fuzzy
 msgid "select all after cursor"
 msgstr "Wiedergabe ab Cursor"
 
-#: editor_ops.cc:1578
+#: gtk2_ardour/editor_ops.cc:1509
 #, fuzzy
 msgid "select all before cursor"
 msgstr "Wiedergabe ab Cursor"
 
-#: editor_ops.cc:1608
+#: gtk2_ardour/editor_ops.cc:1539
 #, fuzzy
 msgid "select all between cursors"
 msgstr "Wiedergabe ab Cursor"
 
-#: editor_ops.cc:1739
+#: gtk2_ardour/editor_ops.cc:1670
 msgid "clear markers"
 msgstr ""
 
-#: editor_ops.cc:1751
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1683
 msgid "clear ranges"
-msgstr "Verbindungen löschen"
+msgstr "Verbindungen entfernen"
 
-#: editor_ops.cc:1770
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1703
 msgid "clear locations"
-msgstr "Verbindungen löschen"
+msgstr "Verbindungen entfernen"
 
-#: editor_ops.cc:1820
+#: gtk2_ardour/editor_ops.cc:1754
 #, fuzzy
 msgid "insert dragged region"
 msgstr "Ardour: Region"
 
-#: editor_ops.cc:1856
+#: gtk2_ardour/editor_ops.cc:1797
 #, fuzzy
 msgid "insert region"
 msgstr "Name für Region:"
 
-#: editor_ops.cc:2047 io_selector.cc:58 io_selector.cc:792
+#: gtk2_ardour/editor_ops.cc:1972
+#: gtk2_ardour/io_selector.cc:60
+#: gtk2_ardour/io_selector.cc:749
+#: gtk2_ardour/connection_editor.cc:86
 msgid "OK"
 msgstr ""
 
-#: editor_ops.cc:2054
+#: gtk2_ardour/editor_ops.cc:1979
 msgid "ardour: rename region"
 msgstr "Ardour: Region umbenennen"
 
-#: editor_ops.cc:2277 editor_ops.cc:2326
+#: gtk2_ardour/editor_ops.cc:2204
+#: gtk2_ardour/editor_ops.cc:2257
 #, fuzzy
 msgid "separate"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: editor_ops.cc:2388
+#: gtk2_ardour/editor_ops.cc:2322
 #, fuzzy
 msgid "trim to selection"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: editor_ops.cc:2428
+#: gtk2_ardour/editor_ops.cc:2363
 msgid "region fill"
 msgstr ""
 
-#: editor_ops.cc:2487
+#: gtk2_ardour/editor_ops.cc:2427
 #, fuzzy
 msgid "fill selection"
 msgstr "Auswahl zu Schleife machen"
 
-#: editor_ops.cc:2508
+#: gtk2_ardour/editor_ops.cc:2448
 msgid "Programming error. that region doesn't cover that position"
 msgstr ""
 
-#: editor_ops.cc:2511
+#: gtk2_ardour/editor_ops.cc:2451
 #, fuzzy
 msgid "set region sync position"
 msgstr "Regionen"
 
-#: editor_ops.cc:2526
+#: gtk2_ardour/editor_ops.cc:2467
 msgid "Place the edit cursor at the desired sync point"
-msgstr ""
-"Positionieren sie den Arbeits-Cursor am gewünschten Synchronisationspunkt"
+msgstr "Positionieren sie den Arbeits-Cursor am gewünschten Synchronisationspunkt"
 
-#: editor_ops.cc:2531
+#: gtk2_ardour/editor_ops.cc:2472
 #, fuzzy
 msgid "set sync from edit cursor"
 msgstr "Wiedergabe ab Cursor"
 
-#: editor_ops.cc:2543
+#: gtk2_ardour/editor_ops.cc:2485
 #, fuzzy
 msgid "remove sync"
 msgstr "Synchronisationspunkt entfernen"
 
-#: editor_ops.cc:2557
+#: gtk2_ardour/editor_ops.cc:2500
 #, fuzzy
 msgid "naturalize"
 msgstr "Ardour: Region"
 
-#: editor_ops.cc:2621
+#: gtk2_ardour/editor_ops.cc:2565
 msgid "align selection (relative)"
 msgstr ""
 
-#: editor_ops.cc:2649
+#: gtk2_ardour/editor_ops.cc:2594
 #, fuzzy
 msgid "align selection"
 msgstr "Auswahl zu Schleife machen"
 
-#: editor_ops.cc:2661
+#: gtk2_ardour/editor_ops.cc:2606
 #, fuzzy
 msgid "align region"
 msgstr "Ardour: Region"
 
-#: editor_ops.cc:2708 editor_ops.cc:2733
+#: gtk2_ardour/editor_ops.cc:2654
+#: gtk2_ardour/editor_ops.cc:2680
 msgid "trim to edit"
 msgstr ""
 
-#: editor_ops.cc:2784
+#: gtk2_ardour/editor_ops.cc:2732
 #, fuzzy
 msgid "ardour: freeze"
 msgstr "Ardour: "
 
-#: editor_ops.cc:2789
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:2737
 msgid "Cancel Freeze"
-msgstr "Abbrechen"
+msgstr "Einfrieren abbrechen"
 
-#: editor_ops.cc:2826
+#: gtk2_ardour/editor_ops.cc:2774
 #, fuzzy
 msgid "bounce range"
 msgstr "Bereich"
 
-#: editor_ops.cc:2879
+#: gtk2_ardour/editor_ops.cc:2828
 #, fuzzy
 msgid "cut"
 msgstr "Ausschneiden"
 
-#: editor_ops.cc:2882
+#: gtk2_ardour/editor_ops.cc:2831
 #, fuzzy
 msgid "copy"
 msgstr "Kopieren"
 
-#: editor_ops.cc:2895
+#: gtk2_ardour/editor_ops.cc:2844
 #, fuzzy
 msgid " objects"
 msgstr "Objekt"
 
-#: editor_ops.cc:2921
+#: gtk2_ardour/editor_ops.cc:2870
 #, fuzzy
 msgid " range"
 msgstr "Bereich"
 
-#: editor_ops.cc:3078
+#: gtk2_ardour/editor_ops.cc:3050
 #, fuzzy
 msgid "paste"
 msgstr "Einfügen"
 
-#: editor_ops.cc:3116
+#: gtk2_ardour/editor_ops.cc:3088
 #, fuzzy
 msgid "paste chunk"
 msgstr "Abschnitt erzeugen:"
 
-#. clear (below) will clear the argument list
-#: editor_ops.cc:3157
+#: gtk2_ardour/editor_ops.cc:3129
 #, fuzzy
 msgid "duplicate region"
 msgstr "Auswahl zu Schleife machen"
 
-#: editor_ops.cc:3202
+#: gtk2_ardour/editor_ops.cc:3174
 #, fuzzy
 msgid "duplicate selection"
 msgstr "Auswahl zu Schleife machen"
 
-#: editor_ops.cc:3259
+#: gtk2_ardour/editor_ops.cc:3232
 #, fuzzy
 msgid "clear playlist"
 msgstr "Name für Schnappschuß"
 
-#: editor_ops.cc:3288
+#: gtk2_ardour/editor_ops.cc:3262
 #, fuzzy
 msgid "nudge track"
 msgstr "Stille einfügen"
 
-#: editor_ops.cc:3315
+#: gtk2_ardour/editor_ops.cc:3290
 #, fuzzy
 msgid ""
 "Do you really want to destroy the last capture?\n"
@@ -4087,715 +4264,756 @@ msgstr ""
 "Wollen Sie wirklich die Spur \"%1\" löschen?\n"
 "(Kann nicht rückgängig gemacht werden!)"
 
-#: editor_ops.cc:3343
+#: gtk2_ardour/editor_ops.cc:3318
 #, fuzzy
 msgid "normalize"
 msgstr "Ardour: Region"
 
-#: editor_ops.cc:3390
+#: gtk2_ardour/editor_ops.cc:3371
 #, fuzzy
 msgid "reverse regions"
 msgstr "Name für Region:"
 
-#: editor_region_list.cc:98 editor_region_list.cc:103
-#: editor_region_list.cc:106 location_ui.cc:56
+#: gtk2_ardour/editor_ops.cc:3484
+#, fuzzy
+msgid "reset region gain"
+msgstr "Name für Region:"
+
+#: gtk2_ardour/editor_region_list.cc:103
+#: gtk2_ardour/editor_region_list.cc:108
+#: gtk2_ardour/editor_region_list.cc:111
+#: gtk2_ardour/location_ui.cc:57
 #, fuzzy
 msgid "Hidden"
 msgstr "Verbergen"
 
-#. added a new fresh one at the end
-#: editor_route_list.cc:102 editor_route_list.cc:103 editor_route_list.cc:247
+#: gtk2_ardour/editor_route_list.cc:100
+#: gtk2_ardour/editor_route_list.cc:101
+#: gtk2_ardour/editor_route_list.cc:250
 msgid "editor"
 msgstr ""
 
-#: editor_route_list.cc:310 mixer_ui.cc:699
+#: gtk2_ardour/editor_route_list.cc:317
+#: gtk2_ardour/mixer_ui.cc:717
 msgid "Show All"
 msgstr "Alles zeigen"
 
-#: editor_route_list.cc:311 mixer_ui.cc:700
+#: gtk2_ardour/editor_route_list.cc:318
+#: gtk2_ardour/mixer_ui.cc:718
 msgid "Hide All"
-msgstr "Alle verstecken"
+msgstr "Alle verbergen"
 
-#: editor_route_list.cc:312 mixer_ui.cc:701
-#, fuzzy
+#: gtk2_ardour/editor_route_list.cc:319
+#: gtk2_ardour/mixer_ui.cc:719
 msgid "Show All Audio Tracks"
-msgstr "Auswahl"
+msgstr "Zeige alle Audio-Spuren"
 
-#: editor_route_list.cc:313 mixer_ui.cc:702
-#, fuzzy
+#: gtk2_ardour/editor_route_list.cc:320
+#: gtk2_ardour/mixer_ui.cc:720
 msgid "Hide All Audio Tracks"
-msgstr "Auswahl"
+msgstr "Verberge alle Audio-Spuren"
 
-#: editor_route_list.cc:314 mixer_ui.cc:703
+#: gtk2_ardour/editor_route_list.cc:321
+#: gtk2_ardour/mixer_ui.cc:721
 msgid "Show All Audio Busses"
-msgstr ""
+msgstr "Zeige alle Audio-Busse"
 
-#: editor_route_list.cc:315 mixer_ui.cc:704
+#: gtk2_ardour/editor_route_list.cc:322
+#: gtk2_ardour/mixer_ui.cc:722
 msgid "Hide All Audio Busses"
-msgstr ""
+msgstr "Verberge alle Audio-Busse"
 
-#: editor_rulers.cc:312
-#, fuzzy
+#: gtk2_ardour/editor_rulers.cc:338
 msgid "New location marker"
-msgstr "Stellen"
+msgstr "Neuer Positionsmarker"
 
-#: editor_rulers.cc:313
-#, fuzzy
+#: gtk2_ardour/editor_rulers.cc:339
 msgid "Clear all locations"
-msgstr "Verbindungen löschen"
+msgstr "Alle Positionsmarker entfernen"
 
-#. ruler_items.push_back (MenuElem (_("New Range")));
-#: editor_rulers.cc:318
-#, fuzzy
+#: gtk2_ardour/editor_rulers.cc:344
 msgid "Clear all ranges"
-msgstr "Verbindungen löschen"
+msgstr "Alle Bereiche entfernen"
 
-#: editor_rulers.cc:327
+#: gtk2_ardour/editor_rulers.cc:353
 msgid "New Tempo"
-msgstr ""
+msgstr "Tempowechsel einfügen..."
 
-#: editor_rulers.cc:328
-#, fuzzy
+#: gtk2_ardour/editor_rulers.cc:354
 msgid "Clear tempo"
-msgstr "leeren"
+msgstr "Tempo zurücksetzen"
 
-#: editor_rulers.cc:333
+#: gtk2_ardour/editor_rulers.cc:359
 msgid "New Meter"
-msgstr ""
+msgstr "Taktwechsel einfügen..."
 
-#: editor_rulers.cc:334
-#, fuzzy
+#: gtk2_ardour/editor_rulers.cc:360
 msgid "Clear meter"
-msgstr "leeren"
+msgstr "Taktart zurücksetzen"
 
-#: editor_rulers.cc:342
+#: gtk2_ardour/editor_rulers.cc:368
 #, fuzzy
 msgid "Min:Secs"
 msgstr "Min:Sek"
 
-#: editor_selection_list.cc:108
+#: gtk2_ardour/editor_selection_list.cc:108
 #, fuzzy
 msgid "Name for Chunk:"
 msgstr "Name für Abschnitt:"
 
-#: editor_selection_list.cc:111
+#: gtk2_ardour/editor_selection_list.cc:111
 #, fuzzy
 msgid "Create Chunk"
 msgstr "Abschnitt erzeugen:"
 
-#: editor_selection_list.cc:111
+#: gtk2_ardour/editor_selection_list.cc:111
 msgid "Forget it"
 msgstr "Abbrechen"
 
-#: editor_tempodisplay.cc:253 editor_tempodisplay.cc:293
+#: gtk2_ardour/editor_tempodisplay.cc:272
+#: gtk2_ardour/editor_tempodisplay.cc:315
 #, fuzzy
 msgid "add"
 msgstr "Hinzufügen"
 
-#: editor_tempodisplay.cc:275
+#: gtk2_ardour/editor_tempodisplay.cc:294
 #, fuzzy
 msgid "add tempo mark"
 msgstr "Ardour: Region umbenennen"
 
-#: editor_tempodisplay.cc:315
+#: gtk2_ardour/editor_tempodisplay.cc:337
 #, fuzzy
 msgid "add meter mark"
 msgstr "Ardour: Region umbenennen"
 
-#: editor_tempodisplay.cc:348 editor_tempodisplay.cc:376
+#: gtk2_ardour/editor_tempodisplay.cc:372
+#: gtk2_ardour/editor_tempodisplay.cc:403
 #, fuzzy
 msgid "done"
 msgstr "keine"
 
-#: editor_tempodisplay.cc:366 editor_tempodisplay.cc:394
+#: gtk2_ardour/editor_tempodisplay.cc:390
+#: gtk2_ardour/editor_tempodisplay.cc:421
 msgid "replace tempo mark"
 msgstr ""
 
-#: editor_tempodisplay.cc:433 editor_tempodisplay.cc:464
+#: gtk2_ardour/editor_tempodisplay.cc:463
+#: gtk2_ardour/editor_tempodisplay.cc:497
 msgid "programming error: marker for meter is not a meter marker!"
 msgstr ""
 
-#: editor_tempodisplay.cc:443 editor_tempodisplay.cc:476
-#, fuzzy
+#: gtk2_ardour/editor_tempodisplay.cc:473
+#: gtk2_ardour/editor_tempodisplay.cc:509
 msgid "remove tempo mark"
-msgstr "Ja, entfernen."
+msgstr "Tempowechsel entfernen"
 
-#: editor_timefx.cc:51
+#: gtk2_ardour/editor_timefx.cc:52
 msgid "Quick but Ugly"
 msgstr ""
 
-#: editor_timefx.cc:52
+#: gtk2_ardour/editor_timefx.cc:53
 msgid "Skip Anti-aliasing"
 msgstr ""
 
-#: editor_timefx.cc:56
+#: gtk2_ardour/editor_timefx.cc:57
 #, fuzzy
 msgid "ardour: timestretch"
 msgstr "Ardour: Mixer"
 
-#: editor_timefx.cc:57
+#: gtk2_ardour/editor_timefx.cc:58
 msgid "TimeStretchDialog"
 msgstr ""
 
-#: editor_timefx.cc:70
+#: gtk2_ardour/editor_timefx.cc:71
 msgid "Stretch/Shrink it"
 msgstr ""
 
-#: editor_timefx.cc:73 editor_timefx.cc:74
+#: gtk2_ardour/editor_timefx.cc:74
+#: gtk2_ardour/editor_timefx.cc:75
 msgid "TimeStretchButton"
 msgstr ""
 
-#: editor_timefx.cc:75
+#: gtk2_ardour/editor_timefx.cc:76
 msgid "TimeStretchProgress"
 msgstr ""
 
-#: editor_timefx.cc:139
+#: gtk2_ardour/editor_timefx.cc:140
 msgid "timestretch cannot be started - thread creation error"
 msgstr ""
 
-#: export_dialog.cc:59 export_dialog.cc:399 export_dialog.cc:1027
-#: export_dialog.cc:1195
+#: gtk2_ardour/export_dialog.cc:57
+#: gtk2_ardour/export_dialog.cc:397
+#: gtk2_ardour/export_dialog.cc:1025
+#: gtk2_ardour/export_dialog.cc:1193
 msgid "22.05kHz"
 msgstr ""
 
-#: export_dialog.cc:60 export_dialog.cc:402 export_dialog.cc:417
-#: export_dialog.cc:1029 export_dialog.cc:1197
+#: gtk2_ardour/export_dialog.cc:58
+#: gtk2_ardour/export_dialog.cc:400
+#: gtk2_ardour/export_dialog.cc:415
+#: gtk2_ardour/export_dialog.cc:1027
+#: gtk2_ardour/export_dialog.cc:1195
 msgid "44.1kHz"
 msgstr ""
 
-#: export_dialog.cc:61 export_dialog.cc:405 export_dialog.cc:1031
-#: export_dialog.cc:1199
+#: gtk2_ardour/export_dialog.cc:59
+#: gtk2_ardour/export_dialog.cc:403
+#: gtk2_ardour/export_dialog.cc:1029
+#: gtk2_ardour/export_dialog.cc:1197
 msgid "48kHz"
 msgstr ""
 
-#: export_dialog.cc:62 export_dialog.cc:408 export_dialog.cc:1033
-#: export_dialog.cc:1201
+#: gtk2_ardour/export_dialog.cc:60
+#: gtk2_ardour/export_dialog.cc:406
+#: gtk2_ardour/export_dialog.cc:1031
+#: gtk2_ardour/export_dialog.cc:1199
 msgid "88.2kHz"
 msgstr ""
 
-#: export_dialog.cc:63 export_dialog.cc:411 export_dialog.cc:1035
-#: export_dialog.cc:1203
+#: gtk2_ardour/export_dialog.cc:61
+#: gtk2_ardour/export_dialog.cc:409
+#: gtk2_ardour/export_dialog.cc:1033
+#: gtk2_ardour/export_dialog.cc:1201
 msgid "96kHz"
 msgstr ""
 
-#: export_dialog.cc:64 export_dialog.cc:414 export_dialog.cc:1037
-#: export_dialog.cc:1205
+#: gtk2_ardour/export_dialog.cc:62
+#: gtk2_ardour/export_dialog.cc:412
+#: gtk2_ardour/export_dialog.cc:1035
+#: gtk2_ardour/export_dialog.cc:1203
 msgid "192kHz"
 msgstr ""
 
-#: export_dialog.cc:69
+#: gtk2_ardour/export_dialog.cc:67
 msgid "best"
 msgstr "bestmöglich"
 
-#: export_dialog.cc:70 export_dialog.cc:1212
+#: gtk2_ardour/export_dialog.cc:68
+#: gtk2_ardour/export_dialog.cc:1210
 msgid "fastest"
 msgstr "schnellstmöglich"
 
-#: export_dialog.cc:71 export_dialog.cc:1214
+#: gtk2_ardour/export_dialog.cc:69
+#: gtk2_ardour/export_dialog.cc:1212
 msgid "linear"
 msgstr ""
 
-#: export_dialog.cc:72 export_dialog.cc:1216
+#: gtk2_ardour/export_dialog.cc:70
+#: gtk2_ardour/export_dialog.cc:1214
 msgid "better"
 msgstr "besser"
 
-#: export_dialog.cc:73 export_dialog.cc:1218
+#: gtk2_ardour/export_dialog.cc:71
+#: gtk2_ardour/export_dialog.cc:1216
 msgid "intermediate"
 msgstr "mittelmäßig"
 
-#: export_dialog.cc:79 export_dialog.cc:1227
+#: gtk2_ardour/export_dialog.cc:77
+#: gtk2_ardour/export_dialog.cc:1225
 msgid "Rectangular"
 msgstr "rechteckig"
 
-#: export_dialog.cc:80
+#: gtk2_ardour/export_dialog.cc:78
 msgid "Shaped Noise"
 msgstr ""
 
-#: export_dialog.cc:81 export_dialog.cc:1229
+#: gtk2_ardour/export_dialog.cc:79
+#: gtk2_ardour/export_dialog.cc:1227
 msgid "Triangular"
 msgstr "dreieckig"
 
-#: export_dialog.cc:86
+#: gtk2_ardour/export_dialog.cc:84
 msgid "stereo"
 msgstr ""
 
-#. default is to use all
-#: export_dialog.cc:87 export_dialog.cc:486 export_dialog.cc:1055
-#: export_dialog.cc:1177
+#: gtk2_ardour/export_dialog.cc:85
+#: gtk2_ardour/export_dialog.cc:484
+#: gtk2_ardour/export_dialog.cc:1053
+#: gtk2_ardour/export_dialog.cc:1175
 msgid "mono"
 msgstr ""
 
-#: export_dialog.cc:93
+#: gtk2_ardour/export_dialog.cc:91
 msgid "CUE"
 msgstr ""
 
-#: export_dialog.cc:94
+#: gtk2_ardour/export_dialog.cc:92
 msgid "TOC"
 msgstr ""
 
-#: export_dialog.cc:102
-#, fuzzy
+#: gtk2_ardour/export_dialog.cc:100
 msgid "Format"
-msgstr "Anschluß"
+msgstr "Format"
 
-#: export_dialog.cc:103
+#: gtk2_ardour/export_dialog.cc:101
 msgid "CD Marker File Type"
-msgstr ""
+msgstr "CD-Marker"
 
-#: export_dialog.cc:104
-#, fuzzy
+#: gtk2_ardour/export_dialog.cc:102
 msgid "Channels"
-msgstr "Abbrechen"
+msgstr "Kanäle"
 
-#: export_dialog.cc:105
-#, fuzzy
+#: gtk2_ardour/export_dialog.cc:103
 msgid "File Type"
-msgstr "nach Dateisystem der Quelle"
+msgstr "Dateiformat"
 
-#: export_dialog.cc:106
-#, fuzzy
+#: gtk2_ardour/export_dialog.cc:104
 msgid "Sample Format"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Sampleformat"
 
-#: export_dialog.cc:107
+#: gtk2_ardour/export_dialog.cc:105
 msgid "Sample Endianness"
-msgstr ""
+msgstr "Bytefolge"
 
-#: export_dialog.cc:108
-#, fuzzy
+#: gtk2_ardour/export_dialog.cc:106
 msgid "Sample Rate"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Samplerate"
 
-#: export_dialog.cc:109
+#: gtk2_ardour/export_dialog.cc:107
 msgid "Conversion Quality"
-msgstr ""
+msgstr "Qualität"
 
-#: export_dialog.cc:110
+#: gtk2_ardour/export_dialog.cc:108
 msgid "Dither Type"
-msgstr ""
+msgstr "Dithering"
 
-#: export_dialog.cc:111
+#: gtk2_ardour/export_dialog.cc:109
 msgid "Export CD Marker File Only"
-msgstr ""
+msgstr "Nur CD-Marker exportieren"
 
-#: export_dialog.cc:112
-#, fuzzy
+#: gtk2_ardour/export_dialog.cc:110
 msgid "Export to File"
-msgstr "Export nach CD"
+msgstr "Als Audiodatei exportieren"
 
-#: export_dialog.cc:113 option_editor.cc:83 option_editor.cc:84
+#: gtk2_ardour/export_dialog.cc:111
+#: gtk2_ardour/option_editor.cc:82
+#: gtk2_ardour/option_editor.cc:83
 msgid "Browse"
-msgstr ""
+msgstr "Durchsuchen"
 
-#: export_dialog.cc:114
+#: gtk2_ardour/export_dialog.cc:112
 msgid "Specific tracks ..."
-msgstr ""
+msgstr "Alle Spuren..."
 
-#: export_dialog.cc:125
+#: gtk2_ardour/export_dialog.cc:123
 msgid "ardour: export"
 msgstr "Ardour: Exportieren"
 
-#: export_dialog.cc:126
+#: gtk2_ardour/export_dialog.cc:124
 #, fuzzy
 msgid "ardour_export"
 msgstr "Ardour: Exportieren"
 
-#: export_dialog.cc:139 export_dialog.cc:155 mixer_strip.cc:124
-#: mixer_strip.cc:767
-#, fuzzy
+#: gtk2_ardour/export_dialog.cc:137
+#: gtk2_ardour/export_dialog.cc:153
+#: gtk2_ardour/mixer_strip.cc:123
+#: gtk2_ardour/mixer_strip.cc:746
 msgid "Output"
-msgstr "Ausgänge"
+msgstr "Ausgang"
 
-#: export_dialog.cc:633
+#: gtk2_ardour/export_dialog.cc:631
 #, fuzzy
 msgid "Editor: cannot open \"%1\" as export file for CD toc file"
-msgstr ""
-"Editor: Kann \"%1\" nicht Ã¶ffnen um CD Track Markierungen zu exportieren."
+msgstr "Editor: Kann \"%1\" nicht Ã¶ffnen um CD Track Markierungen zu exportieren."
 
-#: export_dialog.cc:759
+#: gtk2_ardour/export_dialog.cc:757
 #, fuzzy
 msgid "Editor: cannot open \"%1\" as export file for CD cue file"
-msgstr ""
-"Editor: Kann \"%1\" nicht Ã¶ffnen um CD Track Markierungen zu exportieren."
+msgstr "Editor: Kann \"%1\" nicht Ã¶ffnen um CD Track Markierungen zu exportieren."
 
-#: export_dialog.cc:778
+#: gtk2_ardour/export_dialog.cc:776
 msgid "WAV"
 msgstr ""
 
-#: export_dialog.cc:912
+#: gtk2_ardour/export_dialog.cc:910
 msgid "Stop Export"
 msgstr "Export Abbrechen"
 
-#: export_dialog.cc:1131
+#: gtk2_ardour/export_dialog.cc:1129
 msgid "Please enter a valid filename."
-msgstr ""
+msgstr "Bitte geben Sie einen gültigen Dateinamen ein."
 
-#: export_dialog.cc:1141
+#: gtk2_ardour/export_dialog.cc:1139
 msgid "Please specify a complete filename for the audio file."
-msgstr ""
+msgstr "Bitte geben Sie einen kompletten Dateinamen für die Audiodatei ein."
 
-#: export_dialog.cc:1147
+#: gtk2_ardour/export_dialog.cc:1145
 msgid "File already exists, do you want to overwrite it?"
-msgstr ""
+msgstr "Datei existiert bereits, wollen Sie sie Ã¼berschreiben?"
 
-#: export_dialog.cc:1159 export_range_markers_dialog.cc:153
+#: gtk2_ardour/export_dialog.cc:1157
+#: gtk2_ardour/export_range_markers_dialog.cc:153
 msgid "Cannot write file in: "
-msgstr ""
+msgstr "Konnte Datei nicht in Verzeichnis  schreiben:"
 
-#. warning dialog
-#: export_range_markers_dialog.cc:135
+#: gtk2_ardour/export_range_markers_dialog.cc:135
 msgid "Please enter a valid target directory."
-msgstr ""
+msgstr "Bitte geben Sie ein gültiges Zielverzeichis an."
 
-#: export_range_markers_dialog.cc:143
+#: gtk2_ardour/export_range_markers_dialog.cc:143
 msgid ""
 "Please select an existing target directory. Files\n"
 "are not allowed!"
 msgstr ""
+"Bitte wählen Sie ein vorhandenes Zielverzeichnis aus.\n"
+"Dateien sind nicht möglich."
 
-#: gain_automation_time_axis.cc:62
+#: gtk2_ardour/gain_automation_time_axis.cc:65
 #, fuzzy
 msgid "add gain automation event"
 msgstr "Stellen"
 
-#: gain_meter.cc:67
-msgid "cannot find images for fader slider"
-msgstr ""
-
-#: gain_meter.cc:74
-msgid "cannot find images for fader rail"
-msgstr ""
-
-#: gain_meter.cc:130 gain_meter.cc:339 gain_meter.cc:494 gain_meter.cc:539
+#: gtk2_ardour/gain_meter.cc:112
+#: gtk2_ardour/gain_meter.cc:328
+#: gtk2_ardour/gain_meter.cc:504
+#: gtk2_ardour/gain_meter.cc:571
 msgid "-inf"
 msgstr ""
 
-#: gain_meter.cc:140
-#, fuzzy
+#: gtk2_ardour/gain_meter.cc:123
 msgid "Fader automation mode"
-msgstr "Stellen"
+msgstr "Fader Automationsmodus"
 
-#: gain_meter.cc:141
+#: gtk2_ardour/gain_meter.cc:124
 #, fuzzy
 msgid "Fader automation type"
 msgstr "Stellen"
 
-#. XXX it might different in different languages
-#: gain_meter.cc:182 gain_meter.cc:817 panner_ui.cc:99 panner_ui.cc:807
+#: gtk2_ardour/gain_meter.cc:169
+#: gtk2_ardour/gain_meter.cc:852
+#: gtk2_ardour/panner_ui.cc:97
+#: gtk2_ardour/panner_ui.cc:797
 msgid "Abs"
 msgstr ""
 
-#: gain_meter.cc:472
+#: gtk2_ardour/gain_meter.cc:482
 msgid "-Inf"
 msgstr ""
 
-#: gain_meter.cc:781 mixer_strip.cc:770 panner_ui.cc:771
+#: gtk2_ardour/gain_meter.cc:816
+#: gtk2_ardour/mixer_strip.cc:749
+#: gtk2_ardour/panner_ui.cc:761
 #, fuzzy
 msgid "O"
 msgstr "ODER"
 
-#: gain_meter.cc:784 panner_ui.cc:774
+#: gtk2_ardour/gain_meter.cc:819
+#: gtk2_ardour/panner_ui.cc:764
 msgid "P"
 msgstr ""
 
-#: gain_meter.cc:787 panner_ui.cc:777
+#: gtk2_ardour/gain_meter.cc:822
+#: gtk2_ardour/panner_ui.cc:767
 msgid "T"
 msgstr ""
 
-#: gain_meter.cc:790 panner_ui.cc:780
+#: gtk2_ardour/gain_meter.cc:825
+#: gtk2_ardour/panner_ui.cc:770
 msgid "W"
 msgstr ""
 
-#: gtk-custom-ruler.c:126
+#: gtk2_ardour/gtk-custom-ruler.c:126
 #, fuzzy
 msgid "Lower"
 msgstr "Schicht"
 
-#: gtk-custom-ruler.c:127
+#: gtk2_ardour/gtk-custom-ruler.c:127
 #, fuzzy
 msgid "Lower limit of ruler"
 msgstr "Region ganz nach unten"
 
-#: gtk-custom-ruler.c:136
+#: gtk2_ardour/gtk-custom-ruler.c:136
 msgid "Upper"
 msgstr ""
 
-#: gtk-custom-ruler.c:137
+#: gtk2_ardour/gtk-custom-ruler.c:137
 msgid "Upper limit of ruler"
 msgstr ""
 
-#: gtk-custom-ruler.c:146
+#: gtk2_ardour/gtk-custom-ruler.c:146
 #, fuzzy
 msgid "Position"
 msgstr "Stellen"
 
-#: gtk-custom-ruler.c:147
+#: gtk2_ardour/gtk-custom-ruler.c:147
 msgid "Position of mark on the ruler"
 msgstr ""
 
-#: gtk-custom-ruler.c:156
+#: gtk2_ardour/gtk-custom-ruler.c:156
 msgid "Max Size"
 msgstr ""
 
-#: gtk-custom-ruler.c:157
+#: gtk2_ardour/gtk-custom-ruler.c:157
 msgid "Maximum size of the ruler"
 msgstr ""
 
-#: gtk-custom-ruler.c:166
+#: gtk2_ardour/gtk-custom-ruler.c:166
 #, fuzzy
 msgid "Show Position"
 msgstr "nach Zeitstempel der Region"
 
-#: gtk-custom-ruler.c:167
+#: gtk2_ardour/gtk-custom-ruler.c:167
 msgid "Draw current ruler position"
 msgstr ""
 
-#. end-of-file, other end closed or shutdown?
-#: imageframe_socket_handler.cc:127
+#: gtk2_ardour/imageframe_socket_handler.cc:127
 msgid "Image Compositor Socket has been shutdown/closed"
 msgstr ""
 
-#: imageframe_time_axis.cc:286
+#: gtk2_ardour/imageframe_time_axis.cc:286
 #, fuzzy
 msgid "0.5 seconds"
 msgstr "Minuten:Sekunden"
 
-#: imageframe_time_axis.cc:287 marker_time_axis.cc:242
+#: gtk2_ardour/imageframe_time_axis.cc:287
+#: gtk2_ardour/marker_time_axis.cc:242
 #, fuzzy
 msgid "1 seconds"
 msgstr "Minuten:Sekunden"
 
-#: imageframe_time_axis.cc:288 marker_time_axis.cc:243
+#: gtk2_ardour/imageframe_time_axis.cc:288
+#: gtk2_ardour/marker_time_axis.cc:243
 #, fuzzy
 msgid "1.5 seconds"
 msgstr "Minuten:Sekunden"
 
-#: imageframe_time_axis.cc:289 marker_time_axis.cc:244
+#: gtk2_ardour/imageframe_time_axis.cc:289
+#: gtk2_ardour/marker_time_axis.cc:244
 #, fuzzy
 msgid "2 seconds"
 msgstr "Minuten:Sekunden"
 
-#: imageframe_time_axis.cc:290 marker_time_axis.cc:245
+#: gtk2_ardour/imageframe_time_axis.cc:290
+#: gtk2_ardour/marker_time_axis.cc:245
 #, fuzzy
 msgid "2.5 seconds"
 msgstr "Minuten:Sekunden"
 
-#: imageframe_time_axis.cc:291 marker_time_axis.cc:246
+#: gtk2_ardour/imageframe_time_axis.cc:291
+#: gtk2_ardour/marker_time_axis.cc:246
 #, fuzzy
 msgid "3 seconds"
 msgstr "Minuten:Sekunden"
 
-#. duration_items.push_back(SeparatorElem()) ;
-#. duration_items.push_back(MenuElem (_("custom"), mem_fun(*this, &ImageFrameTimeAxis::set_marker_duration_custom))) ;
-#: imageframe_time_axis.cc:296 marker_time_axis.cc:251
+#: gtk2_ardour/imageframe_time_axis.cc:296
+#: gtk2_ardour/marker_time_axis.cc:251
 #, fuzzy
 msgid "Duration (sec)"
 msgstr "Ardour: Region"
 
-#: imageframe_time_axis.cc:301
+#: gtk2_ardour/imageframe_time_axis.cc:301
 #, fuzzy
 msgid "Remove Frame"
 msgstr "Feld entfernen"
 
-#: imageframe_time_axis.cc:304
+#: gtk2_ardour/imageframe_time_axis.cc:304
 msgid "Image Frame"
 msgstr ""
 
-#: imageframe_time_axis.cc:305 marker_time_axis.cc:257
+#: gtk2_ardour/imageframe_time_axis.cc:305
+#: gtk2_ardour/marker_time_axis.cc:257
 #, fuzzy
 msgid "Rename Track"
 msgstr "Umbenennen"
 
-#: io_selector.cc:60 io_selector.cc:794
+#: gtk2_ardour/io_selector.cc:62
+#: gtk2_ardour/io_selector.cc:751
+#: gtk2_ardour/connection_editor.cc:61
+#: gtk2_ardour/connection_editor.cc:110
 #, fuzzy
 msgid "Rescan"
 msgstr "Auffrischen"
 
-#: io_selector.cc:68
+#: gtk2_ardour/io_selector.cc:70
 msgid "%1 input"
 msgstr "%1 Eingang"
 
-#: io_selector.cc:70
+#: gtk2_ardour/io_selector.cc:72
 msgid "%1 output"
 msgstr "%1 Ausgang"
 
-#: io_selector.cc:142 route_params_ui.cc:107
+#: gtk2_ardour/io_selector.cc:144
+#: gtk2_ardour/route_params_ui.cc:103
 #, fuzzy
 msgid "Inputs"
 msgstr "Eingänge"
 
-#: io_selector.cc:142 route_params_ui.cc:108
-#, fuzzy
+#: gtk2_ardour/io_selector.cc:144
+#: gtk2_ardour/route_params_ui.cc:104
 msgid "Outputs"
 msgstr "Ausgänge"
 
-#: io_selector.cc:143
-#, fuzzy
+#: gtk2_ardour/io_selector.cc:145
 msgid "Add Input"
-msgstr "Port hinzufügen"
+msgstr "Hinzufügen"
 
-#: io_selector.cc:143
-#, fuzzy
+#: gtk2_ardour/io_selector.cc:145
 msgid "Add Output"
-msgstr "%1 Ausgang"
+msgstr "Hinzufügen"
 
-#: io_selector.cc:144
-#, fuzzy
+#: gtk2_ardour/io_selector.cc:146
 msgid "Remove Input"
-msgstr "Synchronisationspunkt entfernen"
+msgstr "Entfernen"
 
-#: io_selector.cc:144
-#, fuzzy
+#: gtk2_ardour/io_selector.cc:146
 msgid "Remove Output"
-msgstr "Ausgänge"
+msgstr "Entfernen"
 
-#: io_selector.cc:145
-#, fuzzy
+#: gtk2_ardour/io_selector.cc:147
 msgid "Disconnect All"
-msgstr "Trennen"
+msgstr "Alle trennen"
 
-#: io_selector.cc:159
+#: gtk2_ardour/io_selector.cc:161
 msgid "Available connections"
 msgstr "Verfügbare Verbindungen"
 
-#: io_selector.cc:555 io_selector.cc:574
+#: gtk2_ardour/io_selector.cc:550
+#: gtk2_ardour/io_selector.cc:561
 msgid "There are no more JACK ports available."
-msgstr ""
-
-#: io_selector.cc:649 io_selector.cc:676 io_selector.cc:729
-msgid "port"
-msgstr "Anschluß"
+msgstr "Es sind keine weiteren JACK Ports verfügbar."
 
-#: io_selector.cc:798
+#: gtk2_ardour/io_selector.cc:755
 msgid "ardour: "
 msgstr "Ardour: "
 
-#: keyboard.cc:299
+#: gtk2_ardour/keyboard.cc:299
 msgid "KeyboardTarget: keyname \"%1\" is unknown."
 msgstr ""
 
-#: keyboard.cc:525
-msgid ""
-"Your system is completely broken - NumLock uses \"%1\"as its modifier. This "
-"is madness - see the man page for xmodmap to find out how to fix this."
-msgstr ""
+#: gtk2_ardour/keyboard.cc:525
+msgid "Your system is completely broken - NumLock uses \"%1\"as its modifier. This is madness - see the man page for xmodmap to find out how to fix this."
+msgstr "Ihr System ist falsch konfiguriert. Die NumLock-Taste nutzt \"%1\" als Modifier. Das wird schwere Probleme bereiten. Auf der man page von xmodmap finden sich Infirmationen, wie dieses Problem behoben werden kann."
 
-#: keyboard.cc:533
-msgid ""
-"Your system generates \"%1\" when the NumLock key is pressed. This can cause "
-"problems when editing so Ardour will use %2 to mean Meta rather than %1"
-msgstr ""
+#: gtk2_ardour/keyboard.cc:533
+msgid "Your system generates \"%1\" when the NumLock key is pressed. This can cause problems when editing so Ardour will use %2 to mean Meta rather than %1"
+msgstr "Ihr System generiert \"%1\" wenn NumLock gedrückt wird. Dies kann zu Problemen führen. Ardour wird deshalb als Meta-Taste %2 an Stelle von %1 benutzen."
 
-#: keyboard.cc:594
+#: gtk2_ardour/keyboard.cc:594
 msgid "You have %1 keys bound to \"mod1\""
 msgstr ""
 
-#: keyboard.cc:609
+#: gtk2_ardour/keyboard.cc:609
 msgid "You have %1 keys bound to \"mod2\""
 msgstr ""
 
-#: keyboard.cc:624
+#: gtk2_ardour/keyboard.cc:624
 msgid "You have %1 keys bound to \"mod3\""
 msgstr ""
 
-#: keyboard.cc:639
+#: gtk2_ardour/keyboard.cc:639
 msgid "You have %1 keys bound to \"mod4\""
 msgstr ""
 
-#: keyboard.cc:654
+#: gtk2_ardour/keyboard.cc:654
 msgid "You have %1 keys bound to \"mod5\""
 msgstr ""
 
-#: location_ui.cc:48 location_ui.cc:51
+#: gtk2_ardour/ladspa_pluginui.cc:77
+msgid "<span size=\"large\">Presets</span>"
+msgstr ""
+
+#: gtk2_ardour/ladspa_pluginui.cc:205
+msgid "Plugin Editor: could not build control element for port %1"
+msgstr ""
+
+#: gtk2_ardour/ladspa_pluginui.cc:296
+#, fuzzy
+msgid "Automation control"
+msgstr "Stellen"
+
+#: gtk2_ardour/location_ui.cc:49
+#: gtk2_ardour/location_ui.cc:52
 #, fuzzy
 msgid "Set"
 msgstr "Auswahl"
 
-#: location_ui.cc:49 location_ui.cc:52
+#: gtk2_ardour/location_ui.cc:50
+#: gtk2_ardour/location_ui.cc:53
 msgid "Go"
 msgstr ""
 
-#: location_ui.cc:55
+#: gtk2_ardour/location_ui.cc:56
 msgid "CD"
 msgstr "CD"
 
-#: location_ui.cc:58
+#: gtk2_ardour/location_ui.cc:59
 msgid "SCMS"
 msgstr ""
 
-#: location_ui.cc:59
+#: gtk2_ardour/location_ui.cc:60
 msgid "Pre-Emphasis"
 msgstr ""
 
-#: location_ui.cc:570
+#: gtk2_ardour/location_ui.cc:571
 #, fuzzy
 msgid "Add New Location"
 msgstr "Stellen"
 
-#: location_ui.cc:571
+#: gtk2_ardour/location_ui.cc:572
 msgid "Add New Range"
-msgstr ""
+msgstr "Neuen Bereich hinzufügen"
 
-#: location_ui.cc:575
+#: gtk2_ardour/location_ui.cc:576
 msgid "ardour: locations"
 msgstr ""
 
-#: location_ui.cc:576
+#: gtk2_ardour/location_ui.cc:577
 #, fuzzy
 msgid "ardour_locations"
 msgstr "Ardour: Verbindungen"
 
-#: location_ui.cc:604
+#: gtk2_ardour/location_ui.cc:605
 #, fuzzy
 msgid "Location (CD Index) Markers"
 msgstr "Stellen"
 
-#: location_ui.cc:624
+#: gtk2_ardour/location_ui.cc:625
 msgid "Range (CD Track) Markers"
 msgstr ""
 
-#: location_ui.cc:790
+#: gtk2_ardour/location_ui.cc:793
 #, fuzzy
 msgid "add range marker"
 msgstr "Ardour: Region umbenennen"
 
-#: main.cc:72
+#: gtk2_ardour/main.cc:73
 msgid "ardour is killing itself for a clean exit\n"
 msgstr ""
 
-#: main.cc:81
+#: gtk2_ardour/main.cc:82
 msgid "stopping user interface\n"
-msgstr ""
+msgstr "Stoppe Benutzeroberfläche\n"
 
-#. XXX its doubtful that snprintf() is async-safe
-#: main.cc:100
+#: gtk2_ardour/main.cc:101
 #, c-format
 msgid "%d(%d): received signal %d\n"
 msgstr ""
 
-#: main.cc:180
+#: gtk2_ardour/main.cc:181
 msgid "cannot become new process group leader (%1)"
 msgstr ""
 
-#: main.cc:207
+#: gtk2_ardour/main.cc:208
 msgid "cannot setup signal handling for %1"
 msgstr ""
 
-#: main.cc:218
+#: gtk2_ardour/main.cc:219
 msgid "cannot set default signal mask (%1)"
 msgstr ""
 
-#: main.cc:248
+#: gtk2_ardour/main.cc:249
 msgid ""
 "Without a UI style file, ardour will look strange.\n"
 " Please set ARDOUR2_UI_RC to point to a valid UI style file"
 msgstr ""
+"Ohne UI-Definitionsdatei wird Ardour merkwürdig aussehen.\n"
+" Bitte setzen Sie ARDOUR_UI_RC auf eine gültige UI-Definitionsdatei"
 
-#: main.cc:270
+#: gtk2_ardour/main.cc:270
 msgid "Ardour could not connect to JACK."
-msgstr ""
+msgstr "Ardour konnte nicht zu JACK verbinden."
 
-#: main.cc:274
+#: gtk2_ardour/main.cc:274
 msgid ""
 "There are several possible reasons:\n"
 "\n"
@@ -4805,493 +5023,433 @@ msgid ""
 "\n"
 "Please consider the possibilities, and perhaps (re)start JACK."
 msgstr ""
-
-#: main.cc:304
-msgid "could not load command line session \"%1\""
-msgstr ""
-
-#. it wasn't new, but we require a new session
-#: main.cc:324
-msgid ""
+"Dafür kann es verschiedene Gründe geben:\n"
 "\n"
+"1) JACK läuft nicht.\n"
+"2) JACK wurde unter einem anderen Benutzer gestartet, möglicherweise als root.\n"
+"3) Es gibt bereits einen anderen Client mit der Bezeichnung \"ardour\".\n"
 "\n"
-"A session named \"%1\" already exists.\n"
-"To avoid this message, start ardour as \"ardour %1"
-msgstr ""
+"Betrachten Sie bitte diese Möglichkeiten und starten Sie JACK neu, wenn dies notwendig sein sollte."
 
-#: main.cc:335
+#: gtk2_ardour/main.cc:316
+msgid "could not load command line session \"%1\""
+msgstr "Konnte die per Kommandozeile Ã¼bergebene Sitzung nicht laden: \"%1\""
+
+#: gtk2_ardour/main.cc:324
 msgid ""
 "\n"
 "\n"
 "No session named \"%1\" exists.\n"
 "To create it from the command line, start ardour as \"ardour --new %1"
 msgstr ""
+"\n"
+"\n"
+"Es existiert keine Sitzung mit dem namen \"%1\".\n"
+"Um sie von der Kommandozeile aus zu erstellen, starten Sie Ardour mit \"ardour --new %1"
 
-#: main.cc:399
+#: gtk2_ardour/main.cc:385
 msgid "Ardour/GTK "
 msgstr ""
 
-#: main.cc:401
+#: gtk2_ardour/main.cc:387
 msgid ""
 "\n"
 "   (built using "
 msgstr ""
 
-#: main.cc:405
-msgid " with libardour "
-msgstr ""
-
-#: main.cc:410
+#: gtk2_ardour/main.cc:390
 msgid " and GCC version "
 msgstr ""
 
-#: main.cc:420
+#: gtk2_ardour/main.cc:400
 msgid "Copyright (C) 1999-2006 Paul Davis"
 msgstr ""
 
-#: main.cc:421
-msgid ""
-"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
-"Baker"
+#: gtk2_ardour/main.cc:401
+msgid "Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker"
 msgstr ""
 
-#: main.cc:423
+#: gtk2_ardour/main.cc:403
 msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
 msgstr "Achtung: Es gibt zu Ardour KEINERLEI Gewährleistung!"
 
-#: main.cc:424
+#: gtk2_ardour/main.cc:404
 msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 msgstr ""
 
-#: main.cc:425
+#: gtk2_ardour/main.cc:405
 msgid "This is free software, and you are welcome to redistribute it "
 msgstr "Dies ist freie Software und Sie dürfen sie gerne weiterverbreiten,"
 
-#: main.cc:426
+#: gtk2_ardour/main.cc:406
 #, fuzzy
 msgid "under certain conditions; see the source for copying conditions."
 msgstr "solange Sie sich an die Spielregeln aus der Datei COPYING halten."
 
-#: main.cc:435
+#: gtk2_ardour/main.cc:416
 msgid "could not create ARDOUR GUI"
 msgstr ""
 
-#: main.cc:453
+#: gtk2_ardour/main.cc:433
 msgid "Could not connect to JACK server as  \"%1\""
-msgstr ""
+msgstr "Konnte nicht zu JACK Server als \"%1\" verbinden"
 
-#: main.cc:456
+#: gtk2_ardour/main.cc:443
 msgid "could not initialize Ardour."
-msgstr ""
+msgstr "Konnte Ardour nicht initialisieren."
 
-#: marker.cc:244
+#: gtk2_ardour/marker.cc:244
 #, fuzzy
 msgid "MarkerText"
 msgstr "Schicht"
 
-#: marker_time_axis.cc:254
-#, fuzzy
+#: gtk2_ardour/marker_time_axis.cc:254
 msgid "Remove Marker"
-msgstr "Feld entfernen"
+msgstr "Marker entfernen"
 
-#: marker_time_axis.cc:256
+#: gtk2_ardour/marker_time_axis.cc:256
 #, fuzzy
 msgid "Marker"
 msgstr "Schicht"
 
-#: meter_bridge.cc:78
-msgid "ardour: meter bridge"
-msgstr ""
-
-#: meter_bridge.cc:79
-msgid "ardour_meter_bridge"
-msgstr ""
-
-#: meter_bridge_strip.cc:80 meter_bridge_strip.cc:94
-#, c-format
-msgid "# of %u-sample overs"
-msgstr ""
-
-#: meter_bridge_strip.cc:222
-#, fuzzy
-msgid "New Name for Meter:"
-msgstr "Name für Mixer-Voreinstellung"
-
-#: mixer_strip.cc:95 mixer_strip.cc:140 mixer_strip.cc:1227
+#: gtk2_ardour/mixer_strip.cc:94
+#: gtk2_ardour/mixer_strip.cc:139
+#: gtk2_ardour/mixer_strip.cc:1218
 msgid "pre"
-msgstr ""
+msgstr "pre"
 
-#: mixer_strip.cc:96 mixer_strip.cc:822
+#: gtk2_ardour/mixer_strip.cc:95
+#: gtk2_ardour/mixer_strip.cc:796
 msgid "Comments"
-msgstr ""
+msgstr "Kommentare"
 
-#: mixer_strip.cc:119
+#: gtk2_ardour/mixer_strip.cc:118
 #, fuzzy
 msgid "Input"
 msgstr "Eingänge"
 
-#: mixer_strip.cc:136 mixer_strip.cc:1223
-#, fuzzy
+#: gtk2_ardour/mixer_strip.cc:135
+#: gtk2_ardour/mixer_strip.cc:1214
 msgid "input"
-msgstr "%1 Eingang"
+msgstr "input"
 
-#: mixer_strip.cc:144 mixer_strip.cc:1231
-#, fuzzy
+#: gtk2_ardour/mixer_strip.cc:143
+#: gtk2_ardour/mixer_strip.cc:1222
 msgid "post"
-msgstr "Anschluß"
+msgstr "post"
 
-#. TRANSLATORS: this string should be longest of the strings
-#. used to describe meter points. In english, its "input".
-#.
-#: mixer_strip.cc:152
+#: gtk2_ardour/mixer_strip.cc:150
 msgid "tupni"
 msgstr ""
 
-#: mixer_strip.cc:207
+#: gtk2_ardour/mixer_strip.cc:204
 msgid "Varispeed"
 msgstr ""
 
-#: mixer_strip.cc:233 mixer_strip.cc:836
+#: gtk2_ardour/mixer_strip.cc:230
+#: gtk2_ardour/mixer_strip.cc:812
 msgid "Click to Add/Edit Comments"
-msgstr ""
+msgstr "Kommentare hinzufügen/ändern"
 
-#: mixer_strip.cc:374
+#: gtk2_ardour/mixer_strip.cc:386
 msgid "unknown strip width \"%1\" in XML GUI information"
 msgstr ""
 
-#: mixer_strip.cc:417
-#, fuzzy
+#: gtk2_ardour/mixer_strip.cc:430
 msgid "record"
-msgstr "Wiederherstellen"
-
-#: mixer_strip.cc:418 region_editor.cc:47
-msgid "mute"
-msgstr "mute"
-
-#: mixer_strip.cc:419
-msgid "solo"
-msgstr "solo"
+msgstr "Aufnahme"
 
-#: mixer_strip.cc:422
+#: gtk2_ardour/mixer_strip.cc:437
 msgid "comments"
-msgstr ""
+msgstr "Kommentare"
 
-#: mixer_strip.cc:424
+#: gtk2_ardour/mixer_strip.cc:440
 msgid "*comments*"
 msgstr ""
 
-#: mixer_strip.cc:438
+#: gtk2_ardour/mixer_strip.cc:455
 #, fuzzy
 msgid "Rec"
 msgstr "Auffrischen"
 
-#: mixer_strip.cc:439
+#: gtk2_ardour/mixer_strip.cc:457
 msgid "M"
-msgstr ""
+msgstr "M"
 
-#: mixer_strip.cc:440
+#: gtk2_ardour/mixer_strip.cc:458
 msgid "S"
-msgstr ""
+msgstr "S"
 
-#: mixer_strip.cc:443 mixer_strip.cc:830
+#: gtk2_ardour/mixer_strip.cc:462
+#: gtk2_ardour/mixer_strip.cc:806
 #, fuzzy
 msgid "Cmt"
 msgstr "Ausschneiden"
 
-#: mixer_strip.cc:445 mixer_strip.cc:828
+#: gtk2_ardour/mixer_strip.cc:465
+#: gtk2_ardour/mixer_strip.cc:803
 msgid "*Cmt*"
 msgstr ""
 
-#: mixer_strip.cc:483 mixer_strip.cc:549 redirect_box.cc:1006
+#: gtk2_ardour/mixer_strip.cc:503
+#: gtk2_ardour/mixer_strip.cc:569
+#: gtk2_ardour/redirect_box.cc:1012
 msgid "Not connected to JACK - no I/O changes are possible"
-msgstr ""
-
-#: mixer_strip.cc:560
-msgid "Track"
-msgstr "Spur"
+msgstr "Nicht mit Jack verbunden - es sind keine Ã„nderungen an Ein-/Ausgängen möglich"
 
-#: mixer_strip.cc:588 mixer_strip.cc:604
+#: gtk2_ardour/mixer_strip.cc:603
+#: gtk2_ardour/mixer_strip.cc:619
 msgid "could not register new ports required for that connection"
-msgstr ""
+msgstr "Konnte die Ports, die diese Verbindung benötigt nicht registrieren"
 
-#: mixer_strip.cc:747
+#: gtk2_ardour/mixer_strip.cc:726
 #, fuzzy
 msgid " Input"
 msgstr "Eingänge"
 
-#: mixer_strip.cc:750
+#: gtk2_ardour/mixer_strip.cc:729
 msgid "I"
 msgstr ""
 
-#: mixer_strip.cc:820
+#: gtk2_ardour/mixer_strip.cc:793
 msgid "*Comments*"
 msgstr ""
 
-#: mixer_strip.cc:859
+#: gtk2_ardour/mixer_strip.cc:848
 #, fuzzy
 msgid ": comment editor"
 msgstr "Der Editor konnte nicht initialisiert werden."
 
-#: mixer_strip.cc:953
+#: gtk2_ardour/mixer_strip.cc:943
 msgid "Grp"
-msgstr ""
+msgstr "Grp"
 
-#: mixer_strip.cc:956
+#: gtk2_ardour/mixer_strip.cc:946
 msgid "~G"
 msgstr ""
 
-#: mixer_strip.cc:1004
-#, fuzzy
+#: gtk2_ardour/mixer_strip.cc:995
 msgid "Invert Polarity"
-msgstr "Polarität"
+msgstr "Polarität umkehren"
 
-#: mixer_ui.cc:85
+#: gtk2_ardour/mixer_ui.cc:83
 msgid "Strips"
-msgstr "Streifen"
+msgstr "Spur"
 
-#: mixer_ui.cc:110
-#, fuzzy
+#: gtk2_ardour/mixer_ui.cc:108
 msgid "Group"
-msgstr "Mix Gruppen"
+msgstr "Gruppe"
 
-#: mixer_ui.cc:211 mixer_ui.cc:370
+#: gtk2_ardour/mixer_ui.cc:209
+#: gtk2_ardour/mixer_ui.cc:389
 msgid "ardour: mixer"
 msgstr "Ardour: Mixer"
 
-#: mixer_ui.cc:212
+#: gtk2_ardour/mixer_ui.cc:210
 #, fuzzy
 msgid "ardour_mixer"
 msgstr "Ardour: Mixer"
 
-#: mixer_ui.cc:346
+#: gtk2_ardour/mixer_ui.cc:361
 msgid "ardour: mixer: "
 msgstr "Ardour: Mixer: "
 
-#: mixer_ui.cc:573
+#: gtk2_ardour/mixer_ui.cc:592
 msgid "signal"
 msgstr "Signal"
 
-#: mixer_ui.cc:723
+#: gtk2_ardour/mixer_ui.cc:741
 msgid "track display list item for renamed strip not found!"
 msgstr ""
 
-#: new_session_dialog.cc:39
+#: gtk2_ardour/new_session_dialog.cc:41
 #, fuzzy
-msgid "New Session Name :"
-msgstr "Name der Sitzung"
+msgid "Name :"
+msgstr "Umbenennen"
 
-#: new_session_dialog.cc:41
-msgid "Create Session Directory In :"
-msgstr ""
+#: gtk2_ardour/new_session_dialog.cc:45
+#: gtk2_ardour/new_session_dialog.cc:46
+#: gtk2_ardour/new_session_dialog.cc:47
+#: gtk2_ardour/new_session_dialog.cc:48
+#: gtk2_ardour/sfdb_ui.cc:172
+msgid "channels"
+msgstr "Kanäle"
 
-#: new_session_dialog.cc:43
-#, fuzzy
-msgid "Use Session Template :"
-msgstr "Name der Sitzung"
+#: gtk2_ardour/new_session_dialog.cc:66
+msgid "<b>Busses</b>"
+msgstr "<b>Busse</b>"
 
-#: new_session_dialog.cc:45
-#, fuzzy
-msgid "Channel Count"
-msgstr "Importieren Abbrechen"
+#: gtk2_ardour/new_session_dialog.cc:67
+msgid "<b>Inputs</b>"
+msgstr "<b>Eingänge</b>"
+
+#: gtk2_ardour/new_session_dialog.cc:68
+msgid "<b>Outputs</b>"
+msgstr "<b>Ausgänge</b>"
+
+#: gtk2_ardour/new_session_dialog.cc:70
+msgid "Create Folder In :"
+msgstr "Verzeichnis erstellen in:"
 
-#: new_session_dialog.cc:46
+#: gtk2_ardour/new_session_dialog.cc:72
+msgid "Template :"
+msgstr "Vorlage :"
+
+#: gtk2_ardour/new_session_dialog.cc:74
 msgid "Create Monitor Bus"
-msgstr ""
+msgstr "Monitor Bus erstellen"
 
-#: new_session_dialog.cc:53
+#: gtk2_ardour/new_session_dialog.cc:81
 msgid "Create Master Bus"
-msgstr ""
+msgstr "Master Bus erstellen"
 
-#: new_session_dialog.cc:55
-#, fuzzy
-msgid "Automatically Connect Inputs"
-msgstr "Verfügbare Verbindungen"
+#: gtk2_ardour/new_session_dialog.cc:83
+msgid "Automatically Connect to Physical Inputs"
+msgstr "Eingänge automatisch mit Soundkarteneingängen verbinden"
 
-#: new_session_dialog.cc:56 new_session_dialog.cc:67
-#, fuzzy
-msgid "Port Limit"
-msgstr "Abbrechen"
-
-#: new_session_dialog.cc:64
-#, fuzzy
-msgid "<b>Track/Bus Inputs</b>"
-msgstr "Ausgänge"
+#: gtk2_ardour/new_session_dialog.cc:84
+#: gtk2_ardour/new_session_dialog.cc:97
+msgid "Use only"
+msgstr "Benutze nur"
 
-#: new_session_dialog.cc:66
-#, fuzzy
+#: gtk2_ardour/new_session_dialog.cc:96
 msgid "Automatically Connect Outputs"
-msgstr "Verfügbare Verbindungen"
+msgstr "Ausgänge automatisch verbinden"
 
-#: new_session_dialog.cc:75
-msgid "Connect to Master Bus"
-msgstr ""
+#: gtk2_ardour/new_session_dialog.cc:105
+msgid "... to Master Bus"
+msgstr "... mit Master Bus"
 
-#: new_session_dialog.cc:76
-msgid "Connect to Physical Outputs"
-msgstr ""
+#: gtk2_ardour/new_session_dialog.cc:106
+msgid "... to Physical Outputs"
+msgstr "... mit Soundkartenausgängen"
 
-#: new_session_dialog.cc:80
-#, fuzzy
-msgid "<b>Track/Bus Outputs</b>"
-msgstr "Ausgänge"
-
-#: new_session_dialog.cc:83
-#, fuzzy
+#: gtk2_ardour/new_session_dialog.cc:112
 msgid "Advanced Options"
-msgstr "Geschwindigkeitseditor"
+msgstr "Erweiterte Einstellungen"
 
-#: new_session_dialog.cc:91
-#, fuzzy
-msgid "Open Recent Session"
-msgstr "Sitzung"
+#: gtk2_ardour/new_session_dialog.cc:120
+msgid "Recent:"
+msgstr "Zuletzt verwendet:"
 
-#: new_session_dialog.cc:127
-#, fuzzy
-msgid "Open Session File :"
-msgstr "Sitzung"
+#: gtk2_ardour/new_session_dialog.cc:157
+msgid "Browse:"
+msgstr "Durchsuchen:"
 
-#: new_session_dialog.cc:274
-#, fuzzy
+#: gtk2_ardour/new_session_dialog.cc:335
 msgid "New Session"
-msgstr "Sitzung"
+msgstr "Neue Sitzung"
 
-#: new_session_dialog.cc:276
-#, fuzzy
+#: gtk2_ardour/new_session_dialog.cc:337
 msgid "Open Session"
-msgstr "Sitzung"
+msgstr "Sitzung Ã¶ffnen"
 
-#: new_session_dialog.cc:281
-#, fuzzy
+#: gtk2_ardour/new_session_dialog.cc:342
 msgid "ardour: session control"
 msgstr "Ardour: Neue Sitzung"
 
-#: new_session_dialog.cc:310
-#, fuzzy
+#: gtk2_ardour/new_session_dialog.cc:371
 msgid "select template"
-msgstr "Voreinstellung"
+msgstr "Vorlage auswählen"
 
-#: new_session_dialog.cc:316
+#: gtk2_ardour/new_session_dialog.cc:377
 #, fuzzy
 msgid "select session file"
 msgstr "Auswahl zu Schleife machen"
 
-#: new_session_dialog.cc:325
+#: gtk2_ardour/new_session_dialog.cc:386
 #, fuzzy
 msgid "select directory"
 msgstr "Auswahl zu Schleife machen"
 
-#: option_editor.cc:76
+#: gtk2_ardour/option_editor.cc:75
 msgid "SMPTE offset is negative"
-msgstr ""
+msgstr "Negatives SMPTE-Offset"
 
-#: option_editor.cc:102
+#: gtk2_ardour/option_editor.cc:101
 #, fuzzy
 msgid "ardour: options editor"
 msgstr "Ardour: Einstellungen"
 
-#: option_editor.cc:103
+#: gtk2_ardour/option_editor.cc:102
 #, fuzzy
 msgid "ardour_option_editor"
 msgstr "Ardour: Einstellungen"
 
-#: option_editor.cc:127
+#: gtk2_ardour/option_editor.cc:126
 msgid "Paths/Files"
-msgstr "Pfade- und Dateinamen"
+msgstr "Pfade"
 
-#: option_editor.cc:128
+#: gtk2_ardour/option_editor.cc:127
 msgid "Kbd/Mouse"
-msgstr ""
+msgstr "Tastatur/Maus"
 
-#: option_editor.cc:131
+#: gtk2_ardour/option_editor.cc:130
 msgid "Layers & Fades"
-msgstr ""
+msgstr "Layer & Fades"
 
-#: option_editor.cc:135
+#: gtk2_ardour/option_editor.cc:134
 msgid "MIDI"
-msgstr ""
-
-#: option_editor.cc:177
-msgid "24 FPS"
-msgstr ""
+msgstr "MIDI"
 
-#: option_editor.cc:179
-msgid "25 FPS"
-msgstr ""
-
-#: option_editor.cc:181
-msgid "30 FPS"
-msgstr ""
-
-#: option_editor.cc:187
-msgid "30 FPS drop"
-msgstr ""
-
-#: option_editor.cc:244
+#: gtk2_ardour/option_editor.cc:222
 msgid "session RAID path"
-msgstr ""
+msgstr "Sitzungsverzeichnis (RAID)"
 
-#: option_editor.cc:249
-#, fuzzy
+#: gtk2_ardour/option_editor.cc:227
 msgid "Soundfile Search Paths"
-msgstr "Ardour: Audio Bibliothek"
-
-#: option_editor.cc:254
-#, fuzzy
-msgid "Paths"
-msgstr "Pfade- und Dateinamen"
+msgstr "Suchpfade für Audiodateien"
 
-#: option_editor.cc:268 option_editor.cc:274 option_editor.cc:723
-#: option_editor.cc:750
-#, fuzzy
+#: gtk2_ardour/option_editor.cc:252
+#: gtk2_ardour/option_editor.cc:258
+#: gtk2_ardour/option_editor.cc:670
+#: gtk2_ardour/option_editor.cc:697
 msgid "internal"
-msgstr "mittelmäßig"
+msgstr "intern"
 
-#: option_editor.cc:287
+#: gtk2_ardour/option_editor.cc:271
 msgid "Short crossfade length (msecs)"
-msgstr ""
+msgstr "Länge für kurze Crossfades (ms)"
 
-#: option_editor.cc:299
+#: gtk2_ardour/option_editor.cc:283
 msgid "Destructive crossfade length (msecs)"
-msgstr ""
-
-#: option_editor.cc:367
-msgid "SMPTE Frames/second"
-msgstr ""
+msgstr "Länge für destruktive Crossfades (ms)"
 
-#: option_editor.cc:368
+#: gtk2_ardour/option_editor.cc:343
 msgid "SMPTE Offset"
-msgstr ""
+msgstr "SMPTE Offset"
 
-#: option_editor.cc:462 option_editor.cc:469 option_editor.cc:472
-#: option_editor.cc:618
+#: gtk2_ardour/option_editor.cc:410
+#: gtk2_ardour/option_editor.cc:417
+#: gtk2_ardour/option_editor.cc:420
+#: gtk2_ardour/option_editor.cc:565
 #, fuzzy
 msgid "online"
 msgstr "Verbindungen"
 
-#. remember, we have to handle the i18n case where the relative
-#. lengths of the strings in language N is different than in english.
-#.
-#: option_editor.cc:469 option_editor.cc:470 option_editor.cc:615
+#: gtk2_ardour/option_editor.cc:417
+#: gtk2_ardour/option_editor.cc:418
+#: gtk2_ardour/option_editor.cc:562
 msgid "offline"
 msgstr ""
 
-#: option_editor.cc:670
+#: gtk2_ardour/option_editor.cc:617
 msgid "Choose Click"
 msgstr ""
 
-#: option_editor.cc:689
+#: gtk2_ardour/option_editor.cc:636
 msgid "Choose Click Emphasis"
 msgstr ""
 
-#: option_editor.cc:803
+#: gtk2_ardour/option_editor.cc:750
 msgid "Click audio file"
-msgstr ""
+msgstr "Audiodatei für Click"
 
-#: option_editor.cc:809
+#: gtk2_ardour/option_editor.cc:756
 msgid "Click emphasis audiofile"
-msgstr ""
+msgstr "Audiodatei für betonten Click "
 
-#: option_editor.cc:846
+#: gtk2_ardour/option_editor.cc:793
 msgid ""
 "The auditioner is a dedicated mixer strip used\n"
 "for listening to specific regions outside the context\n"
@@ -5299,265 +5457,239 @@ msgid ""
 "other mixer strip."
 msgstr ""
 
-#: option_editor.cc:919
-#, fuzzy
+#: gtk2_ardour/option_editor.cc:866
 msgid "Edit using"
-msgstr "Mix Gruppen"
+msgstr "Bearbeiten mit"
 
-#: option_editor.cc:926 option_editor.cc:953
+#: gtk2_ardour/option_editor.cc:873
+#: gtk2_ardour/option_editor.cc:900
 msgid "+ button"
-msgstr ""
+msgstr "und Maustaste"
 
-#: option_editor.cc:946
-#, fuzzy
+#: gtk2_ardour/option_editor.cc:893
 msgid "Delete using"
-msgstr "Messungen"
+msgstr "Entfernen mit"
 
-#: option_editor.cc:973
+#: gtk2_ardour/option_editor.cc:920
 msgid "Ignore snap using"
-msgstr ""
+msgstr "Einrasten Ã¼bergehen mit"
 
-#: opts.cc:46
+#: gtk2_ardour/opts.cc:46
 msgid "Usage: "
 msgstr "Aufruf:"
 
-#: opts.cc:47
+#: gtk2_ardour/opts.cc:47
 msgid "  -v, --version                    Show version information\n"
 msgstr "  -v, --version                    Versionsinformation ausgeben\n"
 
-#: opts.cc:48
+#: gtk2_ardour/opts.cc:48
 msgid "  -h, --help                       Print this message\n"
 msgstr "  -h, --help                       Diese Hinweise\n"
 
-#: opts.cc:49
-msgid ""
-"  -b, --bindings                   Print all possible keyboard binding "
-"names\n"
-msgstr ""
-"  -b, --bindings                   Alle möglichen Tastenzuweisungsnamen "
-"ausgeben\n"
+#: gtk2_ardour/opts.cc:49
+msgid "  -b, --bindings                   Print all possible keyboard binding names\n"
+msgstr "  -b, --bindings                   Alle möglichen Tastenzuweisungsnamen ausgeben\n"
 
-#: opts.cc:50
+#: gtk2_ardour/opts.cc:50
 #, fuzzy
 msgid "  -n, --show-splash                Show splash screen\n"
 msgstr "  -h, --help                       Diese Hinweise\n"
 
-#: opts.cc:51
+#: gtk2_ardour/opts.cc:51
 #, fuzzy
-msgid ""
-"  -c, --name  name                 Use a specific jack client name, default "
-"is ardour\n"
+msgid "  -c, --name  name                 Use a specific jack client name, default is ardour\n"
 msgstr "  -U, --ui-rcfile=FILENAME         Dateiname für UI Einstellungen\n"
 
-#: opts.cc:52
+#: gtk2_ardour/opts.cc:52
 #, fuzzy
-msgid ""
-"  -N, --new session-name           Create a new session from the command "
-"line\n"
+msgid "  -N, --new session-name           Create a new session from the command line\n"
 msgstr "  [session-name]                   Name der zu ladenden Sitzung\n"
 
-#: opts.cc:53
-msgid ""
-"  -o, --use-hw-optimizations        Try to use h/w specific optimizations\n"
+#: gtk2_ardour/opts.cc:53
+msgid "  -o, --use-hw-optimizations        Try to use h/w specific optimizations\n"
 msgstr ""
 
-#: opts.cc:55
+#: gtk2_ardour/opts.cc:55
 #, fuzzy
 msgid "  -V, --novst                      Do not use VST support\n"
 msgstr "  -h, --help                       Diese Hinweise\n"
 
-#: opts.cc:57
+#: gtk2_ardour/opts.cc:57
 msgid "  [session-name]                   Name of session to load\n"
 msgstr "  [session-name]                   Name der zu ladenden Sitzung\n"
 
-#: opts.cc:58
+#: gtk2_ardour/opts.cc:58
 msgid "  -C, --curvetest filename         Curve algorithm debugger\n"
 msgstr ""
 
-#: opts.cc:59
+#: gtk2_ardour/opts.cc:59
 #, fuzzy
 msgid "  -g, --gtktheme                   Allow GTK to load a theme\n"
 msgstr "  -h, --help                       Diese Hinweise\n"
 
-#: pan_automation_time_axis.cc:60
-msgid "You can't graphically edit panning of more than stream"
+#: gtk2_ardour/pan_automation_time_axis.cc:70
+msgid "You need to select which line to edit"
 msgstr ""
 
-#: pan_automation_time_axis.cc:80
+#: gtk2_ardour/pan_automation_time_axis.cc:91
 #, fuzzy
 msgid "add pan automation event"
 msgstr "Stellen"
 
-#: panner2d.cc:589 panner_ui.cc:435 plugin_ui.cc:834
+#: gtk2_ardour/panner2d.cc:589
+#: gtk2_ardour/panner_ui.cc:425
+#: gtk2_ardour/plugin_ui.cc:151
 msgid "Bypass"
-msgstr ""
+msgstr "Bypass"
 
-#: panner_ui.cc:58 panner_ui.cc:225
+#: gtk2_ardour/panner_ui.cc:56
+#: gtk2_ardour/panner_ui.cc:223
 #, fuzzy
 msgid "link"
 msgstr "leer"
 
-#: panner_ui.cc:69
-#, fuzzy
+#: gtk2_ardour/panner_ui.cc:67
 msgid "Pan automation mode"
-msgstr "Stellen"
+msgstr "Pan-Automationsmodus"
 
-#: panner_ui.cc:70
+#: gtk2_ardour/panner_ui.cc:68
 #, fuzzy
 msgid "Pan automation type"
 msgstr "Stellen"
 
-#: panner_ui.cc:81
+#: gtk2_ardour/panner_ui.cc:79
 msgid "panning link control"
-msgstr ""
+msgstr "Pan-Regler gruppieren"
 
-#: panner_ui.cc:83
+#: gtk2_ardour/panner_ui.cc:81
 msgid "panning link direction"
-msgstr ""
+msgstr "Richtung der Gruppierung"
 
-#: panner_ui.cc:235
+#: gtk2_ardour/panner_ui.cc:233
 msgid "L"
-msgstr ""
-
-#: panner_ui.cc:335
-#, c-format
-msgid "panner for channel %lu"
-msgstr ""
+msgstr "L"
 
-#: panner_ui.cc:337
+#: gtk2_ardour/panner_ui.cc:328
 #, c-format
-msgid "panner for channel %u"
-msgstr ""
+msgid "panner for channel %zu"
+msgstr "Pan-Regler für Kanal %zu"
 
-#: panner_ui.cc:445
+#: gtk2_ardour/panner_ui.cc:435
 #, fuzzy
 msgid "Reset all"
 msgstr "bestmöglich"
 
-#: playlist_selector.cc:52
+#: gtk2_ardour/playlist_selector.cc:52
 #, fuzzy
 msgid "ardour: playlists"
 msgstr "Ardour: Plugins"
 
-#: playlist_selector.cc:59
+#: gtk2_ardour/playlist_selector.cc:59
 msgid "Playlists grouped by track"
 msgstr ""
 
-#: playlist_selector.cc:98
+#: gtk2_ardour/playlist_selector.cc:98
 #, fuzzy
 msgid "ardour: playlist for "
 msgstr "Ardour: Editor: "
 
-#: playlist_selector.cc:114
+#: gtk2_ardour/playlist_selector.cc:114
 #, fuzzy
 msgid "Other tracks"
 msgstr "Stille einfügen"
 
-#: playlist_selector.cc:130
+#: gtk2_ardour/playlist_selector.cc:130
 msgid "unassigned"
 msgstr ""
 
-#: plugin_selector.cc:43
+#: gtk2_ardour/plugin_selector.cc:43
 msgid "ardour: plugins"
 msgstr "Ardour: Plugins"
 
-#: plugin_selector.cc:56
-#, fuzzy
+#: gtk2_ardour/plugin_selector.cc:56
 msgid "Available LADSPA Plugins"
 msgstr "Verfügbare LADSPA Plugins"
 
-#: plugin_selector.cc:57
+#: gtk2_ardour/plugin_selector.cc:57
 msgid "Type"
 msgstr "Typ"
 
-#: plugin_selector.cc:58 plugin_selector.cc:81
+#: gtk2_ardour/plugin_selector.cc:58
+#: gtk2_ardour/plugin_selector.cc:81
+#: gtk2_ardour/plugin_selector.cc:99
 msgid "# Inputs"
 msgstr "Eingänge"
 
-#: plugin_selector.cc:59 plugin_selector.cc:82
+#: gtk2_ardour/plugin_selector.cc:59
+#: gtk2_ardour/plugin_selector.cc:82
+#: gtk2_ardour/plugin_selector.cc:100
 msgid "# Outputs"
 msgstr "Ausgänge"
 
-#: plugin_selector.cc:68
+#: gtk2_ardour/plugin_selector.cc:68
 msgid "Plugins to be Connected to Insert"
-msgstr ""
+msgstr "Plugins, die als Insert verbunden werden"
 
-#: plugin_selector.cc:80
-#, fuzzy
+#: gtk2_ardour/plugin_selector.cc:80
+#: gtk2_ardour/plugin_selector.cc:98
 msgid "Available plugins"
-msgstr "Verfügbare LADSPA Plugins"
+msgstr "Verfügbare VST-Plugins"
 
-#: plugin_selector.cc:98
+#: gtk2_ardour/plugin_selector.cc:117
 msgid "Add a plugin to the effect list"
 msgstr "Plugin zur Effektliste hinzufügen"
 
-#: plugin_selector.cc:102
+#: gtk2_ardour/plugin_selector.cc:121
 msgid "Remove a plugin from the effect list"
 msgstr "Plugin aus der Effektliste entfernen"
 
-#: plugin_selector.cc:104
+#: gtk2_ardour/plugin_selector.cc:123
 msgid "Update available plugins"
 msgstr "Verfügbare Plugins auffrischen"
 
-#: plugin_selector.cc:126
+#: gtk2_ardour/plugin_selector.cc:146
 msgid "LADSPA"
-msgstr ""
+msgstr "LADSPA"
 
-#: plugin_selector.cc:129
+#: gtk2_ardour/plugin_selector.cc:150
 msgid "VST"
-msgstr ""
+msgstr "VST"
 
-#: plugin_ui.cc:84
-msgid ""
-"unknown type of editor-supplying plugin (note: no VST support in this "
-"version of ardour)"
+#: gtk2_ardour/plugin_selector.cc:155
+msgid "AudioUnit"
 msgstr ""
 
-#: plugin_ui.cc:139
-msgid "<span size=\"large\">Presets</span>"
+#: gtk2_ardour/plugin_ui.cc:85
+msgid "unknown type of editor-supplying plugin (note: no VST support in this version of ardour)"
 msgstr ""
 
-#: plugin_ui.cc:230
-#, fuzzy
-msgid "Controls"
-msgstr "Verbindungen"
-
-#: plugin_ui.cc:267
-msgid "Plugin Editor: could not build control element for port %1"
-msgstr ""
-
-#: plugin_ui.cc:358
-#, fuzzy
-msgid "Automation control"
-msgstr "Stellen"
-
-#: plugin_ui.cc:854
+#: gtk2_ardour/plugin_ui.cc:171
 msgid "Plugin preset %1 not found"
-msgstr ""
+msgstr "Plugin Preset %1 nicht gefunden"
 
-#: plugin_ui.cc:864
+#: gtk2_ardour/plugin_ui.cc:181
 #, fuzzy
 msgid "Name of New Preset:"
 msgstr "Name für neue Verbindung:"
 
-#: redirect_automation_line.cc:54
+#: gtk2_ardour/redirect_automation_line.cc:54
 msgid "redirect automation created for non-plugin"
 msgstr ""
 
-#: redirect_automation_time_axis.cc:94
+#: gtk2_ardour/redirect_automation_time_axis.cc:96
 #, fuzzy
 msgid "add automation event to "
 msgstr "Stellen"
 
-#: redirect_box.cc:223
+#: gtk2_ardour/redirect_box.cc:226
 msgid "New send"
 msgstr ""
 
-#: redirect_box.cc:224
+#: gtk2_ardour/redirect_box.cc:227
 msgid "Show send controls"
 msgstr ""
 
-#: redirect_box.cc:383
+#: gtk2_ardour/redirect_box.cc:386
 msgid ""
 "You attempted to add a plugin (%1).\n"
 "The plugin has %2 inputs\n"
@@ -5568,7 +5700,7 @@ msgid ""
 "part of the signal."
 msgstr ""
 
-#: redirect_box.cc:395
+#: gtk2_ardour/redirect_box.cc:398
 msgid ""
 "You attempted to add a plugin (%1).\n"
 "The plugin has %2 inputs\n"
@@ -5580,7 +5712,7 @@ msgid ""
 "support this type of configuration."
 msgstr ""
 
-#: redirect_box.cc:408
+#: gtk2_ardour/redirect_box.cc:411
 msgid ""
 "You attempted to add a plugin (%1).\n"
 "\n"
@@ -5593,34 +5725,35 @@ msgid ""
 "Ardour does not understand what to do in such situations.\n"
 msgstr ""
 
-#: redirect_box.cc:495
+#: gtk2_ardour/redirect_box.cc:499
 msgid "Pre-fader inserts, sends & plugins:"
 msgstr ""
 
-#: redirect_box.cc:498
+#: gtk2_ardour/redirect_box.cc:502
 msgid "Post-fader inserts, sends & plugins:"
-msgstr ""
+msgstr "Post-Fader Inserts, Sends & Plugins:"
 
-#: redirect_box.cc:644
+#: gtk2_ardour/redirect_box.cc:650
 msgid ""
 "You cannot reorder this set of redirects\n"
 "in that way because the inputs and\n"
 "outputs do not work correctly."
 msgstr ""
 
-#: redirect_box.cc:749
+#: gtk2_ardour/redirect_box.cc:750
 #, fuzzy
 msgid "rename redirect"
 msgstr "Ardour: Region umbenennen"
 
-#: redirect_box.cc:826 redirect_box.cc:874
+#: gtk2_ardour/redirect_box.cc:824
+#: gtk2_ardour/redirect_box.cc:872
 msgid ""
 "Copying the set of redirects on the clipboard failed,\n"
 "probably because the I/O configuration of the plugins\n"
 "could not match the configuration of this track."
 msgstr ""
 
-#: redirect_box.cc:896
+#: gtk2_ardour/redirect_box.cc:894
 #, fuzzy
 msgid ""
 "Do you really want to remove all redirects from this track?\n"
@@ -5629,7 +5762,7 @@ msgstr ""
 "Wollen Sie wirklich die Spur \"%1\" löschen?\n"
 "(Kann nicht rückgängig gemacht werden!)"
 
-#: redirect_box.cc:899
+#: gtk2_ardour/redirect_box.cc:897
 #, fuzzy
 msgid ""
 "Do you really want to remove all redirects from this bus?\n"
@@ -5638,261 +5771,194 @@ msgstr ""
 "Wollen Sie wirklich die Spur \"%1\" löschen?\n"
 "(Kann nicht rückgängig gemacht werden!)"
 
-#: redirect_box.cc:904
-#, fuzzy
+#: gtk2_ardour/redirect_box.cc:902
 msgid "Yes, remove them all"
-msgstr "Ja, entfernen."
+msgstr "Ja, alle löschen"
 
-#: redirect_box.cc:940
+#: gtk2_ardour/redirect_box.cc:938
 #, fuzzy
 msgid "ardour: %1"
 msgstr "Ardour: "
 
-#: redirect_box.cc:982
-#, fuzzy
-msgid "ardour: %1: %2 (by %3)"
-msgstr "Ardour: "
-
-#. new stuff
-#: redirect_box.cc:1054
+#: gtk2_ardour/redirect_box.cc:1060
 msgid "New Plugin ..."
-msgstr ""
+msgstr "Plugin einfügen..."
 
-#: redirect_box.cc:1055
-#, fuzzy
+#: gtk2_ardour/redirect_box.cc:1062
 msgid "New Insert"
-msgstr "Neuer Eingang"
+msgstr "Insert einfügen"
 
-#: redirect_box.cc:1056
+#: gtk2_ardour/redirect_box.cc:1064
 msgid "New Send ..."
-msgstr ""
+msgstr "Send einfügen..."
 
-#: redirect_box.cc:1068
-#, fuzzy
+#: gtk2_ardour/redirect_box.cc:1078
 msgid "Deselect All"
-msgstr "Auswahl"
+msgstr "Nichts auswählen"
 
-#: redirect_box.cc:1075
-#, fuzzy
+#: gtk2_ardour/redirect_box.cc:1085
 msgid "Activate all"
-msgstr "Aktiv"
+msgstr "Alle aktivieren"
 
-#: redirect_box.cc:1076
-#, fuzzy
+#: gtk2_ardour/redirect_box.cc:1086
 msgid "Deactivate all"
-msgstr "Alles deaktivieren"
-
-#: region_editor.cc:45
-msgid "NAME:"
-msgstr ""
-
-#: region_editor.cc:46
-msgid "lock"
-msgstr ""
-
-#: region_editor.cc:48
-msgid "opaque"
-msgstr ""
-
-#: region_editor.cc:49 region_editor.cc:192 region_editor.cc:226
-msgid "active"
-msgstr ""
-
-#: region_editor.cc:50
-msgid "visible"
-msgstr ""
-
-#: region_editor.cc:53
-msgid "Layer"
-msgstr "Schicht"
-
-#: region_editor.cc:54
-msgid "play"
-msgstr ""
+msgstr "Alle deaktivieren"
 
-#: region_editor.cc:61
-msgid "ENVELOPE"
-msgstr ""
-
-#: region_editor.cc:107
+#: gtk2_ardour/redirect_box.cc:1263
 #, fuzzy
-msgid "mute this region"
-msgstr "Name für Region:"
-
-#: region_editor.cc:108
-msgid "regions underneath this one cannot be heard"
-msgstr ""
-
-#: region_editor.cc:109
-msgid "prevent any changes to this region"
-msgstr ""
-
-#: region_editor.cc:110
-msgid "use the gain envelope during playback"
-msgstr ""
-
-#: region_editor.cc:111
-msgid "show the gain envelope"
-msgstr ""
+msgid "ardour: %1: %2 (by %3)"
+msgstr "Ardour: "
 
-#: region_editor.cc:112
-msgid "use fade in curve during playback"
-msgstr ""
+#: gtk2_ardour/audio_region_editor.cc:47
+msgid "NAME:"
+msgstr "NAME:"
 
-#: region_editor.cc:113
-msgid "use fade out curve during playback"
+#: gtk2_ardour/audio_region_editor.cc:48
+msgid "play"
 msgstr ""
 
-#: region_editor.cc:114
+#: gtk2_ardour/audio_region_editor.cc:67
 msgid "audition this region"
 msgstr ""
 
-#: region_editor.cc:147
+#: gtk2_ardour/audio_region_editor.cc:82
 msgid "START:"
-msgstr ""
+msgstr "BEGINN:"
 
-#: region_editor.cc:149
+#: gtk2_ardour/audio_region_editor.cc:84
 msgid "END:"
-msgstr ""
+msgstr "ENDE:"
 
-#: region_editor.cc:151
+#: gtk2_ardour/audio_region_editor.cc:86
 msgid "LENGTH:"
-msgstr ""
-
-#: region_editor.cc:191
-msgid "FADE IN"
-msgstr ""
+msgstr "LÄNGE:"
 
-#: region_editor.cc:193 region_editor.cc:227
-msgid "msecs"
-msgstr ""
-
-#: region_editor.cc:225
-msgid "FADE OUT"
-msgstr ""
-
-#: region_editor.cc:265
+#: gtk2_ardour/audio_region_editor.cc:122
 msgid "ardour: region "
 msgstr "Ardour: Region"
 
-#: region_editor.cc:402
-msgid "fade in edit"
-msgstr ""
+#: gtk2_ardour/audio_region_editor.cc:202
+#, fuzzy
+msgid "change region start position"
+msgstr "Regionen"
+
+#: gtk2_ardour/audio_region_editor.cc:219
+#, fuzzy
+msgid "change region end position"
+msgstr "Regionen"
 
-#: region_editor.cc:414
+#: gtk2_ardour/audio_region_editor.cc:240
 #, fuzzy
-msgid "fade out edit"
+msgid "change region length"
 msgstr "Ardour: Editor"
 
-#: regionview.cc:1146
+#: gtk2_ardour/audio_region_view.cc:937
 #, fuzzy
 msgid "add gain control point"
 msgstr "Synchronisationspunkt entfernen"
 
-#: route_params_ui.cc:89
+#: gtk2_ardour/route_params_ui.cc:85
 msgid "Tracks/Buses"
 msgstr ""
 
-#: route_params_ui.cc:109
+#: gtk2_ardour/route_params_ui.cc:105
 msgid "Pre-fader Redirects"
 msgstr ""
 
-#: route_params_ui.cc:110
+#: gtk2_ardour/route_params_ui.cc:106
 msgid "Post-fader Redirects"
 msgstr ""
 
-#: route_params_ui.cc:144
+#: gtk2_ardour/route_params_ui.cc:140
 #, fuzzy
 msgid "ardour: track/bus inspector"
 msgstr "Ardour: Editor"
 
-#: route_params_ui.cc:145
+#: gtk2_ardour/route_params_ui.cc:141
 #, fuzzy
 msgid "ardour_route_parameters"
 msgstr "Ardour: Route"
 
-#: route_params_ui.cc:202
+#: gtk2_ardour/route_params_ui.cc:202
 msgid "route display list item for renamed route not found!"
 msgstr ""
 
-#: route_params_ui.cc:453
+#: gtk2_ardour/route_params_ui.cc:449
 msgid "NO TRACK"
 msgstr ""
 
-#: route_params_ui.cc:695
+#: gtk2_ardour/route_params_ui.cc:672
 #, fuzzy
 msgid "ardour: track/bus inspector: "
 msgstr "Ardour: Editor"
 
-#: route_params_ui.cc:699
+#: gtk2_ardour/route_params_ui.cc:676
 msgid "No Route Selected"
 msgstr "Keine Route ausgewählt"
 
-#: route_params_ui.cc:700
+#: gtk2_ardour/route_params_ui.cc:677
 #, fuzzy
 msgid "ardour: track/bus/inspector: no route selected"
 msgstr "Ardour: Route: keine Route ausgewählt"
 
-#. ctrl-shift-click applies change to all routes
-#: route_ui.cc:134
+#: gtk2_ardour/route_ui.cc:144
 #, fuzzy
 msgid "mute change"
 msgstr "Bereich"
 
-#. ctrl-shift-click applies change to all routes
-#. ctrl-alt-click: exclusively solo this track, not a toggle */
-#: route_ui.cc:209 route_ui.cc:219
+#: gtk2_ardour/route_ui.cc:222
+#: gtk2_ardour/route_ui.cc:233
 #, fuzzy
 msgid "solo change"
 msgstr "Bereich"
 
-#: route_ui.cc:282
+#: gtk2_ardour/route_ui.cc:291
+msgid "Not connected to JACK - cannot engage record"
+msgstr ""
+
+#: gtk2_ardour/route_ui.cc:303
 msgid "rec-enable change"
 msgstr ""
 
-#: route_ui.cc:479
+#: gtk2_ardour/route_ui.cc:501
 #, fuzzy
 msgid "Solo-safe"
 msgstr "solo"
 
-#: route_ui.cc:487 route_ui.cc:530
-msgid "MIDI Bind"
-msgstr ""
-
-#: route_ui.cc:501
+#: gtk2_ardour/route_ui.cc:523
 msgid "Pre Fader"
 msgstr ""
 
-#: route_ui.cc:508
+#: gtk2_ardour/route_ui.cc:530
 msgid "Post Fader"
 msgstr ""
 
-#: route_ui.cc:515
+#: gtk2_ardour/route_ui.cc:537
 msgid "Control Outs"
 msgstr ""
 
-#: route_ui.cc:522
+#: gtk2_ardour/route_ui.cc:544
 msgid "Main Outs"
 msgstr ""
 
-#: route_ui.cc:559
+#: gtk2_ardour/route_ui.cc:581
 msgid "mix group solo  change"
 msgstr ""
 
-#: route_ui.cc:593
+#: gtk2_ardour/route_ui.cc:620
 msgid "mix group mute change"
 msgstr ""
 
-#: route_ui.cc:609
+#: gtk2_ardour/route_ui.cc:637
 msgid "mix group rec-enable change"
 msgstr ""
 
-#: route_ui.cc:626 visual_time_axis.cc:237
+#: gtk2_ardour/route_ui.cc:655
+#: gtk2_ardour/visual_time_axis.cc:242
 msgid "ardour: color selection"
 msgstr "Ardour: Farbe auswählen"
 
-#: route_ui.cc:702
-#, fuzzy
+#: gtk2_ardour/route_ui.cc:731
 msgid ""
 "Do you really want to remove track \"%1\" ?\n"
 "\n"
@@ -5900,221 +5966,269 @@ msgid ""
 "(cannot be undone)"
 msgstr ""
 "Wollen Sie wirklich die Spur \"%1\" löschen?\n"
-"(Kann nicht rückgängig gemacht werden!)"
+"\n"
+"Sie werden auch die Wiedergabeliste, die diese Spur benutzt verlieren.(Dies kann nicht rückgängig gemacht werden!)"
 
-#: route_ui.cc:704
+#: gtk2_ardour/route_ui.cc:733
 msgid ""
 "Do you really want to remove bus \"%1\" ?\n"
 "(cannot be undone)"
 msgstr ""
+"Wollen Sie den Bus \"%1\" wirklich löschen?\n"
+"(Dies kann nicht rückgängig gemacht werden!)"
 
-#: route_ui.cc:708 visual_time_axis.cc:279
+#: gtk2_ardour/route_ui.cc:737
+#: gtk2_ardour/visual_time_axis.cc:284
 msgid "Yes, remove it."
 msgstr "Ja, entfernen."
 
-#: route_ui.cc:737
+#: gtk2_ardour/route_ui.cc:758
 #, fuzzy
 msgid "New Name: "
 msgstr "Neuer Name: "
 
-#: sfdb_ui.cc:58
+#: gtk2_ardour/sfdb_ui.cc:61
 msgid "Add Field..."
 msgstr "Feld hinzufügen..."
 
-#: sfdb_ui.cc:59
+#: gtk2_ardour/sfdb_ui.cc:62
 msgid "Remove Field"
 msgstr "Feld entfernen"
 
-#: sfdb_ui.cc:62
+#: gtk2_ardour/sfdb_ui.cc:65
 msgid "Soundfile Info"
 msgstr ""
 
-#: sfdb_ui.cc:80
+#: gtk2_ardour/sfdb_ui.cc:84
 msgid "Field"
 msgstr "Feld"
 
-#: sfdb_ui.cc:81
+#: gtk2_ardour/sfdb_ui.cc:85
 msgid "Value"
 msgstr "Wert"
 
-#: sfdb_ui.cc:161
+#: gtk2_ardour/sfdb_ui.cc:139
+msgid "Length: %1"
+msgstr ""
+
+#: gtk2_ardour/sfdb_ui.cc:145
 #, fuzzy
-msgid "channels"
-msgstr "Abbrechen"
+msgid "Channels: %1"
+msgstr "Kanäle"
+
+#: gtk2_ardour/sfdb_ui.cc:148
+#, fuzzy
+msgid "Samplerate: %1"
+msgstr "Ausgewählten Bereich wiedergeben"
 
-#: sfdb_ui.cc:161
+#: gtk2_ardour/sfdb_ui.cc:151
+#, fuzzy
+msgid "Timecode: %1"
+msgstr "Timecode"
+
+#: gtk2_ardour/sfdb_ui.cc:172
 #, fuzzy
 msgid "samplerate"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: sfdb_ui.cc:162
+#: gtk2_ardour/sfdb_ui.cc:173
 #, fuzzy
 msgid "resolution"
 msgstr "Auswahl wiedergeben"
 
-#: sfdb_ui.cc:162
+#: gtk2_ardour/sfdb_ui.cc:173
 #, fuzzy
 msgid "format"
 msgstr "Anschluß"
 
-#: sfdb_ui.cc:183
+#: gtk2_ardour/sfdb_ui.cc:194
 msgid "Could not read file: %1 (%2)."
 msgstr ""
 
-#: sfdb_ui.cc:199
+#: gtk2_ardour/sfdb_ui.cc:212
 msgid "Could not access soundfile: "
 msgstr ""
 
-#: sfdb_ui.cc:236
+#: gtk2_ardour/sfdb_ui.cc:260
 #, fuzzy
 msgid "Name for Field"
 msgstr "Name für Region:"
 
-#: sfdb_ui.cc:335
+#: gtk2_ardour/sfdb_ui.cc:327
+msgid "Add to Region list"
+msgstr "Zur Liste der Regionen hinzufügen"
+
+#: gtk2_ardour/sfdb_ui.cc:328
+msgid "Add to selected Track(s)"
+msgstr "Zu ausgewählten Spuren hinzufügen"
+
+#: gtk2_ardour/sfdb_ui.cc:329
+msgid "Add as new Track(s)"
+msgstr "Als neue Spur(en) hinzufügen"
+
+#: gtk2_ardour/sfdb_ui.cc:330
+msgid "Add as new Tape Track(s)"
+msgstr "Als neue Tape-Spuren hinzufügen"
+
+#: gtk2_ardour/sfdb_ui.cc:372
 msgid "Split Channels"
-msgstr ""
+msgstr "Kanäle aufteilen"
 
-#: sfdb_ui.cc:342
+#: gtk2_ardour/sfdb_ui.cc:379
 msgid "Create a region for each channel"
-msgstr ""
+msgstr "Erstellt aus jedem Kanal eine eigene Region"
 
-#: sfdb_ui.cc:344
+#: gtk2_ardour/sfdb_ui.cc:381
 msgid "Embed"
-msgstr ""
+msgstr "Einbetten"
 
-#: sfdb_ui.cc:346
+#: gtk2_ardour/sfdb_ui.cc:383
 msgid "Link to an external file"
-msgstr ""
+msgstr "Bettet eine externe Datei ein, ohne sie zu ins Verzeichnis der Sitzung zu importieren"
 
-#: sfdb_ui.cc:348
+#: gtk2_ardour/sfdb_ui.cc:387
 msgid "Import"
 msgstr "Importieren"
 
-#: sfdb_ui.cc:350
+#: gtk2_ardour/sfdb_ui.cc:389
 msgid "Copy a file to the session folder"
-msgstr ""
+msgstr "Kopiert eine Datei in das Verzeichnis der Sitzung"
 
-#: sfdb_ui.cc:414
-msgid "programming error: %1"
-msgstr ""
-
-#: tempo_dialog.cc:18 tempo_dialog.cc:35
+#: gtk2_ardour/tempo_dialog.cc:18
+#: gtk2_ardour/tempo_dialog.cc:35
 msgid "Beats per minute"
 msgstr ""
 
-#: tempo_dialog.cc:21 tempo_dialog.cc:38 tempo_dialog.cc:203
-#: tempo_dialog.cc:221
+#: gtk2_ardour/tempo_dialog.cc:21
+#: gtk2_ardour/tempo_dialog.cc:38
+#: gtk2_ardour/tempo_dialog.cc:203
+#: gtk2_ardour/tempo_dialog.cc:221
 msgid "Bar"
 msgstr ""
 
-#: tempo_dialog.cc:22 tempo_dialog.cc:39 tempo_dialog.cc:204
-#: tempo_dialog.cc:222
+#: gtk2_ardour/tempo_dialog.cc:22
+#: gtk2_ardour/tempo_dialog.cc:39
+#: gtk2_ardour/tempo_dialog.cc:204
+#: gtk2_ardour/tempo_dialog.cc:222
 msgid "Beat"
 msgstr ""
 
-#: tempo_dialog.cc:24 tempo_dialog.cc:41 tempo_dialog.cc:205
-#: tempo_dialog.cc:223
+#: gtk2_ardour/tempo_dialog.cc:24
+#: gtk2_ardour/tempo_dialog.cc:41
+#: gtk2_ardour/tempo_dialog.cc:205
+#: gtk2_ardour/tempo_dialog.cc:223
 #, fuzzy
 msgid "Location"
 msgstr "Stellen"
 
-#: tempo_dialog.cc:199 tempo_dialog.cc:217
+#: gtk2_ardour/tempo_dialog.cc:199
+#: gtk2_ardour/tempo_dialog.cc:217
 msgid "Meter denominator"
 msgstr ""
 
-#: tempo_dialog.cc:200 tempo_dialog.cc:218
+#: gtk2_ardour/tempo_dialog.cc:200
+#: gtk2_ardour/tempo_dialog.cc:218
 msgid "Beats per bar"
 msgstr ""
 
-#: tempo_dialog.cc:236 tempo_dialog.cc:247
+#: gtk2_ardour/tempo_dialog.cc:236
+#: gtk2_ardour/tempo_dialog.cc:247
 msgid "whole (1)"
 msgstr ""
 
-#: tempo_dialog.cc:237 tempo_dialog.cc:249
+#: gtk2_ardour/tempo_dialog.cc:237
+#: gtk2_ardour/tempo_dialog.cc:249
 msgid "second (2)"
 msgstr ""
 
-#: tempo_dialog.cc:238 tempo_dialog.cc:251
+#: gtk2_ardour/tempo_dialog.cc:238
+#: gtk2_ardour/tempo_dialog.cc:251
 msgid "third (3)"
 msgstr ""
 
-#: tempo_dialog.cc:239 tempo_dialog.cc:253 tempo_dialog.cc:261
+#: gtk2_ardour/tempo_dialog.cc:239
+#: gtk2_ardour/tempo_dialog.cc:253
+#: gtk2_ardour/tempo_dialog.cc:261
 msgid "quarter (4)"
 msgstr ""
 
-#: tempo_dialog.cc:240 tempo_dialog.cc:255
+#: gtk2_ardour/tempo_dialog.cc:240
+#: gtk2_ardour/tempo_dialog.cc:255
 msgid "eighth (8)"
 msgstr ""
 
-#: tempo_dialog.cc:241 tempo_dialog.cc:257
+#: gtk2_ardour/tempo_dialog.cc:241
+#: gtk2_ardour/tempo_dialog.cc:257
 msgid "sixteenth (16)"
 msgstr ""
 
-#: tempo_dialog.cc:242 tempo_dialog.cc:259
+#: gtk2_ardour/tempo_dialog.cc:242
+#: gtk2_ardour/tempo_dialog.cc:259
 msgid "thirty-second (32)"
 msgstr ""
 
-#: tempo_dialog.cc:420
+#: gtk2_ardour/tempo_dialog.cc:420
 msgid "garbaged note type entry (%1)"
 msgstr ""
 
-#: tempo_dialog.cc:430
+#: gtk2_ardour/tempo_dialog.cc:430
 msgid "incomprehensible note type entry (%1)"
 msgstr ""
 
-#: time_axis_view.cc:112
+#: gtk2_ardour/time_axis_view.cc:112
 msgid "gTortnam"
 msgstr ""
 
-#: time_axis_view.cc:549
+#: gtk2_ardour/time_axis_view.cc:583
 msgid "Largest"
-msgstr ""
+msgstr "Am größten"
 
-#: time_axis_view.cc:550
-#, fuzzy
+#: gtk2_ardour/time_axis_view.cc:584
 msgid "Large"
-msgstr "Schicht"
+msgstr "Groß"
 
-#: time_axis_view.cc:551
-#, fuzzy
+#: gtk2_ardour/time_axis_view.cc:585
 msgid "Larger"
-msgstr "Schicht"
+msgstr "Größer"
 
-#: time_axis_view.cc:553
+#: gtk2_ardour/time_axis_view.cc:587
 msgid "Smaller"
-msgstr ""
+msgstr "Kleiner"
 
-#: time_axis_view.cc:554
-#, fuzzy
+#: gtk2_ardour/time_axis_view.cc:588
 msgid "Small"
-msgstr "Alle zeigen"
+msgstr "Klein"
 
-#: time_axis_view.cc:870
+#: gtk2_ardour/time_axis_view.cc:902
 msgid "unknown track height name \"%1\" in XML GUI information"
 msgstr ""
 
-#. first constructed item sets up font info
-#: time_axis_view_item.cc:79
+#: gtk2_ardour/time_axis_view_item.cc:79
 msgid "TimeAxisViewItemName"
 msgstr ""
 
-#: time_axis_view_item.cc:298
+#: gtk2_ardour/time_axis_view_item.cc:302
 msgid "new duration %1 frames is out of bounds for %2"
 msgstr ""
 
-#: time_selection.cc:41
+#: gtk2_ardour/time_selection.cc:41
 msgid "programming error: request for non-existent audio range (%1)!"
 msgstr ""
 
-#: utils.cc:107 utils.cc:150
+#: gtk2_ardour/utils.cc:106
+#: gtk2_ardour/utils.cc:149
 msgid "bad XPM header %1"
 msgstr ""
 
-#: utils.cc:332
+#: gtk2_ardour/utils.cc:331
 msgid "missing RGBA style for \"%1\""
 msgstr ""
 
-#: visual_time_axis.cc:276
+#: gtk2_ardour/utils.cc:513
+msgid "cannot find icon image for %1"
+msgstr ""
+
+#: gtk2_ardour/visual_time_axis.cc:281
 msgid ""
 "Do you really want to remove track \"%1\" ?\n"
 "(cannot be undone)"
@@ -6122,368 +6236,107 @@ msgstr ""
 "Wollen Sie wirklich die Spur \"%1\" löschen?\n"
 "(Kann nicht rückgängig gemacht werden!)"
 
-#: visual_time_axis.cc:325
+#: gtk2_ardour/visual_time_axis.cc:330
 msgid "new name: "
 msgstr "Neuer Name: "
 
-#: visual_time_axis.cc:336
+#: gtk2_ardour/visual_time_axis.cc:341
 msgid "A track already exists with that name"
 msgstr ""
 
-#, fuzzy
-#~ msgid "set selected trackview"
-#~ msgstr "Stille einfügen"
-
-#, fuzzy
-#~ msgid "set selected control point"
-#~ msgstr "Synchronisationspunkt entfernen"
-
-#, fuzzy
-#~ msgid "set selected regionview"
-#~ msgstr "Auswahl zu Schleife machen"
-
-#, fuzzy
-#~ msgid "Start a new session\n"
-#~ msgstr "Bitte mittels des \"Sitzung\"-Menüs\n"
-
-#~ msgid "via Session menu"
-#~ msgstr "eine Sitzung laden oder eine neue erstellen!"
-
-#, fuzzy
-#~ msgid "<b>Advanced</b>"
-#~ msgstr "Feld hinzufügen..."
-
-#, fuzzy
-#~ msgid "Select a File"
-#~ msgstr "Auswahl"
-
-#~ msgid "RECORD"
-#~ msgstr "AUFNAHME"
-
-#~ msgid "INPUT"
-#~ msgstr "EINGANG"
-
-#~ msgid "OUTPUT"
-#~ msgstr "AUSGANG"
-
-#, fuzzy
-#~ msgid "Gain automation mode"
-#~ msgstr "Stellen"
-
-#, fuzzy
-#~ msgid "Gain automation type"
-#~ msgstr "Stellen"
-
-#, fuzzy
-#~ msgid "trim"
-#~ msgstr "Streifen"
-
-#, fuzzy
-#~ msgid "gain automation mode"
-#~ msgstr "Stellen"
-
-#, fuzzy
-#~ msgid "gain automation state"
-#~ msgstr "Stellen"
-
-#, fuzzy
-#~ msgid "pan automation state"
-#~ msgstr "Stellen"
-
-#~ msgid "no group"
-#~ msgstr "keine Gruppe"
-
-#, fuzzy
-#~ msgid "normal"
-#~ msgstr "Ardour: Region"
-
-#, fuzzy
-#~ msgid "ardour cleanup"
-#~ msgstr "Ardour: Uhr"
-
-#, fuzzy
-#~ msgid "close session"
-#~ msgstr "Bitte mittels des \"Sitzung\"-Menüs\n"
-
-#, fuzzy
-#~ msgid "SetRegionLayerMode"
-#~ msgstr "Regionen"
-
-#, fuzzy
-#~ msgid "SetCrossfadeModel"
-#~ msgstr "Ardour: Editor"
-
-#, fuzzy
-#~ msgid "Play from"
-#~ msgstr "Wiedergabe ab Anfang"
-
-#, fuzzy
-#~ msgid "Set from range"
-#~ msgstr "Ausgewählten Bereich wiedergeben"
-
-#, fuzzy
-#~ msgid "ardour: unplugged"
-#~ msgstr "Ardour: Plugins"
-
-#~ msgid "To be added"
-#~ msgstr "hinzuzufügen"
-
-#~ msgid "Update"
-#~ msgstr "Auffrischen"
-
-#, fuzzy
-#~ msgid "save"
-#~ msgstr "Speichern"
-
-#~ msgid "Name for plugin settings:"
-#~ msgstr "Name für Plugineinstellungen:"
-
-#, fuzzy
-#~ msgid "spring"
-#~ msgstr "Importieren"
-
-#, fuzzy
-#~ msgid "Sprung"
-#~ msgstr "Sortieren"
-
-#~ msgid "rescan"
-#~ msgstr "Auffrischen"
-
-#, fuzzy
-#~ msgid "Enable/Disable follow playhead"
-#~ msgstr "Wiedergabeschleife an/abschalten"
-
-#~ msgid "Input Connections"
-#~ msgstr "Verbindungen der Eingänge"
-
-#~ msgid "Output Connections"
-#~ msgstr "Verbindungen der Ausgänge"
-
-#, fuzzy
-#~ msgid "New Input"
-#~ msgstr "Neuer Eingang"
-
-#, fuzzy
-#~ msgid "New Output"
-#~ msgstr "Neuer Ausgang"
-
-#, fuzzy
-#~ msgid "Add Port"
-#~ msgstr "Port hinzufügen"
-
-#, fuzzy
-#~ msgid "Available Ports"
-#~ msgstr "Verfügbare Verbindungen"
-
-#~ msgid "ardour: connections"
-#~ msgstr "Ardour: Verbindungen"
-
-#, fuzzy
-#~ msgid "crossfade editor"
-#~ msgstr "Ardour: Editor"
-
-#, fuzzy
-#~ msgid "Regions/name"
-#~ msgstr "Regionen"
-
-#~ msgid "Edit:"
-#~ msgstr "Bearbeiten:"
-
-#, fuzzy
-#~ msgid "Cancel cleanup"
-#~ msgstr "leeren"
-
-#, fuzzy
-#~ msgid "Import selected as tracks"
-#~ msgstr "Auswahl importieren"
-
-#~ msgid "ardour: audio import in progress"
-#~ msgstr "Ardour: Audio Import in Arbeit"
-
-#, fuzzy
-#~ msgid "You can't embed an audiofile until you have a session loaded."
-#~ msgstr ""
-#~ "Sie können keine Audio-Daten importieren, solange keine Sitzung geladen "
-#~ "ist."
-
-#, fuzzy
-#~ msgid "Insert selected as new tracks"
-#~ msgstr "Stille einfügen"
-
-#, fuzzy
-#~ msgid "Insert selected"
-#~ msgstr "Stille einfügen"
-
-#, fuzzy
-#~ msgid "hidden"
-#~ msgstr "Verbergen"
-
-#~ msgid "Sorting"
-#~ msgstr "Sortieren"
-
-#, fuzzy
-#~ msgid "Regions/length"
-#~ msgstr "nach Länge der Region"
-
-#, fuzzy
-#~ msgid "Regions/start"
-#~ msgstr "Regionen"
-
-#, fuzzy
-#~ msgid "Regions/end"
-#~ msgstr "Regionen"
-
-#, fuzzy
-#~ msgid "Regions/file name"
-#~ msgstr "nach Name der Region"
-
-#, fuzzy
-#~ msgid "ardour: soundfile selector"
-#~ msgstr "Ardour: Farbe auswählen"
-
-#~ msgid "Add to Library..."
-#~ msgstr "Zu Bibliothek hinzufügen..."
-
-#~ msgid "Remove..."
-#~ msgstr "Entfernen..."
-
-#~ msgid "Find..."
-#~ msgstr "Suchen..."
-
-#~ msgid "Add Folder"
-#~ msgstr "Verzeichnis hinzufügen"
-
-#~ msgid "Add audio file or directory"
-#~ msgstr "Audio-Datei oder -Verzeichnis hinzufügen"
-
-#, fuzzy
-#~ msgid "Importing"
-#~ msgstr "Importieren"
-
-#~ msgid "Folder name:"
-#~ msgstr "Verzeichnisname:"
-
-#, fuzzy
-#~ msgid "Should not be reached"
-#~ msgstr "Datei \"%1\" konnte nicht geöffnet werden."
-
-#~ msgid "file \"%1\" could not be opened"
-#~ msgstr "Datei \"%1\" konnte nicht geöffnet werden."
-
-#~ msgid "Field name:"
-#~ msgstr "Feldname:"
-
-#~ msgid "Field value:"
-#~ msgstr "Wert des Feldes:"
-
-#~ msgid "AND"
-#~ msgstr "UND"
-
-#~ msgid "Results"
-#~ msgstr "Ergebnisse"
-
-#~ msgid "Create multi-channel region"
-#~ msgstr "Region mit mehreren Kanälen erstellen"
+#: gtk2_ardour/connection_editor.cc:51
+msgid "ardour: connections"
+msgstr "Ardour: Verbindungen"
 
-#~ msgid "Ardour: Search Results"
-#~ msgstr "Ardour: Suchergebnisse"
+#: gtk2_ardour/connection_editor.cc:52
+msgid "Input Connections"
+msgstr "Verbindungen der Eingänge"
 
-#~ msgid "Name for new mix group"
-#~ msgstr "Name für neue Mix Gruppe"
+#: gtk2_ardour/connection_editor.cc:53
+msgid "Output Connections"
+msgstr "Verbindungen der Ausgänge"
 
+#: gtk2_ardour/connection_editor.cc:54
 #, fuzzy
-#~ msgid "Create"
-#~ msgstr "Abschnitt erzeugen:"
-
-#, fuzzy
-#~ msgid "show again"
-#~ msgstr "Stellen"
+msgid "New Input"
+msgstr "Neuer Eingang"
 
+#: gtk2_ardour/connection_editor.cc:55
 #, fuzzy
-#~ msgid "new session setup"
-#~ msgstr "Name der Sitzung"
-
-#~ msgid "blank"
-#~ msgstr "leer"
+msgid "New Output"
+msgstr "Neuer Ausgang"
 
+#: gtk2_ardour/connection_editor.cc:58
+#: gtk2_ardour/connection_editor.cc:101
 #, fuzzy
-#~ msgid "Slave to MTC"
-#~ msgstr "MTC senden"
+msgid "Add Port"
+msgstr "Port hinzufügen"
 
-#, fuzzy
-#~ msgid "Narrow mixer strips"
-#~ msgstr "schmale Mixerstreifen"
+#: gtk2_ardour/connection_editor.cc:106
+msgid "Available Ports"
+msgstr "Verfügbare Verbindungen"
 
+#: gtk2_ardour/connection_editor.cc:501
 #, fuzzy
-#~ msgid "Misc"
-#~ msgstr "Min:Sek"
+msgid "Connection \""
+msgstr "Verbindungen"
 
-#~ msgid "Display"
-#~ msgstr "Anzeige"
+#: gtk2_ardour/connection_editor.cc:503
+msgid "\""
+msgstr ""
 
-#~ msgid "--unknown--"
-#~ msgstr "--unbekannt--"
+#: gtk2_ardour/connection_editor.cc:532
+#, c-format
+msgid "in %d"
+msgstr ""
 
-#, fuzzy
-#~ msgid "Select all"
-#~ msgstr "Auswahl"
+#: gtk2_ardour/connection_editor.cc:534
+#, fuzzy, c-format
+msgid "out %d"
+msgstr "Nur %1"
 
+#: gtk2_ardour/connection_editor.cc:658
 #, fuzzy
-#~ msgid "Inserts"
-#~ msgstr "Stille einfügen"
+msgid "Name for new connection:"
+msgstr "Name für Region:"
 
-#, fuzzy
-#~ msgid "Sends"
-#~ msgstr "Minuten:Sekunden"
+#: gtk2_ardour/analysis_window.cc:46
+msgid "analysis window"
+msgstr ""
 
-#, fuzzy
-#~ msgid "Select all ..."
-#~ msgstr "Auswahl"
+#: gtk2_ardour/analysis_window.cc:48
+msgid "Signal source"
+msgstr ""
 
+#: gtk2_ardour/analysis_window.cc:49
 #, fuzzy
-#~ msgid "Seamless Looping"
-#~ msgstr "Ausgewählten Bereich wiedergeben"
-
-#~ msgid "No toggle button pixmaps found to match toggle-button-[0-9]*.xpm$"
-#~ msgstr ""
-#~ "Keine Grafiken für Umschalter-Knöpfe gefunden!\n"
-#~ "(Gesuchter Dateiname: \"toggle-button[0-9]*.xpm$\")"
-
-#~ msgid ""
-#~ "No small push button pixmaps found to match small-round-button-[0-9]*.xpm$"
-#~ msgstr ""
-#~ "Keine Grafiken für kleine Schaltknöpfe gefunden!\n"
-#~ "(Gesuchter Dateiname: \"small-round-button[0-9]*.xpm$\")"
-
-#~ msgid "ardour: tempo editor"
-#~ msgstr "Ardour: Tempo bearbeiten"
+msgid "Selected ranges"
+msgstr "Ausgewählten Bereich wiedergeben"
 
+#: gtk2_ardour/analysis_window.cc:50
 #, fuzzy
-#~ msgid "ardour_add_track_bus"
-#~ msgstr "Ardour: Editor"
-
-#~ msgid "ok"
-#~ msgstr "OK"
+msgid "Selected regions"
+msgstr "Auswahl zu Schleife machen"
 
+#: gtk2_ardour/analysis_window.cc:52
 #, fuzzy
-#~ msgid "apply"
-#~ msgstr "Anwenden"
+msgid "Display model"
+msgstr "Anzeige"
 
-#, fuzzy
-#~ msgid "Edit left"
-#~ msgstr "Bearbeitungs Modus"
+#: gtk2_ardour/analysis_window.cc:53
+msgid "Composite graphs for each track"
+msgstr ""
 
-#, fuzzy
-#~ msgid "Edit right"
-#~ msgstr "Mix Gruppen"
+#: gtk2_ardour/analysis_window.cc:54
+msgid "Composite graph of all tracks"
+msgstr ""
 
-#, fuzzy
-#~ msgid "Edit fade"
-#~ msgstr "Bearbeitungs Modus"
+#: gtk2_ardour/analysis_window.cc:63
+msgid "Track"
+msgstr "Spur"
 
+#: gtk2_ardour/analysis_window.cc:131
 #, fuzzy
-#~ msgid "Bounce region"
-#~ msgstr "Bereich"
+msgid "Analyze data"
+msgstr "Bereich"
 
-#~ msgid "clear connections"
-#~ msgstr "Verbindungen löschen"
index 6dbef3b7ebe8c0123a968c84c5715dff98045d5d..107e3d36add54c9a6b25375aabe51806c494482d 100644 (file)
@@ -553,7 +553,7 @@ msgstr "fil"
 
 #: ../ardour_ui.cc:2030
 msgid "Are you sure you want to cleanup?"
-msgstr "Är du säker pÃ¥ att du vill göra en rensning?"
+msgstr "Är du säker pÃ¥ att du vill rensa upp?"
 
 #: ../ardour_ui.cc:2035
 msgid ""
@@ -562,17 +562,17 @@ msgid ""
 "After cleanup, unused audio files will be moved to a \"dead sounds\" "
 "location."
 msgstr ""
-"Rensning Ã¤r en destruktiv funktion.\n"
-"ALL Ã¥ngra-/gör om-information kommer att förloras om du rensar.\n"
+"Att rensa Ã¤r en destruktiv funktion.\n"
+"ALL Ã¥ngra-/gör om-information kommer att gÃ¥ förlorad om du rensar.\n"
 "Oanvända filer kommer att flyttas till en \"döda ljud\"-plats."
 
 #: ../ardour_ui.cc:2041
 msgid "Clean Up"
-msgstr "Rensning"
+msgstr "Rensa upp"
 
 #: ../ardour_ui.cc:2044
 msgid "CleanupDialog"
-msgstr "Rensningsdialog"
+msgstr "Rensadialog"
 
 #: ../ardour_ui.cc:2045
 msgid "ardour_cleanup"
@@ -596,7 +596,7 @@ msgstr ""
 "och har flyttats till:\n"
 "%3. \n"
 "\n"
-"Tömma papperskorgen kommer att \n"
+"Att tömma papperskorgen kommer att \n"
 "frigöra ytterligarel\n"
 "%4 %5byte diskutrymme.\n"
 
@@ -616,7 +616,7 @@ msgstr ""
 
 #: ../ardour_ui.cc:2214
 msgid "Recording was stopped because your system could not keep up."
-msgstr "Inspelningen avstannades eftersom ditt system inte kunde hänga med."
+msgstr "Inspelningen stoppades eftersom ditt system inte kunde hänga med."
 
 #: ../ardour_ui.cc:2237
 msgid ""
@@ -932,7 +932,7 @@ msgstr "Ã…teranslut"
 
 #: ../ardour_ui_ed.cc:146 ../mixer_strip.cc:497 ../mixer_strip.cc:565
 msgid "Disconnect"
-msgstr "Koppla ifrÃ¥n"
+msgstr "Koppla frÃ¥n"
 
 #: ../ardour_ui_ed.cc:173
 msgid "Windows"
@@ -1082,11 +1082,11 @@ msgstr "GÃ¥ till slutet"
 
 #: gtk2_ardour/ardour_ui.cc:119 gtk2_ardour/ardour_ui_ed.cc:267
 msgid "Punch In"
-msgstr "Punch-in"
+msgstr "Inslag"
 
 #: gtk2_ardour/ardour_ui.cc:120 gtk2_ardour/ardour_ui_ed.cc:270
 msgid "Punch Out"
-msgstr "Punch-ut"
+msgstr "Utslag"
 
 #: gtk2_ardour/ardour_ui.cc:121 gtk2_ardour/ardour_ui_ed.cc:282
 msgid "Auto Return"
@@ -1371,6 +1371,11 @@ msgstr "Nya fulla Ã¶vertoningar Ã¤r pÃ¥slagna"
 msgid "ST"
 msgstr "HT"
 
+#: gtk2_ardour/audio_clock.cc:1796 gtk2_ardour/editor.cc:180
+msgid "Timecode"
+msgstr "Tidskod"
+
+
 #: ../ardour_ui_options.cc:407 ../ardour_ui_options.cc:417
 #: ../ardour_ui_options.cc:484
 msgid "Internal"
@@ -1560,10 +1565,18 @@ msgstr "Efter inspelningstiden"
 msgid "Alignment"
 msgstr "Justera"
 
+#: gtk2_ardour/route_time_axis.cc:458
+msgid "Normal mode"
+msgstr "Normalt läge"
+
+#: gtk2_ardour/route_time_axis.cc:461
+msgid "Tape mode"
+msgstr "Band-läge"
+
 #: ../audio_time_axis.cc:787 ../editor.cc:526 ../editor_actions.cc:59
 #: ../mixer_strip.cc:1000 ../mixer_ui.cc:110
 msgid "Active"
-msgstr "Aktiva"
+msgstr "Aktiv"
 
 #: ../audio_time_axis.cc:792 ../editor.cc:1921 ../editor_actions.cc:319
 #: ../editor_markers.cc:507 ../imageframe_time_axis.cc:258
@@ -1633,7 +1646,7 @@ msgstr "ta bort kontrollpunkt"
 
 #: ../automation_time_axis.cc:32 ../editor_ops.cc:2886
 msgid "clear"
-msgstr "rensa"
+msgstr "Rensa"
 
 #: ../automation_time_axis.cc:74
 msgid "track height"
@@ -1661,7 +1674,7 @@ msgstr "Manuell"
 #: ../gain_meter.cc:173 ../panner_ui.cc:90 ../plugin_ui.cc:394
 #: ../plugin_ui.cc:636 ../sfdb_ui.cc:55
 msgid "Play"
-msgstr "Spela"
+msgstr "Uppspelning"
 
 #: ../automation_time_axis.cc:187 ../automation_time_axis.cc:234
 #: ../automation_time_axis.cc:468 ../gain_meter.cc:175 ../panner_ui.cc:92
@@ -2109,8 +2122,8 @@ msgstr "Zoom-räckvidd"
 
 #: ../editor.cc:501 ../editor.cc:527 ../editor_actions.cc:61 ../mixer_ui.cc:85
 #: ../mixer_ui.cc:111
-msgid "Visible"
-msgstr "Synliga"
+msgid "Show"
+msgstr "Visa"
 
 #: ../editor.cc:502 ../editor.cc:525
 msgid "Name"
@@ -2263,6 +2276,10 @@ msgstr "Analysera regioner"
 msgid "Lock"
 msgstr "LÃ¥s"
 
+#: gtk2_ardour/editor.cc:1755
+msgid "Opaque"
+msgstr "Ogenomskinlig"
+
 #: ../editor.cc:1852
 msgid "Unlock"
 msgstr "LÃ¥s upp"
@@ -2271,6 +2288,18 @@ msgstr "LÃ¥s upp"
 msgid "Original position"
 msgstr "Ursprunglig position"
 
+#: gtk2_ardour/editor.cc:1773
+msgid "Reset Envelope"
+msgstr "Nollställ konvolut"
+
+#: gtk2_ardour/editor.cc:1775
+msgid "Envelope Visible"
+msgstr "Konvolut synligt"
+
+#: gtk2_ardour/editor.cc:1782
+msgid "Envelope Active"
+msgstr "Konvolut aktivt"
+
 #: ../editor.cc:1868
 msgid "Toggle envelope visibility"
 msgstr "Ändra konvolutsvisning"
@@ -2296,6 +2325,10 @@ msgstr "Motsatt riktning"
 msgid "Add Range Markers"
 msgstr "Lägg till omfÃ¥ngsmarkörer"
 
+#: gtk2_ardour/editor.cc:1804
+msgid "Set Range Selection"
+msgstr "Definiera omfÃ¥ngsmarkering"
+
 #: ../editor.cc:1885
 msgid "Set Range"
 msgstr "Definiera omfÃ¥ng"
@@ -2683,6 +2716,26 @@ msgstr "Automatisk anslutning"
 msgid "Layering"
 msgstr "Lager"
 
+#: gtk2_ardour/editor_actions.cc:43
+msgid "Timecode fps"
+msgstr "Tidskod-FPS"
+
+#: gtk2_ardour/editor_actions.cc:44
+msgid "Pullup / Pulldown"
+msgstr "UppÃ¥tdrag / NedÃ¥tdrag"
+
+#: gtk2_ardour/editor_actions.cc:45
+msgid "Subframes"
+msgstr "Underrutor"
+
+#: gtk2_ardour/editor_actions.cc:388
+msgid "29.97 drop"
+msgstr "29.97 fall"
+
+#: gtk2_ardour/editor_actions.cc:390
+msgid "30 drop"
+msgstr "30 fall"
+
 #: ../editor_actions.cc:41
 msgid "Metering"
 msgstr "NivÃ¥mätning"
@@ -2782,7 +2835,7 @@ msgstr "Redigeringsmarkören till regionslutet"
 
 #: ../editor_actions.cc:104 ../editor_ops.cc:1364
 msgid "select all"
-msgstr "välj allt"
+msgstr "Välj allt"
 
 #: ../editor_actions.cc:106
 msgid "Select All After Edit Cursor"
@@ -2991,7 +3044,7 @@ msgstr "Normalisera region"
 
 #: ../editor_actions.cc:232
 msgid "crop"
-msgstr "beskär"
+msgstr "Beskär"
 
 #: ../editor_actions.cc:234
 msgid "Insert Chunk"
@@ -3263,6 +3316,14 @@ msgstr "Senast flyttade/tillagda Ã¤r högre"
 msgid "Most Recently Added is Higher"
 msgstr "Senast tillagda Ã¤r högre"
 
+#: gtk2_ardour/editor_actions.cc:408
+msgid "80 per frame"
+msgstr "80 per ruta"
+
+#: gtk2_ardour/editor_actions.cc:409
+msgid "100 per frame"
+msgstr "100 per ruta"
+
 #: ../editor_audio_import.cc:72
 msgid "You can't import or embed an audiofile until you have a session loaded."
 msgstr "Du kan inte importera en ljudfil innan du har laddat en session."
@@ -4242,19 +4303,19 @@ msgstr ""
 
 #: ../gain_meter.cc:776 ../mixer_strip.cc:770 ../panner_ui.cc:770
 msgid "O"
-msgstr ""
+msgstr "A"
 
 #: ../gain_meter.cc:779 ../panner_ui.cc:773
 msgid "P"
-msgstr ""
+msgstr "U"
 
 #: ../gain_meter.cc:782 ../panner_ui.cc:776
 msgid "T"
-msgstr ""
+msgstr "B"
 
 #: ../gain_meter.cc:785 ../panner_ui.cc:779
 msgid "W"
-msgstr ""
+msgstr "S"
 
 #: ../gtk-custom-ruler.c:126
 msgid "Lower"
@@ -4664,7 +4725,7 @@ msgstr "Nytt namn för taktart"
 
 #: ../mixer_strip.cc:94 ../mixer_strip.cc:140 ../mixer_strip.cc:1227
 msgid "pre"
-msgstr "för"
+msgstr "pre"
 
 #: ../mixer_strip.cc:95 ../mixer_strip.cc:822
 msgid "Comments"
@@ -4676,18 +4737,18 @@ msgstr "IngÃ¥ng"
 
 #: ../mixer_strip.cc:136 ../mixer_strip.cc:1223
 msgid "input"
-msgstr "ingÃ¥ng"
+msgstr "in"
 
 #: ../mixer_strip.cc:144 ../mixer_strip.cc:1231
 msgid "post"
-msgstr "efter"
+msgstr "post"
 
 #. TRANSLATORS: this string should be longest of the strings
 #. used to describe meter points. In english, its "input".
 #.
 #: ../mixer_strip.cc:152
 msgid "tupni"
-msgstr "gnÃ¥gni"
+msgstr "ni"
 
 #: ../mixer_strip.cc:207
 msgid "Varispeed"
@@ -4703,7 +4764,7 @@ msgstr "okänd strip-bredd \"%1\" i XML-GUI-informationen"
 
 #: ../mixer_strip.cc:417
 msgid "record"
-msgstr "spela in"
+msgstr "Spela in"
 
 #: ../mixer_strip.cc:418 ../region_editor.cc:46
 msgid "mute"
@@ -5431,7 +5492,7 @@ msgstr "Aktivera alla"
 
 #: ../redirect_box.cc:1075
 msgid "Deactivate all"
-msgstr "Aktivera alla"
+msgstr "Avaktivera alla"
 
 #: ../region_editor.cc:44
 msgid "NAME:"
@@ -5450,8 +5511,8 @@ msgid "active"
 msgstr "aktivt"
 
 #: ../region_editor.cc:49
-msgid "visible"
-msgstr "synligt"
+msgid "show"
+msgstr "visa"
 
 #: ../region_editor.cc:52
 msgid "Layer"
index 6039e089e943ab22cd6eb3735716a312d63b515f..8f307f61f2a4513d646fcb0a6040fc2e6489ac4f 100644 (file)
@@ -94,6 +94,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual gulong frame_to_pixel (nframes_t frame) = 0;
        virtual Selection& get_selection() const = 0;
        virtual Selection& get_cut_buffer() const = 0;
+       virtual bool extend_selection_to_track (TimeAxisView&) = 0;
        virtual void play_selection () = 0;
        virtual void set_show_measures (bool yn) = 0;
        virtual bool show_measures () const = 0;
@@ -107,7 +108,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual gdouble   get_current_zoom () = 0;
        virtual PlaylistSelector& playlist_selector() const = 0;
        virtual void route_name_changed (TimeAxisView *) = 0;
-       virtual void clear_playlist (ARDOUR::Playlist&) = 0;
+       virtual void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>) = 0;
        virtual void new_playlists () = 0;
        virtual void copy_playlists () = 0;
        virtual void clear_playlists () = 0;
@@ -118,6 +119,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual void set_follow_playhead (bool yn) = 0;
        virtual void toggle_follow_playhead () = 0;
        virtual bool follow_playhead() const = 0;
+       virtual bool dragging_playhead() const = 0;
        virtual void ensure_float (Gtk::Window&) = 0;
        virtual void show_window () = 0;
        virtual TrackViewList* get_valid_views (TimeAxisView*, ARDOUR::RouteGroup* grp = 0) = 0;
@@ -138,6 +140,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;
 
        Glib::RefPtr<Gtk::ActionGroup> editor_actions;
 
index f2ee2a5b8fe8be751e86c8d9093350ed6bfed6d5..fac6ede6f3a6a66252d9fb8b638cd1ac6e9d6ff7 100644 (file)
@@ -19,6 +19,7 @@
 */
 
 #include <cmath>
+#include <iostream>
 
 #include <sigc++/bind.h>
 
@@ -136,11 +137,12 @@ RedirectBox::RedirectBox (Placement pcmnt, Session& sess, boost::shared_ptr<Rout
        pack_start (redirect_eventbox, true, true);
 
        _route->redirects_changed.connect (mem_fun(*this, &RedirectBox::redisplay_redirects));
+       _route->GoingAway.connect (mem_fun (*this, &RedirectBox::route_going_away));
 
        redirect_eventbox.signal_enter_notify_event().connect (bind (sigc::ptr_fun (RedirectBox::enter_box), this));
 
        redirect_display.signal_button_press_event().connect (mem_fun(*this, &RedirectBox::redirect_button_press_event), false);
-       redirect_display.signal_button_release_event().connect (mem_fun(*this, &RedirectBox::redirect_button_press_event));
+       redirect_display.signal_button_release_event().connect (mem_fun(*this, &RedirectBox::redirect_button_release_event));
 
        /* start off as a passthru strip. we'll correct this, if necessary,
           in update_diskstream_display().
@@ -155,6 +157,13 @@ RedirectBox::~RedirectBox ()
 {
 }
 
+void
+RedirectBox::route_going_away ()
+{
+       /* don't keep updating display as redirects are deleted */
+       no_redirect_redisplay = true;
+}
+
 void
 RedirectBox::object_drop (string type, uint32_t cnt, const boost::shared_ptr<Redirect>* ptr)
 {
@@ -282,13 +291,8 @@ RedirectBox::redirect_button_press_event (GdkEventButton *ev)
                }
                
        }
-       
-       if (redirect && Keyboard::is_delete_event (ev)) {
-               
-               Glib::signal_idle().connect (bind (mem_fun(*this, &RedirectBox::idle_delete_redirect), redirect));
-               ret = true;
-               
-       } else if (redirect && (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS && ev->state == 0))) {
+
+       if (redirect && (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS && ev->state == 0))) {
                
                if (_session.engine().connected()) {
                        /* XXX giving an error message here is hard, because we may be in the midst of a button press */
@@ -296,23 +300,50 @@ RedirectBox::redirect_button_press_event (GdkEventButton *ev)
                }
                ret = true;
                
+       } else if (redirect && ev->button == 1 && selected) {
+
+               // this is purely informational but necessary
+               RedirectSelected (redirect); // emit
+       }
+       
+       return ret;
+}
+
+bool
+RedirectBox::redirect_button_release_event (GdkEventButton *ev)
+{
+       TreeIter iter;
+       TreeModel::Path path;
+       TreeViewColumn* column;
+       int cellx;
+       int celly;
+       boost::shared_ptr<Redirect> redirect;
+       int ret = false;
+
+
+       if (redirect_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
+               if ((iter = model->get_iter (path))) {
+                       redirect = (*iter)[columns.redirect];
+               }
+       }
+
+       if (redirect && Keyboard::is_delete_event (ev)) {
+               
+               Glib::signal_idle().connect (bind (mem_fun(*this, &RedirectBox::idle_delete_redirect), boost::weak_ptr<Redirect>(redirect)));
+               ret = true;
+               
        } else if (Keyboard::is_context_menu_event (ev)) {
 
                show_redirect_menu(ev->time);
                ret = true;
 
-       } else if (redirect && ev->button == 2 && ev->state == 0) {
+       } else if (redirect && ev->button == 2 && ev->state == GDK_BUTTON2_MASK) {
                
                redirect->set_active (!redirect->active(), this);
                ret = true;
 
        } 
-       else if (redirect && ev->button == 1 && selected) {
 
-               // this is purely informational but necessary
-               RedirectSelected (redirect); // emit
-       }
-       
        return ret;
 }
 
@@ -362,7 +393,7 @@ RedirectBox::insert_plugin_chosen (boost::shared_ptr<Plugin> plugin)
 
                boost::shared_ptr<Redirect> redirect (new PluginInsert (_session, plugin, _placement));
                
-               redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active));
+               redirect->active_changed.connect (bind (mem_fun (*this, &RedirectBox::show_redirect_active_r), boost::weak_ptr<Redirect>(redirect)));
 
                uint32_t err_streams;
 
@@ -440,7 +471,7 @@ void
 RedirectBox::choose_insert ()
 {
        boost::shared_ptr<Redirect> redirect (new PortInsert (_session, _placement));
-       redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active));
+       redirect->active_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_active_r), boost::weak_ptr<Redirect>(redirect)));
        _route->add_redirect (redirect, this);
 }
 
@@ -457,15 +488,24 @@ RedirectBox::choose_send ()
        IOSelectorWindow *ios = new IOSelectorWindow (_session, send, false, true);
        
        ios->show_all ();
-       ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), boost::static_pointer_cast<Redirect>(send), ios));
+
+       boost::shared_ptr<Redirect> r = boost::static_pointer_cast<Redirect>(send);
+
+       ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), boost::weak_ptr<Redirect>(r), ios));
 }
 
 void
-RedirectBox::send_io_finished (IOSelector::Result r, boost::shared_ptr<Redirect> redirect, IOSelectorWindow* ios)
+RedirectBox::send_io_finished (IOSelector::Result r, boost::weak_ptr<Redirect> weak_redirect, IOSelectorWindow* ios)
 {
+       boost::shared_ptr<Redirect> redirect (weak_redirect.lock());
+
+       if (!redirect) {
+               return;
+       }
+
        switch (r) {
        case IOSelector::Cancelled:
-               // delete redirect; XXX SHAREDPTR HOW TO DESTROY THE REDIRECT ? do we even need to think about it?
+               // redirect will go away when all shared_ptrs to it vanish
                break;
 
        case IOSelector::Accepted:
@@ -484,7 +524,7 @@ RedirectBox::redisplay_redirects (void *src)
        if (no_redirect_redisplay) {
                return;
        }
-
+       
        ignore_delete = true;
        model->clear ();
        ignore_delete = false;
@@ -515,16 +555,22 @@ RedirectBox::add_redirect_to_display (boost::shared_ptr<Redirect> redirect)
        Gtk::TreeModel::Row row = *(model->append());
        row[columns.text] = redirect_name (redirect);
        row[columns.redirect] = redirect;
-       
-       show_redirect_active (redirect.get(), this);
 
-       redirect_active_connections.push_back (redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active)));
-       redirect_name_connections.push_back (redirect->name_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_name), redirect)));
+       show_redirect_active (redirect);
+
+       redirect_active_connections.push_back (redirect->active_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_active_r), boost::weak_ptr<Redirect>(redirect))));
+       redirect_name_connections.push_back (redirect->name_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_name), boost::weak_ptr<Redirect>(redirect))));
 }
 
 string
-RedirectBox::redirect_name (boost::shared_ptr<Redirect> redirect)
+RedirectBox::redirect_name (boost::weak_ptr<Redirect> weak_redirect)
 {
+       boost::shared_ptr<Redirect> redirect (weak_redirect.lock());
+
+       if (!redirect) {
+               return string();
+       }
+
        boost::shared_ptr<Send> send;
        string name_display;
 
@@ -586,16 +632,28 @@ RedirectBox::build_redirect_tooltip (EventBox& box, string start)
 }
 
 void
-RedirectBox::show_redirect_name (void* src, boost::shared_ptr<Redirect> redirect)
+RedirectBox::show_redirect_name (void* src, boost::weak_ptr<Redirect> redirect)
 {
        ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_name), src, redirect));
-       show_redirect_active (redirect.get(), src);
+       show_redirect_active (redirect);
 }
 
 void
-RedirectBox::show_redirect_active (Redirect* redirect, void *src)
+RedirectBox::show_redirect_active_r (Redirect* r, void *src, boost::weak_ptr<Redirect> weak_redirect)
 {
-       ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_active), redirect, src));
+       show_redirect_active (weak_redirect);
+}
+
+void
+RedirectBox::show_redirect_active (boost::weak_ptr<Redirect> weak_redirect)
+{
+       ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_active), weak_redirect));
+       
+       boost::shared_ptr<Redirect> redirect (weak_redirect.lock());
+       
+       if (!redirect) {
+               return;
+       }
 
        Gtk::TreeModel::Children children = model->children();
        Gtk::TreeModel::Children::iterator iter = children.begin();
@@ -604,7 +662,7 @@ RedirectBox::show_redirect_active (Redirect* redirect, void *src)
 
                boost::shared_ptr<Redirect> r = (*iter)[columns.redirect];
 
-               if (r.get() == redirect) {
+               if (r == redirect) {
                        (*iter)[columns.text] = redirect_name (r);
                        
                        if (redirect->active()) {
@@ -699,6 +757,7 @@ RedirectBox::cut_redirects ()
        
        _rr_selection.set (to_be_removed);
 
+       no_redirect_redisplay = true;
        for (vector<boost::shared_ptr<Redirect> >::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) {
                
                void* gui = (*i)->get_gui ();
@@ -713,6 +772,8 @@ RedirectBox::cut_redirects ()
                }
 
        }
+       no_redirect_redisplay = false;
+       redisplay_redirects (this);
 }
 
 void
@@ -735,12 +796,22 @@ RedirectBox::copy_redirects ()
 }
 
 gint
-RedirectBox::idle_delete_redirect (boost::shared_ptr<Redirect> redirect)
+RedirectBox::idle_delete_redirect (boost::weak_ptr<Redirect> weak_redirect)
 {
+       boost::shared_ptr<Redirect> redirect (weak_redirect.lock());
+
+       if (!redirect) {
+               return false;
+       }
+
        /* NOT copied to _mixer.selection() */
 
+       no_redirect_redisplay = true;
        _route->remove_redirect (redirect, this);
-       return FALSE;
+       no_redirect_redisplay = false;
+       redisplay_redirects (this);
+
+       return false;
 }
 
 void
@@ -765,7 +836,6 @@ RedirectBox::rename_redirect (boost::shared_ptr<Redirect> redirect)
        }
 
        return;
-  
 }
 
 void
@@ -784,9 +854,12 @@ RedirectBox::cut_redirect (boost::shared_ptr<Redirect> redirect)
                static_cast<Gtk::Widget*>(gui)->hide ();
        }
        
+       no_redirect_redisplay = true;
        if (_route->remove_redirect (redirect, this)) {
                _rr_selection.remove (redirect);
        }
+       no_redirect_redisplay = false;
+       redisplay_redirects (this);
 }
 
 void
@@ -847,8 +920,9 @@ RedirectBox::get_selected_redirects (vector<boost::shared_ptr<Redirect> >& redir
 {
     vector<Gtk::TreeModel::Path> pathlist = redirect_display.get_selection()->get_selected_rows();
  
-       for (vector<Gtk::TreeModel::Path>::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter)
-               redirects.push_back ((*(model->get_iter(*iter)))[columns.redirect]);
+    for (vector<Gtk::TreeModel::Path>::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) {
+           redirects.push_back ((*(model->get_iter(*iter)))[columns.redirect]);
+    }
 }
 
 void
@@ -980,7 +1054,7 @@ RedirectBox::edit_redirect (boost::shared_ptr<Redirect> redirect)
                                        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, plugin_insert));
+                                       _route->name_changed.connect (bind (mem_fun(*this, &RedirectBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_insert)));
                                        
                                
                                } else {
@@ -1240,11 +1314,13 @@ RedirectBox::rb_edit ()
 }
 
 void
-RedirectBox::route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::shared_ptr<PluginInsert> pi)
+RedirectBox::route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::weak_ptr<PluginInsert> wpi)
 {
-       ENSURE_GUI_THREAD(bind (mem_fun (*this, &RedirectBox::route_name_changed), src, plugin_ui, pi));
-       
-       plugin_ui->set_title (generate_redirect_title (pi));
+       ENSURE_GUI_THREAD(bind (mem_fun (*this, &RedirectBox::route_name_changed), src, plugin_ui, wpi));
+       boost::shared_ptr<PluginInsert> pi (wpi.lock());
+       if (pi) {
+               plugin_ui->set_title (generate_redirect_title (pi));
+       }
 }
 
 string 
index 27ba950899ee450b28e4a6fb224b007c63a17b82..7ab7d03cac115cebc977d32676f8b008b0a61027 100644 (file)
@@ -97,7 +97,9 @@ class RedirectBox : public Gtk::HBox
 
        PluginSelector     & _plugin_selector;
        RouteRedirectSelection  & _rr_selection;
-       
+
+       void route_going_away ();
+
        struct ModelColumns : public Gtk::TreeModel::ColumnRecord {
            ModelColumns () {
                    add (text);
@@ -140,7 +142,7 @@ class RedirectBox : public Gtk::HBox
        void show_redirect_menu (gint arg);
 
        void choose_send ();
-       void send_io_finished (IOSelector::Result, boost::shared_ptr<ARDOUR::Redirect>, IOSelectorWindow*);
+       void send_io_finished (IOSelector::Result, boost::weak_ptr<ARDOUR::Redirect>, IOSelectorWindow*);
        void choose_insert ();
        void choose_plugin ();
        void insert_plugin_chosen (boost::shared_ptr<ARDOUR::Plugin>);
@@ -149,18 +151,14 @@ class RedirectBox : public Gtk::HBox
        bool ignore_delete;
 
        bool redirect_button_press_event (GdkEventButton *);
+       bool redirect_button_release_event (GdkEventButton *);
        void redisplay_redirects (void* src);
        void add_redirect_to_display (boost::shared_ptr<ARDOUR::Redirect>);
        void row_deleted (const Gtk::TreeModel::Path& path);
-       void show_redirect_name (void*, boost::shared_ptr<ARDOUR::Redirect>);
-
-       /* these are handlers for Redirect signals, so they take Redirect*
-          directly, rather than shared_ptr<Redirect>
-       */
-
-       void show_redirect_active (ARDOUR::Redirect*, void *);
-
-       string redirect_name (boost::shared_ptr<ARDOUR::Redirect>);
+       void show_redirect_active_r (ARDOUR::Redirect*, void *, boost::weak_ptr<ARDOUR::Redirect>);
+       void show_redirect_active (boost::weak_ptr<ARDOUR::Redirect>);
+       void show_redirect_name (void* src, boost::weak_ptr<ARDOUR::Redirect>);
+       string redirect_name (boost::weak_ptr<ARDOUR::Redirect>);
 
        void remove_redirect_gui (boost::shared_ptr<ARDOUR::Redirect>);
 
@@ -195,7 +193,7 @@ class RedirectBox : public Gtk::HBox
        void hide_redirect_editor (boost::shared_ptr<ARDOUR::Redirect>);
        void rename_redirect (boost::shared_ptr<ARDOUR::Redirect>);
 
-       gint idle_delete_redirect (boost::shared_ptr<ARDOUR::Redirect>);
+       gint idle_delete_redirect (boost::weak_ptr<ARDOUR::Redirect>);
 
        void wierd_plugin_dialog (ARDOUR::Plugin& p, uint32_t streams, boost::shared_ptr<ARDOUR::IO> io);
 
@@ -219,7 +217,7 @@ class RedirectBox : public Gtk::HBox
        static void rb_deactivate_all ();
        static void rb_edit ();
        
-       void route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::shared_ptr<ARDOUR::PluginInsert> pi);
+       void route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::weak_ptr<ARDOUR::PluginInsert> pi);
        std::string generate_redirect_title (boost::shared_ptr<ARDOUR::PluginInsert> pi);
 };
 
index 3374d44655eb56a88bcc7fdfc5d53f9934f4a6a4..1241a1b3a7b6d90c564f08fef9358d30e61581f0 100644 (file)
@@ -44,9 +44,9 @@ AudioRegionGainLine::model_to_view_y (double& y)
 }
 
 void
-AudioRegionGainLine::start_drag (ControlPoint* cp, float fraction) 
+AudioRegionGainLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) 
 {
-       AutomationLine::start_drag(cp,fraction);
+       AutomationLine::start_drag (cp, x, fraction);
        if (!rv.audio_region()->envelope_active()) {
                 trackview.session().add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), &rv.audio_region()->get_state(), 0));
                 rv.audio_region()->set_envelope_active(false);
index 3781fe60bb2ee0abbcaac9b185c8d582e69f06b5..e98627f81411bcc0a26b6870f0bb913e67e344e9 100644 (file)
@@ -21,7 +21,7 @@ class AudioRegionGainLine : public AutomationLine
        void view_to_model_y (double&);
        void model_to_view_y (double&);
 
-       void start_drag (ControlPoint*, float fraction);
+       void start_drag (ControlPoint*, nframes_t x, float fraction);
        void end_drag (ControlPoint*);
 
        void remove_point (ControlPoint&);
index 49e7872f498bf759114272ca2ac2d0ce4b5b762e..a9315bb76f88dd2734d3cdce4baaa5b08adde1f2 100644 (file)
@@ -367,7 +367,7 @@ void
 RegionView::set_frame_color ()
 {
        if (_region->opaque()) {
-               fill_opacity = 180;
+               fill_opacity = 230;
        } else {
                fill_opacity = 100;
        }
index 5f61b0528cdf7f975ccde2adb53c4ac00e74946c..14d9fa02cbc8b90d095da9397de252aa5c0c9eff 100644 (file)
@@ -138,7 +138,7 @@ RouteParams_UI::RouteParams_UI (AudioEngine& eng)
        set_name ("RouteParamsWindow");
        set_default_size (620,370);
        set_title (_("ardour: track/bus inspector"));
-       set_wmclass (_("ardour_route_parameters"), "Ardour");
+       set_wmclass (X_("ardour_route_parameters"), "Ardour");
 
        // events
        route_display.get_selection()->signal_changed().connect(mem_fun(*this, &RouteParams_UI::route_selected));
@@ -510,7 +510,7 @@ RouteParams_UI::show_track_menu()
                                (MenuElem (_("Add Track/Bus"), 
                                           mem_fun (*(ARDOUR_UI::instance()), &ARDOUR_UI::add_route)));
        }
-       track_menu->popup (1, 0);
+       track_menu->popup (1, gtk_get_current_event_time());
 }
 
 
index 7195c83a998356a54cbf24f4c9d625722bbe1041..9684f74024b083469db5bfe8cfcdcc3dc1423874 100644 (file)
@@ -189,13 +189,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
        hide_button.unset_flags (Gtk::CAN_FOCUS);
        visual_button.unset_flags (Gtk::CAN_FOCUS);
 
-       /* map current state of the route */
-
-       update_diskstream_display ();
-       solo_changed(0);
-       mute_changed(0);
-       //redirects_changed (0);
-       //reset_redirect_automation_curves ();
        y_position = -1;
 
        _route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
@@ -212,11 +205,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
                track()->DiskstreamChanged.connect (mem_fun(*this, &RouteTimeAxisView::diskstream_changed));
                get_diskstream()->SpeedChanged.connect (mem_fun(*this, &RouteTimeAxisView::speed_changed));
 
-               /* ask for notifications of any new RegionViews */
-               // FIXME: _view is NULL, but it would be nice to attach this here :/
-               //_view->RegionViewAdded.connect (mem_fun(*this, &RouteTimeAxisView::region_view_added));
-               //_view->attach ();
-
                /* pick up the correct freeze state */
                map_frozen ();
 
@@ -224,7 +212,6 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
 
        editor.ZoomChanged.connect (mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit));
        ColorChanged.connect (mem_fun (*this, &RouteTimeAxisView::color_handler));
-
 }
 
 RouteTimeAxisView::~RouteTimeAxisView ()
@@ -254,9 +241,20 @@ RouteTimeAxisView::~RouteTimeAxisView ()
 }
 
 void
-RouteTimeAxisView::set_playlist (Playlist *newplaylist)
+RouteTimeAxisView::post_construct ()
+{
+       /* map current state of the route */
+
+       update_diskstream_display ();
+       _route->foreach_redirect (this, &RouteTimeAxisView::add_redirect_to_subplugin_menu);
+       _route->foreach_redirect (this, &RouteTimeAxisView::add_existing_redirect_automation_curves);
+       reset_redirect_automation_curves ();
+}
+
+void
+RouteTimeAxisView::set_playlist (boost::shared_ptr<Playlist> newplaylist)
 {
-       Playlist *pl = playlist();
+       boost::shared_ptr<Playlist> pl = playlist();
        assert(pl);
 
        modified_connection.disconnect ();
@@ -321,7 +319,7 @@ RouteTimeAxisView::playlist_changed ()
        label_view ();
 
        if (is_track()) {
-               set_playlist (dynamic_cast<Playlist*>(get_diskstream()->playlist()));
+               set_playlist (get_diskstream()->playlist());
        }
 }
 
@@ -367,7 +365,7 @@ RouteTimeAxisView::playlist_click ()
        
        build_playlist_menu (playlist_action_menu);
        editor.set_selected_track (*this, Selection::Add);
-       playlist_action_menu->popup (1, 0);
+       playlist_action_menu->popup (1, gtk_get_current_event_time());
 }
 
 void
@@ -380,7 +378,7 @@ RouteTimeAxisView::automation_click ()
                build_display_menu ();
        }
        editor.set_selected_track (*this, Selection::Add);
-       automation_action_menu->popup (1, 0);
+       automation_action_menu->popup (1, gtk_get_current_event_time());
 }
 
 void
@@ -672,7 +670,9 @@ RouteTimeAxisView::set_height (TrackHeight h)
 
        ensure_xml_node ();
 
-       _view->set_height ((double) height);
+       if (_view) {
+               _view->set_height ((double) height);
+       }
 
        switch (height_style) {
        case Largest:
@@ -852,7 +852,7 @@ RouteTimeAxisView::rename_current_playlist ()
        if (!ds || ds->destructive())
                return;
 
-       Playlist *const pl = ds->playlist();
+       boost::shared_ptr<Playlist> pl = ds->playlist();
        if (!pl)
                return;
 
@@ -883,11 +883,18 @@ RouteTimeAxisView::use_copy_playlist (bool prompt)
        if (!ds || ds->destructive())
                return;
 
-       Playlist *const pl = ds->playlist();
+       boost::shared_ptr<const Playlist> pl = ds->playlist();
        if (!pl)
                return;
 
-       name = Playlist::bump_name (pl->name(), _session);
+       name = pl->name();
+
+       do {
+               name = Playlist::bump_name (name, _session);
+       } while (_session.playlist_by_name(name));
+
+       // TODO: The prompter "new" button should be de-activated if the user
+       // specifies a playlist name which already exists in the session.
 
        if (prompt) {
 
@@ -896,7 +903,7 @@ RouteTimeAxisView::use_copy_playlist (bool prompt)
                prompter.set_prompt (_("Name for Playlist"));
                prompter.set_initial_text (name);
                prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
-               prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+               prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
                prompter.show_all ();
                
                switch (prompter.run ()) {
@@ -924,11 +931,16 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
        if (!ds || ds->destructive())
                return;
 
-       Playlist *const pl = ds->playlist();
+       boost::shared_ptr<const Playlist> pl = ds->playlist();
        if (!pl)
                return;
 
-       name = Playlist::bump_name (pl->name(), _session);
+       name = pl->name();
+
+       do {
+               name = Playlist::bump_name (name, _session);
+       } while (_session.playlist_by_name(name));
+
 
        if (prompt) {
                
@@ -937,7 +949,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
                prompter.set_prompt (_("Name for Playlist"));
                prompter.set_initial_text (name);
                prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
-               prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+               prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
 
                switch (prompter.run ()) {
                case Gtk::RESPONSE_ACCEPT:
@@ -962,11 +974,11 @@ RouteTimeAxisView::clear_playlist ()
        if (!ds || ds->destructive())
                return;
 
-       Playlist *const pl = ds->playlist();
+       boost::shared_ptr<Playlist> pl = ds->playlist();
        if (!pl)
                return;
 
-       editor.clear_playlist (*pl);
+       editor.clear_playlist (pl);
 }
 
 void
@@ -1006,7 +1018,13 @@ RouteTimeAxisView::selection_click (GdkEventButton* ev)
                break;
 
        case Selection::Extend:
-               /* not defined yet */
+               if (tracks->size() > 1) {
+                       /* add each one, do not "extend" */
+                       editor.get_selection().add (*tracks);
+               } else {
+                       /* extend to the single track */
+                       editor.extend_selection_to_track (*tracks->front());
+               }
                break;
 
        case Selection::Add:
@@ -1028,7 +1046,9 @@ RouteTimeAxisView::set_selected_points (PointSelection& points)
 void
 RouteTimeAxisView::set_selected_regionviews (RegionSelection& regions)
 {
-       _view->set_selected_regionviews (regions);
+       if (_view) {
+               _view->set_selected_regionviews (regions);
+       }
 }
 
 void
@@ -1084,7 +1104,7 @@ RouteTimeAxisView::name() const
        return _route->name();
 }
 
-Playlist *
+boost::shared_ptr<Playlist>
 RouteTimeAxisView::playlist () const 
 {
        boost::shared_ptr<Diskstream> ds;
@@ -1092,7 +1112,7 @@ RouteTimeAxisView::playlist () const
        if ((ds = get_diskstream()) != 0) {
                return ds->playlist(); 
        } else {
-               return 0; 
+               return boost::shared_ptr<Playlist> ();
        }
 }
 
@@ -1107,17 +1127,17 @@ RouteTimeAxisView::name_entry_changed ()
                return;
        }
 
+       strip_whitespace_edges(x);
+
        if (x.length() == 0) {
                name_entry.set_text (_route->name());
                return;
        }
 
-       strip_whitespace_edges(x);
-
        if (_session.route_name_unique (x)) {
                _route->set_name (x, this);
        } else {
-               ARDOUR_UI::instance()->popup_error (_("a track already exists with that name"));
+               ARDOUR_UI::instance()->popup_error (_("A track already exists with that name"));
                name_entry.set_text (_route->name());
        }
 }
@@ -1143,7 +1163,7 @@ boost::shared_ptr<Region>
 RouteTimeAxisView::find_next_region (nframes_t pos, RegionPoint point, int32_t dir)
 {
        boost::shared_ptr<Diskstream> stream;
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
 
        if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
                return playlist->find_next_region (pos, point, dir);
@@ -1155,9 +1175,9 @@ RouteTimeAxisView::find_next_region (nframes_t pos, RegionPoint point, int32_t d
 bool
 RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
 {
-       Playlist* what_we_got;
+       boost::shared_ptr<Playlist> what_we_got;
        boost::shared_ptr<Diskstream> ds = get_diskstream();
-       Playlist* playlist;
+       boost::shared_ptr<Playlist> playlist;
        bool ret = false;
 
        if (ds == 0) {
@@ -1167,7 +1187,6 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
 
        playlist = ds->playlist();
 
-
        TimeSelection time (selection.time);
        float speed = ds->speed();
        if (speed != 1.0f) {
@@ -1182,7 +1201,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
        case Cut:
                if ((what_we_got = playlist->cut (time)) != 0) {
                        editor.get_cut_buffer().add (what_we_got);
-                       _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+                       _session.add_command( new MementoCommand<Playlist>(*playlist.get(), &before, &playlist->get_state()));
                        ret = true;
                }
                break;
@@ -1195,7 +1214,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
        case Clear:
                if ((what_we_got = playlist->cut (time)) != 0) {
                        _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
-                       what_we_got->unref ();
+                       what_we_got->release ();
                        ret = true;
                }
                break;
@@ -1211,7 +1230,7 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
                return false;
        }
 
-       Playlist* playlist = get_diskstream()->playlist();
+       boost::shared_ptr<Playlist> playlist = get_diskstream()->playlist();
        PlaylistSelection::iterator p;
        
        for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth);
@@ -1224,7 +1243,7 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
                pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
        
        XMLNode &before = playlist->get_state();
-       playlist->paste (**p, pos, times);
+       playlist->paste (*p, pos, times);
        _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
 
        return true;
@@ -1266,20 +1285,26 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
        playlist_menu = new Menu;
        playlist_menu->set_name ("ArdourContextMenu");
 
-       vector<Playlist*> playlists;
+       vector<boost::shared_ptr<Playlist> > playlists;
        boost::shared_ptr<Diskstream> ds = get_diskstream();
        RadioMenuItem::Group playlist_group;
 
        _session.get_playlists (playlists);
        
-       for (vector<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+       for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
 
                if ((*i)->get_orig_diskstream_id() == ds->id()) {
-                       playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), (*i))));
+                       playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist),
+                                                                                                    boost::weak_ptr<Playlist> (*i))));
 
                        if (ds->playlist()->id() == (*i)->id()) {
                                static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
                        }
+               } else if (ds->playlist()->id() == (*i)->id()) {
+                       playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), 
+                                                                                                    boost::weak_ptr<Playlist>(*i))));
+                       static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
+                       
                }
        }
 
@@ -1297,12 +1322,18 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
 }
 
 void
-RouteTimeAxisView::use_playlist (Playlist* pl)
+RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
 {
-       AudioPlaylist* apl = dynamic_cast<AudioPlaylist*> (pl);
-       
        assert (is_track());
 
+       boost::shared_ptr<Playlist> pl (wpl.lock());
+
+       if (!pl) {
+               return;
+       }
+
+       boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
+       
        if (apl) {
                get_diskstream()->use_playlist (apl);
        }
@@ -1533,7 +1564,9 @@ RouteTimeAxisView::add_redirect_automation_curve (boost::shared_ptr<Redirect> re
 
        add_child (ran->view);
 
-       _view->foreach_regionview (bind (mem_fun(*this, &RouteTimeAxisView::add_ghost_to_redirect), ran->view));
+       if (_view) {
+               _view->foreach_regionview (bind (mem_fun(*this, &RouteTimeAxisView::add_ghost_to_redirect), ran->view));
+       }
 
        redirect->mark_automation_visible (what, true);
 }
index cefe954c9a5c31b9a762a43d92941253ec378f1c..c597f2893ca3a0fa774c3c87db666d398394bd4d 100644 (file)
@@ -99,7 +99,7 @@ public:
        string              name() const;
        StreamView*         view() const { return _view; }
        ARDOUR::RouteGroup* edit_group() const;
-       ARDOUR::Playlist*   playlist() const;
+       boost::shared_ptr<ARDOUR::Playlist> playlist() const;
 
 protected:
        friend class StreamView;
@@ -176,7 +176,7 @@ protected:
        void align_style_changed ();
        void set_align_style (ARDOUR::AlignStyle);
        
-       virtual void set_playlist (ARDOUR::Playlist *);
+       virtual void set_playlist (boost::shared_ptr<ARDOUR::Playlist>);
        void         playlist_click ();
        void         show_playlist_selector ();
        void         playlist_changed ();
@@ -229,7 +229,7 @@ protected:
        Gtk::Menu*          playlist_action_menu;
        Gtk::MenuItem*      playlist_item;
 
-       void use_playlist (ARDOUR::Playlist*);
+       void use_playlist (boost::weak_ptr<ARDOUR::Playlist>);
 
        ArdourCanvas::SimpleRect* timestretch_rect;
 
@@ -241,6 +241,8 @@ protected:
        vector<RedirectAutomationLine*> redirect_automation_curves;
 
        sigc::connection modified_connection;
+
+       void post_construct ();
 };
 
 #endif /* __ardour_route_time_axis_h__ */
index 851c45aaa0234aeae87d77035ef600cd57551da4..070ad4203777641be76b162bdb33c88723397379 100644 (file)
@@ -674,7 +674,7 @@ RouteUI::set_color (const Gdk::Color & c)
        snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue());
        xml_node->add_property ("color", buf);
 
-        _route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
+       _route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
 }
 
 
index 06475aa1d481266835d5dc3323d522de2df0c678..38a0cdd8e2d429910c2008d148244339d2300acd 100644 (file)
@@ -132,7 +132,7 @@ Selection::clear_playlists ()
        /* Selections own their playlists */
 
        for (PlaylistSelection::iterator i = playlists.begin(); i != playlists.end(); ++i) {
-               (*i)->unref ();
+               (*i)->release ();
        }
 
        if (!playlists.empty()) {
@@ -165,12 +165,12 @@ Selection::toggle (boost::shared_ptr<Redirect> r)
 }
 
 void
-Selection::toggle (Playlist* pl)
+Selection::toggle (boost::shared_ptr<Playlist> pl)
 {
        PlaylistSelection::iterator i;
 
        if ((i = find (playlists.begin(), playlists.end(), pl)) == playlists.end()) {
-               pl->ref ();
+               pl->use ();
                playlists.push_back(pl);
        } else {
                playlists.erase (i);
@@ -260,23 +260,23 @@ Selection::add (boost::shared_ptr<Redirect> r)
 }
 
 void
-Selection::add (Playlist* pl)
+Selection::add (boost::shared_ptr<Playlist> pl)
 {
        if (find (playlists.begin(), playlists.end(), pl) == playlists.end()) {
-               pl->ref ();
+               pl->use ();
                playlists.push_back(pl);
                PlaylistsChanged ();
        }
 }
 
 void
-Selection::add (const list<Playlist*>& pllist)
+Selection::add (const list<boost::shared_ptr<Playlist> >& pllist)
 {
        bool changed = false;
 
-       for (list<Playlist*>::const_iterator i = pllist.begin(); i != pllist.end(); ++i) {
+       for (list<boost::shared_ptr<Playlist> >::const_iterator i = pllist.begin(); i != pllist.end(); ++i) {
                if (find (playlists.begin(), playlists.end(), (*i)) == playlists.end()) {
-                       (*i)->ref ();
+                       (*i)->use ();
                        playlists.push_back (*i);
                        changed = true;
                }
@@ -429,9 +429,9 @@ Selection::remove (const list<TimeAxisView*>& track_list)
 }
 
 void
-Selection::remove (Playlist* track)
+Selection::remove (boost::shared_ptr<Playlist> track)
 {
-       list<Playlist*>::iterator i;
+       list<boost::shared_ptr<Playlist> >::iterator i;
        if ((i = find (playlists.begin(), playlists.end(), track)) != playlists.end()) {
                playlists.erase (i);
                PlaylistsChanged();
@@ -439,13 +439,13 @@ Selection::remove (Playlist* track)
 }
 
 void
-Selection::remove (const list<Playlist*>& pllist)
+Selection::remove (const list<boost::shared_ptr<Playlist> >& pllist)
 {
        bool changed = false;
 
-       for (list<Playlist*>::const_iterator i = pllist.begin(); i != pllist.end(); ++i) {
+       for (list<boost::shared_ptr<Playlist> >::const_iterator i = pllist.begin(); i != pllist.end(); ++i) {
 
-               list<Playlist*>::iterator x;
+               list<boost::shared_ptr<Playlist> >::iterator x;
 
                if ((x = find (playlists.begin(), playlists.end(), (*i))) != playlists.end()) {
                        playlists.erase (x);
@@ -520,14 +520,14 @@ Selection::set (const list<TimeAxisView*>& track_list)
 }
 
 void
-Selection::set (Playlist* playlist)
+Selection::set (boost::shared_ptr<Playlist> playlist)
 {
        clear_playlists ();
        add (playlist);
 }
 
 void
-Selection::set (const list<Playlist*>& pllist)
+Selection::set (const list<boost::shared_ptr<Playlist> >& pllist)
 {
        clear_playlists ();
        add (pllist);
index c4336fba21bbf62746fcd4a6ac122b608c166125..a2997cd7b55ee83bfbfc876feef5d0c09ab0b0e1 100644 (file)
@@ -101,8 +101,8 @@ class Selection : public sigc::trackable
        void set (std::vector<RegionView*>&);
        long set (TimeAxisView*, nframes_t, nframes_t);
        void set (ARDOUR::AutomationList*);
-       void set (ARDOUR::Playlist*);
-       void set (const list<ARDOUR::Playlist*>&);
+       void set (boost::shared_ptr<ARDOUR::Playlist>);
+       void set (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
        void set (boost::shared_ptr<ARDOUR::Redirect>);
        void set (AutomationSelectable*);
 
@@ -112,8 +112,8 @@ class Selection : public sigc::trackable
        void toggle (std::vector<RegionView*>&);
        long toggle (nframes_t, nframes_t);
        void toggle (ARDOUR::AutomationList*);
-       void toggle (ARDOUR::Playlist*);
-       void toggle (const list<ARDOUR::Playlist*>&);
+       void toggle (boost::shared_ptr<ARDOUR::Playlist>);
+       void toggle (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
        void toggle (boost::shared_ptr<ARDOUR::Redirect>);
 
        void add (TimeAxisView*);
@@ -122,8 +122,8 @@ class Selection : public sigc::trackable
        void add (std::vector<RegionView*>&);
        long add (nframes_t, nframes_t);
        void add (ARDOUR::AutomationList*);
-       void add (ARDOUR::Playlist*);
-       void add (const list<ARDOUR::Playlist*>&);
+       void add (boost::shared_ptr<ARDOUR::Playlist>);
+       void add (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
        void add (boost::shared_ptr<ARDOUR::Redirect>);
        
        void remove (TimeAxisView*);
@@ -132,8 +132,8 @@ class Selection : public sigc::trackable
        void remove (uint32_t selection_id);
        void remove (nframes_t, nframes_t);
        void remove (ARDOUR::AutomationList*);
-       void remove (ARDOUR::Playlist*);
-       void remove (const list<ARDOUR::Playlist*>&);
+       void remove (boost::shared_ptr<ARDOUR::Playlist>);
+       void remove (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
        void remove (boost::shared_ptr<ARDOUR::Redirect>);
 
        void replace (uint32_t time_index, nframes_t start, nframes_t end);
index c4d6d7edfcbfa7a9fe92824204bcb422bb7ff727..5d3be0399b5c023fe2217630114f6f8a842bc452 100644 (file)
@@ -1,6 +1,5 @@
 /*
-    Copyright (C) 2005 Paul Davis 
-    Written by Taybin Rutkin
+    Copyright (C) 2005-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
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-
 */
 
 #include <map>
 #include <cerrno>
+#include <sstream>
 
 #include <gtkmm/box.h>
 #include <gtkmm/stock.h>
 
 #include <pbd/convert.h>
+#include <pbd/tokenizer.h>
 
 #include <gtkmm2ext/utils.h>
 
@@ -52,16 +52,16 @@ SoundFileBox::SoundFileBox ()
        :
        _session(0),
        current_pid(0),
-       fields(Gtk::ListStore::create(label_columns)),
        main_box (false, 3),
-       top_box (true, 4),
        bottom_box (true, 4),
        play_btn(_("Play")),
        stop_btn(_("Stop")),
-       add_field_btn(_("Add Field...")),
-       remove_field_btn(_("Remove Field"))
+       apply_btn(_("Apply"))
 {
        set_name (X_("SoundFileBox"));
+       
+       set_size_request (250, 500);
+       
        border_frame.set_label (_("Soundfile Info"));
        border_frame.add (main_box);
 
@@ -75,41 +75,29 @@ SoundFileBox::SoundFileBox ()
        main_box.pack_start(channels, false, false);
        main_box.pack_start(samplerate, false, false);
        main_box.pack_start(timecode, false, false);
-       main_box.pack_start(field_view, true, true);
-       main_box.pack_start(top_box, false, false);
+       main_box.pack_start(tags_entry, true, true);
+       main_box.pack_start(apply_btn, false, false);
        main_box.pack_start(bottom_box, false, false);
 
-       field_view.set_model (fields);
-       field_view.set_size_request(200, 150);
-       field_view.append_column (_("Field"), label_columns.field);
-       field_view.append_column_editable (_("Value"), label_columns.data);
-
-       top_box.set_homogeneous(true);
-       top_box.pack_start(add_field_btn);
-       top_box.pack_start(remove_field_btn);
-
-       remove_field_btn.set_sensitive(false);
-
        bottom_box.set_homogeneous(true);
        bottom_box.pack_start(play_btn);
        bottom_box.pack_start(stop_btn);
 
+//     tags_entry.signal_focus_out_event().connect (mem_fun (*this, &SoundFileBox::tags_entry_left));
        play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::play_btn_clicked));
        stop_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::stop_btn_clicked));
+       apply_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::apply_btn_clicked));
 
-       add_field_btn.signal_clicked().connect
-                       (mem_fun (*this, &SoundFileBox::add_field_clicked));
-       remove_field_btn.signal_clicked().connect
-                       (mem_fun (*this, &SoundFileBox::remove_field_clicked));
-       
-       Gtk::CellRendererText* cell(dynamic_cast<Gtk::CellRendererText*>(field_view.get_column_cell_renderer(1)));
-       cell->signal_edited().connect (mem_fun (*this, &SoundFileBox::field_edited));
-
-       field_view.get_selection()->signal_changed().connect (mem_fun (*this, &SoundFileBox::field_selected));
-       Library->fields_changed.connect (mem_fun (*this, &SoundFileBox::setup_fields));
+       length.set_alignment (0.0f, 0.0f);
+       format.set_alignment (0.0f, 0.0f);
+       channels.set_alignment (0.0f, 0.0f);
+       samplerate.set_alignment (0.0f, 0.0f);
+       timecode.set_alignment (0.0f, 0.0f);
 
-       show_all();
+       stop_btn.set_no_show_all (true);
        stop_btn.hide();
+       
+       show_all();
 }
 
 void
@@ -132,53 +120,52 @@ SoundFileBox::setup_labels (string filename)
        string error_msg;
 
        if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
+               length.set_text (_("Length: n/a"));
+               format.set_text (_("Format: n/a"));
+               channels.set_text (_("Channels: n/a"));
+               samplerate.set_text (_("Samplerate: n/a"));
+               timecode.set_text (_("Timecode: n/a"));
+               tags_entry.set_text ("");
+               
+               tags_entry.set_sensitive (false);
+               play_btn.set_sensitive (false);
+               apply_btn.set_sensitive (false);
+               
                return false;
        }
 
-       length.set_alignment (0.0f, 0.0f);
-       length.set_text (string_compose(_("Length: %1"), PBD::length2string(sf_info.length, sf_info.samplerate)));
-
-       format.set_alignment (0.0f, 0.0f);
+       length.set_text (string_compose(_("Length: %1"), length2string(sf_info.length, sf_info.samplerate)));
        format.set_text (sf_info.format_name);
-
-       channels.set_alignment (0.0f, 0.0f);
        channels.set_text (string_compose(_("Channels: %1"), sf_info.channels));
-
-       samplerate.set_alignment (0.0f, 0.0f);
        samplerate.set_text (string_compose(_("Samplerate: %1"), sf_info.samplerate));
+       timecode.set_text (string_compose (_("Timecode: %1"), length2string(sf_info.timecode, sf_info.samplerate)));
 
-       timecode.set_alignment (0.0f, 0.0f);
-       timecode.set_text (string_compose (_("Timecode: %1"), PBD::length2string(sf_info.timecode, sf_info.samplerate)));
-
-       setup_fields ();
-
+       vector<string> tags = Library->get_tags (filename);
+       
+       stringstream tag_string;
+       for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
+               if (i != tags.begin()) {
+                       tag_string << ", ";
+               }
+               tag_string << *i;
+       }
+       tags_entry.set_text (tag_string.str());
+       
+       tags_entry.set_sensitive (true);
+       if (_session) {
+               play_btn.set_sensitive (true);
+       }
+       apply_btn.set_sensitive (true);
+       
        return true;
 }
 
-void
-SoundFileBox::setup_fields ()
-{
-       ENSURE_GUI_THREAD(mem_fun (*this, &SoundFileBox::setup_fields));
-
-       fields->clear ();
-
-       vector<string> field_list;
-       Library->get_fields(field_list);
-
-       vector<string>::iterator i;
-       Gtk::TreeModel::iterator iter;
-       Gtk::TreeModel::Row row;
-       for (i = field_list.begin(); i != field_list.end(); ++i) {
-               if (!(*i == _("channels") || *i == _("samplerate") ||
-                       *i == _("resolution") || *i == _("format"))) {
-                       iter = fields->append();
-                       row = *iter;
-
-                       string value = Library->get_field(path, *i);
-                       row[label_columns.field] = *i;
-                       row[label_columns.data]  = value;
-               }
-       }
+bool
+SoundFileBox::tags_entry_left (GdkEventFocus* event)
+{      
+       apply_btn_clicked ();
+       
+       return true;
 }
 
 void
@@ -228,7 +215,6 @@ SoundFileBox::play_btn_clicked ()
                newpair.first = path;
                newpair.second = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, 0, srclist[0]->length(), rname, 0, Region::DefaultFlags, false));
 
-
                res = region_cache.insert (newpair);
                the_region = res.first;
        }
@@ -252,56 +238,21 @@ SoundFileBox::stop_btn_clicked ()
 }
 
 void
-SoundFileBox::add_field_clicked ()
-{
-    ArdourPrompter prompter (true);
-    string name;
-
-    prompter.set_prompt (_("Name for Field"));
-    prompter.add_button (Gtk::Stock::ADD, Gtk::RESPONSE_ACCEPT);
-    prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
-
-    switch (prompter.run ()) {
-               case Gtk::RESPONSE_ACCEPT:
-               prompter.get_result (name);
-                       if (name.length()) {
-                               Library->add_field (name);
-                               Library->save_changes ();
-                       }
-               break;
-
-           default:
-               break;
-    }
-}
-
-void
-SoundFileBox::remove_field_clicked ()
+SoundFileBox::apply_btn_clicked ()
 {
-       field_view.get_selection()->selected_foreach_iter(mem_fun(*this, &SoundFileBox::delete_row));
+       string tag_string = tags_entry.get_text ();
 
-       Library->save_changes ();
-}
+       vector<string> tags;
 
-void
-SoundFileBox::field_edited (const Glib::ustring& str1, const Glib::ustring& str2)
-{
-       Gtk::TreeModel::Children rows(fields->children());
-       Gtk::TreeModel::Row row(rows[atoi(str1.c_str())]);
-       
-       Library->set_field (path, row[label_columns.field], str2);
+    if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
+               warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg;
+               return;
+       }
        
+       Library->set_tags (path, tags);
        Library->save_changes ();
 }
 
-void
-SoundFileBox::delete_row (const Gtk::TreeModel::iterator& iter)
-{
-       Gtk::TreeModel::Row row = *iter;
-
-       Library->remove_field(row[label_columns.field]);
-}
-
 void
 SoundFileBox::audition_status_changed (bool active)
 {
@@ -312,16 +263,6 @@ SoundFileBox::audition_status_changed (bool active)
        }
 }
 
-void
-SoundFileBox::field_selected ()
-{
-       if (field_view.get_selection()->count_selected_rows()) {
-               remove_field_btn.set_sensitive(true);
-       } else {
-               remove_field_btn.set_sensitive(false);
-       }
-}
-
 // this needs to be kept in sync with the ImportMode enum defined in editing.h and editing_syms.h.
 static const char *import_mode_strings[] = {
        N_("Add to Region list"),
@@ -333,14 +274,41 @@ static const char *import_mode_strings[] = {
 
 SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s)
        : ArdourDialog (title, false),
-         chooser (Gtk::FILE_CHOOSER_ACTION_OPEN)
+         chooser (Gtk::FILE_CHOOSER_ACTION_OPEN),
+         found_list (Gtk::ListStore::create(found_list_columns)),
+         found_list_view (found_list),
+         found_search_btn (_("Search"))
 {
-       get_vbox()->pack_start(chooser);
-       chooser.set_preview_widget(preview);
-       chooser.set_select_multiple (true);
+       set_default_size (700, 500);
+       Gtk::HBox* hbox = manage(new Gtk::HBox);
+       hbox->pack_start(notebook);
+       hbox->pack_start(preview, Gtk::PACK_SHRINK);
+       get_vbox()->pack_start(*hbox);
+
+       hbox = manage(new Gtk::HBox);
+       hbox->pack_start (found_entry);
+       hbox->pack_start (found_search_btn);
+       
+       Gtk::VBox* vbox = manage(new Gtk::VBox);
+       vbox->pack_start (*hbox, Gtk::PACK_SHRINK);
+       vbox->pack_start (found_list_view);
+       found_list_view.append_column(_("Paths"), found_list_columns.pathname);
+       
+       notebook.append_page (chooser, _("Files"));
+       notebook.append_page (*vbox, _("Tags"));
+
+       found_list_view.get_selection()->set_mode (Gtk::SELECTION_MULTIPLE);
 
+       filter.add_custom (Gtk::FILE_FILTER_FILENAME, mem_fun(*this, &SoundFileBrowser::on_custom));
+       chooser.set_filter (filter);
+       chooser.set_select_multiple (true);
        chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
+       found_list_view.get_selection()->signal_changed().connect(mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
+       
+       found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
 
+       show_all ();
+       
        set_session (s);
 }
 
@@ -350,10 +318,54 @@ SoundFileBrowser::set_session (Session* s)
        preview.set_session(s);
 }
 
+bool
+SoundFileBrowser::on_custom (const Gtk::FileFilter::Info& filter_info)
+{
+       return AudioFileSource::safe_file_extension(filter_info.filename);
+}
+
 void
 SoundFileBrowser::update_preview ()
 {
-       chooser.set_preview_widget_active(preview.setup_labels(chooser.get_filename()));
+       preview.setup_labels(chooser.get_filename());
+}
+
+void
+SoundFileBrowser::found_list_view_selected ()
+{
+       string file;
+       
+       Gtk::TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows ();
+       
+       if (!rows.empty()) {
+               Gtk::TreeIter iter = found_list->get_iter(*rows.begin());
+               file = (*iter)[found_list_columns.pathname];
+               chooser.set_filename (file);
+       }
+       preview.setup_labels (file);
+}
+
+void
+SoundFileBrowser::found_search_clicked ()
+{
+       string tag_string = found_entry.get_text ();
+
+       vector<string> tags;
+
+    if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) {
+               warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg;
+               return;
+       }
+
+       vector<string> results;
+       Library->search_members_and (results, tags);
+       
+       found_list->clear();
+       for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) {
+               Gtk::TreeModel::iterator new_row = found_list->append();
+               Gtk::TreeModel::Row row = *new_row;
+               row[found_list_columns.pathname] = *i;
+       }
 }
 
 SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
@@ -362,19 +374,37 @@ SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
 {
        add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
        add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+       
+       chooser.set_select_multiple (false);
+       found_list_view.get_selection()->set_mode (Gtk::SELECTION_SINGLE);
        show_all ();
 }
 
+string
+SoundFileChooser::get_filename ()
+{
+       Gtk::TreeModel::iterator iter;
+       Gtk::TreeModel::Row row;
+       
+       switch (notebook.get_current_page()) {
+               case 0:
+                       return chooser.get_filename();
+               case 1:
+                       iter = found_list_view.get_selection()->get_selected();
+                       row = *iter;
+                       return row[found_list_columns.pathname];
+               default:
+                       /* NOT REACHED */
+                       return "";
+       }
+}
+
 vector<string> SoundFileOmega::mode_strings;
 
 SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s)
        : SoundFileBrowser (title, s),
          split_check (_("Split Channels"))
 {
-       if (mode_strings.empty()) {
-               mode_strings = I18N (import_mode_strings);
-       }
-
        ARDOUR_UI::instance()->tooltips().set_tip(split_check, 
                        _("Create a region for each channel"));
 
@@ -382,24 +412,23 @@ SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s)
        ARDOUR_UI::instance()->tooltips().set_tip(*btn, 
                        _("Link to an external file"));
 
-       add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
-
        btn = add_button (_("Import"), ResponseImport);
        ARDOUR_UI::instance()->tooltips().set_tip(*btn, 
                        _("Copy a file to the session folder"));
 
-       Gtk::HBox *box = manage (new Gtk::HBox());
-
+       add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
+       
+       if (mode_strings.empty()) {
+               mode_strings = I18N (import_mode_strings);
+       }
        Gtkmm2ext::set_popdown_strings (mode_combo, mode_strings);
 
        set_mode (Editing::ImportAsRegion);
 
-       box->pack_start (split_check);
-       box->pack_start (mode_combo);
+       get_action_area()->pack_start (split_check);
+       get_action_area()->pack_start (mode_combo);
 
        mode_combo.signal_changed().connect (mem_fun (*this, &SoundFileOmega::mode_changed));
-
-       chooser.set_extra_widget (*box);
        
        show_all ();
 }
@@ -413,7 +442,22 @@ SoundFileOmega::get_split ()
 vector<Glib::ustring>
 SoundFileOmega::get_paths ()
 {
-       return chooser.get_filenames();
+       int n = notebook.get_current_page ();
+       
+       if (n == 0) {
+               return chooser.get_filenames ();
+       }
+       
+       typedef Gtk::TreeView::Selection::ListHandle_Path ListPath;
+       
+       vector<Glib::ustring> results;
+       ListPath rows = found_list_view.get_selection()->get_selected_rows ();
+       for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
+               Gtk::TreeIter iter = found_list->get_iter(*i);
+               string str = (*iter)[found_list_columns.pathname];
+               results.push_back (str);
+       }
+       return results;
 }
 
 void
index d7c2c14014af4816ab58c58cefef54034b513d97..fb0b7da60022e96456fa6d341800b9939d84e31e 100644 (file)
@@ -1,6 +1,5 @@
 /*
-    Copyright (C) 2005 Paul Davis 
-    Written by Taybin Rutkin
+    Copyright (C) 2005-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
@@ -16,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-
 */
 
 #ifndef __ardour_sfdb_ui_h__
 #include <gtkmm/box.h>
 #include <gtkmm/button.h>
 #include <gtkmm/checkbutton.h>
+#include <gtkmm/comboboxtext.h>
 #include <gtkmm/dialog.h>
 #include <gtkmm/entry.h>
 #include <gtkmm/filechooserwidget.h>
-#include <gtkmm/comboboxtext.h>
 #include <gtkmm/frame.h>
 #include <gtkmm/label.h>
-#include <gtkmm/liststore.h>
-#include <gtkmm/treeview.h>
 
 #include <ardour/session.h>
 #include <ardour/audiofilesource.h>
 class SoundFileBox : public Gtk::VBox
 {
   public:
-    SoundFileBox ();
-    virtual ~SoundFileBox () {};
-
-    void set_session (ARDOUR::Session* s);
-    bool setup_labels (std::string filename);
+       SoundFileBox ();
+       virtual ~SoundFileBox () {};
+       
+       void set_session (ARDOUR::Session* s);
+       bool setup_labels (std::string filename);
 
   protected:
        ARDOUR::Session* _session;
        std::string path;
-
-    struct LabelModelColumns : public Gtk::TreeModel::ColumnRecord
-    {
-    public:
-      Gtk::TreeModelColumn<std::string> field;
-      Gtk::TreeModelColumn<std::string> data;
-
-      LabelModelColumns() { add(field); add(data); }
-    };
-
-    LabelModelColumns label_columns;
-    
-    ARDOUR::SoundFileInfo sf_info;
-
-    pid_t current_pid;
-
-    Gtk::Label length;
-    Gtk::Label format;
-    Gtk::Label channels;
-    Gtk::Label samplerate;
-    Gtk::Label timecode;
-
-    Gtk::TreeView field_view;
-    Glib::RefPtr<Gtk::ListStore> fields;
-    std::string selected_field;
-
-    Gtk::Frame border_frame;
-
-    Gtk::VBox main_box;
-    Gtk::VBox path_box;
-    Gtk::HBox top_box;
-    Gtk::HBox bottom_box;
-
-    Gtk::Button play_btn;
-    Gtk::Button stop_btn;
-    Gtk::Button add_field_btn;
-    Gtk::Button remove_field_btn;
-
-    void setup_fields ();
-
-    void play_btn_clicked ();
-    void stop_btn_clicked ();
-    void add_field_clicked ();
-    void remove_field_clicked ();
-       void field_edited (const Glib::ustring&, const Glib::ustring&);
-       void delete_row (const Gtk::TreeModel::iterator& iter);
-
-    void field_selected ();
-    void audition_status_changed (bool state);
+       
+       ARDOUR::SoundFileInfo sf_info;
+       
+       pid_t current_pid;
+       
+       Gtk::Label length;
+       Gtk::Label format;
+       Gtk::Label channels;
+       Gtk::Label samplerate;
+       Gtk::Label timecode;
+       
+       Gtk::Frame border_frame;
+       
+       Gtk::Entry tags_entry;
+       
+       Gtk::VBox main_box;
+       Gtk::VBox path_box;
+       Gtk::HBox bottom_box;
+       
+       Gtk::Button play_btn;
+       Gtk::Button stop_btn;
+       Gtk::Button apply_btn;
+       
+       bool tags_entry_left (GdkEventFocus* event);
+       void play_btn_clicked ();
+       void stop_btn_clicked ();
+       void apply_btn_clicked ();
+       
+       void audition_status_changed (bool state);
 };
 
 class SoundFileBrowser : public ArdourDialog
 {
   public:
-    SoundFileBrowser (std::string title, ARDOUR::Session* _s = 0);
-    virtual ~SoundFileBrowser () {}; 
-
-    virtual void set_session (ARDOUR::Session*);
+       SoundFileBrowser (std::string title, ARDOUR::Session* _s = 0);
+       virtual ~SoundFileBrowser () {}; 
+       
+       virtual void set_session (ARDOUR::Session*);
 
   protected:
-    Gtk::FileChooserWidget chooser;
-    SoundFileBox preview;
-
-    void update_preview ();
+       Gtk::FileChooserWidget chooser;
+       Gtk::FileFilter filter;
+       SoundFileBox preview;
+       
+       class FoundTagColumns : public Gtk::TreeModel::ColumnRecord
+       {
+         public:
+               Gtk::TreeModelColumn<string> pathname;
+               
+               FoundTagColumns() { add(pathname); }
+       };
+       
+       FoundTagColumns found_list_columns;
+       Glib::RefPtr<Gtk::ListStore> found_list;
+       Gtk::TreeView found_list_view;
+       Gtk::Entry found_entry;
+       Gtk::Button found_search_btn;
+       
+       Gtk::Notebook notebook;
+       
+       void update_preview ();
+       void found_list_view_selected ();
+       void found_search_clicked ();
+       
+       bool on_custom (const Gtk::FileFilter::Info& filter_info);
 };
 
 class SoundFileChooser : public SoundFileBrowser
 {
   public:
-    SoundFileChooser (std::string title, ARDOUR::Session* _s = 0);
-    virtual ~SoundFileChooser () {};
-
-    std::string get_filename () {return chooser.get_filename();};
+       SoundFileChooser (std::string title, ARDOUR::Session* _s = 0);
+       virtual ~SoundFileChooser () {};
+       
+       std::string get_filename ();
 };
 
 class SoundFileOmega : public SoundFileBrowser
 {
   public:
-    SoundFileOmega (std::string title, ARDOUR::Session* _s);
-    virtual ~SoundFileOmega () {};
-
-    /* these are returned by the Dialog::run() method. note
-       that builtin GTK responses are all negative, leaving
-       positive values for application-defined responses.
-    */
-
-    const static int ResponseImport = 1;
-    const static int ResponseEmbed = 2;
-
-    std::vector<Glib::ustring> get_paths ();
-    bool get_split ();
-
-    void set_mode (Editing::ImportMode);
-    Editing::ImportMode get_mode ();
+       SoundFileOmega (std::string title, ARDOUR::Session* _s);
+       virtual ~SoundFileOmega () {};
+       
+       /* these are returned by the Dialog::run() method. note
+          that builtin GTK responses are all negative, leaving
+          positive values for application-defined responses.
+       */
+       
+       const static int ResponseImport = 1;
+       const static int ResponseEmbed = 2;
+       
+       std::vector<Glib::ustring> get_paths ();
+       bool get_split ();
+       
+       void set_mode (Editing::ImportMode);
+       Editing::ImportMode get_mode ();
 
   protected:
-    Gtk::CheckButton  split_check;
-    Gtk::ComboBoxText mode_combo;
-
-    void mode_changed ();
-
-    static std::vector<std::string> mode_strings;
+       Gtk::CheckButton  split_check;
+       Gtk::ComboBoxText mode_combo;
+       
+       void mode_changed ();
+       
+       static std::vector<std::string> mode_strings;
 };
 
 #endif // __ardour_sfdb_ui_h__
index ce0b6a4250386f4c1da318458ff42aec5be50fca..53a0ee45531bf137942f15fbecb9d4746faa3f2d 100644 (file)
@@ -761,8 +761,9 @@ TimeAxisView::get_selection_rect (uint32_t id)
 
        for (list<SelectionRect*>::iterator i = free_selection_rects.begin(); i != free_selection_rects.end(); ++i) {
                if ((*i)->id == id) {
+                       SelectionRect* ret = (*i);
                        free_selection_rects.erase (i);
-                       return (*i);
+                       return ret;
                }
        }
 
@@ -1068,3 +1069,24 @@ TimeAxisView::color_handler (ColorID id, uint32_t val)
        }
 }
 
+TimeAxisView*
+TimeAxisView::covers_y_position (double y)
+{
+       if (hidden()) {
+               return 0;
+       }
+
+       if (y_position <= y && y < (y_position + height)) {
+               return this;
+       }
+
+       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+               TimeAxisView* tv;
+
+               if ((tv = (*i)->covers_y_position (y)) != 0) {
+                       return tv;
+               }
+       }
+
+       return 0;
+}
index 0ba4dc1938fd4dbbd51dd647a35aa5af1ff50eff..96437a9991b55a211ac48f96f60ca46d670939ae 100644 (file)
@@ -31,6 +31,8 @@
 #include <gtkmm/entry.h>
 #include <gtkmm/label.h>
 
+#include <gtkmm2ext/focus_entry.h>
+
 #include <ardour/types.h>
 #include <ardour/region.h>
 
@@ -118,7 +120,7 @@ class TimeAxisView : public virtual AxisView
        Gtk::VBox     controls_vbox;
        Gtk::HBox     name_hbox;
        Gtk::Frame    name_frame;
-       Gtk::Entry    name_entry;
+       Gtkmm2ext::FocusEntry name_entry;
        
        void hide_name_label ();
        void hide_name_entry ();
@@ -152,7 +154,16 @@ class TimeAxisView : public virtual AxisView
        virtual void set_height (TrackHeight h);
        void reset_height();
 
-       /** Steps through the defined heights for this TrackView.
+       /**
+        * Returns a TimeAxisView* if this object covers y, or one of its children does.
+        *  If the covering object is a child axis, then the child is returned.
+        * Returns 0 otherwise.
+        */
+
+       TimeAxisView* covers_y_position (double y);
+
+       /**
+        * Steps through the defined heights for this TrackView.
         * Sets bigger to true to step up in size, set to fals eot step smaller.
         *
         * @param bigger true if stepping should increase in size, false otherwise
@@ -160,7 +171,7 @@ class TimeAxisView : public virtual AxisView
        virtual void step_height (bool bigger);
 
        virtual ARDOUR::RouteGroup* edit_group() const { return 0; }
-       virtual ARDOUR::Playlist* playlist() const { return 0; }
+       virtual boost::shared_ptr<ARDOUR::Playlist> playlist() const { return boost::shared_ptr<ARDOUR::Playlist> (); }
 
        virtual void set_samples_per_unit (double);
        virtual void show_selection (TimeSelection&);
index b23e7972ae953ad661447d5330c70c10b42bcd2a..6af38deaee2e99ff3f589514dac7aa1a3bacef42 100644 (file)
@@ -102,7 +102,7 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group&
        frame_position = start ;
        item_duration = duration ;
        name_connected = false;
-       fill_opacity = 50;
+       fill_opacity = 230;
        position_locked = false ;
        max_item_duration = ARDOUR::max_frames;
        min_item_duration = 0 ;
index 4d7c133770b1103a52c20e6192970908fc296421..887494829eab97dbc8c4fd3102cd1bc029e6233d 100644 (file)
@@ -46,11 +46,13 @@ using namespace Glib;
 using namespace PBD;
 
 ustring
-fit_to_pixels (const ustring& str, int pixel_width, Pango::FontDescription& font, int& actual_width)
+fit_to_pixels (const ustring& str, int pixel_width, Pango::FontDescription& font, int& actual_width, bool with_ellipses)
 {
        Label foo;
        Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout ("");
-       
+       ustring::size_type shorter_by = 0;
+       ustring txt;
+
        layout->set_font_description (font);
 
        actual_width = 0;
@@ -59,9 +61,11 @@ fit_to_pixels (const ustring& str, int pixel_width, Pango::FontDescription& font
        ustring::iterator last = ustr.end();
        --last; /* now points at final entry */
 
+       txt = ustr;
+
        while (!ustr.empty()) {
 
-               layout->set_text (ustr);
+               layout->set_text (txt);
 
                int width, height;
                Gtkmm2ext::get_ink_pixel_size (layout, width, height);
@@ -72,9 +76,17 @@ fit_to_pixels (const ustring& str, int pixel_width, Pango::FontDescription& font
                }
                
                ustr.erase (last--);
+               shorter_by++;
+
+               if (with_ellipses && shorter_by > 3) {
+                       txt = ustr;
+                       txt += "...";
+               } else {
+                       txt = ustr;
+               }
        }
 
-       return ustr;
+       return txt;
 }
 
 gint
@@ -224,64 +236,6 @@ get_font_for_style (string widgetname)
        return style->get_font();
 }
 
-gint
-pane_handler (GdkEventButton* ev, Gtk::Paned* pane)
-{
-       if (ev->window != Gtkmm2ext::get_paned_handle (*pane)) {
-               return FALSE;
-       }
-
-       if (Keyboard::is_delete_event (ev)) {
-
-               gint pos;
-               gint cmp;
-               
-               pos = pane->get_position ();
-
-               if (dynamic_cast<VPaned*>(pane)) {
-                       cmp = pane->get_height();
-               } else {
-                       cmp = pane->get_width();
-               }
-
-               /* we have to use approximations here because we can't predict the
-                  exact position or sizes of the pane (themes, etc)
-               */
-
-               if (pos < 10 || abs (pos - cmp) < 10) {
-
-                       /* already collapsed: restore it (note that this is cast from a pointer value to int, which is tricky on 64bit */
-                       
-                       pane->set_position ((intptr_t) pane->get_data ("rpos"));
-
-               } else {        
-
-                       int collapse_direction;
-
-                       /* store the current position */
-
-                       pane->set_data ("rpos", (gpointer) pos);
-
-                       /* collapse to show the relevant child in full */
-                       
-                       collapse_direction = (intptr_t) pane->get_data ("collapse-direction");
-
-                       if (collapse_direction) {
-                               pane->set_position (1);
-                       } else {
-                               if (dynamic_cast<VPaned*>(pane)) {
-                                       pane->set_position (pane->get_height());
-                               } else {
-                                       pane->set_position (pane->get_width());
-                               }
-                       }
-               }
-
-               return TRUE;
-       } 
-
-       return FALSE;
-}
 uint32_t
 rgba_from_style (string style, uint32_t r, uint32_t g, uint32_t b, uint32_t a, string attr, int state, bool rgba)
 {
@@ -544,3 +498,52 @@ longest (vector<string>& strings)
        
        return *longest;
 }
+
+bool
+key_is_legal_for_numeric_entry (guint keyval)
+{
+       switch (keyval) {
+       case GDK_minus:
+       case GDK_plus:
+       case GDK_period:
+       case GDK_comma:
+       case GDK_0:
+       case GDK_1:
+       case GDK_2:
+       case GDK_3:
+       case GDK_4:
+       case GDK_5:
+       case GDK_6:
+       case GDK_7:
+       case GDK_8:
+       case GDK_9:
+       case GDK_KP_Add:
+       case GDK_KP_Subtract:
+       case GDK_KP_Decimal:
+       case GDK_KP_0:
+       case GDK_KP_1:
+       case GDK_KP_2:
+       case GDK_KP_3:
+       case GDK_KP_4:
+       case GDK_KP_5:
+       case GDK_KP_6:
+       case GDK_KP_7:
+       case GDK_KP_8:
+       case GDK_KP_9:
+       case GDK_Return:
+       case GDK_BackSpace:
+       case GDK_Delete:
+       case GDK_KP_Enter:
+       case GDK_Home:
+       case GDK_End:
+       case GDK_Left:
+       case GDK_Right:
+               return true;
+               
+       default:
+               break;
+       }
+
+       return false;
+}
+
index bb2a21d6c3655e55382202c524c0a9569a52590b..6d5ff0702d8b7443577a6cb30ac58ea6db0894a1 100644 (file)
@@ -53,7 +53,7 @@ slider_position_to_gain (double pos)
        return pow (2.0,(sqrt(sqrt(sqrt(pos)))*198.0-192.0)/6.0);
 }
 
-Glib::ustring fit_to_pixels (const Glib::ustring&, int pixel_width, Pango::FontDescription& font, int& actual_width);
+Glib::ustring fit_to_pixels (const Glib::ustring&, int pixel_width, Pango::FontDescription& font, int& actual_width, bool with_ellipses = false);
 
 gint   just_hide_it (GdkEventAny*, Gtk::Window*);
 void   allow_keyboard_focus (bool);
@@ -65,7 +65,6 @@ ArdourCanvas::Points* get_canvas_points (std::string who, uint32_t npoints);
 
 Pango::FontDescription get_font_for_style (std::string widgetname);
 
-gint pane_handler (GdkEventButton*, Gtk::Paned*);
 uint32_t rgba_from_style (std::string, uint32_t, uint32_t, uint32_t, uint32_t, std::string = "fg", int = Gtk::STATE_NORMAL, bool = true);
 
 void decorate (Gtk::Window& w, Gdk::WMDecoration d);
@@ -81,5 +80,6 @@ Glib::RefPtr<Gdk::Pixbuf> get_icon (const char*);
 static std::map<std::string, Glib::RefPtr<Gdk::Pixbuf> > xpm_map;
 const char* const *get_xpm_data (std::string path);
 std::string longest (std::vector<std::string>&);
+bool key_is_legal_for_numeric_entry (guint keyval);
 
 #endif /* __ardour_gtk_utils_h__ */
index 24cafdbe67a0985b74bc3e660ab6d53c7ed11361..20fe13603e742a8bb188edd6f0a057d7a2f9f045 100644 (file)
@@ -375,17 +375,17 @@ VisualTimeAxis::name_entry_changed()
                return;
        }
 
+       strip_whitespace_edges(x);
+
        if (x.length() == 0) {
                name_entry.set_text (time_axis_name);
                return;
        }
 
-       strip_whitespace_edges(x);
-
        if (!editor.get_named_time_axis(x)) {
                set_time_axis_name(x, this);
        } else {
-               ARDOUR_UI::instance()->popup_error (_("a track already exists with that name"));
+               ARDOUR_UI::instance()->popup_error (_("A track already exists with that name"));
                name_entry.set_text(time_axis_name);
        }
 }
index 05cc97701d1e680a1d15d478feb075820dd11279..92e4fdd24a4bb6192952c162850ba747c3993308 100644 (file)
@@ -268,6 +268,14 @@ Glib::PropertyProxy_ReadOnly<guint> WaveView::property_region_start() const
 {
        return Glib::PropertyProxy_ReadOnly<guint> (this, "region_start");
 }
+Glib::PropertyProxy<gint> WaveView::property_logscaled()
+{
+       return Glib::PropertyProxy<gint> (this, "logscaled");
+}
+Glib::PropertyProxy_ReadOnly<gint> WaveView::property_logscaled() const
+{
+       return Glib::PropertyProxy_ReadOnly<gint> (this, "logscaled");
+}
 
 } // namespace Canvas
 
index 15efbbcef5a694fa776228790ae039fdd1b8ad98..56d0ed76753b9c178184c4b1984307584fc69222 100644 (file)
@@ -147,6 +147,8 @@ public:
   Glib::PropertyProxy_ReadOnly<gint> property_rectified() const;
   Glib::PropertyProxy<guint> property_region_start();
   Glib::PropertyProxy_ReadOnly<guint> property_region_start() const;
+  Glib::PropertyProxy<gint> property_logscaled();
+  Glib::PropertyProxy_ReadOnly<gint> property_logscaled() const;
 };
 
 } /* namespace Canvas */
index c8bab03a87e1063f54e1df32f70317cdd648b1af..68b731c78ed7e12786eff895a2ac76e8f6543d2e 100644 (file)
@@ -17,6 +17,6 @@ appleutility.Append(LINKFLAGS='-framework CoreServices')
 libappleutility = appleutility.SharedLibrary('appleutility', appleutility_files)
 if appleutility['COREAUDIO']:
     Default(libappleutility)
-    env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libappleutility))
+    env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libappleutility))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'], ['SConscript'] + appleutility_files + glob.glob('*.h') ))
index 98a1b362bb16d43081d113a20ab9c3a3892656c3..68d9112cafe3fc404710519275efeabf0a1bc926 100644 (file)
@@ -65,6 +65,7 @@ crossfade.cc
 curve.cc
 cycle_timer.cc
 default_click.cc
+enums.cc
 gain.cc
 gdither.cc
 globals.cc
@@ -127,10 +128,10 @@ if ardour['LIBLO']:
     extra_sources += osc_files
 
 ardour.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
-ardour.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"")
-ardour.Append(CXXFLAGS="-DMODULE_DIR=\\\""+final_prefix+"/lib\\\"")
-ardour.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"")
-ardour.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
+ardour.Append(CXXFLAGS="-DDATA_DIR=\\\"" + os.path.join (final_prefix, 'share') + "\\\"")
+ardour.Append(CXXFLAGS="-DMODULE_DIR=\\\"" + os.path.join (final_prefix, env['LIBDIR']) + "\\\"")
+ardour.Append(CXXFLAGS="-DCONFIG_DIR=\\\"" + final_config_prefix + "\\\"")
+ardour.Append(CXXFLAGS="-DLOCALEDIR=\\\"" + os.path.join (final_prefix, 'share', 'locale') + "\\\"")
 
 ardour.Merge ([ libraries['jack'] ])
 
@@ -180,17 +181,38 @@ int main(int argc, char** argv)
        return 0;
 }
 """
-
 def CheckJackVideoFrameOffset(context):
        context.Message('Checking for JackVideoFrameOffset in jack_position_bits_t enum...')
        result = context.TryLink(jack_video_frame_offset_test, '.c')
        context.Result(result)
        return result
 
+#
+# See if JACK supports jack_port_ensure_monitor_input()
+#
+jack_ensure_monitor_input_test = """
+#include <jack/jack.h>
+int main(int argc, char** argv)
+{
+           jack_port_t **port;
+
+           jack_port_ensure_monitor (*port, 1);
+           return 0;
+
+}
+"""
+
+def CheckJackEnsureMonitorInput(context):
+        context.Message('Checking for jack_port_ensure_monitor_input()...')
+        result = context.TryLink(jack_ensure_monitor_input_test, '.c')
+        context.Result(result)
+        return result
+
 conf = Configure(ardour, custom_tests = {
        'CheckJackClientOpen' : CheckJackClientOpen,
        'CheckJackRecomputeLatencies' : CheckJackRecomputeLatencies,
-       'CheckJackVideoFrameOffset' : CheckJackVideoFrameOffset
+       'CheckJackVideoFrameOffset' : CheckJackVideoFrameOffset,
+       'CheckJackEnsureMonitorInput' : CheckJackEnsureMonitorInput
 })
 
 if conf.CheckJackClientOpen():
@@ -201,9 +223,9 @@ if conf.CheckJackRecomputeLatencies():
 
 if conf.CheckJackVideoFrameOffset():
        ardour.Append(CXXFLAGS="-DHAVE_JACK_VIDEO_SUPPORT")
-
-if conf.CheckFunc('jack_port_ensure_monitor'):
-    env.Append(CCFLAGS='-DHAVE_JACK_PORT_ENSURE_MONITOR')
+       
+if conf.CheckJackEnsureMonitorInput():
+       ardour.Append(CXXFLAGS='-DHAVE_JACK_PORT_ENSURE_MONITOR')
 else:
     print '\nWARNING: You need at least svn revision 985 of jack for hardware monitoring to work correctly.\n'
 
@@ -220,14 +242,19 @@ if conf.CheckCHeader('sys/vfs.h'):
 if conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
     ardour.Append(LINKFLAGS="-framework CoreMIDI")
 
+if conf.CheckCHeader('/System/Library/Frameworks/AudioToolbox.framework/Headers/ExtendedAudioFile.h'):
+    ardour.Append(LINKFLAGS="-framework AudioToolbox")
+
+if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h'):
+    ardour.Append(CXXFLAGS="-DHAVE_WEAK_COREAUDIO")
+
 if conf.CheckCHeader('/System/Library/Frameworks/AudioUnit.framework/Headers/AudioUnit.h') and ardour['AUDIOUNITS']:
     ardour.Append(CXXFLAGS="-DHAVE_AUDIOUNITS")
     ardour.Append(LINKFLAGS="-framework AudioUnit")
     extra_sources += audiounit_files
  
-if conf.CheckCHeader('/System/Library/Frameworks/AudioToolbox.framework/Headers/ExtendedAudioFile.h') and ardour['COREAUDIO']:
+if ardour['COREAUDIO']:
     ardour.Append(CXXFLAGS="-DHAVE_COREAUDIO")    
-    ardour.Append(LINKFLAGS="-framework AudioToolbox")
     extra_sources += coreaudio_files
 
 if env['CONFIG_ARCH'] == 'apple':
@@ -287,7 +314,7 @@ if env['NLS']:
        i18n (ardour, ardour_files + vst_files + coreaudio_files + audiounit_files, env)
 
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libardour))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libardour))
 
 env.Alias('version', ardour.VersionBuild(['version.cc', 'ardour/version.h'], []))
 
index 4a95e094a9abfc75b070963ba2dff8559958c46c..1da8903a41b1c61d62b86db8fcf91932a80bfba6 100644 (file)
@@ -90,9 +90,9 @@ class AudioDiskstream : public Diskstream
                }
        }
        
-       AudioPlaylist* audio_playlist () { return dynamic_cast<AudioPlaylist*>(_playlist); }
+       boost::shared_ptr<AudioPlaylist> audio_playlist () { return boost::dynamic_pointer_cast<AudioPlaylist>(_playlist); }
 
-       int use_playlist (Playlist *);
+       int use_playlist (boost::shared_ptr<Playlist>);
        int use_new_playlist ();
        int use_copy_playlist ();
 
@@ -173,33 +173,39 @@ class AudioDiskstream : public Diskstream
   private:
 
        struct ChannelInfo {
-
-               Sample     *playback_wrap_buffer;
-               Sample     *capture_wrap_buffer;
-               Sample     *speed_buffer;
-
-               float       peak_power;
            
-               boost::shared_ptr<AudioFileSource> fades_source;
-               boost::shared_ptr<AudioFileSource> write_source;
-
-               Port         *source;
-               Sample       *current_capture_buffer;
-               Sample       *current_playback_buffer;
+           ChannelInfo ();
+           ~ChannelInfo ();
 
-               RingBufferNPT<Sample> *playback_buf;
-               RingBufferNPT<Sample> *capture_buf;
+           void init (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size);
+           void release ();
 
-               Sample* scrub_buffer;
-               Sample* scrub_forward_buffer;
-               Sample* scrub_reverse_buffer;
-
-               RingBufferNPT<Sample>::rw_vector playback_vector;
-               RingBufferNPT<Sample>::rw_vector capture_vector;
-
-               RingBufferNPT<CaptureTransition> * capture_transition_buf;
-               // the following are used in the butler thread only
-               nframes_t                     curr_capture_cnt;
+           Sample     *playback_wrap_buffer;
+           Sample     *capture_wrap_buffer;
+           Sample     *speed_buffer;
+           
+           float       peak_power;
+           
+           boost::shared_ptr<AudioFileSource> fades_source;
+           boost::shared_ptr<AudioFileSource> write_source;
+           
+           Port         *source;
+           Sample       *current_capture_buffer;
+           Sample       *current_playback_buffer;
+           
+           RingBufferNPT<Sample> *playback_buf;
+           RingBufferNPT<Sample> *capture_buf;
+           
+           Sample* scrub_buffer;
+           Sample* scrub_forward_buffer;
+           Sample* scrub_reverse_buffer;
+           
+           RingBufferNPT<Sample>::rw_vector playback_vector;
+           RingBufferNPT<Sample>::rw_vector capture_vector;
+           
+           RingBufferNPT<CaptureTransition> * capture_transition_buf;
+           // the following are used in the butler thread only
+           nframes_t                     curr_capture_cnt;
        };
 
        /* The two central butler operations */
index f5ac6da65497683fdb979b38677736d25e57ccc5..8c01f0e3dc1562176fd78b213081e563391d5993 100644 (file)
@@ -1,6 +1,5 @@
 /*
-    Copyright (C) 2003 Paul Davis
-    Author: Taybin Rutkin
+    Copyright (C) 2003-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
@@ -16,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #ifndef __ardour_audio_library_h__
 #include <map>
 #include <vector>
 
-#include <sigc++/signal.h>
-
-#include <pbd/stateful.h>
-
 using std::vector;
 using std::string;
 using std::map;
 
 namespace ARDOUR {
 
-class AudioLibrary : public Stateful
+class AudioLibrary
 {
   public:
        AudioLibrary ();
        ~AudioLibrary ();
 
-       static string state_node_name;
-       
-       XMLNode& get_state (void);
-       int set_state (const XMLNode&);
-
-       void set_paths (vector<string> paths);
-       vector<string> get_paths ();
-       void scan_paths ();
-
-       void add_member (string member);
-       void remove_member (string uri);
+       void set_tags (string member, vector<string> tags);
+       vector<string> get_tags (string member);
 
-       void search_members_and (vector<string>& results, 
-                                                        const map<string,string>& fields);
-       void search_members_or (vector<string>& results, 
-                                                       const map<string,string>& fields);
-
-       void add_field (string field);
-       void get_fields (vector<string>& fields);
-       void remove_field (string field);
-       string get_field (string uri, string field);
-       void set_field (string uri, string field, string literal);
-       string get_label (string uri);
-       void set_label (string uri, string name);
+       void search_members_and (vector<string>& results, const vector<string> tags);
 
        void save_changes();
-
-       sigc::signal<void> fields_changed;
        
   private:
-       vector<string> sfdb_paths;
-
-       string field_uri (string name);
-
-       bool is_rdf_type (string uri, string type);
-       void remove_uri (string uri);
-
        string src;
        
-       void initialize_db();
-       void compact_vector (vector<string>& vec);
-       bool safe_file_extension (string);
+       string path2uri (string path);
+       string uri2path (string uri);   
 };
 
 extern AudioLibrary* Library;
index 207e3c6428911b348de661251fc25746ac2dc334..3dbd30f84156d190dbf6232f376c18009823747b 100644 (file)
@@ -61,7 +61,7 @@ class AudioEngine : public sigc::trackable
        bool will_reconnect_at_halt ();
        void set_reconnect_at_halt (bool);
 
-       int stop ();
+       int stop (bool forever = false);
        int start ();
        bool running() const { return _running; }
 
@@ -195,8 +195,7 @@ class AudioEngine : public sigc::trackable
        jack_client_t       *_jack;
        std::string           jack_client_name;
        Glib::Mutex           _process_lock;
-       Glib::Mutex           session_remove_lock;
-    Glib::Cond            session_removed;
+       Glib::Cond            session_removed;
        bool                  session_remove_pending;
        bool                 _running;
        bool                 _has_run;
index bd609a7d80e75ece44cbeddae0536f7f90c1abb8..c1dc7d1e930b9bbe7b51b96c34a12628033e2a2b 100644 (file)
@@ -59,6 +59,8 @@ class AudioFileSource : public AudioSource {
 
        static bool get_soundfile_info (string path, SoundFileInfo& _info, string& error);
 
+       static bool safe_file_extension (string path);
+
        void set_allow_remove_if_empty (bool yn);
        void mark_for_remove();
 
index 383ec73531bc9b505b4022af3c5fe5182639bcc7..c0d5ed6e758d3c6ea03ad68c30af85e06d7a95af 100644 (file)
@@ -42,8 +42,10 @@ class AudioPlaylist : public ARDOUR::Playlist
    public:
        AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
        AudioPlaylist (Session&, string name, bool hidden = false);
-       AudioPlaylist (const AudioPlaylist&, string name, bool hidden = false);
-       AudioPlaylist (const AudioPlaylist&, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+       AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, string name, bool hidden = false);
+       AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+
+       ~AudioPlaylist ();
 
        void clear (bool with_signals=true);
 
@@ -70,9 +72,6 @@ class AudioPlaylist : public ARDOUR::Playlist
         void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
         void remove_dependents (boost::shared_ptr<Region> region);
 
-    protected:
-       ~AudioPlaylist (); /* public should use unref() */
-
     private:
        Crossfades      _crossfades;    /* xfades currently in use */
        Crossfades      _pending_xfade_adds;
index 2ada2552369a490eee4d672ebab8d43fa35732c8..0734a66319b66183a7cbe6ab6470ed12e0b9728c 100644 (file)
@@ -113,6 +113,9 @@ const nframes_t frames_per_peak = 256;
        void build_peaks_from_scratch ();
 
        int  do_build_peak (nframes_t, nframes_t);
+       void truncate_peakfile();
+
+       mutable off_t _peak_byte_max; // modified in do_build_peaks()
 
        virtual nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const = 0;
        virtual nframes_t write_unlocked (Sample *dst, nframes_t cnt) = 0;
@@ -135,7 +138,7 @@ const nframes_t frames_per_peak = 256;
        static vector<boost::shared_ptr<AudioSource> > pending_peak_sources;
        static Glib::Mutex* pending_peak_sources_lock;
 
-       static void queue_for_peaks (boost::shared_ptr<AudioSource>);
+       static void queue_for_peaks (boost::shared_ptr<AudioSource>, bool notify=true);
        static void clear_queue_for_peaks ();
        
        struct PeakBuildRecord {
index e5c194e683b4b80d245b6b358efe556b824e8b28..a2cfb23e61161fa179ddc0df7d344f4a0daffceb 100644 (file)
@@ -82,7 +82,8 @@ class AutomationList : public PBD::StatefulDestructible
        void clear ();
        void x_scale (double factor);
        bool extend_to (double);
-
+       void slide (iterator before, double distance);
+       
        void reposition_for_rt_add (double when);
        void rt_add (double when, double value);
        void add (double when, double value);
@@ -190,7 +191,7 @@ class AutomationList : public PBD::StatefulDestructible
 
        AutomationEventList events;
        mutable Glib::Mutex lock;
-       bool   _frozen;
+       int8_t  _frozen;
        bool    changed_when_thawed;
        bool   _dirty;
 
@@ -209,6 +210,7 @@ class AutomationList : public PBD::StatefulDestructible
        double min_yval;
        double max_yval;
        double default_value;
+       bool   sort_pending;
 
        iterator rt_insertion_point;
        double   rt_pos;
index 8044190066c8ed38addc2a3214a2c48a37049e15..c520477c551608c549ecd3d6e8ccfee114919d5d 100644 (file)
@@ -3,13 +3,8 @@
 CONFIG_VARIABLE (AutoConnectOption, output_auto_connect, "output-auto-connect", AutoConnectOption (0))
 CONFIG_VARIABLE (AutoConnectOption, input_auto_connect, "input-auto-connect", AutoConnectOption (0))
 
-#ifdef __APPLE__
-CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left",  "coreaudio:Built-in Audio:in1")
-CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "coreaudio:Built-in Audio:in2")
-#else
-CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "alsa_pcm:playback_1")
-CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "alsa_pcm:playback_2")
-#endif
+CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "default")
+CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "default")
 
 /* MIDI and MIDI related */
 
@@ -100,16 +95,15 @@ CONFIG_VARIABLE (bool, quieten_at_speed, "quieten-at-speed", true)
 /* timecode and sync */
 
 CONFIG_VARIABLE (bool, jack_time_master, "jack-time-master", true)
+CONFIG_VARIABLE (SmpteFormat, smpte_format, "smpte-format", smpte_30)
 CONFIG_VARIABLE (bool, use_video_sync, "use-video-sync", false)
 CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", true)
-CONFIG_VARIABLE (float, smpte_frames_per_second, "smpte-frames-per-second", 30.0f)
 CONFIG_VARIABLE (float, video_pullup, "video-pullup", 0.0f)
-CONFIG_VARIABLE (bool,  smpte_drop_frames, "smpte-drop-frames", false)
 
 /* metering */
 
 CONFIG_VARIABLE (float, meter_hold, "meter-hold", 100.0f)
-CONFIG_VARIABLE (float, meter_falloff, "meter-falloff", 0.375f)
+CONFIG_VARIABLE (float, meter_falloff, "meter-falloff", 27.0f)
 CONFIG_VARIABLE (nframes_t, over_length_short, "over-length-short", 2)
 CONFIG_VARIABLE (nframes_t, over_length_long, "over-length-long", 10)
 
@@ -119,6 +113,8 @@ CONFIG_VARIABLE (bool, hiding_groups_deactivates_groups, "hiding-groups-deactiva
 CONFIG_VARIABLE (bool, verify_remove_last_capture, "verify-remove-last-capture", true)
 CONFIG_VARIABLE (bool, no_new_session_dialog, "no-new-session-dialog", false)
 CONFIG_VARIABLE (bool, use_vst, "use-vst", true)
+CONFIG_VARIABLE (uint32_t, subframes_per_frame, "subframes-per-frame", 100)
+CONFIG_VARIABLE (uint32_t, saved_history_depth, "save-history-depth", 100)
 
 /* BWAV */
 
@@ -127,4 +123,4 @@ CONFIG_VARIABLE (string, bwf_organization_code, "bwf-organization-code", "US")
 
 /* these variables have custom set() methods (e.g. path globbing) */
 
-CONFIG_VARIABLE_SPECIAL(std::string, raid_path, "raid-path", "", path_expand)
+CONFIG_VARIABLE_SPECIAL(Glib::ustring, raid_path, "raid-path", "", path_expand)
index d29ba47056f2e4bf8c8854ce3b85e258d81bfdf2..0422698c5e5afd525f776347680c364fc24b57fe 100644 (file)
@@ -64,12 +64,13 @@ class Crossfade : public PBD::StatefulDestructible
 
 
        /* copy constructor to copy a crossfade with new regions. used (for example)
-          when a playlist copy is made */
+          when a playlist copy is made 
+       */
        Crossfade (const Crossfade &, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>);
        
        /* the usual XML constructor */
 
-       Crossfade (const ARDOUR::Playlist&, XMLNode&);
+       Crossfade (const Playlist&, XMLNode&);
        virtual ~Crossfade();
 
        bool operator== (const ARDOUR::Crossfade&);
index ad3e5126690471aee915459af4e2f45fed2282c1..a6f34d59be5d16a77a72f09ccac99d4908de648a 100644 (file)
@@ -187,7 +187,7 @@ static inline cycles_t get_cycles (void)
 /* begin mach */
 #elif defined(__APPLE__)
 
-#ifdef HAVE_COREAUDIO
+#ifdef HAVE_WEAK_COREAUDIO
 #include <CoreAudio/HostTime.h>
 #else // Due to MacTypes.h and libgnomecanvasmm Rect conflict
 typedef unsigned long long              UInt64;
index eb6d9362228e3c25d7b0f2f915452996d2d8e25b..a81921b9f173973aa1663acd80c256b6240b0877 100644 (file)
@@ -76,8 +76,8 @@ class IO;
        virtual float playback_buffer_load() const = 0;
        virtual float capture_buffer_load() const = 0;
 
-       void set_flag (Flag f)   { _flags |= f; }
-       void unset_flag (Flag f) { _flags &= ~f; }
+       void set_flag (Flag f)   { _flags = Flag (_flags | f); }
+       void unset_flag (Flag f) { _flags = Flag (_flags & ~f); }
 
        AlignStyle alignment_style() const { return _alignment_style; }
        void       set_align_style (AlignStyle);
@@ -104,9 +104,9 @@ class IO;
        void set_speed (double);
        void non_realtime_set_speed ();
 
-       Playlist* playlist () { return _playlist; }
+       boost::shared_ptr<Playlist> playlist () { return _playlist; }
 
-       virtual int use_playlist (Playlist *);
+       virtual int use_playlist (boost::shared_ptr<Playlist>);
        virtual int use_new_playlist () = 0;
        virtual int use_copy_playlist () = 0;
 
@@ -205,7 +205,7 @@ class IO;
 
        virtual void playlist_changed (Change);
        virtual void playlist_modified ();
-       virtual void playlist_deleted (Playlist*);
+       virtual void playlist_deleted (boost::weak_ptr<Playlist>);
 
        virtual void finish_capture (bool rec_monitors_input) = 0;
        virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
@@ -245,7 +245,8 @@ class IO;
        ARDOUR::Session&  _session;
        ARDOUR::IO*       _io;
        ChanCount         _n_channels;
-       Playlist*         _playlist;
+
+       boost::shared_ptr<Playlist> _playlist;
 
        mutable gint             _record_enabled;
        double                   _visible_speed;
@@ -299,10 +300,9 @@ class IO;
 
        sigc::connection ports_created_c;
        sigc::connection plmod_connection;
-       sigc::connection plstate_connection;
        sigc::connection plgone_connection;
        
-       unsigned char _flags;
+       Flag _flags;
 };
 
 }; /* namespace ARDOUR */
index 217fd898850db9f22591fbe147874a560df4da80..31e59e670488a0e7f401da267d13439e556282ab 100644 (file)
@@ -46,10 +46,8 @@ class Plugin;
 class Insert : public Redirect
 {
   public:
-       Insert(Session& s, Placement p);
-       Insert(Session& s, string name, Placement p);
-
-       Insert(Session& s, Placement p, int imin, int imax, int omin, int omax);
+       Insert(Session& s, std::string name, Placement p);
+       Insert(Session& s, std::string name, Placement p, int imin, int imax, int omin, int omax);
        
        virtual ~Insert() { }
 
@@ -87,6 +85,11 @@ class PortInsert : public Insert
        int32_t can_support_input_configuration (int32_t) const;
        int32_t configure_io (int32_t magic, int32_t in, int32_t out);
        int32_t compute_output_streams (int32_t cnt) const;
+
+       uint32_t bit_slot() const { return bitslot; }
+
+  private:
+       uint32_t bitslot;
 };
 
 class PluginInsert : public Insert
index f7e1993bb2eda240958ffd564a3be93c8a1cdc25..c4df46415b859b838ddd673002f5ae6592a81192 100644 (file)
@@ -203,16 +203,16 @@ class IO : public PBD::StatefulDestructible
        PBD::Controllable& gain_control() {
                return _gain_control;
        }
-
+       
     static void update_meters();
 
-private: 
+  private: 
 
     static sigc::signal<void>   Meter;
     static Glib::StaticMutex    m_meter_signal_lock;
     sigc::connection            m_meter_connection;
 
-public:
+  public:
 
        /* automation */
 
index 94f70bb4e8ecf02fcf249eeca8f0619883975f48..57e13de5af3542ba1f9d3d5e338206ceb84f53e6 100644 (file)
@@ -68,7 +68,7 @@ class Location : public PBD::StatefulDestructible
        Location () {
                _start = 0;
                _end = 0;
-               _flags = 0;     
+               _flags = Flags (0);
        }
 
        Location (const Location& other);
@@ -124,7 +124,7 @@ class Location : public PBD::StatefulDestructible
        string        _name;
        nframes_t     _start;
        nframes_t     _end;
-       uint32_t _flags;
+       Flags         _flags;
 
        void set_mark (bool yn);
        bool set_flag_internal (bool yn, Flags flag);
@@ -153,6 +153,7 @@ class Locations : public PBD::StatefulDestructible
        Location* end_location() const;
        Location* start_location() const;
 
+       int next_available_name(string& result,string base);
        uint32_t num_range_markers() const;
 
        int set_current (Location *, bool want_lock = true);
index f18a2e6de9cfa848d1e01e6929cfde3aeedb2e07..17379c3baa40d41caefb242261696b6420b8ba48 100644 (file)
@@ -38,6 +38,7 @@ public:
 
        void setup (const ChanCount& in);
        void reset ();
+       void reset_max ();
 
        /** Compute peaks */
        void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset=0);
@@ -49,6 +50,14 @@ public:
                        return minus_infinity();
                }
        }
+       
+       float max_peak_power (uint32_t n) {
+               if (n < _max_peak_power.size()) {
+                       return _max_peak_power[n];
+               } else {
+                       return minus_infinity();
+               }
+       }
 
 private:
        
@@ -58,6 +67,7 @@ private:
        Session&           _session;
        std::vector<float> _peak_power;
        std::vector<float> _visible_peak_power;
+       std::vector<float> _max_peak_power;
 };
 
 
index 583cc23de5aa37ba0183ccebd6d12abdf43bbb83..ee11b5e1330406ddac2c02caf2b055ec28b26b06 100644 (file)
@@ -72,9 +72,9 @@ class MidiDiskstream : public Diskstream
 
        void set_record_enabled (bool yn);
 
-       MidiPlaylist* midi_playlist () { return dynamic_cast<MidiPlaylist*>(_playlist); }
+       boost::shared_ptr<MidiPlaylist> midi_playlist () { return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist); }
 
-       int use_playlist (Playlist *);
+       int use_playlist (boost::shared_ptr<Playlist>);
        int use_new_playlist ();
        int use_copy_playlist ();
 
index 6f89d2340473cc72f941c0a9f15aaa276b51bfe5..492241d6b582de1e40c433851192f69ed984c164 100644 (file)
@@ -40,10 +40,12 @@ class MidiPlaylist : public ARDOUR::Playlist
 public:
        MidiPlaylist (Session&, const XMLNode&, bool hidden = false);
        MidiPlaylist (Session&, string name, bool hidden = false);
-       MidiPlaylist (const MidiPlaylist&, string name, bool hidden = false);
-       MidiPlaylist (const MidiPlaylist&, jack_nframes_t start, jack_nframes_t cnt,
+       MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, string name, bool hidden = false);
+       MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, jack_nframes_t start, jack_nframes_t cnt,
                      string name, bool hidden = false);
 
+       ~MidiPlaylist ();
+
        nframes_t read (MidiRingBuffer& buf,
                        jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0);
 
@@ -63,9 +65,6 @@ protected:
        void refresh_dependents (boost::shared_ptr<Region> region);
        void remove_dependents (boost::shared_ptr<Region> region);
 
-protected:
-       ~MidiPlaylist (); /* public should use unref() */
-
 private:
        XMLNode& state (bool full_state);
        void dump () const;
index 87b71e73ffb12c3176ec199d9c2ecbe9068ea475..fd5777ccf640895202570aaa4865a3de7cc58bb3 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <string>
 #include <list>
+#include <boost/shared_ptr.hpp>
 
 #include <pbd/stateful.h> 
 
@@ -35,12 +36,12 @@ class Playlist;
 
 struct NamedSelection : public Stateful
 {
-    NamedSelection (std::string, std::list<Playlist*>&);
+    NamedSelection (std::string, std::list<boost::shared_ptr<Playlist> >&);
     NamedSelection (Session&, const XMLNode&);
     virtual ~NamedSelection ();
 
     std::string name;
-    std::list<Playlist*> playlists;
+    std::list<boost::shared_ptr<Playlist> > playlists;
 
     XMLNode& get_state (void);
 
index 831c9b39058c6f5c50f34083733bedbd67df1fa0..9893f7391a69e20dda942844a8afb4564e10f64f 100644 (file)
@@ -26,6 +26,7 @@
 #include <map>
 #include <list>
 #include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
 
 #include <sys/stat.h>
 
@@ -47,21 +48,25 @@ namespace ARDOUR  {
 class Session;
 class Region;
 
-class Playlist : public PBD::StatefulDestructible {
+class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_from_this<Playlist> {
   public:
        typedef list<boost::shared_ptr<Region> >    RegionList;
 
        Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
        Playlist (Session&, string name, DataType type, bool hidden = false);
-       Playlist (const Playlist&, string name, bool hidden = false);
-       Playlist (const Playlist&, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+       Playlist (boost::shared_ptr<const Playlist>, string name, bool hidden = false);
+       Playlist (boost::shared_ptr<const Playlist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+
+       virtual ~Playlist ();  
+
+       void set_region_ownership ();
 
        virtual void clear (bool with_signals=true);
        virtual void dump () const;
 
-       void ref();
-       void unref();
-       uint32_t refcnt() const { return _refcnt; }
+       void use();
+       void release();
+       bool used () const { return _refcnt != 0; }
 
        std::string name() const { return _name; }
        void set_name (std::string str);
@@ -92,9 +97,9 @@ class Playlist : public PBD::StatefulDestructible {
        void duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
        void nudge_after (nframes_t start, nframes_t distance, bool forwards);
 
-       Playlist* cut  (list<AudioRange>&, bool result_is_hidden = true);
-       Playlist* copy (list<AudioRange>&, bool result_is_hidden = true);
-       int       paste (Playlist&, nframes_t position, float times);
+       boost::shared_ptr<Playlist> cut  (list<AudioRange>&, bool result_is_hidden = true);
+       boost::shared_ptr<Playlist> copy (list<AudioRange>&, bool result_is_hidden = true);
+       int                         paste (boost::shared_ptr<Playlist>, nframes_t position, float times);
 
        RegionList*                regions_at (nframes_t frame);
        RegionList*                regions_touched (nframes_t start, nframes_t end);
@@ -109,14 +114,11 @@ class Playlist : public PBD::StatefulDestructible {
        int set_state (const XMLNode&);
        XMLNode& get_template ();
 
-       sigc::signal<void,Playlist*,bool> InUse;
-       sigc::signal<void>                Modified;
-       sigc::signal<void>                NameChanged;
-       sigc::signal<void>                LengthChanged;
-       sigc::signal<void>                LayeringChanged;
-       sigc::signal<void>                StatePushed;
-
-       static sigc::signal<void,Playlist*> PlaylistCreated;
+       sigc::signal<void,bool> InUse;
+       sigc::signal<void>      Modified;
+       sigc::signal<void>      NameChanged;
+       sigc::signal<void>      LengthChanged;
+       sigc::signal<void>      LayeringChanged;
 
        static string bump_name (string old_name, Session&);
        static string bump_name_once (string old_name);
@@ -142,7 +144,6 @@ class Playlist : public PBD::StatefulDestructible {
 
   protected:
        friend class Session;
-       virtual ~Playlist ();  /* members of the public use unref() */
 
   protected:
        struct RegionLock {
@@ -244,26 +245,23 @@ class Playlist : public PBD::StatefulDestructible {
 
        boost::shared_ptr<Region> region_by_id (PBD::ID);
 
-       void add_region_internal (boost::shared_ptr<Region>, nframes_t position, bool delay_sort = false);
-
-       int remove_region_internal (boost::shared_ptr<Region>, bool delay_sort = false);
+       void add_region_internal (boost::shared_ptr<Region>, nframes_t position);
+       
+       int remove_region_internal (boost::shared_ptr<Region>);
        RegionList *find_regions_at (nframes_t frame);
        void copy_regions (RegionList&) const;
        void partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist);
 
        nframes_t _get_maximum_extent() const;
 
-       Playlist* cut_copy (Playlist* (Playlist::*pmf)(nframes_t, nframes_t, bool), 
-                           list<AudioRange>& ranges, bool result_is_hidden);
-       Playlist *cut (nframes_t start, nframes_t cnt, bool result_is_hidden);
-       Playlist *copy (nframes_t start, nframes_t cnt, bool result_is_hidden);
+       boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t, bool), 
+                                             list<AudioRange>& ranges, bool result_is_hidden);
+       boost::shared_ptr<Playlist> cut (nframes_t start, nframes_t cnt, bool result_is_hidden);
+       boost::shared_ptr<Playlist> copy (nframes_t start, nframes_t cnt, bool result_is_hidden);
 
 
        int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir);
        void relayer ();
-
-       static Playlist* copyPlaylist (const Playlist&, nframes_t start, nframes_t length,
-                                      string name, bool result_is_hidden);
        
        void unset_freeze_parent (Playlist*);
        void unset_freeze_child (Playlist*);
diff --git a/libs/ardour/ardour/playlist_factory.h b/libs/ardour/ardour/playlist_factory.h
new file mode 100644 (file)
index 0000000..23aad3c
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __ardour_playlist_factory_h__
+#define __ardour_playlist_factory_h__
+
+#include <ardour/playlist.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+
+class PlaylistFactory {
+
+  public:
+       static sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistCreated;
+
+       static boost::shared_ptr<Playlist> create (Session&, const XMLNode&, bool hidden = false);
+       static boost::shared_ptr<Playlist> create (DataType type, Session&, string name, bool hidden = false);
+       static boost::shared_ptr<Playlist> create (boost::shared_ptr<const Playlist>, string name, bool hidden = false);
+       static boost::shared_ptr<Playlist> create (boost::shared_ptr<const Playlist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+};
+
+}
+
+#endif /* __ardour_playlist_factory_h__  */
index 79ae4516c59affe218dc2c876fc0a83ba8065ca8..8c3de09c105d4eb24f19e3bd3586ea6959646ab1 100644 (file)
@@ -111,8 +111,6 @@ class Redirect : public IO
        virtual void transport_stopped (nframes_t frame) {};
        
   protected:
-       void set_placement (const string&, void *src);
-
        /* children may use this stuff as they see fit */
 
        map<uint32_t,AutomationList*> parameter_automation;
index 88bb294e5d65c8273fd4a1dd79e25876fd8b0f9f..46865d8357b8b1568cc5e2fb3279a71eb2c32a54 100644 (file)
@@ -167,9 +167,8 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
 
        virtual uint32_t read_data_count() const { return _read_data_count; }
 
-       ARDOUR::Playlist* playlist() const { return _playlist; }
-
-       void set_playlist (ARDOUR::Playlist*);
+       boost::shared_ptr<ARDOUR::Playlist> playlist() const { return _playlist.lock(); }
+       virtual void set_playlist (boost::weak_ptr<ARDOUR::Playlist>);
 
        void source_deleted (boost::shared_ptr<Source>);
        
@@ -238,7 +237,7 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
        Change                  _pending_changed;
        uint64_t                _last_layer_op;  ///< timestamp
        Glib::Mutex             _lock;
-       ARDOUR::Playlist*       _playlist;
+       boost::weak_ptr<ARDOUR::Playlist> _playlist;
        SourceList              _sources;
        /** Used when timefx are applied, so we can always use the original source */
        SourceList              _master_sources;
index 6bc37ee51efae7b54c62153e8f65abe23872e7d0..2f94e0c80a43548cfc72a366c09b0eeb036cc303 100644 (file)
@@ -248,7 +248,7 @@ class Route : public IO
        void curve_reallocate ();
 
   protected:
-       unsigned char _flags;
+       Flag _flags;
 
        /* tight cache-line access here is more important than sheer speed of
           access.
index e9fad1aa2b66986fe8123bbf2f78a7d287ca6040..d87d3fa3a487bbf18a839ce94bd1ac274423fc85 100644 (file)
@@ -115,7 +115,7 @@ class RouteGroup : public Stateful, public sigc::trackable {
     Session& _session;
     list<Route *> routes;
     string _name;
-    uint32_t _flags;
+    Flag _flags;
 
     void remove_when_going_away (Route*);
 };
index 12a0cba3ecf71fa69afa15a3c7e6df5bcd8847de..eceb301bf87ab87b369e989823860bcfd6d33fd6 100644 (file)
 
 namespace ARDOUR {
 
-class Send : public Redirect {
+class Send : public Redirect 
+{
   public:      
        Send (Session&, Placement);
        Send (Session&, const XMLNode&);
        Send (const Send&);
        ~Send ();
+
+       uint32_t bit_slot() const { return bitslot; }
        
        void run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
        
@@ -54,9 +57,12 @@ class Send : public Redirect {
        uint32_t pans_required() const { return _expected_inputs.get(DataType::AUDIO); }
        void expect_inputs (const ChanCount&);
 
+       static uint32_t how_many_sends();
+
   private:
        bool      _metering;
        ChanCount _expected_inputs;
+       uint32_t bitslot;
 };
 
 } // namespace ARDOUR
index 039bf923628b2d187e3c233ad84ac68f599dac12..1c1ea9e62c254b4927170fe9ebf50c40a5c95241 100644 (file)
@@ -29,6 +29,7 @@
 #include <stack>
 
 #include <boost/weak_ptr.hpp>
+#include <boost/dynamic_bitset.hpp>
 
 #include <stdint.h>
 
@@ -117,9 +118,9 @@ using std::set;
 class Session : public PBD::StatefulDestructible
 {
   private:
-       typedef std::pair<boost::shared_ptr<Route>,bool> RouteBooleanState;
+       typedef std::pair<boost::weak_ptr<Route>,bool> RouteBooleanState;
        typedef vector<RouteBooleanState> GlobalRouteBooleanState;
-       typedef std::pair<boost::shared_ptr<Route>,MeterPoint> RouteMeterState;
+       typedef std::pair<boost::weak_ptr<Route>,MeterPoint> RouteMeterState;
        typedef vector<RouteMeterState> GlobalRouteMeterState;
 
   public:
@@ -253,6 +254,7 @@ class Session : public PBD::StatefulDestructible
        void set_dirty ();
        void set_clean ();
        bool dirty() const { return _state_of_the_state & Dirty; }
+       void set_deletion_in_progress ();
        bool deletion_in_progress() const { return _state_of_the_state & Deletion; }
        sigc::signal<void> DirtyChanged;
 
@@ -391,6 +393,9 @@ class Session : public PBD::StatefulDestructible
        double frames_per_smpte_frame() const { return _frames_per_smpte_frame; }
        nframes_t smpte_frames_per_hour() const { return _smpte_frames_per_hour; }
 
+       float smpte_frames_per_second() const;
+       bool smpte_drop_frames() const;
+
        /* Locations */
 
        Locations *locations() { return &_locations; }
@@ -401,6 +406,7 @@ class Session : public PBD::StatefulDestructible
 
        void set_auto_punch_location (Location *);
        void set_auto_loop_location (Location *);
+       int location_name(string& result, string base = string(""));
 
        void reset_input_monitor_state ();
 
@@ -495,19 +501,6 @@ class Session : public PBD::StatefulDestructible
        nframes_t transport_frame () const {return _transport_frame; }
        nframes_t audible_frame () const;
 
-       enum SmpteFormat {
-               smpte_23976,
-               smpte_24,
-               smpte_24976,
-               smpte_25,
-               smpte_2997,
-               smpte_2997drop,
-               smpte_30,
-               smpte_30drop,
-               smpte_5994,
-               smpte_60,
-       };
-
        enum PullupFormat {
                pullup_Plus4Plus1,
                pullup_Plus4,
@@ -517,11 +510,10 @@ class Session : public PBD::StatefulDestructible
                pullup_Minus1,
                pullup_Minus4Plus1,
                pullup_Minus4,
-               pullup_Minus4Minus1,
+               pullup_Minus4Minus1
        };
 
-       int  set_smpte_type (float fps, bool drop_frames);
-
+       int  set_smpte_format (SmpteFormat);
        void sync_time_vars();
 
        void bbt_time (nframes_t when, BBT_Time&);
@@ -584,7 +576,7 @@ class Session : public PBD::StatefulDestructible
            bool multichan;
            bool sample_convert;
            volatile bool freeze;
-           string pathname;
+           std::vector<Glib::ustring> paths;
            
            /* result */
            std::vector<boost::shared_ptr<Region> > new_regions;
@@ -602,7 +594,6 @@ class Session : public PBD::StatefulDestructible
        
        void add_source (boost::shared_ptr<Source>);
        void remove_source (boost::weak_ptr<Source>);
-       int  cleanup_audio_file_source (boost::shared_ptr<AudioFileSource>);
 
        struct cleanup_report {
            vector<string> paths;
@@ -622,8 +613,7 @@ class Session : public PBD::StatefulDestructible
           this playlist.
        */
        
-       sigc::signal<int,ARDOUR::Playlist*> AskAboutPlaylistDeletion;
-
+       sigc::signal<int,boost::shared_ptr<ARDOUR::Playlist> > AskAboutPlaylistDeletion;
 
        /* handlers should return !0 for use pending state, 0 for
           ignore it.
@@ -631,9 +621,6 @@ class Session : public PBD::StatefulDestructible
 
        static sigc::signal<int> AskAboutPendingState;
        
-       sigc::signal<void,boost::shared_ptr<Source> > SourceAdded;
-       sigc::signal<void,boost::shared_ptr<Source> > SourceRemoved;
-
        boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
 
        boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&);
@@ -642,15 +629,15 @@ class Session : public PBD::StatefulDestructible
 
        /* playlist management */
 
-       Playlist* playlist_by_name (string name);
-       void add_playlist (Playlist *);
-       sigc::signal<void,Playlist*> PlaylistAdded;
-       sigc::signal<void,Playlist*> PlaylistRemoved;
+       boost::shared_ptr<Playlist> playlist_by_name (string name);
+       void add_playlist (boost::shared_ptr<Playlist>);
+       sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistAdded;
+       sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistRemoved;
 
        uint32_t n_playlists() const;
 
-       template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *));
-       void get_playlists (std::vector<Playlist*>&);
+       template<class T> void foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr<Playlist>));
+       void get_playlists (std::vector<boost::shared_ptr<Playlist> >&);
 
        /* named selections */
 
@@ -711,9 +698,11 @@ class Session : public PBD::StatefulDestructible
        uint32_t n_plugin_inserts() const { return _plugin_inserts.size(); }
        uint32_t n_sends() const { return _sends.size(); }
 
-       string next_send_name();
-       string next_insert_name();
-       
+       uint32_t next_send_id();
+       uint32_t next_insert_id();
+       void mark_send_id (uint32_t);
+       void mark_insert_id (uint32_t);
+
        /* s/w "RAID" management */
        
        nframes_t available_capture_duration();
@@ -786,59 +775,75 @@ class Session : public PBD::StatefulDestructible
        std::map<PBD::ID, PBD::StatefulThingWithGoingAway*> registry;
 
         // these commands are implemented in libs/ardour/session_command.cc
-       Command *memento_command_factory(XMLNode *n);
-        void register_with_memento_command_factory(PBD::ID, PBD::StatefulThingWithGoingAway *);
+       Command* memento_command_factory(XMLNode* n);
+        void register_with_memento_command_factory(PBD::ID, PBD::StatefulThingWithGoingAway*);
+
+       Command* global_state_command_factory (const XMLNode& n);
+
+       class GlobalRouteStateCommand : public Command
+       {
+         public:
+               GlobalRouteStateCommand (Session&, void*);
+               GlobalRouteStateCommand (Session&, const XMLNode& node);
+               int set_state (const XMLNode&);
+               XMLNode& get_state ();
+
+         protected:
+               GlobalRouteBooleanState before, after;
+               Session& sess;
+               void* src;
+               
+       };
 
-        class GlobalSoloStateCommand : public Command
+        class GlobalSoloStateCommand : public GlobalRouteStateCommand
         {
-            GlobalRouteBooleanState before, after;
-            Session &sess;
-            void *src;
-        public:
-            GlobalSoloStateCommand(Session &, void *src);
-            void operator()();
-            void undo();
-            XMLNode &get_state();
-            void mark();
+         public:
+               GlobalSoloStateCommand (Session &, void *src);
+               GlobalSoloStateCommand (Session&, const XMLNode&);
+               void operator()(); //redo
+               void undo();
+               XMLNode &get_state();
+               void mark();
         };
 
-        class GlobalMuteStateCommand : public Command
+        class GlobalMuteStateCommand : public GlobalRouteStateCommand
         {
-            GlobalRouteBooleanState before, after;
-            Session &sess;
-            void *src;
-        public:
-            GlobalMuteStateCommand(Session &, void *src);
-            void operator()();
-            void undo();
-            XMLNode &get_state();
-            void mark();
+         public:
+               GlobalMuteStateCommand(Session &, void *src);
+               GlobalMuteStateCommand (Session&, const XMLNode&);
+               void operator()(); // redo
+               void undo();
+               XMLNode &get_state();
+               void mark();
         };
 
-        class GlobalRecordEnableStateCommand : public Command
+        class GlobalRecordEnableStateCommand : public GlobalRouteStateCommand
         {
-            GlobalRouteBooleanState before, after;
-            Session &sess;
-            void *src;
-        public:
-            GlobalRecordEnableStateCommand(Session &, void *src);
-            void operator()();
-            void undo();
-            XMLNode &get_state();
-            void mark();
+         public:
+               GlobalRecordEnableStateCommand(Session &, void *src);
+               GlobalRecordEnableStateCommand (Session&, const XMLNode&);
+               void operator()(); // redo
+               void undo();
+               XMLNode &get_state();
+               void mark();
         };
 
         class GlobalMeteringStateCommand : public Command
         {
-            GlobalRouteMeterState before, after;
-            Session &sess;
-            void *src;
-        public:
-            GlobalMeteringStateCommand(Session &, void *src);
-            void operator()();
-            void undo();
-            XMLNode &get_state();
-            void mark();
+         public:
+               GlobalMeteringStateCommand(Session &, void *src);
+               GlobalMeteringStateCommand (Session&, const XMLNode&);
+               void operator()();
+               void undo();
+               XMLNode &get_state();
+               int set_state (const XMLNode&);
+               void mark();
+
+         protected:
+               Session& sess;
+               void* src;
+               GlobalRouteMeterState before;
+               GlobalRouteMeterState after;
         };
 
        /* clicking */
@@ -951,6 +956,7 @@ class Session : public PBD::StatefulDestructible
        
   private:
        int  create (bool& new_session, string* mix_template, nframes_t initial_length);
+       void destroy ();
 
        nframes_t compute_initial_length ();
 
@@ -1102,7 +1108,6 @@ class Session : public PBD::StatefulDestructible
 
        void hookup_io ();
        void when_engine_running ();
-       sigc::connection first_time_running;
        void graph_reordered ();
 
        string _current_snapshot_name;
@@ -1134,6 +1139,8 @@ class Session : public PBD::StatefulDestructible
        bool              butler_should_run;
        mutable gint      butler_should_do_transport_work;
        int               butler_request_pipe[2];
+
+       inline bool transport_work_requested() const { return g_atomic_int_get(&butler_should_do_transport_work); }
        
        struct ButlerRequest {
            enum Type {
@@ -1306,7 +1313,7 @@ class Session : public PBD::StatefulDestructible
        nframes_t _smpte_frames_per_hour;
        nframes_t _smpte_offset;
        bool _smpte_offset_negative;
-       
+
        /* cache the most-recently requested time conversions. This helps when we
         * have multiple clocks showing the same time (e.g. the transport frame) */
        bool           last_smpte_valid;
@@ -1392,9 +1399,8 @@ class Session : public PBD::StatefulDestructible
        void realtime_stop (bool abort);
        void non_realtime_start_scrub ();
        void non_realtime_set_speed ();
-       void non_realtime_stop (bool abort);
-       void non_realtime_overwrite ();
-       void non_realtime_buffer_fill ();
+       void non_realtime_stop (bool abort, int entry_request_count, bool& finished);
+       void non_realtime_overwrite (int entry_request_count, bool& finished);
        void butler_transport_work ();
        void post_transport ();
        void engine_halted ();
@@ -1469,19 +1475,19 @@ class Session : public PBD::StatefulDestructible
        /* PLAYLISTS */
        
        mutable Glib::Mutex playlist_lock;
-       typedef set<Playlist *> PlaylistList;
+       typedef set<boost::shared_ptr<Playlist> > PlaylistList;
        PlaylistList playlists;
        PlaylistList unused_playlists;
 
        int load_playlists (const XMLNode&);
        int load_unused_playlists (const XMLNode&);
-       void remove_playlist (Playlist *);
-       void track_playlist (Playlist *, bool);
+       void remove_playlist (boost::weak_ptr<Playlist>);
+       void track_playlist (bool, boost::weak_ptr<Playlist>);
 
-       Playlist *playlist_factory (string name);
-       Playlist *XMLPlaylistFactory (const XMLNode&);
+       boost::shared_ptr<Playlist> playlist_factory (string name);
+       boost::shared_ptr<Playlist> XMLPlaylistFactory (const XMLNode&);
 
-       void playlist_length_changed (Playlist *);
+       void playlist_length_changed ();
        void diskstream_playlist_changed (boost::shared_ptr<Diskstream>);
 
        /* NAMED SELECTIONS */
@@ -1522,9 +1528,12 @@ class Session : public PBD::StatefulDestructible
        list<PortInsert *>   _port_inserts;
        list<PluginInsert *> _plugin_inserts;
        list<Send *>         _sends;
+       boost::dynamic_bitset<uint32_t>  send_bitset;
+       boost::dynamic_bitset<uint32_t>  insert_bitset;
        uint32_t          send_cnt;
        uint32_t          insert_cnt;
 
+
        void add_redirect (Redirect *);
        void remove_redirect (Redirect *);
 
index 6f1b8dbd1243985cef6360a92c2e1f21268e6315..20cf4d8f2e7bd7f7a863df2c84d1bb8f78d6dd57 100644 (file)
@@ -27,7 +27,7 @@
 namespace ARDOUR {
 
 template<class T> void 
-Session::foreach_playlist (T *obj, void (T::*func)(Playlist *)) 
+Session::foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr<Playlist>)) 
 {
        Glib::Mutex::Lock lm (playlist_lock);
        for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); i++) {
index e94b1af54f87ede9f0a7f384c5a1db5530e2b60b..8eaab14ec5ea9c7cec1eff4b8acc0c44b0e3fca4 100644 (file)
@@ -66,8 +66,8 @@ class Source : public PBD::StatefulDestructible
        void use () { _in_use++; }
        void disuse () { if (_in_use) { _in_use--; } }
        
-       void add_playlist (ARDOUR::Playlist*);
-       void remove_playlist (ARDOUR::Playlist*);
+       void add_playlist (boost::shared_ptr<ARDOUR::Playlist>);
+       void remove_playlist (boost::weak_ptr<ARDOUR::Playlist>);
 
        uint32_t used() const;
 
@@ -83,7 +83,7 @@ class Source : public PBD::StatefulDestructible
        time_t            _timestamp;
        jack_nframes_t    _length;
 
-       std::set<ARDOUR::Playlist*> _playlists;
+       std::set<boost::shared_ptr<ARDOUR::Playlist> > _playlists;
 
   private:
        uint32_t          _in_use;
index d7a2da2f469b0987efbfb2faf3d3a6229a2e4791..eee04d9bfa35cc53b8522f0b02074954400c4a7b 100644 (file)
@@ -115,13 +115,12 @@ class Track : public Route
 
        struct FreezeRecord {
            FreezeRecord()
-               : playlist(0)
-               , have_mementos(false)
+               : have_mementos(false)
            {}
 
            ~FreezeRecord();
 
-           Playlist*                       playlist;
+           boost::shared_ptr<Playlist>     playlist;
            vector<FreezeRecordInsertInfo*> insert_info;
            bool                            have_mementos;
            FreezeState                     state;
index 1138b5208f462b4ead8f9006c2341c5cadeb8f37..30cdcd82328f02dc498937d4a364d688b8967748 100644 (file)
@@ -143,6 +143,18 @@ namespace ARDOUR {
            }
            
        };
+       enum SmpteFormat {
+               smpte_23976,
+               smpte_24,
+               smpte_24976,
+               smpte_25,
+               smpte_2997,
+               smpte_2997drop,
+               smpte_30,
+               smpte_30drop,
+               smpte_5994,
+               smpte_60
+       };
 
        struct AnyTime {
            enum Type {
@@ -322,7 +334,7 @@ namespace ARDOUR {
        };
 
        enum ShuttleUnits {
-               Percentage,
+               Percentage,
                Semitones
        };
 
@@ -340,6 +352,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::CrossfadeModel& sf);
 std::istream& operator>>(std::istream& o, ARDOUR::SlaveSource& sf);
 std::istream& operator>>(std::istream& o, ARDOUR::ShuttleBehaviour& sf);
 std::istream& operator>>(std::istream& o, ARDOUR::ShuttleUnits& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::SmpteFormat& sf);
 
 using ARDOUR::nframes_t;
 
index d926f52f82868b9a7b64c0904501186fb8ecb4ed..de97a5c1508618ba071fae15cc7c00fcdcaca19c 100644 (file)
 class XMLNode;
 
 void elapsed_time_to_str (char *buf, uint32_t seconds);
-std::string legalize_for_path (std::string str);
+Glib::ustring legalize_for_path (Glib::ustring str);
 std::ostream& operator<< (std::ostream& o, const ARDOUR::BBT_Time& bbt);
 XMLNode* find_named_node (const XMLNode& node, std::string name);
-std::string placement_as_string (ARDOUR::Placement);
 
 static inline float f_max(float x, float a) {
        x -= a;
@@ -52,10 +51,11 @@ int cmp_nocase (const std::string& s, const std::string& s2);
 
 int tokenize_fullpath (std::string fullpath, std::string& path, std::string& name);
 
-int touch_file(std::string path);
+int touch_file(Glib::ustring path);
 
-std::string region_name_from_path (std::string path);
-std::string path_expand (std::string);
+Glib::ustring path_expand (Glib::ustring);
+Glib::ustring region_name_from_path (Glib::ustring path, bool strip_channels);
+bool path_is_paired (Glib::ustring path, Glib::ustring& pair_base);
 
 void compute_equal_power_fades (nframes_t nframes, float* in, float* out);
 
@@ -66,6 +66,8 @@ const char* edit_mode_to_string (ARDOUR::EditMode);
 ARDOUR::EditMode string_to_edit_mode (std::string);
 
 float meter_falloff_to_float (ARDOUR::MeterFalloff);
+ARDOUR::MeterFalloff meter_falloff_from_float (float);
+float meter_falloff_to_db_per_sec (float);
 float meter_hold_to_float (ARDOUR::MeterHold);
 
 #if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS)
index 9c5f5233b702c888c819b7f62559219982fb215a..7165a58b27898657476028b35f2051cd1b11d4cd 100644 (file)
@@ -35,6 +35,7 @@
 #include <glibmm/thread.h>
 #include <pbd/xml++.h>
 #include <pbd/memento_command.h>
+#include <pbd/enumwriter.h>
 
 #include <ardour/ardour.h>
 #include <ardour/audioengine.h>
@@ -46,6 +47,7 @@
 #include <ardour/send.h>
 #include <ardour/region_factory.h>
 #include <ardour/audioplaylist.h>
+#include <ardour/playlist_factory.h>
 #include <ardour/cycle_timer.h>
 #include <ardour/audioregion.h>
 #include <ardour/audio_port.h>
@@ -95,34 +97,6 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
        }
 }
 
-void
-AudioDiskstream::init_channel (ChannelInfo &chan)
-{
-       chan.playback_wrap_buffer = 0;
-       chan.capture_wrap_buffer = 0;
-       chan.speed_buffer = 0;
-       chan.peak_power = 0.0f;
-       chan.source = 0;
-       chan.current_capture_buffer = 0;
-       chan.current_playback_buffer = 0;
-       chan.curr_capture_cnt = 0;
-       
-       chan.playback_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
-       chan.capture_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
-       chan.capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
-       
-       
-       /* touch the ringbuffer buffers, which will cause
-          them to be mapped into locked physical RAM if
-          we're running with mlockall(). this doesn't do
-          much if we're not.  
-       */
-       memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize());
-       memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize());
-       memset (chan.capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * chan.capture_transition_buf->bufsize());
-}
-
-
 void
 AudioDiskstream::init (Diskstream::Flag f)
 {
@@ -140,40 +114,21 @@ AudioDiskstream::init (Diskstream::Flag f)
        assert(_n_channels == ChanCount(DataType::AUDIO, 1));
 }
 
-void
-AudioDiskstream::destroy_channel (ChannelInfo &chan)
-{
-       if (chan.write_source) {
-               chan.write_source.reset ();
-       }
-               
-       if (chan.speed_buffer) {
-               delete [] chan.speed_buffer;
-       }
-
-       if (chan.playback_wrap_buffer) {
-               delete [] chan.playback_wrap_buffer;
-       }
-       if (chan.capture_wrap_buffer) {
-               delete [] chan.capture_wrap_buffer;
-       }
-       
-       delete chan.playback_buf;
-       delete chan.capture_buf;
-       delete chan.capture_transition_buf;
-       
-       chan.playback_buf = 0;
-       chan.capture_buf = 0;
-}
-
 AudioDiskstream::~AudioDiskstream ()
 {
-       Glib::Mutex::Lock lm (state_lock);
+       notify_callbacks ();
 
-       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan)
-               destroy_channel((*chan));
-       
-       channels.clear();
+       {
+               /* don't be holding this lock as we exit the destructor, glib will wince
+                  visibly since the mutex gets destroyed before we release it.
+               */
+
+               Glib::Mutex::Lock lm (state_lock);
+               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+                       (*chan).release ();
+               }
+               channels.clear();
+       }
 }
 
 void
@@ -288,15 +243,13 @@ AudioDiskstream::get_input_sources ()
 int
 AudioDiskstream::find_and_use_playlist (const string& name)
 {
-       Playlist* pl;
-       AudioPlaylist* playlist;
+       boost::shared_ptr<AudioPlaylist> playlist;
                
-       if ((pl = _session.playlist_by_name (name)) == 0) {
-               playlist = new AudioPlaylist(_session, name);
-               pl = playlist;
+       if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlist_by_name (name))) == 0) {
+               playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (_session, name));
        }
 
-       if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
+       if (!playlist) {
                error << string_compose(_("AudioDiskstream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
                return -1;
        }
@@ -305,9 +258,9 @@ AudioDiskstream::find_and_use_playlist (const string& name)
 }
 
 int
-AudioDiskstream::use_playlist (Playlist* playlist)
+AudioDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
 {
-       assert(dynamic_cast<AudioPlaylist*>(playlist));
+       assert(boost::dynamic_pointer_cast<AudioPlaylist>(playlist));
 
        Diskstream::use_playlist(playlist);
 
@@ -318,7 +271,7 @@ int
 AudioDiskstream::use_new_playlist ()
 {
        string newname;
-       AudioPlaylist* playlist;
+       boost::shared_ptr<AudioPlaylist> playlist;
 
        if (!in_set_state && destructive()) {
                return 0;
@@ -330,9 +283,11 @@ AudioDiskstream::use_new_playlist ()
                newname = Playlist::bump_name (_name, _session);
        }
 
-       if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
+       if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (_session, newname, hidden()))) != 0) {
+               
                playlist->set_orig_diskstream_id (id());
                return use_playlist (playlist);
+
        } else { 
                return -1;
        }
@@ -353,11 +308,11 @@ AudioDiskstream::use_copy_playlist ()
        }
 
        string newname;
-       AudioPlaylist* playlist;
+       boost::shared_ptr<AudioPlaylist> playlist;
 
        newname = Playlist::bump_name (_playlist->name(), _session);
        
-       if ((playlist  = new AudioPlaylist (*audio_playlist(), newname)) != 0) {
+       if ((playlist  = boost::dynamic_pointer_cast<AudioPlaylist>(PlaylistFactory::create (audio_playlist(), newname))) != 0) {
                playlist->set_orig_diskstream_id (id());
                return use_playlist (playlist);
        } else { 
@@ -1553,7 +1508,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
        } else {
 
                string whole_file_region_name;
-               whole_file_region_name = region_name_from_path (channels[0].write_source->name());
+               whole_file_region_name = region_name_from_path (channels[0].write_source->name(), true);
 
                /* Register a new region with the Session that
                   describes the entire source. Do this first
@@ -1684,7 +1639,7 @@ AudioDiskstream::finish_capture (bool rec_monitors_input)
 void
 AudioDiskstream::set_record_enabled (bool yn)
 {
-       if (!recordable() || !_session.record_enabling_legal()) {
+       if (!recordable() || !_session.record_enabling_legal() || _io->n_inputs().get(DataType::AUDIO) == 0) {
                return;
        }
 
@@ -1762,8 +1717,7 @@ AudioDiskstream::get_state ()
        char buf[64] = "";
        LocaleGuard lg (X_("POSIX"));
 
-       snprintf (buf, sizeof(buf), "0x%x", _flags);
-       node->add_property ("flags", buf);
+       node->add_property ("flags", enum_2_string (_flags));
 
        snprintf (buf, sizeof(buf), "%zd", channels.size());
        node->add_property ("channels", buf);
@@ -1850,7 +1804,7 @@ AudioDiskstream::set_state (const XMLNode& node)
        }
 
        if ((prop = node.property ("flags")) != 0) {
-               _flags = strtol (prop->value().c_str(), 0, 0);
+               _flags = Flag (string_2_enum (prop->value(), _flags));
        }
 
        if ((prop = node.property ("channels")) != 0) {
@@ -1982,7 +1936,7 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force)
        }
        
        capturing_sources.clear ();
-       
+
        for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
                if (!destructive()) {
 
@@ -2109,15 +2063,19 @@ AudioDiskstream::add_channel ()
 {
        /* XXX need to take lock??? */
 
-       ChannelInfo chan;
+       /* this copies the ChannelInfo, which currently has no buffers. kind
+          of pointless really, but we want the channels list to contain
+          actual objects, not pointers to objects. mostly for convenience,
+          which isn't much in evidence.
+       */
 
-       init_channel (chan);
+       channels.push_back (ChannelInfo());
 
-       chan.speed_buffer = new Sample[speed_buffer_size];
-       chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
-       chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
+       /* now allocate the buffers */
 
-       channels.push_back (chan);
+       channels.back().init (_session.diskstream_buffer_size(), 
+                             speed_buffer_size,
+                             wrap_buffer_size);
 
        _n_channels.set(DataType::AUDIO, channels.size());
 
@@ -2129,10 +2087,8 @@ AudioDiskstream::remove_channel ()
 {
        if (channels.size() > 1) {
                /* XXX need to take lock??? */
-               ChannelInfo & chan = channels.back();
-               destroy_channel (chan);
+               channels.back().release ();
                channels.pop_back();
-
                _n_channels.set(DataType::AUDIO, channels.size());
                return 0;
        }
@@ -2217,7 +2173,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
        
        try {
                region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(),
-                                                                                         region_name_from_path (first_fs->name()), 
+                                                                                         region_name_from_path (first_fs->name(), true), 
                                                                                          0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
                region->special_set_position (0);
        }
@@ -2231,7 +2187,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
        }
 
        try {
-               region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name())));
+               region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name(), true)));
        }
 
        catch (failed_constructor& err) {
@@ -2261,10 +2217,10 @@ AudioDiskstream::set_destructive (bool yn)
                        if (!can_become_destructive (bounce_ignored)) {
                                return -1;
                        }
-                       _flags |= Destructive;
+                       _flags = Flag (_flags | Destructive);
                        use_destructive_playlist ();
                } else {
-                       _flags &= ~Destructive;
+                       _flags = Flag (_flags & ~Destructive);
                        reset_write_sources (true, true);
                }
        }
@@ -2313,3 +2269,82 @@ AudioDiskstream::can_become_destructive (bool& requires_bounce) const
        requires_bounce = false;
        return true;
 }
+
+AudioDiskstream::ChannelInfo::ChannelInfo ()
+{
+       playback_wrap_buffer = 0;
+       capture_wrap_buffer = 0;
+       speed_buffer = 0;
+       peak_power = 0.0f;
+       source = 0;
+       current_capture_buffer = 0;
+       current_playback_buffer = 0;
+       curr_capture_cnt = 0;
+       playback_buf = 0;
+       capture_buf = 0;
+       capture_transition_buf = 0;
+}
+
+void
+AudioDiskstream::ChannelInfo::init (nframes_t bufsize, nframes_t speed_size, nframes_t wrap_size)
+{
+       speed_buffer = new Sample[speed_size];
+       playback_wrap_buffer = new Sample[wrap_size];
+       capture_wrap_buffer = new Sample[wrap_size];
+
+       playback_buf = new RingBufferNPT<Sample> (bufsize);
+       capture_buf = new RingBufferNPT<Sample> (bufsize);
+       capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
+       
+       /* touch the ringbuffer buffers, which will cause
+          them to be mapped into locked physical RAM if
+          we're running with mlockall(). this doesn't do
+          much if we're not.  
+       */
+
+       memset (playback_buf->buffer(), 0, sizeof (Sample) * playback_buf->bufsize());
+       memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize());
+       memset (capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * capture_transition_buf->bufsize());
+}
+
+AudioDiskstream::ChannelInfo::~ChannelInfo ()
+{
+}
+
+void
+AudioDiskstream::ChannelInfo::release ()
+{
+       if (write_source) {
+               write_source.reset ();
+       }
+               
+       if (speed_buffer) {
+               delete [] speed_buffer;
+               speed_buffer = 0;
+       }
+
+       if (playback_wrap_buffer) {
+               delete [] playback_wrap_buffer;
+               playback_wrap_buffer = 0;
+       }
+
+       if (capture_wrap_buffer) {
+               delete [] capture_wrap_buffer;
+               capture_wrap_buffer = 0;
+       }
+       
+       if (playback_buf) {
+               delete playback_buf;
+               playback_buf = 0;
+       }
+
+       if (capture_buf) {
+               delete capture_buf;
+               capture_buf = 0;
+       }
+
+       if (capture_transition_buf) {
+               delete capture_transition_buf;
+               capture_transition_buf = 0;
+       }
+}
index 3aa6d05be1fea88bc087318d349829c1583e8ab8..2ed4739a961fe357e58caf49821ebf657d8cccfd 100644 (file)
@@ -1,6 +1,5 @@
 /*
-    Copyright (C) 2003 Paul Davis 
-    Author: Taybin Rutkin
+    Copyright (C) 2003-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
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
-#include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
-#include <cerrno>
-#include <iostream>
 #include <sstream>
-#include <cctype>
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fts.h>
+#include <libxml/uri.h>
 
 #include <lrdf.h>
 
 #include <pbd/compose.h>
 
-#include <ardour/ardour.h>
-#include <ardour/configuration.h>
 #include <ardour/audio_library.h>
 #include <ardour/utils.h>
 
 
 using namespace std;
 using namespace ARDOUR;
-using namespace PBD;
 
-static char* SOUNDFILE = "http://ardour.org/ontology/Soundfile";
-
-string AudioLibrary::state_node_name = "AudioLibrary";
+static char* TAG = "http://ardour.org/ontology/Tag";
 
 AudioLibrary::AudioLibrary ()
 {
-//     sfdb_paths.push_back("/Users/taybin/sounds");
-
        src = "file:" + get_user_ardour_path() + "sfdb";
 
        // workaround for possible bug in raptor that crashes when saving to a
@@ -59,80 +44,103 @@ AudioLibrary::AudioLibrary ()
        touch_file(get_user_ardour_path() + "sfdb");
 
        lrdf_read_file(src.c_str());
-
-       lrdf_statement pattern;
-
-       pattern.subject = SOUNDFILE;
-       pattern.predicate = RDF_TYPE;
-       pattern.object = RDFS_CLASS;
-       pattern.object_type = lrdf_uri;
-
-       lrdf_statement* matches = lrdf_matches(&pattern);
-
-       // if empty DB, create basic schema
-       if (matches == 0) {
-               initialize_db ();
-               save_changes();
-       } 
-
-       lrdf_free_statements(matches);
 }
 
 AudioLibrary::~AudioLibrary ()
 {
 }
 
-void
-AudioLibrary::initialize_db ()
-{
-       // define ardour:Soundfile
-       lrdf_add_triple(src.c_str(), SOUNDFILE, RDF_TYPE, RDFS_CLASS, lrdf_uri);
-
-       // add intergral fields
-       add_field(_("channels"));
-       add_field(_("samplerate"));
-       add_field(_("resolution"));
-       add_field(_("format"));
-}
-
 void
 AudioLibrary::save_changes ()
 {
        if (lrdf_export_by_source(src.c_str(), src.substr(5).c_str())) {
-               warning << string_compose(_("Could not open %1.  Audio Library not saved"), src) << endmsg;
+               PBD::warning << string_compose(_("Could not open %1.  Audio Library not saved"), src) << endmsg;
        }
 }
 
-void
-AudioLibrary::add_member (string member)
+string
+AudioLibrary::path2uri (string path)
 {
-       string file_uri(string_compose("file:%1", member));
+       xmlURI temp;
+       memset(&temp, 0, sizeof(temp));
+       
+       xmlChar *cal = xmlCanonicPath((xmlChar*) path.c_str());
+       temp.path = (char *) cal;
+       xmlChar *ret = xmlSaveUri(&temp);
+       xmlFree(cal);
+       
+       stringstream uri;
+       uri << "file:" << (const char*) ret;
+       
+       xmlFree (ret);
+       
+       return uri.str();
+}
 
-       lrdf_add_triple(src.c_str(), file_uri.c_str(), RDF_TYPE, 
-                       SOUNDFILE, lrdf_uri);
+string
+AudioLibrary::uri2path (string uri)
+{
+       string path = xmlURIUnescapeString(uri.c_str(), 0, 0);
+       return path.substr(5);
 }
 
 void
-AudioLibrary::remove_member (string uri)
+AudioLibrary::set_tags (string member, vector<string> tags)
+{
+       sort (tags.begin(), tags.end());
+       tags.erase (unique(tags.begin(), tags.end()), tags.end());
+       
+       string file_uri(path2uri(member));
+       
+       lrdf_remove_uri_matches (file_uri.c_str());
+       
+       for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
+               lrdf_add_triple (src.c_str(), file_uri.c_str(), TAG, (*i).c_str(), lrdf_literal);
+       }
+}
+
+vector<string>
+AudioLibrary::get_tags (string member)
 {
-       lrdf_remove_uri_matches (uri.c_str());
+       vector<string> tags;
+       
+       lrdf_statement pattern;
+       pattern.subject = strdup(path2uri(member).c_str());
+       pattern.predicate = TAG;
+       pattern.object = 0;
+       pattern.object_type = lrdf_literal;
+       
+       lrdf_statement* matches = lrdf_matches (&pattern);
+       free (pattern.subject);
+       
+       lrdf_statement* current = matches;
+       while (current != 0) {
+               tags.push_back (current->object);
+               
+               current = current->next;
+       }
+       
+       lrdf_free_statements (matches);
+       
+       sort (tags.begin(), tags.end());
+       
+       return tags;
 }
 
 void
-AudioLibrary::search_members_and (vector<string>& members, 
-                                                                 const map<string,string>& fields)
+AudioLibrary::search_members_and (vector<string>& members, const vector<string> tags)
 {
        lrdf_statement **head;
        lrdf_statement* pattern = 0;
        lrdf_statement* old = 0;
        head = &pattern;
 
-       map<string,string>::const_iterator i;
-       for (i = fields.begin(); i != fields.end(); ++i){
+       vector<string>::const_iterator i;
+       for (i = tags.begin(); i != tags.end(); ++i){
                pattern = new lrdf_statement;
                pattern->subject = "?";
-               pattern->predicate = strdup(field_uri(i->first).c_str());
-               pattern->object = strdup((i->second).c_str());
+               pattern->predicate = TAG;
+               pattern->object = strdup((*i).c_str());
                pattern->next = old;
 
                old = pattern;
@@ -141,340 +149,21 @@ AudioLibrary::search_members_and (vector<string>& members,
        if (*head != 0) {
                lrdf_uris* ulist = lrdf_match_multi(*head);
                for (uint32_t j = 0; ulist && j < ulist->count; ++j) {
-//                     printf("AND: %s\n", ulist->items[j]);
-                       members.push_back(ulist->items[j]);
+//                     cerr << "AND: " << uri2path(ulist->items[j]) << endl;
+                       members.push_back(uri2path(ulist->items[j]));
                }
                lrdf_free_uris(ulist);
 
-               compact_vector(members);
+           sort(members.begin(), members.end());
+           unique(members.begin(), members.end());
        }
 
        // memory clean up
        pattern = *head;
        while(pattern){
-               free(pattern->predicate);
                free(pattern->object);
                old = pattern;
                pattern = pattern->next;
                delete old;
        }
 }
-
-void
-AudioLibrary::search_members_or (vector<string>& members, 
-                                                                const map<string,string>& fields)
-{
-       map<string,string>::const_iterator i;
-
-       lrdf_statement pattern;
-       for (i = fields.begin(); i != fields.end(); ++i) {
-               pattern.subject = 0;
-               pattern.predicate = strdup(field_uri(i->first).c_str());
-               pattern.object = strdup((i->second).c_str());
-               pattern.object_type = lrdf_literal;
-
-               lrdf_statement* matched = lrdf_matches(&pattern);
-
-               lrdf_statement* old = matched;
-               while(matched) {
-//                     printf ("OR: %s\n", matched->subject);
-                       members.push_back(matched->subject);
-                       matched = matched->next;
-               }
-
-               free(pattern.predicate);
-               free(pattern.object);
-               lrdf_free_statements (old);
-       }
-
-       compact_vector(members);
-}
-
-void
-AudioLibrary::add_field (string name)
-{
-       string local_field = field_uri(name);
-       lrdf_statement pattern;
-       pattern.subject = strdup(local_field.c_str());
-       pattern.predicate = RDF_TYPE;
-       pattern.object = RDF_BASE "Property";
-       pattern.object_type = lrdf_uri;
-
-       if(lrdf_exists_match(&pattern)) {
-               return;
-       }
-
-       // of type rdf:Property
-       lrdf_add_triple(src.c_str(), local_field.c_str(), RDF_TYPE, 
-                       RDF_BASE "Property", lrdf_uri);
-       // of range ardour:Soundfile
-       lrdf_add_triple(src.c_str(), local_field.c_str(), RDFS_BASE "range",
-                       SOUNDFILE, lrdf_uri);
-       // of domain rdf:Literal
-       lrdf_add_triple(src.c_str(), local_field.c_str(), RDFS_BASE "domain", 
-                                       RDF_BASE "Literal", lrdf_uri);
-
-       set_label (local_field, name);
-       
-       fields_changed(); /* EMIT SIGNAL */
-}
-
-void
-AudioLibrary::get_fields (vector<string>& fields)
-{
-       lrdf_statement pattern;
-
-       pattern.subject = 0;
-       pattern.predicate = RDFS_BASE "range";
-       pattern.object = SOUNDFILE;
-       pattern.object_type = lrdf_uri;
-
-       lrdf_statement* matches = lrdf_matches(&pattern);
-
-       lrdf_statement* current = matches;
-       while (current != 0) {
-               fields.push_back(get_label(current->subject));
-
-               current = current->next;
-       }
-
-       lrdf_free_statements(matches);
-
-       compact_vector(fields);
-}
-
-void
-AudioLibrary::remove_field (string name)
-{
-       lrdf_remove_uri_matches(field_uri(name).c_str());
-       fields_changed (); /* EMIT SIGNAL */
-}
-
-string 
-AudioLibrary::get_field (string uri, string field)
-{
-       lrdf_statement pattern;
-
-       pattern.subject = strdup(uri.c_str());
-
-       pattern.predicate = strdup(field_uri(field).c_str());
-
-       pattern.object = 0;
-       pattern.object_type = lrdf_literal;
-
-       lrdf_statement* matches = lrdf_matches(&pattern);
-       free(pattern.subject);
-       free(pattern.predicate);
-
-       stringstream object;
-       if (matches != 0){
-               object << matches->object;
-       }
-
-       lrdf_free_statements(matches);
-       return object.str();
-}
-
-void 
-AudioLibrary::set_field (string uri, string field, string literal)
-{
-       lrdf_statement pattern;
-
-       pattern.subject = strdup(uri.c_str());
-
-       string local_field = field_uri(field);
-       pattern.predicate = strdup(local_field.c_str());
-
-       pattern.object = 0;
-       pattern.object_type = lrdf_literal;
-
-       lrdf_remove_matches(&pattern);
-       free(pattern.subject);
-       free(pattern.predicate);
-
-       lrdf_add_triple(src.c_str(), uri.c_str(), local_field.c_str(), 
-                       literal.c_str(), lrdf_literal);
-
-        fields_changed(); /* EMIT SIGNAL */
-}
-
-string
-AudioLibrary::field_uri (string name)
-{
-       stringstream local_field;
-       local_field << "file:sfdb/fields/" << name;
-
-       return local_field.str();
-}
-
-string
-AudioLibrary::get_label (string uri)
-{
-       lrdf_statement pattern;
-       pattern.subject = strdup(uri.c_str());
-       pattern.predicate = RDFS_BASE "label";
-       pattern.object = 0;
-       pattern.object_type = lrdf_literal;
-
-       lrdf_statement* matches = lrdf_matches (&pattern);
-       free(pattern.subject);
-
-       stringstream label;
-       if (matches != 0){
-               label << matches->object;
-       }
-
-       lrdf_free_statements(matches);
-
-       return label.str();
-}
-
-void
-AudioLibrary::set_label (string uri, string label)
-{
-       lrdf_statement pattern;
-       pattern.subject = strdup(uri.c_str());
-       pattern.predicate = RDFS_BASE "label";
-       pattern.object = 0;
-       pattern.object_type = lrdf_literal;
-
-       lrdf_remove_matches(&pattern);
-       free(pattern.subject);
-
-       lrdf_add_triple(src.c_str(), uri.c_str(), RDFS_BASE "label", 
-                       label.c_str(), lrdf_literal);
-}
-
-void
-AudioLibrary::compact_vector(vector<string>& vec)
-{
-    sort(vec.begin(), vec.end());
-    unique(vec.begin(), vec.end());
-}
-
-void 
-AudioLibrary::set_paths (vector<string> paths)
-{
-       sfdb_paths = paths;
-       
-       scan_paths ();
-}
-
-vector<string> 
-AudioLibrary::get_paths ()
-{
-       return sfdb_paths;
-}
-
-void
-AudioLibrary::scan_paths ()
-{
-       if (sfdb_paths.size() < 1) {
-               return;
-       }
-
-       vector<char *> pathv(sfdb_paths.size());
-       unsigned int i;
-       for (i = 0; i < sfdb_paths.size(); ++i) {
-               pathv[i] = new char[sfdb_paths[i].length() +1];
-               sfdb_paths[i].copy(pathv[i], string::npos);
-               pathv[i][sfdb_paths[i].length()] = 0;
-       }
-       pathv[i] = 0;
-
-       FTS* ft = fts_open(&pathv[0], FTS_LOGICAL|FTS_NOSTAT|FTS_PHYSICAL|FTS_XDEV, 0);
-       if (errno) {
-               error << strerror(errno) << endmsg;
-               return;
-       }
-
-       lrdf_statement s;
-       s.predicate = RDF_TYPE;
-       s.object = SOUNDFILE;
-       s.object_type = lrdf_uri;
-       string filename;
-       while (FTSENT* file = fts_read(ft)) {
-               if ((file->fts_info & FTS_F) && (safe_file_extension(file->fts_name))) {
-                       filename = "file:";
-                       filename.append(file->fts_accpath);
-                       s.subject = strdup(filename.c_str());
-                       if (lrdf_exists_match(&s)) {
-                               continue;
-                       } else {
-                               add_member(file->fts_accpath);
-                               cout << file->fts_accpath << endl;
-                       }
-                       free(s.subject);
-               }
-       }
-       fts_close(ft);
-
-       for (i = 0; i < pathv.size(); ++i) {
-               delete[] pathv[i];
-       }
-
-       save_changes();
-}
-
-bool
-AudioLibrary::safe_file_extension(string file)
-{
-       return !(file.rfind(".wav") == string::npos &&
-        file.rfind(".aiff")== string::npos &&
-        file.rfind(".aif") == string::npos &&
-        file.rfind(".snd") == string::npos &&
-        file.rfind(".au")  == string::npos &&
-        file.rfind(".raw") == string::npos &&
-        file.rfind(".sf")  == string::npos &&
-        file.rfind(".cdr") == string::npos &&
-        file.rfind(".smp") == string::npos &&
-        file.rfind(".maud")== string::npos &&
-        file.rfind(".vwe") == string::npos &&
-        file.rfind(".paf") == string::npos &&
-#ifdef HAVE_COREAUDIO
-       file.rfind(".mp3") == string::npos &&
-       file.rfind(".aac") == string::npos &&
-       file.rfind(".mp4") == string::npos &&
-#endif // HAVE_COREAUDIO
-        file.rfind(".voc") == string::npos);
-}
-
-XMLNode&
-AudioLibrary::get_state ()
-{
-       XMLNode* root = new XMLNode(X_("AudioLibrary"));
-       
-       for (vector<string>::iterator i = sfdb_paths.begin(); i != sfdb_paths.end(); ++i) {
-               XMLNode* node = new XMLNode(X_("Path"));
-               node->add_property("value", *i);
-               root->add_child_nocopy(*node);
-       }
-       
-       return *root;
-}
-
-int
-AudioLibrary::set_state (const XMLNode& node)
-{
-       if (node.name() != X_("AudioLibrary")) {
-               fatal << "programming error: AudioLibrary: incorrect XML node sent to set_state()" << endmsg;
-               return -1;
-       }
-       
-       XMLNodeList nodes = node.children(X_("Path"));
-       
-       vector<string> paths;
-       XMLProperty* prop;
-       XMLNode* child;
-       for (XMLNodeConstIterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
-               child = *iter;
-               
-               if ((prop = child->property(X_("value"))) != 0) {
-                       paths.push_back(prop->value());
-               }
-       }
-       
-       set_paths (paths);
-       
-       return 0;
-}
index 335cb020ae07cb1f33edd9d14d716ece9f9b2275..91bed1a4fae3ba7bd15e14536b2dba3cee9678bd 100644 (file)
@@ -48,39 +48,31 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden
        in_set_state++;
        set_state (node);
        in_set_state--;
-
-       if (!hidden) {
-               PlaylistCreated (this); /* EMIT SIGNAL */
-       }
 }
 
 AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
        : Playlist (session, name, DataType::AUDIO, hidden)
 {
-       if (!hidden) {
-               PlaylistCreated (this); /* EMIT SIGNAL */
-       }
-
 }
 
-AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidden)
+AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, string name, bool hidden)
        : Playlist (other, name, hidden)
 {
-       RegionList::const_iterator in_o  = other.regions.begin();
+       RegionList::const_iterator in_o  = other->regions.begin();
        RegionList::iterator in_n = regions.begin();
 
-       while (in_o != other.regions.end()) {
+       while (in_o != other->regions.end()) {
                boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o);
 
                // We look only for crossfades which begin with the current region, so we don't get doubles
-               for (list<Crossfade *>::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) {
+               for (list<Crossfade *>::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) {
                        if ((*xfades)->in() == ar) {
                                // We found one! Now copy it!
 
-                               RegionList::const_iterator out_o = other.regions.begin();
+                               RegionList::const_iterator out_o = other->regions.begin();
                                RegionList::const_iterator out_n = regions.begin();
 
-                               while (out_o != other.regions.end()) {
+                               while (out_o != other->regions.end()) {
                                        
                                        boost::shared_ptr<AudioRegion>ar2 = boost::dynamic_pointer_cast<AudioRegion>(*out_o);
                                        
@@ -102,13 +94,9 @@ AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidd
                in_o++;
                in_n++;
        }
-
-       if (!hidden) {
-               PlaylistCreated (this); /* EMIT SIGNAL */
-       }
 }
 
-AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, nframes_t start, nframes_t cnt, string name, bool hidden)
+AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nframes_t start, nframes_t cnt, string name, bool hidden)
        : Playlist (other, start, cnt, name, hidden)
 {
        /* this constructor does NOT notify others (session) */
@@ -437,8 +425,15 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
                                                            /*  in,      out */
                                        xfade = new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn);
                                        add_crossfade (*xfade);
-                                       xfade = new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
-                                       add_crossfade (*xfade);
+
+                                       if (top_region_at (top->last_frame() - 1) == top) {
+                                         /* 
+                                            only add a fade out if there is no region on top of the end of 'top' (which 
+                                            would cover it).
+                                         */
+                                         xfade = new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
+                                         add_crossfade (*xfade);
+                                       }
                                        
                                } else {
 
@@ -666,7 +661,7 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
                        x = xtmp;
                }
 
-               region->set_playlist (0);
+               region->set_playlist (boost::shared_ptr<Playlist>());
        }
 
        for (c = _crossfades.begin(); c != _crossfades.end(); ) {
index f2681acebaffb4c0115129c5879f6a06d8e4bed2..b0ac7a4bd78dffaa234015b1f07f745b37156a4c 100644 (file)
 
     $Id$
 */
-#include <pbd/error.h>
+
 #include <sigc++/retype.h>
 #include <sigc++/retype_return.h>
 #include <sigc++/bind.h>
 
+#include <pbd/error.h>
+#include <pbd/enumwriter.h>
+
 #include <ardour/audio_track.h>
 #include <ardour/audio_diskstream.h>
 #include <ardour/session.h>
@@ -32,6 +35,7 @@
 #include <ardour/route_group_specialized.h>
 #include <ardour/insert.h>
 #include <ardour/audioplaylist.h>
+#include <ardour/playlist_factory.h>
 #include <ardour/panner.h>
 #include <ardour/utils.h>
 #include <ardour/buffer_set.h>
@@ -235,14 +239,7 @@ AudioTrack::_set_state (const XMLNode& node, bool call_base)
        }
 
        if ((prop = node.property (X_("mode"))) != 0) {
-               if (prop->value() == X_("normal")) {
-                       _mode = Normal;
-               } else if (prop->value() == X_("destructive")) {
-                       _mode = Destructive;
-               } else {
-                       warning << string_compose ("unknown audio track mode \"%1\" seen and ignored", prop->value()) << endmsg;
-                       _mode = Normal;
-               }
+               _mode = TrackMode (string_2_enum (prop->value(), _mode));
        } else {
                _mode = Normal;
        }
@@ -311,8 +308,7 @@ AudioTrack::state(bool full_state)
 
                freeze_node = new XMLNode (X_("freeze-info"));
                freeze_node->add_property ("playlist", _freeze_record.playlist->name());
-               snprintf (buf, sizeof (buf), "%d", (int) _freeze_record.state);
-               freeze_node->add_property ("state", buf);
+               freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
 
                for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
                        inode = new XMLNode (X_("insert"));
@@ -329,15 +325,8 @@ AudioTrack::state(bool full_state)
        /* Alignment: act as a proxy for the diskstream */
        
        XMLNode* align_node = new XMLNode (X_("alignment"));
-       switch (_diskstream->alignment_style()) {
-       case ExistingMaterial:
-               snprintf (buf, sizeof (buf), X_("existing"));
-               break;
-       case CaptureTime:
-               snprintf (buf, sizeof (buf), X_("capture"));
-               break;
-       }
-       align_node->add_property (X_("style"), buf);
+       AlignStyle as = _diskstream->alignment_style ();
+       align_node->add_property (X_("style"), enum_2_string (as));
        root.add_child_nocopy (*align_node);
 
        XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
@@ -345,14 +334,7 @@ AudioTrack::state(bool full_state)
        remote_control_node->add_property (X_("id"), buf);
        root.add_child_nocopy (*remote_control_node);
 
-       switch (_mode) {
-       case Normal:
-               root.add_property (X_("mode"), X_("normal"));
-               break;
-       case Destructive:
-               root.add_property (X_("mode"), X_("destructive"));
-               break;
-       }
+       root.add_property (X_("mode"), enum_2_string (_mode));
 
        /* we don't return diskstream state because we don't
           own the diskstream exclusively. control of the diskstream
@@ -395,18 +377,18 @@ AudioTrack::set_state_part_two ()
                _freeze_record.insert_info.clear ();
                
                if ((prop = fnode->property (X_("playlist"))) != 0) {
-                       Playlist* pl = _session.playlist_by_name (prop->value());
+                       boost::shared_ptr<Playlist> pl = _session.playlist_by_name (prop->value());
                        if (pl) {
-                               _freeze_record.playlist = dynamic_cast<AudioPlaylist*> (pl);
+                               _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
                        } else {
-                               _freeze_record.playlist = 0;
+                               _freeze_record.playlist.reset ();
                                _freeze_record.state = NoFreeze;
                        return;
                        }
                }
                
                if ((prop = fnode->property (X_("state"))) != 0) {
-                       _freeze_record.state = (FreezeState) atoi (prop->value().c_str());
+                       _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
                }
                
                XMLNodeConstIterator citer;
@@ -433,11 +415,21 @@ AudioTrack::set_state_part_two ()
        if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) {
 
                if ((prop = fnode->property (X_("style"))) != 0) {
-                       if (prop->value() == "existing") {
-                               _diskstream->set_persistent_align_style (ExistingMaterial);
-                       } else if (prop->value() == "capture") {
-                               _diskstream->set_persistent_align_style (CaptureTime);
+
+                       /* fix for older sessions from before EnumWriter */
+
+                       string pstr;
+
+                       if (prop->value() == "capture") {
+                               pstr = "CaptureTime";
+                       } else if (prop->value() == "existing") {
+                               pstr = "ExistingMaterial";
+                       } else {
+                               pstr = prop->value();
                        }
+
+                       AlignStyle as = AlignStyle (string_2_enum (pstr, as));
+                       _diskstream->set_persistent_align_style (as);
                }
        }
        return;
@@ -669,8 +661,7 @@ AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes
        
        Glib::RWLock::ReaderLock rlock (redirect_lock);
 
-       // FIXME
-       AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(diskstream->playlist());
+       boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
        assert(apl);
 
        if (apl->read (buffers.get_audio(nframes).data(nframes),
@@ -777,12 +768,12 @@ AudioTrack::freeze (InterThreadInfo& itt)
 {
        vector<boost::shared_ptr<Source> > srcs;
        string new_playlist_name;
-       Playlist* new_playlist;
+       boost::shared_ptr<Playlist> new_playlist;
        string dir;
        string region_name;
        boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
        
-       if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(diskstream->playlist())) == 0) {
+       if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
                return;
        }
 
@@ -839,7 +830,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
                }
        }
 
-       new_playlist = new AudioPlaylist (_session, new_playlist_name, false);
+       new_playlist = PlaylistFactory::create (_session, new_playlist_name, false);
        region_name = new_playlist_name;
 
        /* create a new region from all filesources, keep it private */
@@ -854,7 +845,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
        new_playlist->set_frozen (true);
        region->set_locked (true);
 
-       diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
+       diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
        diskstream->set_record_enabled (false);
 
        _freeze_record.state = Frozen;
@@ -886,7 +877,7 @@ AudioTrack::unfreeze ()
                        }
                }
                
-               _freeze_record.playlist = 0;
+               _freeze_record.playlist.reset ();
        }
 
        _freeze_record.state = UnFrozen;
index b0cd64c8d1f304e04d85af7ddc176ed4b57ddf2e..be070c74e625d50ff36c39e04b4cba8363c7216d 100644 (file)
@@ -49,6 +49,12 @@ using namespace PBD;
 
 gint AudioEngine::m_meter_exit;
 
+static void 
+ardour_jack_error (const char* msg) 
+{
+       error << "JACK: " << msg << endmsg;
+}
+
 AudioEngine::AudioEngine (string client_name) 
        : ports (new Ports)
 {
@@ -80,11 +86,16 @@ AudioEngine::AudioEngine (string client_name)
 
 AudioEngine::~AudioEngine ()
 {
-       if (_running) {
-               jack_client_close (_jack);
+       {
+               Glib::Mutex::Lock tm (_process_lock);
+               session_removed.signal ();
+               
+               if (_running) {
+                       jack_client_close (_jack);
+               }
+               
+               stop_metering_thread ();
        }
-
-       stop_metering_thread ();
 }
 
 void
@@ -152,11 +163,18 @@ AudioEngine::start ()
 }
 
 int
-AudioEngine::stop ()
+AudioEngine::stop (bool forever)
 {
        if (_running) {
                _running = false;
-               jack_deactivate (_jack);
+               if (forever) {
+                       jack_client_t* foo = _jack;
+                       _jack = 0;
+                       jack_client_close (foo);
+                       stop_metering_thread ();
+               } else {
+                       jack_deactivate (_jack);
+               }
                Stopped(); /* EMIT SIGNAL */
        }
 
@@ -164,7 +182,6 @@ AudioEngine::stop ()
 }
 
 
-       
 bool
 AudioEngine::get_sync_offset (nframes_t& offset) const
 {
@@ -196,7 +213,7 @@ void
 AudioEngine::jack_timebase_callback (jack_transport_state_t state, nframes_t nframes,
                                     jack_position_t* pos, int new_position)
 {
-       if (session && session->synced_to_jack()) {
+       if (_jack && session && session->synced_to_jack()) {
                session->jack_timebase_callback (state, nframes, pos, new_position);
        }
 }
@@ -210,7 +227,7 @@ AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t*
 int
 AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
 {
-       if (session) {
+       if (_jack && session) {
                return session->jack_sync_callback (state, pos);
        } else {
                return true;
@@ -220,14 +237,20 @@ AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t*
 int
 AudioEngine::_xrun_callback (void *arg)
 {
-        static_cast<AudioEngine *>(arg)->Xrun (); /* EMIT SIGNAL */
+       AudioEngine* ae = static_cast<AudioEngine*> (arg);
+       if (ae->jack()) {
+               ae->Xrun (); /* EMIT SIGNAL */
+       }
        return 0;
 }
 
 int
 AudioEngine::_graph_order_callback (void *arg)
 {
-       static_cast<AudioEngine *>(arg)->GraphReordered (); /* EMIT SIGNAL */
+       AudioEngine* ae = static_cast<AudioEngine*> (arg);
+       if (ae->jack()) {
+               ae->GraphReordered (); /* EMIT SIGNAL */
+       }
        return 0;
 }
 
@@ -381,9 +404,9 @@ AudioEngine::stop_metering_thread ()
 {
        if (m_meter_thread) {
                g_atomic_int_set (&m_meter_exit, 1);
+               m_meter_thread->join ();
+               m_meter_thread = 0;
        }
-       m_meter_thread->join ();
-       m_meter_thread = 0;
 }
 
 void
@@ -397,8 +420,11 @@ AudioEngine::start_metering_thread ()
 void
 AudioEngine::meter_thread ()
 {
-       while (g_atomic_int_get(&m_meter_exit) != true) {
+       while (true) {
                Glib::usleep (10000); /* 1/100th sec interval */
+               if (g_atomic_int_get(&m_meter_exit)) {
+                       break;
+               }
                IO::update_meters ();
        }
 }
@@ -406,8 +432,26 @@ AudioEngine::meter_thread ()
 void 
 AudioEngine::set_session (Session *s)
 {
+       Glib::Mutex::Lock pl (_process_lock);
+
        if (!session) {
+
                session = s;
+
+               nframes_t blocksize = jack_get_buffer_size (_jack);
+               
+               /* page in as much of the session process code as we
+                  can before we really start running.
+               */
+               
+               session->process (blocksize);
+               session->process (blocksize);
+               session->process (blocksize);
+               session->process (blocksize);
+               session->process (blocksize);
+               session->process (blocksize);
+               session->process (blocksize);
+               session->process (blocksize);
        }
 }
 
@@ -421,16 +465,13 @@ AudioEngine::remove_session ()
                if (session) {
                        session_remove_pending = true;
                        session_removed.wait(_process_lock);
-               } 
+               }
 
        } else {
-
                session = 0;
-
        }
        
        remove_all_ports ();
-
 }
 
 Port *
@@ -468,8 +509,6 @@ AudioEngine::register_input_port (DataType type, const string& portname)
                return newport;
 
        } else {
-
-               _process_lock.unlock();
                throw PortRegistrationFailure();
        }
 
@@ -512,8 +551,6 @@ AudioEngine::register_output_port (DataType type, const string& portname)
                return newport;
                
        } else {
-
-               _process_lock.unlock();
                throw PortRegistrationFailure ();
        }
 
@@ -719,11 +756,9 @@ AudioEngine::get_ports (const string& port_name_pattern, const string& type_name
 void
 AudioEngine::halted (void *arg)
 {
-       AudioEngine *ae = reinterpret_cast<AudioEngine *> (arg);
+       AudioEngine* ae = static_cast<AudioEngine *> (arg);
 
        ae->_running = false;
-       ae->_jack = 0;
-
        ae->_buffer_size = 0;
        ae->_frame_rate = 0;
 
@@ -1006,6 +1041,8 @@ AudioEngine::connect_to_jack (string client_name)
        if (status & JackNameNotUnique) {
                jack_client_name = jack_get_client_name (_jack);
        }
+
+       jack_set_error_function (ardour_jack_error);
        
        return 0;
 }
@@ -1033,9 +1070,7 @@ AudioEngine::disconnect_from_jack ()
                return 0;
        }
 
-       if (jack_client_close (_jack)) {
-               error << _("cannot shutdown connection to JACK") << endmsg;
-       }
+       jack_client_close (_jack);
 
        _buffer_size = 0;
        _frame_rate = 0;
index 16cb990ec22ed70c43d32e6ea207339f913fa8ca..af41094748a4af635ce8169877e8187ec6c8b610 100644 (file)
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <errno.h>
 
 #include <pbd/mountpoint.h>
 #include <pbd/pathscanner.h>
 #include <pbd/stl_delete.h>
 #include <pbd/strsplit.h>
+#include <pbd/enumwriter.h>
 
 #include <sndfile.h>
 
@@ -193,9 +195,7 @@ XMLNode&
 AudioFileSource::get_state ()
 {
        XMLNode& root (AudioSource::get_state());
-       char buf[16];
-       snprintf (buf, sizeof (buf), "0x%x", (int)_flags);
-       root.add_property ("flags", buf);
+       root.add_property ("flags", enum_2_string (_flags));
        return root;
 }
 
@@ -210,9 +210,7 @@ AudioFileSource::set_state (const XMLNode& node)
 
        if ((prop = node.property (X_("flags"))) != 0) {
 
-               int ival;
-               sscanf (prop->value().c_str(), "0x%x", &ival);
-               _flags = Flag (ival);
+               _flags = Flag (string_2_enum (prop->value(), _flags));
 
        } else {
 
@@ -257,7 +255,7 @@ AudioFileSource::mark_streaming_write_completed ()
 
        if (_peaks_built || pending_peak_builds.empty()) {
                _peaks_built = true;
-                PeaksReady (); /* EMIT SIGNAL */
+               PeaksReady (); /* EMIT SIGNAL */
        }
 }
 
@@ -287,9 +285,11 @@ AudioFileSource::move_to_trash (const string trash_dir_name)
           stick it in the `trash_dir_name' directory
           on whichever filesystem it was already on.
        */
-
+       
        newpath = Glib::path_get_dirname (_path);
-       newpath = Glib::path_get_dirname (newpath);
+       newpath = Glib::path_get_dirname (newpath); 
+
+       cerr << "from " << _path << " dead dir looks like " << newpath << endl;
 
        newpath += '/';
        newpath += trash_dir_name;
@@ -522,7 +522,7 @@ AudioFileSource::set_name (string newname, bool destructive)
        }
 
        if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
-               error << string_compose (_("cannot rename audio file for %1 to %2"), _name, newpath) << endmsg;
+               error << string_compose (_("cannot rename audio file %1 to %2"), _name, newpath) << endmsg;
                return -1;
        }
 
@@ -556,3 +556,26 @@ AudioFileSource::setup_peakfile ()
                return 0;
        }
 }
+
+bool
+AudioFileSource::safe_file_extension(string file)
+{
+       return !(file.rfind(".wav") == string::npos &&
+               file.rfind(".aiff")== string::npos &&
+               file.rfind(".aif") == string::npos &&
+               file.rfind(".snd") == string::npos &&
+               file.rfind(".au")  == string::npos &&
+               file.rfind(".raw") == string::npos &&
+               file.rfind(".sf")  == string::npos &&
+               file.rfind(".cdr") == string::npos &&
+               file.rfind(".smp") == string::npos &&
+               file.rfind(".maud")== string::npos &&
+               file.rfind(".vwe") == string::npos &&
+               file.rfind(".paf") == string::npos &&
+#ifdef HAVE_COREAUDIO
+               file.rfind(".mp3") == string::npos &&
+               file.rfind(".aac") == string::npos &&
+               file.rfind(".mp4") == string::npos &&
+#endif // HAVE_COREAUDIO
+               file.rfind(".voc") == string::npos);
+}
index 939f9c02dd083b95198d2e7aa48ba6ec87841e14..8b533deda3922a9e4ff4214de51db53754ea05b9 100644 (file)
@@ -32,6 +32,7 @@
 #include <pbd/basename.h>
 #include <pbd/xml++.h>
 #include <pbd/stacktrace.h>
+#include <pbd/enumwriter.h>
 
 #include <ardour/audioregion.h>
 #include <ardour/session.h>
@@ -482,8 +483,8 @@ AudioRegion::state (bool full)
        char buf2[64];
        LocaleGuard lg (X_("POSIX"));
        
-       snprintf (buf, sizeof (buf), "0x%x", (int) _flags);
-       node.add_property ("flags", buf);
+       node.add_property ("flags", enum_2_string (_flags));
+
        snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
        node.add_property ("scale-gain", buf);
 
@@ -564,7 +565,9 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen
        uint32_t old_flags = _flags;
                
        if ((prop = node.property ("flags")) != 0) {
-               _flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
+               _flags = Flag (string_2_enum (prop->value(), _flags));
+
+               //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
 
                _flags = Flag (_flags & ~Region::LeftOfSplit);
                _flags = Flag (_flags & ~Region::RightOfSplit);
@@ -662,49 +665,49 @@ AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
 
        switch (shape) {
        case Linear:
-               _fade_in.add (0.0, 0.0);
-               _fade_in.add (len, 1.0);
+               _fade_in.fast_simple_add (0.0, 0.0);
+               _fade_in.fast_simple_add (len, 1.0);
                break;
 
        case Fast:
-               _fade_in.add (0, 0);
-               _fade_in.add (len * 0.389401, 0.0333333);
-               _fade_in.add (len * 0.629032, 0.0861111);
-               _fade_in.add (len * 0.829493, 0.233333);
-               _fade_in.add (len * 0.9447, 0.483333);
-               _fade_in.add (len * 0.976959, 0.697222);
-               _fade_in.add (len, 1);
+               _fade_in.fast_simple_add (0, 0);
+               _fade_in.fast_simple_add (len * 0.389401, 0.0333333);
+               _fade_in.fast_simple_add (len * 0.629032, 0.0861111);
+               _fade_in.fast_simple_add (len * 0.829493, 0.233333);
+               _fade_in.fast_simple_add (len * 0.9447, 0.483333);
+               _fade_in.fast_simple_add (len * 0.976959, 0.697222);
+               _fade_in.fast_simple_add (len, 1);
                break;
 
        case Slow:
-               _fade_in.add (0, 0);
-               _fade_in.add (len * 0.0207373, 0.197222);
-               _fade_in.add (len * 0.0645161, 0.525);
-               _fade_in.add (len * 0.152074, 0.802778);
-               _fade_in.add (len * 0.276498, 0.919444);
-               _fade_in.add (len * 0.481567, 0.980556);
-               _fade_in.add (len * 0.767281, 1);
-               _fade_in.add (len, 1);
+               _fade_in.fast_simple_add (0, 0);
+               _fade_in.fast_simple_add (len * 0.0207373, 0.197222);
+               _fade_in.fast_simple_add (len * 0.0645161, 0.525);
+               _fade_in.fast_simple_add (len * 0.152074, 0.802778);
+               _fade_in.fast_simple_add (len * 0.276498, 0.919444);
+               _fade_in.fast_simple_add (len * 0.481567, 0.980556);
+               _fade_in.fast_simple_add (len * 0.767281, 1);
+               _fade_in.fast_simple_add (len, 1);
                break;
 
        case LogA:
-               _fade_in.add (0, 0);
-               _fade_in.add (len * 0.0737327, 0.308333);
-               _fade_in.add (len * 0.246544, 0.658333);
-               _fade_in.add (len * 0.470046, 0.886111);
-               _fade_in.add (len * 0.652074, 0.972222);
-               _fade_in.add (len * 0.771889, 0.988889);
-               _fade_in.add (len, 1);
+               _fade_in.fast_simple_add (0, 0);
+               _fade_in.fast_simple_add (len * 0.0737327, 0.308333);
+               _fade_in.fast_simple_add (len * 0.246544, 0.658333);
+               _fade_in.fast_simple_add (len * 0.470046, 0.886111);
+               _fade_in.fast_simple_add (len * 0.652074, 0.972222);
+               _fade_in.fast_simple_add (len * 0.771889, 0.988889);
+               _fade_in.fast_simple_add (len, 1);
                break;
 
        case LogB:
-               _fade_in.add (0, 0);
-               _fade_in.add (len * 0.304147, 0.0694444);
-               _fade_in.add (len * 0.529954, 0.152778);
-               _fade_in.add (len * 0.725806, 0.333333);
-               _fade_in.add (len * 0.847926, 0.558333);
-               _fade_in.add (len * 0.919355, 0.730556);
-               _fade_in.add (len, 1);
+               _fade_in.fast_simple_add (0, 0);
+               _fade_in.fast_simple_add (len * 0.304147, 0.0694444);
+               _fade_in.fast_simple_add (len * 0.529954, 0.152778);
+               _fade_in.fast_simple_add (len * 0.725806, 0.333333);
+               _fade_in.fast_simple_add (len * 0.847926, 0.558333);
+               _fade_in.fast_simple_add (len * 0.919355, 0.730556);
+               _fade_in.fast_simple_add (len, 1);
                break;
        }
 
@@ -722,47 +725,47 @@ AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
 
        switch (shape) {
        case Fast:
-               _fade_out.add (len * 0, 1);
-               _fade_out.add (len * 0.023041, 0.697222);
-               _fade_out.add (len * 0.0553,   0.483333);
-               _fade_out.add (len * 0.170507, 0.233333);
-               _fade_out.add (len * 0.370968, 0.0861111);
-               _fade_out.add (len * 0.610599, 0.0333333);
-               _fade_out.add (len * 1, 0);
+               _fade_out.fast_simple_add (len * 0, 1);
+               _fade_out.fast_simple_add (len * 0.023041, 0.697222);
+               _fade_out.fast_simple_add (len * 0.0553,   0.483333);
+               _fade_out.fast_simple_add (len * 0.170507, 0.233333);
+               _fade_out.fast_simple_add (len * 0.370968, 0.0861111);
+               _fade_out.fast_simple_add (len * 0.610599, 0.0333333);
+               _fade_out.fast_simple_add (len * 1, 0);
                break;
 
        case LogA:
-               _fade_out.add (len * 0, 1);
-               _fade_out.add (len * 0.228111, 0.988889);
-               _fade_out.add (len * 0.347926, 0.972222);
-               _fade_out.add (len * 0.529954, 0.886111);
-               _fade_out.add (len * 0.753456, 0.658333);
-               _fade_out.add (len * 0.9262673, 0.308333);
-               _fade_out.add (len * 1, 0);
+               _fade_out.fast_simple_add (len * 0, 1);
+               _fade_out.fast_simple_add (len * 0.228111, 0.988889);
+               _fade_out.fast_simple_add (len * 0.347926, 0.972222);
+               _fade_out.fast_simple_add (len * 0.529954, 0.886111);
+               _fade_out.fast_simple_add (len * 0.753456, 0.658333);
+               _fade_out.fast_simple_add (len * 0.9262673, 0.308333);
+               _fade_out.fast_simple_add (len * 1, 0);
                break;
 
        case Slow:
-               _fade_out.add (len * 0, 1);
-               _fade_out.add (len * 0.305556, 1);
-               _fade_out.add (len * 0.548611, 0.991736);
-               _fade_out.add (len * 0.759259, 0.931129);
-               _fade_out.add (len * 0.918981, 0.68595);
-               _fade_out.add (len * 0.976852, 0.22865);
-               _fade_out.add (len * 1, 0);
+               _fade_out.fast_simple_add (len * 0, 1);
+               _fade_out.fast_simple_add (len * 0.305556, 1);
+               _fade_out.fast_simple_add (len * 0.548611, 0.991736);
+               _fade_out.fast_simple_add (len * 0.759259, 0.931129);
+               _fade_out.fast_simple_add (len * 0.918981, 0.68595);
+               _fade_out.fast_simple_add (len * 0.976852, 0.22865);
+               _fade_out.fast_simple_add (len * 1, 0);
                break;
 
        case LogB:
-               _fade_out.add (len * 0, 1);
-               _fade_out.add (len * 0.080645, 0.730556);
-               _fade_out.add (len * 0.277778, 0.289256);
-               _fade_out.add (len * 0.470046, 0.152778);
-               _fade_out.add (len * 0.695853, 0.0694444);
-               _fade_out.add (len * 1, 0);
+               _fade_out.fast_simple_add (len * 0, 1);
+               _fade_out.fast_simple_add (len * 0.080645, 0.730556);
+               _fade_out.fast_simple_add (len * 0.277778, 0.289256);
+               _fade_out.fast_simple_add (len * 0.470046, 0.152778);
+               _fade_out.fast_simple_add (len * 0.695853, 0.0694444);
+               _fade_out.fast_simple_add (len * 1, 0);
                break;
 
        case Linear:
-               _fade_out.add (len * 0, 1);
-               _fade_out.add (len * 1, 0);
+               _fade_out.fast_simple_add (len * 0, 1);
+               _fade_out.fast_simple_add (len * 1, 0);
                break;
        }
 
@@ -851,8 +854,8 @@ AudioRegion::set_default_envelope ()
 {
        _envelope.freeze ();
        _envelope.clear ();
-       _envelope.add (0, 1.0f);
-       _envelope.add (_length, 1.0f);
+       _envelope.fast_simple_add (0, 1.0f);
+       _envelope.fast_simple_add (_length, 1.0f);
        _envelope.thaw ();
 }
 
@@ -996,12 +999,14 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
 void
 AudioRegion::set_scale_amplitude (gain_t g)
 {
+       boost::shared_ptr<Playlist> pl (playlist());
+
        _scale_amplitude = g;
 
        /* tell the diskstream we're in */
-
-       if (_playlist) {
-               _playlist->Modified();
+       
+       if (pl) {
+               pl->Modified();
        }
 
        /* tell everybody else */
@@ -1068,8 +1073,10 @@ AudioRegion::normalize_to (float target_dB)
 
        /* tell the diskstream we're in */
 
-       if (_playlist) {
-               _playlist->Modified();
+       boost::shared_ptr<Playlist> pl (playlist());
+
+       if (pl) {
+               pl->Modified();
        }
 
        /* tell everybody else */
index 93165b7fe4a13fcd0a330189f3fb015f800d6be1..203590a4e124dacfd5316e15599fb7d853838766 100644 (file)
@@ -35,6 +35,7 @@
 #include <pbd/pthread_utils.h>
 
 #include <ardour/audiosource.h>
+#include <ardour/cycle_timer.h>
 
 #include "i18n.h"
 
@@ -59,6 +60,7 @@ AudioSource::AudioSource (Session& s, string name)
        }
 
        _peaks_built = false;
+       _peak_byte_max = 0;
        next_peak_clear_should_notify = true;
        _read_data_count = 0;
        _write_data_count = 0;
@@ -72,6 +74,7 @@ AudioSource::AudioSource (Session& s, const XMLNode& node)
        }
 
        _peaks_built = false;
+       _peak_byte_max = 0;
        next_peak_clear_should_notify = true;
        _read_data_count = 0;
        _write_data_count = 0;
@@ -251,13 +254,13 @@ AudioSource::stop_peak_thread ()
 }
 
 void 
-AudioSource::queue_for_peaks (boost::shared_ptr<AudioSource> source)
+AudioSource::queue_for_peaks (boost::shared_ptr<AudioSource> source, bool notify)
 {
        if (have_peak_thread) {
                
                Glib::Mutex::Lock lm (*pending_peak_sources_lock);
                
-               source->next_peak_clear_should_notify = true;
+               source->next_peak_clear_should_notify = notify;
                
                if (find (pending_peak_sources.begin(),
                          pending_peak_sources.end(),
@@ -384,8 +387,10 @@ AudioSource::initialize_peakfile (bool newfile, string audio_path)
                                
                                if (!err && stat_file.st_mtime > statbuf.st_mtime){
                                        _peaks_built = false;
+                                       _peak_byte_max = 0;
                                } else {
                                        _peaks_built = true;
+                                       _peak_byte_max = statbuf.st_size;
                                }
                        }
                }
@@ -431,7 +436,8 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
        expected_peaks = (cnt / (double) frames_per_peak);
        scale = npeaks/expected_peaks;
 
-#if 0
+#undef DEBUG_READ_PEAKS
+#ifdef DEBUG_READ_PEAKS
        cerr << "======>RP: npeaks = " << npeaks 
             << " start = " << start 
             << " cnt = " << cnt 
@@ -457,8 +463,9 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
        
        if (npeaks == cnt) {
 
+#ifdef DEBUG_READ_PEAKS
                cerr << "RAW DATA\n";
-               
+#endif         
                /* no scaling at all, just get the sample data and duplicate it for
                   both max and min peak values.
                */
@@ -485,12 +492,14 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
 
                /* open, read, close */
 
-               if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
+               if ((peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) {
                        error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
                        return -1;
                }
 
-               // cerr << "DIRECT PEAKS\n";
+#ifdef DEBUG_READ_PEAKS
+               cerr << "DIRECT PEAKS\n";
+#endif
                
                nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
                close (peakfile);
@@ -523,8 +532,9 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
 
        if (scale < 1.0) {
 
-               // cerr << "DOWNSAMPLE\n";
-
+#ifdef DEBUG_READ_PEAKS
+               cerr << "DOWNSAMPLE\n";
+#endif         
                /* the caller wants:
 
                    - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
@@ -535,7 +545,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
                    to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks  
                */
 
-               const uint32_t chunksize = (uint32_t) min (expected_peaks, 4096.0);
+               const uint32_t chunksize = (uint32_t) min (expected_peaks, 65536.0);
                
                staging = new PeakData[chunksize];
                
@@ -556,7 +566,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
 
                /* open ... close during out: handling */
 
-               if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
+               if ((peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) {
                        error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
                        return 0;
                }
@@ -569,10 +579,15 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
                                tnp = min ((_length/frames_per_peak - current_stored_peak), (nframes_t) expected_peaks);
                                to_read = min (chunksize, tnp);
                                
-                               off_t fend = lseek (peakfile, 0, SEEK_END);
+#ifdef DEBUG_READ_PEAKS
+                               cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl;
+#endif
                                
                                if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
                                    != sizeof (PeakData) * to_read) {
+
+                                       off_t fend = lseek (peakfile, 0, SEEK_END);
+                                       
                                        cerr << "AudioSource["
                                             << _name
                                             << "]: cannot read peak data from peakfile ("
@@ -589,11 +604,11 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
                                             << endl;
                                        goto out;
                                }
-
+                               
                                i = 0;
                                stored_peaks_read = nread / sizeof(PeakData);
                        }
-
+                       
                        xmax = -1.0;
                        xmin = 1.0;
 
@@ -624,8 +639,9 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
 
        } else {
                
-               // cerr << "UPSAMPLE\n";
-
+#ifdef DEBUG_READ_PEAKS
+               cerr << "UPSAMPLE\n";
+#endif
                /* the caller wants 
 
                     - less frames-per-peak (more resolution)
@@ -704,6 +720,10 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr
                delete [] raw_staging;
        }
 
+#ifdef DEBUG_READ_PEAKS
+       cerr << "RP DONE\n";
+#endif
+
        return ret;
 }
 
@@ -757,6 +777,7 @@ AudioSource::build_peaks ()
                }
 
                if (pr_signal) {
+                       truncate_peakfile();
                        PeaksReady (); /* EMIT SIGNAL */
                }
        }
@@ -777,6 +798,8 @@ AudioSource::do_build_peak (nframes_t first_frame, nframes_t cnt)
        off_t first_peak_byte;
        int peakfile = -1;
        int ret = -1;
+       off_t target_length;
+       off_t endpos;
 
 #ifdef DEBUG_PEAK_BUILD
        cerr << pthread_self() << ": " << _name << ": building peaks for " << first_frame << " to " << first_frame + cnt - 1 << endl;
@@ -828,11 +851,32 @@ AudioSource::do_build_peak (nframes_t first_frame, nframes_t cnt)
                cnt -= frames_read;
        }
 
+#define BLOCKSIZE (128 * 1024)
+
+       /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
+          the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
+          it does not cause single-extent allocation even for peakfiles of 
+          less than BLOCKSIZE bytes.  only call ftruncate if we'll make the file larger.
+       */
+       endpos = lseek (peakfile, 0, SEEK_END);
+               
+       target_length = BLOCKSIZE * ((first_peak_byte + BLOCKSIZE + 1) / BLOCKSIZE);
+
+       if (endpos < target_length) {
+               // XXX - we really shouldn't be doing this for destructive source peaks
+               ftruncate (peakfile, target_length);
+               //cerr << "do build TRUNC: " << peakpath << "  " << target_length << endl;
+
+               /* error doesn't actually matter though, so continue on without testing */
+       }
+
        if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaki, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaki)) {
                error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
                goto out;
        }
 
+       _peak_byte_max = max(_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaki));
+
        ret = 0;
 
   out:
@@ -850,7 +894,28 @@ AudioSource::build_peaks_from_scratch ()
 
        next_peak_clear_should_notify = true;
        pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
-       queue_for_peaks (shared_from_this());
+       queue_for_peaks (shared_from_this(), true);
+}
+
+void
+AudioSource::truncate_peakfile ()
+{
+       int peakfile = -1;
+
+       /* truncate the peakfile down to its natural length if necessary */
+
+       if ((peakfile = ::open (peakpath.c_str(), O_RDWR)) >= 0) {
+               off_t end = lseek (peakfile, 0, SEEK_END);
+               
+               if (end > _peak_byte_max) {
+                       ftruncate(peakfile, _peak_byte_max);
+                       //cerr << "truncated " << peakpath << " to " << _peak_byte_max << " bytes" << endl;
+               }
+               else {
+                       //cerr << "NOT truncated " << peakpath << " to " << _peak_byte_max << " end " << end << endl;
+               }
+               close (peakfile);
+       }
 }
 
 bool
@@ -872,26 +937,19 @@ AudioSource::file_changed (string path)
 nframes_t
 AudioSource::available_peaks (double zoom_factor) const
 {
-       int peakfile;
        off_t end;
 
        if (zoom_factor < frames_per_peak) {
                return length(); // peak data will come from the audio file
        } 
        
-       /* peak data comes from peakfile */
-
-       if ((peakfile = ::open (peakpath.c_str(), O_RDONLY)) < 0) {
-               error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
-               return 0;
-       }
-
-       { 
-               Glib::Mutex::Lock lm (_lock);
-               end = lseek (peakfile, 0, SEEK_END);
-       }
+       /* peak data comes from peakfile, but the filesize might not represent
+          the valid data due to ftruncate optimizations, so use _peak_byte_max state.
+          XXX - there might be some atomicity issues here, we should probably add a lock,
+          but _peak_byte_max only monotonically increases after initialization.
+       */
 
-       close (peakfile);
+       end = _peak_byte_max;
 
        return (end/sizeof(PeakData)) * frames_per_peak;
 }
index 34cf5637b6a7eeee80574158fd4167283e543aab..7bbc4cd0ba3534a4022ba3b22f63e0b5dfb1d0c4 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <ardour/audio_diskstream.h>
 #include <ardour/audioregion.h>
+#include <ardour/audioengine.h>
 #include <ardour/route.h>
 #include <ardour/session.h>
 #include <ardour/auditioner.h>
@@ -43,8 +44,17 @@ Auditioner::Auditioner (Session& s)
 {
        string left = Config->get_auditioner_output_left();
        string right = Config->get_auditioner_output_right();
+
+       if (left == "default") {
+               left = _session.engine().get_nth_physical_output (DataType::AUDIO, 0);  
+       }
+
+       if (right == "default") {
+               right = _session.engine().get_nth_physical_output (DataType::AUDIO, 1);
+       }
        
        if ((left.length() == 0) && (right.length() == 0)) {
+               warning << _("no outputs available for auditioner - manual connection required") << endmsg;
                return;
        }
 
@@ -77,7 +87,7 @@ AudioPlaylist&
 Auditioner::prepare_playlist ()
 {
        // FIXME auditioner is still audio-only
-       AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
+       boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_diskstream->playlist());
        assert(apl);
 
        apl->clear ();
@@ -184,18 +194,34 @@ Auditioner::play_audition (nframes_t nframes)
 void
 Auditioner::output_changed (IOChange change, void* src)
 {
+       string phys;
+
        if (change & ConnectionsChanged) {
                const char ** connections;
                connections =  output (0)->get_connections ();
                if (connections) {
-                       Config->set_auditioner_output_left (connections[0]);
+                       phys = _session.engine().get_nth_physical_output (DataType::AUDIO, 0);
+                       if (phys != connections[0]) {
+                               Config->set_auditioner_output_left (connections[0]);
+                       } else {
+                               Config->set_auditioner_output_left ("default");
+                       }
                        free (connections);
+               } else {
+                       Config->set_auditioner_output_left ("");
                }
                
                connections = output (1)->get_connections ();
                if (connections) {
-                       Config->set_auditioner_output_right (connections[0]);
+                       phys = _session.engine().get_nth_physical_output (DataType::AUDIO, 1);
+                       if (phys != connections[0]) {
+                               Config->set_auditioner_output_right (connections[0]);
+                       } else {
+                               Config->set_auditioner_output_right ("default");
+                       }
                        free (connections);
+               } else {
+                       Config->set_auditioner_output_right ("");
                }
        }
 }
index 5cc2f50e386d60cf4bde0aebfaef860b76d1d426..af6fffdeb95e026ba4d8c06af734bfbb58eab8e3 100644 (file)
@@ -26,7 +26,7 @@
 #include <algorithm>
 #include <sigc++/bind.h>
 #include <ardour/automation_event.h>
-#include <pbd/convert.h>
+#include <pbd/stacktrace.h>
 
 #include "i18n.h"
 
@@ -37,6 +37,11 @@ using namespace PBD;
 
 sigc::signal<void,AutomationList *> AutomationList::AutomationListCreated;
 
+static bool sort_events_by_time (ControlEvent* a, ControlEvent* b)
+{
+       return a->when < b->when;
+}
+
 #if 0
 static void dumpit (const AutomationList& al, string prefix = "")
 {
@@ -50,7 +55,7 @@ static void dumpit (const AutomationList& al, string prefix = "")
 
 AutomationList::AutomationList (double defval)
 {
-       _frozen = false;
+       _frozen = 0;
        changed_when_thawed = false;
        _state = Off;
        _style = Absolute;
@@ -63,13 +68,14 @@ AutomationList::AutomationList (double defval)
        rt_insertion_point = events.end();
        lookup_cache.left = -1;
        lookup_cache.range.first = events.end();
+       sort_pending = false;
 
         AutomationListCreated(this);
 }
 
 AutomationList::AutomationList (const AutomationList& other)
 {
-       _frozen = false;
+       _frozen = 0;
        changed_when_thawed = false;
        _style = other._style;
        min_yval = other.min_yval;
@@ -82,6 +88,7 @@ AutomationList::AutomationList (const AutomationList& other)
        rt_insertion_point = events.end();
        lookup_cache.left = -1;
        lookup_cache.range.first = events.end();
+       sort_pending = false;
 
        for (const_iterator i = other.events.begin(); i != other.events.end(); ++i) {
                /* we have to use other point_factory() because
@@ -96,7 +103,7 @@ AutomationList::AutomationList (const AutomationList& other)
 
 AutomationList::AutomationList (const AutomationList& other, double start, double end)
 {
-       _frozen = false;
+       _frozen = 0;
        changed_when_thawed = false;
        _style = other._style;
        min_yval = other.min_yval;
@@ -109,6 +116,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl
        rt_insertion_point = events.end();
        lookup_cache.left = -1;
        lookup_cache.range.first = events.end();
+       sort_pending = false;
 
        /* now grab the relevant points, and shift them back if necessary */
 
@@ -129,7 +137,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl
 
 AutomationList::AutomationList (const XMLNode& node)
 {
-       _frozen = false;
+       _frozen = 0;
        changed_when_thawed = false;
        _touching = false;
        min_yval = FLT_MIN;
@@ -141,6 +149,7 @@ AutomationList::AutomationList (const XMLNode& node)
        rt_insertion_point = events.end();
        lookup_cache.left = -1;
        lookup_cache.range.first = events.end();
+       sort_pending = false;
        
        set_state (node);
 
@@ -402,7 +411,7 @@ AutomationList::add (double when, double value)
                }
 
                if (insert) {
-
+                       
                        events.insert (insertion_point, point_factory (when, value));
                        reposition_for_rt_add (0);
 
@@ -512,15 +521,43 @@ AutomationList::move_range (iterator start, iterator end, double xdelta, double
                while (start != end) {
                        (*start)->when += xdelta;
                        (*start)->value += ydelta;
+                       if (isnan ((*start)->value)) {
+                               abort ();
+                       }
                        ++start;
                }
 
+               if (!_frozen) {
+                       events.sort (sort_events_by_time);
+               } else {
+                       sort_pending = true;
+               }
+
                mark_dirty ();
        }
 
        maybe_signal_changed ();
 }
 
+void
+AutomationList::slide (iterator before, double distance)
+{
+       {
+               Glib::Mutex::Lock lm (lock);
+
+               if (before == events.end()) {
+                       return;
+               }
+               
+               while (before != events.end()) {
+                       (*before)->when += distance;
+                       ++before;
+               }
+       }
+
+       maybe_signal_changed ();
+}
+
 void
 AutomationList::modify (iterator iter, double when, double val)
 {
@@ -531,11 +568,23 @@ AutomationList::modify (iterator iter, double when, double val)
 
        {
                Glib::Mutex::Lock lm (lock);
+
                (*iter)->when = when;
                (*iter)->value = val;
+
+               if (isnan (val)) {
+                       abort ();
+               }
+
+               if (!_frozen) {
+                       events.sort (sort_events_by_time);
+               } else {
+                       sort_pending = true;
+               }
+
                mark_dirty ();
        }
-       
+
        maybe_signal_changed ();
 }
 
@@ -576,13 +625,31 @@ AutomationList::control_points_adjacent (double xval)
 void
 AutomationList::freeze ()
 {
-       _frozen = true;
+       _frozen++;
 }
 
 void
 AutomationList::thaw ()
 {
-       _frozen = false;
+       if (_frozen == 0) {
+               PBD::stacktrace (cerr);
+               fatal << string_compose (_("programming error: %1"), X_("AutomationList::thaw() called while not frozen")) << endmsg;
+               /*NOTREACHED*/
+       }
+
+       if (--_frozen > 0) {
+               return;
+       }
+
+       {
+               Glib::Mutex::Lock lm (lock);
+
+               if (sort_pending) {
+                       events.sort (sort_events_by_time);
+                       sort_pending = false;
+               }
+       }
+
        if (changed_when_thawed) {
                StateChanged(); /* EMIT SIGNAL */
        }
@@ -1240,6 +1307,7 @@ AutomationList::deserialize_events (const XMLNode& node)
        }
 
        thaw ();
+
        return 0;
 }
 
@@ -1271,6 +1339,7 @@ AutomationList::set_state (const XMLNode& node)
                jack_nframes_t x;
                double y;
                
+               freeze ();
                clear ();
                
                for (i = elist.begin(); i != elist.end(); ++i) {
@@ -1287,9 +1356,11 @@ AutomationList::set_state (const XMLNode& node)
                        }
                        y = atof (prop->value().c_str());
                        
-                       add (x, y);
+                       fast_simple_add (x, y);
                }
                
+               thaw ();
+
                return 0;
        }
 
@@ -1345,7 +1416,7 @@ AutomationList::set_state (const XMLNode& node)
                        deserialize_events (*(*niter));
                }
        }
-       
+
        return 0;
 }
 
index e84e92fa26beabc64d5fe3a976ccef2aa0265379..eb3d8794472932bb0f195ddefb89027c4d4d3838 100644 (file)
@@ -25,7 +25,6 @@
 #include <pbd/xml++.h>
 
 #include <ardour/ardour.h>
-#include <ardour/audio_library.h>
 #include <ardour/configuration.h>
 #include <ardour/audio_diskstream.h>
 #include <ardour/destructive_filesource.h>
@@ -172,7 +171,6 @@ Configuration::get_state ()
        }
        
        root->add_child_nocopy (ControlProtocolManager::instance().get_state());
-       root->add_child_nocopy (Library->get_state());
        
        return *root;
 }
@@ -235,8 +233,6 @@ Configuration::set_state (const XMLNode& root)
 
                } else if (node->name() == ControlProtocolManager::state_node_name) {
                        _control_protocol_state = new XMLNode (*node);
-               } else if (node->name() == AudioLibrary::state_node_name) {
-                       Library->set_state (*node);
                }
        }
 
index a7152547472d6cdb516d7064ed897c7c2f18bb10..de177d0e3d91c115e2a2854b94f3e6c0a7a9a337 100644 (file)
@@ -154,9 +154,11 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi)
 
 static bool protocol_filter (const string& str, void *arg)
 {
-       /* Not a dotfile, has a prefix before a period, suffix is "so" */
+       /* Not a dotfile, has a prefix before a period, suffix is "so", or "dylib" */
        
-       return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
+       return str[0] != '.' 
+         && ((str.length() > 3 && str.find (".so") == (str.length() - 3))
+             || (str.length() > 6 && str.find (".dylib") == (str.length() - 6)));
 }
 
 void
index 739ea1cc0e5cc89654c1bd99fefefd6ddad0e733..fd2fced83c473ffb1c445e716ea5bea4e39c2d5e 100644 (file)
@@ -759,7 +759,7 @@ Crossfade::set_state (const XMLNode& node)
        
         /* fade out */
        
-       _fade_in.freeze ();
+       _fade_out.freeze ();
        _fade_out.clear ();
 
        children = fo->children();
index 5f6f3956cfd5b5154720733c8c26ae829ed20b34..09c5b75b86b1111532e0e06d245e43734996621f 100644 (file)
@@ -71,14 +71,12 @@ sigc::signal<void>                Diskstream::DiskUnderrun;
 Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
        : _name (name)
        , _session (sess)
-       , _playlist(NULL)
 {
        init (flag);
 }
        
 Diskstream::Diskstream (Session& sess, const XMLNode& node)
        : _session (sess)
-       , _playlist(NULL)
 {
        init (Recordable);
 }
@@ -131,7 +129,7 @@ Diskstream::~Diskstream ()
        //Glib::Mutex::Lock lm (state_lock);
 
        if (_playlist)
-               _playlist->unref ();
+               _playlist->release ();
 }
 
 void
@@ -305,7 +303,7 @@ Diskstream::set_speed (double sp)
 }
 
 int
-Diskstream::use_playlist (Playlist* playlist)
+Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
 {
        {
                Glib::Mutex::Lock lm (state_lock);
@@ -314,26 +312,30 @@ Diskstream::use_playlist (Playlist* playlist)
                        return 0;
                }
 
-               plstate_connection.disconnect();
                plmod_connection.disconnect ();
                plgone_connection.disconnect ();
 
                if (_playlist) {
-                       _playlist->unref();
+                       _playlist->release();
                }
                        
                _playlist = playlist;
-               _playlist->ref();
+               _playlist->use();
 
                if (!in_set_state && recordable()) {
                        reset_write_sources (false);
                }
                
                plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified));
-               plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), _playlist));
+               plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), boost::weak_ptr<Playlist>(_playlist)));
        }
 
-       if (!overwrite_queued) {
+       /* don't do this if we've already asked for it *or* if we are setting up
+          the diskstream for the very first time - the input changed handling will
+          take care of the buffer refill.
+       */
+
+       if (!overwrite_queued && !(_session.state_of_the_state() & Session::CannotSave)) {
                _session.request_overwrite_buffer (this);
                overwrite_queued = true;
        }
@@ -360,14 +362,21 @@ Diskstream::playlist_modified ()
 }
 
 void
-Diskstream::playlist_deleted (Playlist* pl)
+Diskstream::playlist_deleted (boost::weak_ptr<Playlist> wpl)
 {
-       /* this catches an ordering issue with session destruction. playlists 
-          are destroyed before diskstreams. we have to invalidate any handles
-          we have to the playlist.
-       */
+       boost::shared_ptr<Playlist> pl (wpl.lock());
+
+       if (pl == _playlist) {
 
-       _playlist = 0;
+               /* this catches an ordering issue with session destruction. playlists 
+                  are destroyed before diskstreams. we have to invalidate any handles
+                  we have to the playlist.
+               */
+               
+               if (_playlist) {
+                       _playlist.reset ();
+               } 
+       }
 }
 
 int
diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc
new file mode 100644 (file)
index 0000000..0460df4
--- /dev/null
@@ -0,0 +1,327 @@
+#include <pbd/enumwriter.h>
+
+#include <ardour/types.h>
+#include <ardour/session.h>
+#include <ardour/location.h>
+#include <ardour/audiofilesource.h>
+#include <ardour/diskstream.h>
+#include <ardour/audioregion.h>
+#include <ardour/route_group.h>
+#include <ardour/panner.h>
+#include <ardour/track.h>
+
+using namespace std;
+using namespace PBD;
+using namespace ARDOUR;
+
+void
+setup_enum_writer ()
+{
+       EnumWriter* enum_writer = new EnumWriter();
+       vector<int> i;
+       vector<string> s;
+
+       OverlapType _OverlapType;
+       AlignStyle _AlignStyle;
+       MeterPoint _MeterPoint;
+       TrackMode _TrackMode;
+       MeterFalloff _MeterFalloff;
+       MeterHold _MeterHold;
+       EditMode _EditMode;
+       RegionPoint _RegionPoint;
+       Placement _Placement;
+       MonitorModel _MonitorModel;
+       CrossfadeModel _CrossfadeModel;
+       LayerModel _LayerModel;
+       SoloModel _SoloModel;
+       SampleFormat _SampleFormat;
+       HeaderFormat _HeaderFormat;
+       PluginType _PluginType;
+       SlaveSource _SlaveSource;
+       ShuttleBehaviour _ShuttleBehaviour;
+       ShuttleUnits _ShuttleUnits;
+       mute_type _mute_type;
+       Session::RecordState _Session_RecordState;
+       Session::Event::Type _Session_Event_Type;
+       SmpteFormat _Session_SmpteFormat;
+       Session::PullupFormat _Session_PullupFormat;
+       AudioRegion::FadeShape _AudioRegion_FadeShape;
+       Panner::LinkDirection _Panner_LinkDirection;
+       IOChange _IOChange;
+       AutomationType _AutomationType;
+       AutoState _AutoState;
+       AutoStyle _AutoStyle;
+       AutoConnectOption _AutoConnectOption;
+       Session::StateOfTheState _Session_StateOfTheState;
+       Route::Flag _Route_Flag;
+       AudioFileSource::Flag _AudioFileSource_Flag;
+       Diskstream::Flag _Diskstream_Flag;
+       Location::Flags _Location_Flags;
+       RouteGroup::Flag _RouteGroup_Flag;
+       Region::Flag _Region_Flag;
+       Track::FreezeState _Track_FreezeState;
+
+#define REGISTER(e) enum_writer->register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
+#define REGISTER_BITS(e) enum_writer->register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
+#define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e)
+#define REGISTER_CLASS_ENUM(t,e) i.push_back (t::e); s.push_back (#e)
+
+       REGISTER_ENUM (NoChange);
+       REGISTER_ENUM (ConfigurationChanged);
+       REGISTER_ENUM (ConnectionsChanged);
+       REGISTER_BITS (_IOChange);
+
+       REGISTER_ENUM (OverlapNone);
+       REGISTER_ENUM (OverlapInternal);
+       REGISTER_ENUM (OverlapStart);
+       REGISTER_ENUM (OverlapEnd);
+       REGISTER_ENUM (OverlapExternal);
+       REGISTER (_OverlapType);
+       
+       REGISTER_ENUM (GainAutomation);
+       REGISTER_ENUM (PanAutomation);
+       REGISTER_ENUM (PluginAutomation);
+       REGISTER_ENUM (SoloAutomation);
+       REGISTER_ENUM (MuteAutomation);
+       REGISTER_BITS (_AutomationType);
+
+       REGISTER_ENUM (Off);
+       REGISTER_ENUM (Write);
+       REGISTER_ENUM (Touch);
+       REGISTER_ENUM (Play);
+       REGISTER_BITS (_AutoState);
+
+       REGISTER_ENUM (Absolute);
+       REGISTER_ENUM (Trim);
+       REGISTER_BITS (_AutoStyle);
+
+       REGISTER_ENUM (CaptureTime);
+       REGISTER_ENUM (ExistingMaterial);       
+       REGISTER (_AlignStyle);
+
+       REGISTER_ENUM (MeterInput);
+       REGISTER_ENUM (MeterPreFader);
+       REGISTER_ENUM (MeterPostFader); 
+       REGISTER (_MeterPoint);
+
+       REGISTER_ENUM (Normal);
+       REGISTER_ENUM (Destructive);
+       REGISTER (_TrackMode);
+
+       REGISTER_ENUM (MeterFalloffOff);
+       REGISTER_ENUM (MeterFalloffSlowest);
+       REGISTER_ENUM (MeterFalloffSlow);
+       REGISTER_ENUM (MeterFalloffMedium);
+       REGISTER_ENUM (MeterFalloffFast);
+       REGISTER_ENUM (MeterFalloffFaster);
+       REGISTER_ENUM (MeterFalloffFastest);
+       REGISTER (_MeterFalloff);
+       
+       REGISTER_ENUM (MeterHoldOff);
+       REGISTER_ENUM (MeterHoldShort);
+       REGISTER_ENUM (MeterHoldMedium);
+       REGISTER_ENUM (MeterHoldLong);
+       REGISTER (_MeterHold);
+
+       REGISTER_ENUM (Slide);
+       REGISTER_ENUM (Splice); 
+       REGISTER (_EditMode);
+
+       REGISTER_ENUM (Start);
+       REGISTER_ENUM (End);
+       REGISTER_ENUM (SyncPoint);      
+       REGISTER (_RegionPoint);
+
+
+       REGISTER_ENUM (PreFader);
+       REGISTER_ENUM (PostFader);
+       REGISTER (_Placement);
+
+       REGISTER_ENUM (HardwareMonitoring);
+       REGISTER_ENUM (SoftwareMonitoring);
+       REGISTER_ENUM (ExternalMonitoring);
+       REGISTER (_MonitorModel);
+
+       REGISTER_ENUM (FullCrossfade);
+       REGISTER_ENUM (ShortCrossfade);
+       REGISTER (_CrossfadeModel);
+
+       REGISTER_ENUM (LaterHigher);
+       REGISTER_ENUM (MoveAddHigher);
+       REGISTER_ENUM (AddHigher);      
+       REGISTER (_LayerModel);
+
+       REGISTER_ENUM (InverseMute);
+       REGISTER_ENUM (SoloBus);        
+       REGISTER (_SoloModel);
+
+       REGISTER_ENUM (AutoConnectPhysical);
+       REGISTER_ENUM (AutoConnectMaster);
+       REGISTER_BITS (_AutoConnectOption);
+
+       REGISTER_ENUM (FormatFloat);
+       REGISTER_ENUM (FormatInt24);
+       REGISTER (_SampleFormat);
+
+       REGISTER_ENUM (BWF);
+       REGISTER_ENUM (WAVE);
+       REGISTER_ENUM (WAVE64);
+       REGISTER_ENUM (CAF);
+       REGISTER_ENUM (AIFF);
+       REGISTER_ENUM (iXML);
+       REGISTER_ENUM (RF64);   
+       REGISTER (_HeaderFormat);
+
+       REGISTER_ENUM (AudioUnit);
+       REGISTER_ENUM (LADSPA);
+       REGISTER_ENUM (VST);
+       REGISTER (_PluginType);
+
+       REGISTER_ENUM (None);
+       REGISTER_ENUM (MTC);
+       REGISTER_ENUM (JACK);   
+       REGISTER (_SlaveSource);
+
+       REGISTER_ENUM (Sprung);
+       REGISTER_ENUM (Wheel);  
+       REGISTER (_ShuttleBehaviour);
+
+       REGISTER_ENUM (Percentage);
+       REGISTER_ENUM (Semitones);      
+       REGISTER (_ShuttleUnits);
+
+       REGISTER_CLASS_ENUM (Session, Disabled);
+       REGISTER_CLASS_ENUM (Session, Enabled);
+       REGISTER_CLASS_ENUM (Session, Recording);
+       REGISTER (_Session_RecordState);
+
+       REGISTER_CLASS_ENUM (Session::Event, SetTransportSpeed);
+       REGISTER_CLASS_ENUM (Session::Event, SetDiskstreamSpeed);
+       REGISTER_CLASS_ENUM (Session::Event, Locate);
+       REGISTER_CLASS_ENUM (Session::Event, LocateRoll);
+       REGISTER_CLASS_ENUM (Session::Event, SetLoop);
+       REGISTER_CLASS_ENUM (Session::Event, PunchIn);
+       REGISTER_CLASS_ENUM (Session::Event, PunchOut);
+       REGISTER_CLASS_ENUM (Session::Event, RangeStop);
+       REGISTER_CLASS_ENUM (Session::Event, RangeLocate);
+       REGISTER_CLASS_ENUM (Session::Event, Overwrite);
+       REGISTER_CLASS_ENUM (Session::Event, SetSlaveSource);
+       REGISTER_CLASS_ENUM (Session::Event, Audition);
+       REGISTER_CLASS_ENUM (Session::Event, InputConfigurationChange);
+       REGISTER_CLASS_ENUM (Session::Event, SetAudioRange);
+       REGISTER_CLASS_ENUM (Session::Event, SetPlayRange);
+       REGISTER_CLASS_ENUM (Session::Event, StopOnce);
+       REGISTER_CLASS_ENUM (Session::Event, AutoLoop);
+       REGISTER (_Session_Event_Type);
+
+       REGISTER_CLASS_ENUM (Session, Clean);
+       REGISTER_CLASS_ENUM (Session, Dirty);
+       REGISTER_CLASS_ENUM (Session, CannotSave);
+       REGISTER_CLASS_ENUM (Session, Deletion);
+       REGISTER_CLASS_ENUM (Session, InitialConnecting);
+       REGISTER_CLASS_ENUM (Session, Loading);
+       REGISTER_CLASS_ENUM (Session, InCleanup);
+       REGISTER_BITS (_Session_StateOfTheState);
+
+       REGISTER_ENUM (smpte_23976);
+       REGISTER_ENUM (smpte_24);
+       REGISTER_ENUM (smpte_24976);
+       REGISTER_ENUM (smpte_25);
+       REGISTER_ENUM (smpte_2997);
+       REGISTER_ENUM (smpte_2997drop);
+       REGISTER_ENUM (smpte_30);
+       REGISTER_ENUM (smpte_30drop);
+       REGISTER_ENUM (smpte_5994);
+       REGISTER_ENUM (smpte_60);
+       REGISTER (_Session_SmpteFormat);
+
+       REGISTER_CLASS_ENUM (Session, pullup_Plus4Plus1);
+       REGISTER_CLASS_ENUM (Session, pullup_Plus4);
+       REGISTER_CLASS_ENUM (Session, pullup_Plus4Minus1);
+       REGISTER_CLASS_ENUM (Session, pullup_Plus1);
+       REGISTER_CLASS_ENUM (Session, pullup_None);
+       REGISTER_CLASS_ENUM (Session, pullup_Minus1);
+       REGISTER_CLASS_ENUM (Session, pullup_Minus4Plus1);
+       REGISTER_CLASS_ENUM (Session, pullup_Minus4);
+       REGISTER_CLASS_ENUM (Session, pullup_Minus4Minus1);
+       REGISTER (_Session_PullupFormat);
+
+       REGISTER_ENUM (PRE_FADER);
+       REGISTER_ENUM (POST_FADER);
+       REGISTER_ENUM (CONTROL_OUTS);
+       REGISTER_ENUM (MAIN_OUTS);
+       REGISTER (_mute_type);
+
+       REGISTER_CLASS_ENUM (Route, Hidden);
+       REGISTER_CLASS_ENUM (Route, MasterOut);
+       REGISTER_CLASS_ENUM (Route, ControlOut);
+       REGISTER_BITS (_Route_Flag);
+
+       REGISTER_CLASS_ENUM (AudioFileSource, Writable);
+       REGISTER_CLASS_ENUM (AudioFileSource, CanRename);
+       REGISTER_CLASS_ENUM (AudioFileSource, Broadcast);
+       REGISTER_CLASS_ENUM (AudioFileSource, Removable);
+       REGISTER_CLASS_ENUM (AudioFileSource, RemovableIfEmpty);
+       REGISTER_CLASS_ENUM (AudioFileSource, RemoveAtDestroy);
+       REGISTER_CLASS_ENUM (AudioFileSource, NoPeakFile);
+       REGISTER_CLASS_ENUM (AudioFileSource, Destructive);
+       REGISTER_BITS (_AudioFileSource_Flag);
+
+       REGISTER_CLASS_ENUM (AudioRegion, Linear);
+       REGISTER_CLASS_ENUM (AudioRegion, Fast);
+       REGISTER_CLASS_ENUM (AudioRegion, Slow);
+       REGISTER_CLASS_ENUM (AudioRegion, LogA);
+       REGISTER_CLASS_ENUM (AudioRegion, LogB);
+       REGISTER (_AudioRegion_FadeShape);
+
+       REGISTER_CLASS_ENUM (Diskstream, Recordable);
+       REGISTER_CLASS_ENUM (Diskstream, Hidden);
+       REGISTER_CLASS_ENUM (Diskstream, Destructive);
+       REGISTER_BITS (_Diskstream_Flag);
+
+       REGISTER_CLASS_ENUM (Location, IsMark);
+       REGISTER_CLASS_ENUM (Location, IsAutoPunch);
+       REGISTER_CLASS_ENUM (Location, IsAutoLoop);
+       REGISTER_CLASS_ENUM (Location, IsHidden);
+       REGISTER_CLASS_ENUM (Location, IsCDMarker);
+       REGISTER_CLASS_ENUM (Location, IsEnd);
+       REGISTER_CLASS_ENUM (Location, IsRangeMarker);
+       REGISTER_CLASS_ENUM (Location, IsStart);
+       REGISTER_BITS (_Location_Flags);
+
+
+       REGISTER_CLASS_ENUM (RouteGroup, Relative);
+       REGISTER_CLASS_ENUM (RouteGroup, Active);
+       REGISTER_CLASS_ENUM (RouteGroup, Hidden);
+       REGISTER_BITS (_RouteGroup_Flag);
+
+       REGISTER_CLASS_ENUM (Panner, SameDirection);
+       REGISTER_CLASS_ENUM (Panner, OppositeDirection);
+       REGISTER (_Panner_LinkDirection);
+
+       REGISTER_CLASS_ENUM (Region, Muted);
+       REGISTER_CLASS_ENUM (Region, Opaque);
+       REGISTER_CLASS_ENUM (Region, EnvelopeActive);
+       REGISTER_CLASS_ENUM (Region, DefaultFadeIn);
+       REGISTER_CLASS_ENUM (Region, DefaultFadeOut);
+       REGISTER_CLASS_ENUM (Region, Locked);
+       REGISTER_CLASS_ENUM (Region, Automatic);
+       REGISTER_CLASS_ENUM (Region, WholeFile);
+       REGISTER_CLASS_ENUM (Region, FadeIn);
+       REGISTER_CLASS_ENUM (Region, FadeOut);
+       REGISTER_CLASS_ENUM (Region, Copied);
+       REGISTER_CLASS_ENUM (Region, Import);
+       REGISTER_CLASS_ENUM (Region, External);
+       REGISTER_CLASS_ENUM (Region, SyncMarked);
+       REGISTER_CLASS_ENUM (Region, LeftOfSplit);
+       REGISTER_CLASS_ENUM (Region, RightOfSplit);
+       REGISTER_CLASS_ENUM (Region, Hidden);
+       REGISTER_CLASS_ENUM (Region, DoNotSaveState);
+       REGISTER_BITS (_Region_Flag);
+
+       REGISTER_CLASS_ENUM (Track, NoFreeze);
+       REGISTER_CLASS_ENUM (Track, Frozen);
+       REGISTER_CLASS_ENUM (Track, UnFrozen);
+       REGISTER (_Track_FreezeState);
+       
+}
index f92660470c0b92583224ef8fa6ce724cd75dc3b3..515d9e1c2f0eac01e394af0db708e07f83f6db5e 100644 (file)
@@ -191,42 +191,11 @@ setup_midi (AudioEngine& engine   )
 
        return 0;
 }
-
-int
-ARDOUR::init (ARDOUR::AudioEngine& engine, bool use_vst, bool try_optimization)
+       
+void
+setup_hardware_optimization (bool try_optimization)
 {
-       bool generic_mix_functions = true;
-
-       (void) bindtextdomain(PACKAGE, LOCALEDIR);
-
-       PBD::ID::init ();
-
-       lrdf_init();
-       Library = new AudioLibrary;
-
-       Config = new Configuration;
-
-       if (Config->load_state ()) {
-               return -1;
-       }
-
-       Config->set_use_vst (use_vst);
-
-       if (setup_midi (engine)) {
-               return -1;
-       }
-    
-#ifdef HAVE_LIBLO
-       if (setup_osc ()) {
-               return -1;
-       }
-#endif
-
-#ifdef VST_SUPPORT
-       if (Config->get_use_vst() && fst_init ()) {
-               return -1;
-       }
-#endif
+        bool generic_mix_functions = true;
 
        if (try_optimization) {
 
@@ -261,7 +230,7 @@ ARDOUR::init (ARDOUR::AudioEngine& engine, bool use_vst, bool try_optimization)
 #endif /* USE_X86_64_ASM */
                
                if (use_sse) {
-                       cerr << "Enabling SSE optimized routines" << endl;
+                       info << "Using SSE optimized routines" << endmsg;
        
                        // SSE SET
                        Session::compute_peak                   = x86_sse_compute_peak;
@@ -301,6 +270,47 @@ ARDOUR::init (ARDOUR::AudioEngine& engine, bool use_vst, bool try_optimization)
                
                info << "No H/W specific optimizations in use" << endmsg;
        }
+}
+
+int
+ARDOUR::init (ARDOUR::AudioEngine& engine, bool use_vst, bool try_optimization)
+{
+       extern void setup_enum_writer ();
+
+       (void) bindtextdomain(PACKAGE, LOCALEDIR);
+
+       PBD::ID::init ();
+       
+       setup_enum_writer ();
+
+       lrdf_init();
+       Library = new AudioLibrary;
+
+       Config = new Configuration;
+
+       if (Config->load_state ()) {
+               return -1;
+       }
+
+       Config->set_use_vst (use_vst);
+
+       if (setup_midi (engine)) {
+               return -1;
+       }
+    
+#ifdef HAVE_LIBLO
+       if (setup_osc ()) {
+               return -1;
+       }
+#endif
+
+#ifdef VST_SUPPORT
+       if (Config->get_use_vst() && fst_init ()) {
+               return -1;
+       }
+#endif
+
+       setup_hardware_optimization (try_optimization);
 
        /* singleton - first object is "it" */
        new PluginManager ();
@@ -393,8 +403,14 @@ ARDOUR::get_system_data_path ()
 {
        string path;
 
-       path += DATA_DIR;
-       path += "/ardour2/";
+       char *envvar;
+
+       if ((envvar = getenv ("ARDOUR_DATA_PATH")) != 0) {
+               path = envvar;
+       } else {
+               path += DATA_DIR;
+               path += "/ardour2/";
+       }
        
        return path;
 }
@@ -403,9 +419,14 @@ string
 ARDOUR::get_system_module_path ()
 {
        string path;
+       char *envvar;
 
-       path += MODULE_DIR;
-       path += "/ardour2/";
+       if ((envvar = getenv ("ARDOUR_MODULE_PATH")) != 0) {
+               path = envvar;
+       } else {
+               path += MODULE_DIR;
+               path += "/ardour2/";
+       }
        
        return path;
 }
@@ -602,4 +623,5 @@ std::istream& operator>>(std::istream& o, CrossfadeModel& var) { return int_to_t
 std::istream& operator>>(std::istream& o, SlaveSource& var) { return int_to_type<SlaveSource> (o, var); }
 std::istream& operator>>(std::istream& o, ShuttleBehaviour& var) { return int_to_type<ShuttleBehaviour> (o, var); }
 std::istream& operator>>(std::istream& o, ShuttleUnits& var) { return int_to_type<ShuttleUnits> (o, var); }
+std::istream& operator>>(std::istream& o, SmpteFormat& var) { return int_to_type<SmpteFormat> (o, var); }
 
index f16a6e7d8c28f3fe990860e9d7377254f2aad7f5..4466c40a321d9d74a75ee92466e6bc9f7d9669ec 100644 (file)
@@ -74,22 +74,22 @@ Session::import_audiofile (import_status& status)
        
        status.new_regions.clear ();
 
-       if ((in = sf_open (status.pathname.c_str(), SFM_READ, &info)) == 0) {
-               error << string_compose(_("Import: cannot open input sound file \"%1\""), status.pathname) << endmsg;
+       if ((in = sf_open (status.paths.front().c_str(), SFM_READ, &info)) == 0) {
+               error << string_compose(_("Import: cannot open input sound file \"%1\""), status.paths.front()) << endmsg;
                return -1;
        } else {
                if ((uint32_t) info.samplerate != frame_rate()) {
                        sf_close(in);
                        status.doing_what = _("resampling audio");
                        // resample to session frame_rate
-                       if (sample_rate_convert(status, status.pathname, tmp_convert_file)) {
+                       if (sample_rate_convert(status, status.paths.front(), tmp_convert_file)) {
                                if ((in = sf_open (tmp_convert_file.c_str(), SFM_READ, &info)) == 0) {
                                        error << string_compose(_("Import: cannot open converted sound file \"%1\""), tmp_convert_file) << endmsg;
                                        return -1;
                                }
                        } else if (!status.cancel){
                                // error
-                               error << string_compose(_("Import: error while resampling sound file \"%1\""), status.pathname) << endmsg;
+                               error << string_compose(_("Import: error while resampling sound file \"%1\""), status.paths.front()) << endmsg;
                                return -1;
                        } else {
                                // canceled
@@ -103,7 +103,7 @@ Session::import_audiofile (import_status& status)
        }
 
        sounds_dir = discover_best_sound_dir ();
-       basepath = PBD::basename_nosuffix (status.pathname);
+       basepath = PBD::basename_nosuffix (status.paths.front());
 
        for (n = 0; n < info.channels; ++n) {
 
@@ -112,14 +112,14 @@ Session::import_audiofile (import_status& status)
                do {
                        if (info.channels == 2) {
                                if (n == 0) {
-                                       snprintf (buf, sizeof(buf), "%s%s-L.wav", sounds_dir.c_str(), basepath.c_str());
+                                       snprintf (buf, sizeof(buf), "%s/%s-L.wav", sounds_dir.c_str(), basepath.c_str());
                                } else {
-                                       snprintf (buf, sizeof(buf), "%s%s-R.wav", sounds_dir.c_str(), basepath.c_str());
+                                       snprintf (buf, sizeof(buf), "%s/%s-R.wav", sounds_dir.c_str(), basepath.c_str());
                                }
                        } else if (info.channels > 1) {
-                               snprintf (buf, sizeof(buf), "%s%s-c%lu.wav", sounds_dir.c_str(), basepath.c_str(), n+1);
+                               snprintf (buf, sizeof(buf), "%s/%s-c%lu.wav", sounds_dir.c_str(), basepath.c_str(), n+1);
                        } else {
-                               snprintf (buf, sizeof(buf), "%s%s.wav", sounds_dir.c_str(), basepath.c_str());
+                               snprintf (buf, sizeof(buf), "%s/%s.wav", sounds_dir.c_str(), basepath.c_str());
                        }
 
                        if (::access (buf, F_OK) == 0) {
@@ -217,8 +217,13 @@ Session::import_audiofile (import_status& status)
                        sources.push_back(newfiles[n]);
                }
 
-               boost::shared_ptr<AudioRegion> r (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, 0, newfiles[0]->length(), region_name_from_path (Glib::path_get_basename (basepath)),
-                                                                                                                  0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile))));
+               bool strip_paired_suffixes = (newfiles.size() > 1);
+
+               boost::shared_ptr<AudioRegion> r (boost::dynamic_pointer_cast<AudioRegion> 
+                                                 (RegionFactory::create (sources, 0, 
+                                                                         newfiles[0]->length(), 
+                                                                         region_name_from_path (basepath, strip_paired_suffixes),
+                                                                         0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile))));
                
                status.new_regions.push_back (r);
 
@@ -231,11 +236,14 @@ Session::import_audiofile (import_status& status)
 
                        /* The sources had zero-length when created, which means that the Session
                           did not bother to create whole-file AudioRegions for them. Do it now.
+
+                          Note: leave any trailing paired indicators from the file names as part
+                          of the region name.
                        */
                
                        status.new_regions.push_back (boost::dynamic_pointer_cast<AudioRegion> 
                                                      (RegionFactory::create (boost::static_pointer_cast<Source> (newfiles[n]), 0, newfiles[n]->length(), 
-                                                                             region_name_from_path (Glib::path_get_basename (newfiles[n]->name())),
+                                                                             region_name_from_path (newfiles[n]->name(), false),
                                                                              0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile | AudioRegion::Import))));
                }
        }
index 034b043763022a5ed9a087111d0caeff870d1b3e..d109642fd4f7d0de30fe921091e0cf4a5537a6fc 100644 (file)
@@ -50,21 +50,15 @@ using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
-/* ********** FIXME: TYPE ************** */
-/* Inserts are still definitely audio only */
-
-Insert::Insert(Session& s, Placement p)
-       : Redirect (s, s.next_insert_name(), p)
-{
-}
-
-Insert::Insert(Session& s, Placement p, int imin, int imax, int omin, int omax)
-       : Redirect (s, s.next_insert_name(), p, imin, imax, omin, omax)
+/* ********** FIXME: TYPE **************
+ * Inserts are still definitely audio only */
+Insert::Insert(Session& s, string name, Placement p)
+       : Redirect (s, name, p)
 {
 }
 
-Insert::Insert(Session& s, string name, Placement p)
-       : Redirect (s, name, p)
+Insert::Insert(Session& s, string name, Placement p, int imin, int imax, int omin, int omax)
+       : Redirect (s, name, p, imin, imax, omin, omax)
 {
 }
 
@@ -624,14 +618,8 @@ PluginInsert::state (bool full)
                XMLNode* child = new XMLNode("port");
                snprintf(buf, sizeof(buf), "%" PRIu32, *x);
                child->add_property("number", string(buf));
-               
-               if (full) {
-                       snprintf(buf, sizeof(buf), "0x%x", automation_list (*x).automation_state ());
-               } else {
-                       snprintf(buf, sizeof(buf), "0x%x", ARDOUR::Off);
-               }
-               child->add_property("auto", string(buf));
-               
+
+               child->add_child_nocopy (automation_list (*x).state (full));
                autonode->add_child_nocopy (*child);
        }
 
@@ -735,43 +723,62 @@ PluginInsert::set_state(const XMLNode& node)
        /* look for port automation node */
        
        for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-               if ((*niter)->name() == port_automation_node_name) {
-                       XMLNodeList cnodes;
-                       XMLProperty *cprop;
-                       XMLNodeConstIterator iter;
-                       XMLNode *child;
-                       const char *port;
-                       uint32_t port_id;
-
-                       cnodes = (*niter)->children ("port");
-       
-                       for(iter = cnodes.begin(); iter != cnodes.end(); ++iter){
-                               
-                               child = *iter;
-                               
-                               if ((cprop = child->property("number")) != 0) {
-                                       port = cprop->value().c_str();
-                               } else {
-                                       warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
-                                       continue;
-                               }
 
-                               sscanf (port, "%" PRIu32, &port_id);
+               if ((*niter)->name() != port_automation_node_name) {
+                       continue;
+               }
 
-                               if (port_id >= _plugins[0]->parameter_count()) {
-                                       warning << _("PluginInsert: Auto: port id out of range") << endmsg;
-                                       continue;
-                               }
-                               
+               XMLNodeList cnodes;
+               XMLProperty *cprop;
+               XMLNodeConstIterator iter;
+               XMLNode *child;
+               const char *port;
+               uint32_t port_id;
+               
+               cnodes = (*niter)->children ("port");
+               
+               for(iter = cnodes.begin(); iter != cnodes.end(); ++iter){
+                       
+                       child = *iter;
+                       
+                       if ((cprop = child->property("number")) != 0) {
+                               port = cprop->value().c_str();
+                       } else {
+                               warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
+                               continue;
+                       }
+                       
+                       sscanf (port, "%" PRIu32, &port_id);
+                       
+                       if (port_id >= _plugins[0]->parameter_count()) {
+                               warning << _("PluginInsert: Auto: port id out of range") << endmsg;
+                               continue;
+                       }
+
+                       if (!child->children().empty()) {
+                               automation_list (port_id).set_state (*child->children().front());
+                       } else {
                                if ((cprop = child->property("auto")) != 0) {
+                                       
+                                       /* old school */
+
                                        int x;
                                        sscanf (cprop->value().c_str(), "0x%x", &x);
                                        automation_list (port_id).set_automation_state (AutoState (x));
+
+                               } else {
+                                       
+                                       /* missing */
+                                       
+                                       automation_list (port_id).set_automation_state (Off);
                                }
                        }
-                       
-                       break;
+
                }
+
+               /* done */
+
+               break;
        } 
 
        if (niter == nlist.end()) {
@@ -830,14 +837,14 @@ PluginInsert::type ()
  ***************************************************************/
 
 PortInsert::PortInsert (Session& s, Placement p)
-       : Insert (s, p, 1, -1, 1, -1)
+       : Insert (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
 {
        init ();
        RedirectCreated (this); /* EMIT SIGNAL */
 }
 
 PortInsert::PortInsert (const PortInsert& other)
-       : Insert (other._session, other.placement(), 1, -1, 1, -1)
+       : Insert (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1)
 {
        init ();
        RedirectCreated (this); /* EMIT SIGNAL */
@@ -900,9 +907,11 @@ XMLNode&
 PortInsert::state (bool full)
 {
        XMLNode *node = new XMLNode("Insert");
-
+       char buf[32];
        node->add_child_nocopy (Redirect::state(full)); 
-       node->add_property("type", "port");
+       node->add_property ("type", "port");
+       snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
+       node->add_property ("bitslot", buf);
 
        return *node;
 }
@@ -925,6 +934,13 @@ PortInsert::set_state(const XMLNode& node)
                return -1;
        }
 
+       if ((prop = node.property ("bitslot")) == 0) {
+               bitslot = _session.next_insert_id();
+       } else {
+               sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
+               _session.mark_insert_id (bitslot);
+       }
+
        for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
                if ((*niter)->name() == Redirect::state_node_name) {
                        Redirect::set_state (**niter);
index 60e7ec3f4283aa5f4bad4339fb963042e675f4a6..7ed6158b850aff72d751c9468077727762bf92f8 100644 (file)
@@ -55,6 +55,7 @@ extern "C" int isnan (double);
 extern "C" int isinf (double);
 #endif
 
+#define BLOCK_PROCESS_CALLBACK() Glib::Mutex::Lock em (_session.engine().process_lock())
 
 using namespace std;
 using namespace ARDOUR;
@@ -339,7 +340,7 @@ IO::disconnect_input (Port* our_port, string other_port, void* src)
        }
 
        { 
-               Glib::Mutex::Lock em (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                
                {
                        Glib::Mutex::Lock lm (io_lock);
@@ -375,7 +376,7 @@ IO::connect_input (Port* our_port, string other_port, void* src)
        }
 
        {
-               Glib::Mutex::Lock em(_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                
                {
                        Glib::Mutex::Lock lm (io_lock);
@@ -409,7 +410,7 @@ IO::disconnect_output (Port* our_port, string other_port, void* src)
        }
 
        {
-               Glib::Mutex::Lock em(_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                
                {
                        Glib::Mutex::Lock lm (io_lock);
@@ -444,7 +445,8 @@ IO::connect_output (Port* our_port, string other_port, void* src)
        }
 
        {
-               Glib::Mutex::Lock em(_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
+
                
                {
                        Glib::Mutex::Lock lm (io_lock);
@@ -503,7 +505,8 @@ IO::remove_output_port (Port* port, void* src)
        IOChange change (NoChange);
 
        {
-               Glib::Mutex::Lock em(_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
+
                
                {
                        Glib::Mutex::Lock lm (io_lock);
@@ -554,7 +557,8 @@ IO::add_output_port (string destination, void* src, DataType type)
                type = _default_type;
 
        {
-               Glib::Mutex::Lock em(_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
+
                
                { 
                        Glib::Mutex::Lock lm (io_lock);
@@ -605,7 +609,8 @@ IO::remove_input_port (Port* port, void* src)
        IOChange change (NoChange);
 
        {
-               Glib::Mutex::Lock em(_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
+
                
                {
                        Glib::Mutex::Lock lm (io_lock);
@@ -657,7 +662,7 @@ IO::add_input_port (string source, void* src, DataType type)
                type = _default_type;
 
        {
-               Glib::Mutex::Lock em (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                
                { 
                        Glib::Mutex::Lock lm (io_lock);
@@ -707,7 +712,7 @@ int
 IO::disconnect_inputs (void* src)
 {
        { 
-               Glib::Mutex::Lock em (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                
                {
                        Glib::Mutex::Lock lm (io_lock);
@@ -729,7 +734,7 @@ int
 IO::disconnect_outputs (void* src)
 {
        {
-               Glib::Mutex::Lock em (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                
                {
                        Glib::Mutex::Lock lm (io_lock);
@@ -793,7 +798,7 @@ IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
                                setup_peak_meters ();
                                reset_panner ();
                                /* pass it on */
-                               throw err;
+                               throw AudioEngine::PortRegistrationFailure();
                        }
 
                        _inputs.add (input_port);
@@ -845,7 +850,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
        }
 
        {
-               Glib::Mutex::Lock em (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                Glib::Mutex::Lock lm (io_lock);
 
                Port* port;
@@ -904,12 +909,12 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
                                                return -1;
                                        }
                                }
-
+                               
                                catch (AudioEngine::PortRegistrationFailure& err) {
                                        setup_peak_meters ();
                                        reset_panner ();
                                        /* pass it on */
-                                       throw err;
+                                       throw AudioEngine::PortRegistrationFailure();
                                }
 
                                _inputs.add (port);
@@ -941,7 +946,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
                                        setup_peak_meters ();
                                        reset_panner ();
                                        /* pass it on */
-                                       throw err;
+                                       throw AudioEngine::PortRegistrationFailure ();
                                }
 
                                _outputs.add (port);
@@ -998,7 +1003,7 @@ IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src)
        }
 
        if (lockit) {
-               Glib::Mutex::Lock em (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                Glib::Mutex::Lock im (io_lock);
                changed = ensure_inputs_locked (count, clear, src);
        } else {
@@ -1095,7 +1100,7 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
        /* XXX caller should hold io_lock, but generally doesn't */
 
        if (lockit) {
-               Glib::Mutex::Lock em (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                Glib::Mutex::Lock im (io_lock);
                changed = ensure_outputs_locked (count, clear, src);
        } else {
@@ -1906,7 +1911,7 @@ IO::use_input_connection (Connection& c, void* src)
        uint32_t limit;
 
        {
-               Glib::Mutex::Lock lm (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                Glib::Mutex::Lock lm2 (io_lock);
                
                limit = c.nports();
@@ -1985,7 +1990,7 @@ IO::use_output_connection (Connection& c, void* src)
        uint32_t limit; 
 
        {
-               Glib::Mutex::Lock lm (_session.engine().process_lock());
+               BLOCK_PROCESS_CALLBACK ();
                Glib::Mutex::Lock lm2 (io_lock);
 
                limit = c.nports();
index e09a59d42f607ddb99ba8683225681e1ce7bcdfc..bec87e5dd6b6d41863304aa3e5e0183720bdde81 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <pbd/stl_delete.h>
 #include <pbd/xml++.h>
+#include <pbd/enumwriter.h>
 
 #include <ardour/location.h>
 #include <ardour/session.h>
@@ -35,6 +36,8 @@
 
 #include "i18n.h"
 
+#define SUFFIX_MAX 32
+
 using namespace std;
 using namespace ARDOUR;
 using namespace sigc;
@@ -217,12 +220,12 @@ Location::set_flag_internal (bool yn, Flags flag)
 {
        if (yn) {
                if (!(_flags & flag)) {
-                       _flags |= flag;
+                       _flags = Flags (_flags | flag);
                        return true;
                }
        } else {
                if (_flags & flag) {
-                       _flags &= ~flag;
+                       _flags = Flags (_flags & ~flag);
                        return true;
                }
        }
@@ -273,8 +276,7 @@ Location::get_state (void)
        node->add_property ("start", buf);
        snprintf (buf, sizeof (buf), "%u", end());
        node->add_property ("end", buf);
-       snprintf (buf, sizeof (buf), "%" PRIu32, (uint32_t) _flags);
-       node->add_property ("flags", buf);
+       node->add_property ("flags", enum_2_string (_flags));
 
        return *node;
 }
@@ -327,14 +329,12 @@ Location::set_state (const XMLNode& node)
                
        _end = atoi (prop->value().c_str());
                
-       _flags = 0;
-               
        if ((prop = node.property ("flags")) == 0) {
                  error << _("XML node for Location has no flags information") << endmsg; 
                  return -1;
        }
                
-       _flags = Flags (atoi (prop->value().c_str()));
+       _flags = Flags (string_2_enum (prop->value(), _flags));
 
        for (cd_iter = cd_list.begin(); cd_iter != cd_list.end(); ++cd_iter) {
                  
@@ -403,6 +403,40 @@ Locations::set_current (Location *loc, bool want_lock)
        return ret;
 }
 
+int
+Locations::next_available_name(string& result,string base)
+{
+       LocationList::iterator i;
+       Location* location;
+       string temp;
+       string::size_type l;
+       int suffix;
+       char buf[32];
+       bool available[SUFFIX_MAX+1];
+
+       result = base;
+       for (int k=1; k<SUFFIX_MAX; k++) {
+               available[k] = true;
+       }
+       l = base.length();
+       for (i = locations.begin(); i != locations.end(); ++i) {
+               location =* i;
+               temp = location->name();
+               if (l && !temp.find(base,0)) {
+                       suffix = atoi(temp.substr(l,3));
+                       if (suffix) available[suffix] = false;
+               }
+       }
+       for (int k=1; k<=SUFFIX_MAX; k++) {
+               if (available[k]) { 
+                       snprintf (buf, 31, "%d", k);
+                       result += buf;
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 int
 Locations::set_current_unlocked (Location *loc)
 {
index 1ce610d13c21efacf4377781c3247b791747cf32..66e0a98dd3da27b7493883738f9eebe52bca7a46 100644 (file)
@@ -56,6 +56,14 @@ PeakMeter::reset ()
        }
 }
 
+void
+PeakMeter::reset_max ()
+{
+       for (size_t i = 0; i < _max_peak_power.size(); ++i) {
+               _max_peak_power[i] = -INFINITY;
+       }
+}
+
 void
 PeakMeter::setup (const ChanCount& in)
 {
@@ -68,11 +76,13 @@ PeakMeter::setup (const ChanCount& in)
 
        while (_peak_power.size() < limit) {
                _peak_power.push_back (0);
-               _visible_peak_power.push_back (0);
+               _visible_peak_power.push_back (minus_infinity());
+               _max_peak_power.push_back (minus_infinity());
        }
 
        assert(_peak_power.size() == limit);
        assert(_visible_peak_power.size() == limit);
+       assert(_max_peak_power.size() == limit);
 }
 
 /** To be driven by the Meter signal from IO.
@@ -102,6 +112,10 @@ PeakMeter::meter ()
                        new_peak = minus_infinity();
                }
                
+               /* update max peak */
+               
+               _max_peak_power[n] = std::max (new_peak, _max_peak_power[n]);
+               
                if (Config->get_meter_falloff() == 0.0f || new_peak > _visible_peak_power[n]) {
                        _visible_peak_power[n] = new_peak;
                } else {
index b1ec7da965c57e40c92a799b8bcea291339ef87b..f3de2147916bca04ce31a6a98a2b66963b477919 100644 (file)
@@ -14,8 +14,6 @@
     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: diskstream.cc 567 2006-06-07 14:54:12Z trutkin $
 */
 
 #include <fstream>
@@ -36,6 +34,7 @@
 #include <glibmm/thread.h>
 #include <pbd/xml++.h>
 #include <pbd/memento_command.h>
+#include <pbd/enumwriter.h>
 
 #include <ardour/ardour.h>
 #include <ardour/audioengine.h>
@@ -47,6 +46,7 @@
 #include <ardour/send.h>
 #include <ardour/region_factory.h>
 #include <ardour/midi_playlist.h>
+#include <ardour/playlist_factory.h>
 #include <ardour/cycle_timer.h>
 #include <ardour/midi_region.h>
 #include <ardour/midi_port.h>
@@ -220,16 +220,14 @@ MidiDiskstream::get_input_sources ()
 int
 MidiDiskstream::find_and_use_playlist (const string& name)
 {
-       Playlist* pl;
-       MidiPlaylist* playlist;
+       boost::shared_ptr<MidiPlaylist> playlist;
                
-       if ((pl = _session.playlist_by_name (name)) == 0) {
-               playlist = new MidiPlaylist(_session, name);
-               pl = playlist;
+       if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlist_by_name (name))) == 0) {
+               playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (_session, name));
        }
 
-       if ((playlist = dynamic_cast<MidiPlaylist*> (pl)) == 0) {
-               error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
+       if (!playlist) {
+               error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't an midi playlist"), name) << endmsg;
                return -1;
        }
 
@@ -237,18 +235,20 @@ MidiDiskstream::find_and_use_playlist (const string& name)
 }
 
 int
-MidiDiskstream::use_playlist (Playlist* playlist)
-{
-       assert(dynamic_cast<MidiPlaylist*>(playlist));
+MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
+{      
+       assert(boost::dynamic_pointer_cast<MidiPlaylist>(playlist));
 
-       return Diskstream::use_playlist(playlist);
+       Diskstream::use_playlist(playlist);
+
+       return 0;
 }
 
 int
 MidiDiskstream::use_new_playlist ()
-{
+{      
        string newname;
-       MidiPlaylist* playlist;
+       boost::shared_ptr<MidiPlaylist> playlist;
 
        if (!in_set_state && destructive()) {
                return 0;
@@ -260,9 +260,11 @@ MidiDiskstream::use_new_playlist ()
                newname = Playlist::bump_name (_name, _session);
        }
 
-       if ((playlist = new MidiPlaylist (_session, newname, hidden())) != 0) {
+       if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (_session, newname, hidden()))) != 0) {
+               
                playlist->set_orig_diskstream_id (id());
                return use_playlist (playlist);
+
        } else { 
                return -1;
        }
@@ -271,6 +273,8 @@ MidiDiskstream::use_new_playlist ()
 int
 MidiDiskstream::use_copy_playlist ()
 {
+       assert(midi_playlist());
+
        if (destructive()) {
                return 0;
        }
@@ -281,11 +285,11 @@ MidiDiskstream::use_copy_playlist ()
        }
 
        string newname;
-       MidiPlaylist* playlist;
+       boost::shared_ptr<MidiPlaylist> playlist;
 
        newname = Playlist::bump_name (_playlist->name(), _session);
        
-       if ((playlist  = new MidiPlaylist (*midi_playlist(), newname)) != 0) {
+       if ((playlist  = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
                playlist->set_orig_diskstream_id (id());
                return use_playlist (playlist);
        } else { 
@@ -1039,6 +1043,8 @@ MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_cap
 
                }
 
+               string whole_file_region_name;
+               whole_file_region_name = region_name_from_path (_write_source->name(), true);
                /* Register a new region with the Session that
                   describes the entire source. Do this first
                   so that any sub-regions will obviously be
@@ -1048,7 +1054,7 @@ MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_cap
                        assert(_write_source);
                        
                        boost::shared_ptr<Region> rx (RegionFactory::create (srcs, _write_source->last_capture_start_frame(), total_capture, 
-                                                                            region_name_from_path (_write_source->name())
+                                                                            whole_file_region_name
                                                                             0, Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
 
                        region = boost::dynamic_pointer_cast<MidiRegion> (rx);
@@ -1289,7 +1295,7 @@ MidiDiskstream::set_state (const XMLNode& node)
        }
 
        if ((prop = node.property ("flags")) != 0) {
-               _flags = strtol (prop->value().c_str(), 0, 0);
+               _flags = Flag (string_2_enum (prop->value(), _flags));
        }
 
        if ((prop = node.property ("channels")) != 0) {
index b2318bbe96257e74ef3135f288fe155902093259..0352e1e910e0e0b86afd7d723fceadc1b9b36014 100644 (file)
@@ -49,22 +49,14 @@ MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden)
        in_set_state = true;
        set_state (node);
        in_set_state = false;
-
-       if (!hidden) {
-               PlaylistCreated (this); /* EMIT SIGNAL */
-       }
 }
 
 MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden)
                : Playlist (session, name, DataType::MIDI, hidden)
 {
-       if (!hidden) {
-               PlaylistCreated (this); /* EMIT SIGNAL */
-       }
-
 }
 
-MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, string name, bool hidden)
+MidiPlaylist::MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, string name, bool hidden)
                : Playlist (other, name, hidden)
 {
        throw; // nope
@@ -106,12 +98,9 @@ MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, string name, bool hidden)
                in_n++;
        }
 */
-       if (!hidden) {
-               PlaylistCreated (this); /* EMIT SIGNAL */
-       }
 }
 
-MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, jack_nframes_t start, jack_nframes_t dur, string name, bool hidden)
+MidiPlaylist::MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, jack_nframes_t start, jack_nframes_t dur, string name, bool hidden)
                : Playlist (other, start, dur, name, hidden)
 {
        /* this constructor does NOT notify others (session) */
index f4d1912061b1d9bc1faa3e93747f099974518c9c..d7ce12d411f52bd1656cd5b614ae985f06f11927 100644 (file)
@@ -61,7 +61,7 @@ MidiPort::cycle_start (jack_nframes_t nframes)
        void* jack_buffer = jack_port_get_buffer(_port, nframes);
 
        const jack_nframes_t event_count
-               = jack_midi_port_get_info(jack_buffer, nframes)->event_count;
+               = jack_midi_get_event_count(jack_buffer, nframes);
 
        assert(event_count < _buffer.capacity());
 
index a18d0c20ce8c038fcc2315725b94a1533dac9e6f..26441203a366ae0de44ce34062b8374c07822d92 100644 (file)
@@ -303,11 +303,11 @@ MidiTrack::set_state_part_two ()
                _freeze_record.insert_info.clear ();
                
                if ((prop = fnode->property (X_("playlist"))) != 0) {
-                       Playlist* pl = _session.playlist_by_name (prop->value());
+                       boost::shared_ptr<Playlist> pl = _session.playlist_by_name (prop->value());
                        if (pl) {
-                               _freeze_record.playlist = dynamic_cast<MidiPlaylist*> (pl);
+                               _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
                        } else {
-                               _freeze_record.playlist = 0;
+                               _freeze_record.playlist.reset();
                                _freeze_record.state = NoFreeze;
                        return;
                        }
index 605d7cae13109346695f54525363e730bede9bf9..ecce09692f20ccc8d7a224247688775ba46fd08e 100644 (file)
@@ -33,12 +33,14 @@ using namespace PBD;
 
 sigc::signal<void,NamedSelection*> NamedSelection::NamedSelectionCreated;
 
-NamedSelection::NamedSelection (string n, list<Playlist*>& l) 
+typedef std::list<boost::shared_ptr<Playlist> > PlaylistList;
+
+NamedSelection::NamedSelection (string n, PlaylistList& l) 
        : name (n)
 {
        playlists = l;
-       for (list<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
-               (*i)->ref();
+       for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               (*i)->use();
        }
        NamedSelectionCreated (this);
 }
@@ -65,13 +67,13 @@ NamedSelection::NamedSelection (Session& session, const XMLNode& node)
 
                const XMLNode* plnode;
                string playlist_name;
-               Playlist* playlist;
+               boost::shared_ptr<Playlist> playlist;
 
                plnode = *niter;
 
                if ((property = plnode->property ("name")) != 0) {
                        if ((playlist = session.playlist_by_name (property->value())) != 0) {
-                               playlist->ref();
+                               playlist->use();
                                playlists.push_back (playlist);
                        } else {
                                warning << string_compose (_("Chunk %1 uses an unknown playlist \"%2\""), name, property->value()) << endmsg;
@@ -87,8 +89,8 @@ NamedSelection::NamedSelection (Session& session, const XMLNode& node)
 
 NamedSelection::~NamedSelection ()
 {
-       for (list<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
-               (*i)->unref();
+       for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               (*i)->release();
        }
 }
 
@@ -107,7 +109,7 @@ NamedSelection::get_state ()
        root->add_property ("name", name);
        child = root->add_child ("Playlists");
 
-       for (list<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+       for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
                XMLNode* plnode = new XMLNode ("Playlist");
 
                plnode->add_property ("name", (*i)->name());
index ee8e100e4aa3931fbe95a7fcfde4e3a1acc387f7..c69bd844022acc765ec94f9e27b2ed3bb9883697 100644 (file)
@@ -36,6 +36,7 @@
 #include <pbd/error.h>
 #include <pbd/failed_constructor.h>
 #include <pbd/xml++.h>
+#include <pbd/enumwriter.h>
 
 #include <ardour/session.h>
 #include <ardour/panner.h>
@@ -1068,8 +1069,7 @@ Panner::state (bool full)
        char buf[32];
 
        root->add_property (X_("linked"), (_linked ? "yes" : "no"));
-       snprintf (buf, sizeof (buf), "%d", _link_direction);
-       root->add_property (X_("link_direction"), buf);
+       root->add_property (X_("link_direction"), enum_2_string (_link_direction));
        root->add_property (X_("bypassed"), (bypassed() ? "yes" : "no"));
 
        /* add each output */
@@ -1113,8 +1113,8 @@ Panner::set_state (const XMLNode& node)
        }
 
        if ((prop = node.property (X_("link_direction"))) != 0) {
-               sscanf (prop->value().c_str(), "%d", &i);
-               set_link_direction ((LinkDirection) (i));
+               LinkDirection ld; /* here to provide type information */
+               set_link_direction (LinkDirection (string_2_enum (prop->value(), ld)));
        }
 
        nlist = node.children();
index d439cf126536fc2a0361cd6e9b48bd6d46fe0b3c..2becdc19b42b2ff4b083da571f17c6a0fb38ffb7 100644 (file)
@@ -36,6 +36,7 @@
 #include <ardour/session.h>
 #include <ardour/region.h>
 #include <ardour/region_factory.h>
+#include <ardour/playlist_factory.h>
 
 #include "i18n.h"
 
@@ -43,14 +44,12 @@ using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
-sigc::signal<void,Playlist*> Playlist::PlaylistCreated;
-
 struct ShowMeTheList {
-    ShowMeTheList (Playlist *pl, const string& n) : playlist (pl), name (n) {}
+    ShowMeTheList (boost::shared_ptr<Playlist> pl, const string& n) : playlist (pl), name (n) {}
     ~ShowMeTheList () { 
            cerr << ">>>>" << name << endl; playlist->dump(); cerr << "<<<<" << name << endl << endl; 
     };
-    Playlist *playlist;
+    boost::shared_ptr<Playlist> playlist;
     string name;
 };
 
@@ -91,51 +90,52 @@ Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide
        init (hide);
        _name = "unnamed"; /* reset by set_state */
 
-       /* derived class calls set_state() */
+       /* set state called by derived class */
 }
 
-Playlist::Playlist (const Playlist& other, string namestr, bool hide)
-       : _name (namestr), _session (other._session), _type(other._type), _orig_diskstream_id(other._orig_diskstream_id)
+Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, bool hide)
+       : _name (namestr), _session (other->_session), _type(other->_type), _orig_diskstream_id(other->_orig_diskstream_id)
 {
        init (hide);
 
        RegionList tmp;
-       other.copy_regions (tmp);
+       other->copy_regions (tmp);
        
        in_set_state++;
 
        for (list<boost::shared_ptr<Region> >::iterator x = tmp.begin(); x != tmp.end(); ++x) {
-               add_region_internal( (*x), (*x)->position() );
+               add_region_internal( (*x), (*x)->position());
        }
 
        in_set_state--;
 
-       _splicing  = other._splicing;
-       _nudging   = other._nudging;
-       _edit_mode = other._edit_mode;
+       _splicing  = other->_splicing;
+       _nudging   = other->_nudging;
+       _edit_mode = other->_edit_mode;
 
        in_set_state = 0;
        in_flush = false;
        in_partition = false;
        subcnt = 0;
        _read_data_count = 0;
-       _frozen = other._frozen;
-       
-       layer_op_counter = other.layer_op_counter;
-       freeze_length = other.freeze_length;
+       _frozen = other->_frozen;
        
+       layer_op_counter = other->layer_op_counter;
+       freeze_length = other->freeze_length;
 }
 
-Playlist::Playlist (const Playlist& other, nframes_t start, nframes_t cnt, string str, bool hide)
-       : _name (str), _session (other._session), _type(other._type), _orig_diskstream_id(other._orig_diskstream_id)
+Playlist::Playlist (boost::shared_ptr<const Playlist> other, nframes_t start, nframes_t cnt, string str, bool hide)
+       : _name (str), _session (other->_session), _type(other->_type), _orig_diskstream_id(other->_orig_diskstream_id)
 {
-       RegionLock rlock2 (&((Playlist&)other));
-       
+       RegionLock rlock2 (const_cast<Playlist*> (other.get()));
+
        nframes_t end = start + cnt - 1;
 
        init (hide);
 
-       for (RegionList::const_iterator i = other.regions.begin(); i != other.regions.end(); i++) {
+       in_set_state++;
+
+       for (RegionList::const_iterator i = other->regions.begin(); i != other->regions.end(); i++) {
 
                boost::shared_ptr<Region> region;
                boost::shared_ptr<Region> new_region;
@@ -182,32 +182,30 @@ Playlist::Playlist (const Playlist& other, nframes_t start, nframes_t cnt, strin
 
                new_region = RegionFactory::RegionFactory::create (region, offset, len, new_name, region->layer(), region->flags());
 
-               add_region_internal (new_region, position, true);
+               add_region_internal (new_region, position);
        }
        
+       in_set_state--;
+
        /* this constructor does NOT notify others (session) */
 }
 
 void
-Playlist::ref ()
+Playlist::use ()
 {
        ++_refcnt;
-       InUse (this, true); /* EMIT SIGNAL */
+       InUse (true); /* EMIT SIGNAL */
 }
 
 void
-Playlist::unref ()
+Playlist::release ()
 {
        if (_refcnt > 0) {
                _refcnt--; 
        }
+
        if (_refcnt == 0) {
-               InUse (this, false); /* EMIT SIGNAL */
-               
-               if (_hidden) {
-                       /* nobody knows we exist */
-                       delete this;
-               }
+               InUse (false); /* EMIT SIGNAL */
        }
 }
 
@@ -266,7 +264,7 @@ Playlist::~Playlist ()
                RegionLock rl (this);
 
                for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) {
-                       (*i)->set_playlist (0);
+                       (*i)->set_playlist (boost::shared_ptr<Playlist>());
                }
        }
 
@@ -411,12 +409,8 @@ Playlist::flush_notifications ()
                        timestamp_layer_op (*r);
                }
                pending_length = true;
-               n++;
-       }
-
-       for (RegionList::iterator r = pending_bounds.begin(); r != pending_bounds.end(); ++r) {
                dependent_checks_needed.insert (*r);
-               /* don't increment n again - its the same list */
+               n++;
        }
 
        for (s = pending_adds.begin(); s != pending_adds.end(); ++s) {
@@ -424,10 +418,6 @@ Playlist::flush_notifications ()
                n++;
        }
 
-       for (s = dependent_checks_needed.begin(); s != dependent_checks_needed.end(); ++s) {
-               check_dependents (*s, false);
-       }
-
        for (s = pending_removes.begin(); s != pending_removes.end(); ++s) {
                remove_dependents (*s);
                n++;
@@ -448,6 +438,10 @@ Playlist::flush_notifications ()
                Modified (); /* EMIT SIGNAL */
        }
 
+       for (s = dependent_checks_needed.begin(); s != dependent_checks_needed.end(); ++s) {
+               check_dependents (*s, false);
+       }
+
        pending_adds.clear ();
        pending_removes.clear ();
        pending_bounds.clear ();
@@ -471,7 +465,7 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
        nframes_t pos = position;
        
        if (itimes >= 1) {
-               add_region_internal (region, pos, true);
+               add_region_internal (region, pos);
                pos += region->length();
                --itimes;
        }
@@ -488,7 +482,7 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
 
        for (int i = 0; i < itimes; ++i) {
                boost::shared_ptr<Region> copy = RegionFactory::create (region);
-               add_region_internal (copy, pos, true);
+               add_region_internal (copy, pos);
                pos += region->length();
        }
        
@@ -497,12 +491,24 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
                string name;
                _session.region_name (name, region->name(), false);
                boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
-               add_region_internal (sub, pos, true);
+               add_region_internal (sub, pos);
+       }
+}
+
+void
+Playlist::set_region_ownership ()
+{
+       RegionLock rl (this);
+       RegionList::iterator i;
+       boost::weak_ptr<Playlist> pl (shared_from_this());
+
+       for (i = regions.begin(); i != regions.end(); ++i) {
+               (*i)->set_playlist (pl);
        }
 }
 
 void
-Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t position, bool delay_sort)
+Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t position)
 {
        RegionSortByPosition cmp;
        nframes_t old_length = 0;
@@ -511,7 +517,11 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t posit
                 old_length = _get_maximum_extent();
        }
 
-       region->set_playlist (this);
+       if (!in_set_state) {
+               boost::shared_ptr<Playlist> foo (shared_from_this());
+               region->set_playlist (boost::weak_ptr<Playlist>(foo));
+       }
+
        region->set_position (position, this);
 
        timestamp_layer_op (region);
@@ -564,7 +574,7 @@ Playlist::remove_region (boost::shared_ptr<Region> region)
 }
 
 int
-Playlist::remove_region_internal (boost::shared_ptr<Region>region, bool delay_sort)
+Playlist::remove_region_internal (boost::shared_ptr<Region>region)
 {
        RegionList::iterator i;
        nframes_t old_length = 0;
@@ -698,7 +708,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
                                _session.region_name (new_name, current->name(), false);
                                region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
                                                       regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit));
-                               add_region_internal (region, start, true);
+                               add_region_internal (region, start);
                                new_regions.push_back (region);
                        }
                        
@@ -708,7 +718,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
                        region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name, 
                                               regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
 
-                       add_region_internal (region, end, true);
+                       add_region_internal (region, end);
                        new_regions.push_back (region);
 
                        /* "front" ***** */
@@ -737,7 +747,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
                                _session.region_name (new_name, current->name(), false);
                                region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
                                                       Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
-                               add_region_internal (region, start, true);
+                               add_region_internal (region, start);
                                new_regions.push_back (region);
                        }
 
@@ -771,7 +781,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
                                 _session.region_name (new_name, current->name(), false);
                                 region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
                                                        regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
-                                add_region_internal (region, pos1, true);
+                                add_region_internal (region, pos1);
                                 new_regions.push_back (region);
                        } 
                        
@@ -813,20 +823,19 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
        }
 }
 
-Playlist*
-Playlist::cut_copy (Playlist* (Playlist::*pmf)(nframes_t, nframes_t,bool), list<AudioRange>& ranges, bool result_is_hidden)
+boost::shared_ptr<Playlist>
+Playlist::cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t,bool), list<AudioRange>& ranges, bool result_is_hidden)
 {
-       Playlist* ret;
-       Playlist* pl;
+       boost::shared_ptr<Playlist> ret;
+       boost::shared_ptr<Playlist> pl;
        nframes_t start;
 
        if (ranges.empty()) {
-               return 0;
+               return boost::shared_ptr<Playlist>();
        }
 
        start = ranges.front().start;
 
-
        for (list<AudioRange>::iterator i = ranges.begin(); i != ranges.end(); ++i) {
 
                pl = (this->*pmf)((*i).start, (*i).length(), result_is_hidden);
@@ -840,39 +849,31 @@ Playlist::cut_copy (Playlist* (Playlist::*pmf)(nframes_t, nframes_t,bool), list<
                           chopped.
                        */
 
-                       ret->paste (*pl, (*i).start - start, 1.0f);
-                       delete pl;
+                       ret->paste (pl, (*i).start - start, 1.0f);
                }
        }
 
-       if (ret) {
-               /* manually notify session of new playlist here
-                  because the playlists were constructed without notifying 
-               */
-               PlaylistCreated (ret);
-       }
-       
        return ret;
 }
 
-Playlist*
+boost::shared_ptr<Playlist>
 Playlist::cut (list<AudioRange>& ranges, bool result_is_hidden)
 {
-       Playlist* (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::cut;
+       boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::cut;
        return cut_copy (pmf, ranges, result_is_hidden);
 }
 
-Playlist*
+boost::shared_ptr<Playlist>
 Playlist::copy (list<AudioRange>& ranges, bool result_is_hidden)
 {
-       Playlist* (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::copy;
+       boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::copy;
        return cut_copy (pmf, ranges, result_is_hidden);
 }
 
-Playlist *
+boost::shared_ptr<Playlist>
 Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
 {
-       Playlist *the_copy;
+       boost::shared_ptr<Playlist> the_copy;
        RegionList thawlist;
        char buf[32];
 
@@ -881,8 +882,8 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
        new_name += '.';
        new_name += buf;
 
-       if ((the_copy = copyPlaylist (*this, start, cnt, new_name, result_is_hidden)) == 0) {
-               return 0;
+       if ((the_copy = PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden)) == 0) {
+               return boost::shared_ptr<Playlist>();
        }
 
        partition_internal (start, start+cnt-1, true, thawlist);
@@ -895,7 +896,7 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
        return the_copy;
 }
 
-Playlist *
+boost::shared_ptr<Playlist>
 Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden)
 {
        char buf[32];
@@ -906,28 +907,28 @@ Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden)
        new_name += buf;
 
        cnt = min (_get_maximum_extent() - start, cnt);
-       return copyPlaylist (*this, start, cnt, new_name, result_is_hidden);
+       return PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden);
 }
 
 int
-Playlist::paste (Playlist& other, nframes_t position, float times)
+Playlist::paste (boost::shared_ptr<Playlist> other, nframes_t position, float times)
 {
        times = fabs (times);
        nframes_t old_length;
 
        {
                RegionLock rl1 (this);
-               RegionLock rl2 (&other);
+               RegionLock rl2 (other.get());
 
                old_length = _get_maximum_extent();
        
                int itimes = (int) floor (times);
                nframes_t pos = position;
-               nframes_t shift = other._get_maximum_extent();
+               nframes_t shift = other->_get_maximum_extent();
                layer_t top_layer = regions.size();
 
                while (itimes--) {
-                       for (RegionList::iterator i = other.regions.begin(); i != other.regions.end(); ++i) {
+                       for (RegionList::iterator i = other->regions.begin(); i != other->regions.end(); ++i) {
                                boost::shared_ptr<Region> copy_of_region = RegionFactory::create (*i);
 
                                /* put these new regions on top of all existing ones, but preserve
@@ -966,7 +967,7 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
 
        while (itimes--) {
                boost::shared_ptr<Region> copy = RegionFactory::create (region);
-               add_region_internal (copy, pos, true);
+               add_region_internal (copy, pos);
                pos += region->length();
        }
 
@@ -975,7 +976,7 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
                string name;
                _session.region_name (name, region->name(), false);
                boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
-               add_region_internal (sub, pos, true);
+               add_region_internal (sub, pos);
        }
 }
 
@@ -1010,7 +1011,7 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos
        _session.region_name (after_name, region->name(), false);
        right = RegionFactory::create (region, before, after, after_name, region->layer(), Region::Flag (region->flags()|Region::RightOfSplit));
 
-       add_region_internal (left, region->position(), true);
+       add_region_internal (left, region->position());
        add_region_internal (right, region->position() + before);
        
        uint64_t orig_layer_op = region->last_layer_op();
@@ -1027,7 +1028,7 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos
 
        finalize_split_region (region, left, right);
        
-       if (remove_region_internal (region, true)) {
+       if (remove_region_internal (region)) {
                return;
        }
 }
@@ -1118,7 +1119,6 @@ Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region>
        }
 
        if (what_changed & Change (ARDOUR::PositionChanged|ARDOUR::LengthChanged)) {
-       
                if (holding_state ()) {
                        pending_bounds.push_back (region);
                } else {
@@ -1128,9 +1128,9 @@ Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region>
                        }
                        
                        possibly_splice ();
-                       check_dependents (region, false);
                        notify_length_changed ();
                        relayer ();
+                       check_dependents (region, false);
                }
        }
 }
@@ -1397,6 +1397,10 @@ Playlist::set_state (const XMLNode& node)
                }                       
        }
        
+       notify_modified ();
+
+       thaw ();
+
        /* update dependents, which was not done during add_region_internal 
           due to in_set_state being true 
        */
@@ -1405,10 +1409,6 @@ Playlist::set_state (const XMLNode& node)
                check_dependents (*r, false);
        }
 
-       notify_modified ();
-
-       thaw ();
-
        in_set_state--;
 
        return 0;
index 4461783874211cb2939c0d4528fad06672cdea82..862f85a402f87236dc47b2f49f5d10f0d8d701cc 100644 (file)
 
 #include <ardour/playlist.h>
 #include <ardour/audioplaylist.h>
+#include <ardour/midi_playlist.h>
+#include <ardour/playlist_factory.h>
 
 #include "i18n.h"
 
 using namespace ARDOUR;
 using namespace PBD;
 
-Playlist*
-Playlist::copyPlaylist (const Playlist& playlist, nframes_t start, nframes_t length,
-                       string name, bool result_is_hidden)
+sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistFactory::PlaylistCreated;
+
+boost::shared_ptr<Playlist> 
+PlaylistFactory::create (Session& s, const XMLNode& node, bool hidden) 
+{
+       const XMLProperty* type = node.property("type");
+
+       boost::shared_ptr<Playlist> pl;
+
+       if ( !type || type->value() == "audio" )
+               pl = boost::shared_ptr<Playlist> (new AudioPlaylist (s, node, hidden));
+       else if ( type->value() == "midi" )
+               pl = boost::shared_ptr<Playlist> (new MidiPlaylist (s, node, hidden));
+
+       pl->set_region_ownership ();
+
+       if (pl && !hidden) {
+               PlaylistCreated (pl);
+       }
+       return pl;
+}
+
+boost::shared_ptr<Playlist> 
+PlaylistFactory::create (DataType type, Session& s, string name, bool hidden) 
+{
+       boost::shared_ptr<Playlist> pl;
+
+       if (type == DataType::AUDIO)
+               pl = boost::shared_ptr<Playlist> (new AudioPlaylist (s, name, hidden));
+       else if (type == DataType::MIDI)
+               pl = boost::shared_ptr<Playlist> (new MidiPlaylist (s, name, hidden));
+
+       if (pl && !hidden) {
+               PlaylistCreated (pl);
+       }
+
+       return pl;
+}
+
+boost::shared_ptr<Playlist> 
+PlaylistFactory::create (boost::shared_ptr<const Playlist> old, string name, bool hidden) 
 {
-       const AudioPlaylist* apl;
-
-       if ((apl = dynamic_cast<const AudioPlaylist*> (&playlist)) != 0) {
-               return new AudioPlaylist (*apl, start, length, name, result_is_hidden);
-       } else {
-               fatal << _("programming error: Playlist::copyPlaylist called with unknown Playlist type")
-                     << endmsg;
-               /*NOTREACHED*/
-               return 0;
+       boost::shared_ptr<Playlist> pl;
+       boost::shared_ptr<const AudioPlaylist> apl;
+       boost::shared_ptr<const MidiPlaylist> mpl;
+
+       if ((apl = boost::dynamic_pointer_cast<const AudioPlaylist> (old)) != 0) {
+               pl = boost::shared_ptr<Playlist> (new AudioPlaylist (apl, name, hidden));
+               pl->set_region_ownership ();
+       } else if ((mpl = boost::dynamic_pointer_cast<const MidiPlaylist> (old)) != 0) {
+               pl = boost::shared_ptr<Playlist> (new MidiPlaylist (mpl, name, hidden));
+               pl->set_region_ownership ();
        }
+
+       if (pl && !hidden) {
+               PlaylistCreated (pl);
+       }
+
+       return pl;
+}
+
+boost::shared_ptr<Playlist> 
+PlaylistFactory::create (boost::shared_ptr<const Playlist> old, nframes_t start, nframes_t cnt, string name, bool hidden) 
+{
+       boost::shared_ptr<Playlist> pl;
+       boost::shared_ptr<const AudioPlaylist> apl;
+       boost::shared_ptr<const MidiPlaylist> mpl;
+       
+       if ((apl = boost::dynamic_pointer_cast<const AudioPlaylist> (old)) != 0) {
+               pl = boost::shared_ptr<Playlist> (new AudioPlaylist (apl, start, cnt, name, hidden));
+               pl->set_region_ownership ();
+       } else if ((mpl = boost::dynamic_pointer_cast<const MidiPlaylist> (old)) != 0) {
+               pl = boost::shared_ptr<Playlist> (new MidiPlaylist (mpl, start, cnt, name, hidden));
+               pl->set_region_ownership ();
+       }
+
+       /* this factory method does NOT notify others */
+
+       return pl;
 }
index b24b2619d3624bd80e07a395a8921e41643da25a..09da4c9ca7a2d9eda23f8d770ebe4527f53f927c 100644 (file)
@@ -343,7 +343,7 @@ PluginManager::add_vst_directory (string path)
 static bool vst_filter (const string& str, void *arg)
 {
        /* Not a dotfile, has a prefix before a period, suffix is "dll" */
-       
+
        return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
 }
 
@@ -375,6 +375,7 @@ PluginManager::vst_discover (string path)
        FSTInfo* finfo;
 
        if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) {
+               warning << "Cannot get VST information from " << path << endmsg;
                return -1;
        }
 
index adad79e2a3522799bcc23af6300767e1c2427a2c..dbdd3d1dddf12fb574d5b5fae958ad44929609a5 100644 (file)
@@ -28,6 +28,7 @@
 #include <sigc++/bind.h>
 
 #include <pbd/xml++.h>
+#include <pbd/enumwriter.h>
 
 #include <ardour/redirect.h>
 #include <ardour/session.h>
@@ -58,6 +59,7 @@ Redirect::Redirect (Session& s, const string& name, Placement p,
 
 Redirect::~Redirect ()
 {
+       notify_callbacks ();
 }
 
 boost::shared_ptr<Redirect>
@@ -96,18 +98,6 @@ Redirect::set_placement (Placement p, void *src)
        }
 }
 
-void
-Redirect::set_placement (const string& str, void *src)
-{
-       if (str == _("pre")) {
-               set_placement (PreFader, this);
-       } else if (str == _("post")) {
-               set_placement (PostFader, this);
-       } else {
-               error << string_compose(_("Redirect: unknown placement string \"%1\" (ignored)"), str) << endmsg;
-       }
-}
-
 /* NODE STRUCTURE 
    
     <Automation [optionally with visible="...." ]>
@@ -194,7 +184,7 @@ Redirect::state (bool full_state)
        stringstream sstr;
 
        node->add_property("active", active() ? "yes" : "no");  
-       node->add_property("placement", placement_as_string (placement()));
+       node->add_property("placement", enum_2_string (_placement));
        node->add_child_nocopy (IO::state (full_state));
 
        if (_extra_xml){
@@ -294,7 +284,20 @@ Redirect::set_state (const XMLNode& node)
                return -1;
        }
 
-       set_placement (prop->value(), this);
+       /* hack to handle older sessions before we only used EnumWriter */
+
+       string pstr;
+
+       if (prop->value() == "pre") {
+               pstr = "PreFader";
+       } else if (prop->value() == "post") {
+               pstr = "PostFader";
+       } else {
+               pstr = prop->value();
+       }
+
+       Placement p = Placement (string_2_enum (pstr, p));
+       set_placement (p, this);
 
        return 0;
 }
index 6d8c71b563f2dd0807fad15f640540dcc0e90753..973e14fd313a25b9a2dc53516fcc594a6bbb2949 100644 (file)
@@ -65,7 +65,6 @@ Region::Region (boost::shared_ptr<Source> src, jack_nframes_t start, jack_nframe
        , _read_data_count(0)
        , _pending_changed(Change (0))
        , _last_layer_op(0)
-       , _playlist(0)
 {
        _sources.push_back (src);
        _master_sources.push_back (src);
@@ -89,7 +88,6 @@ Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, c
        , _read_data_count(0)
        , _pending_changed(Change (0))
        , _last_layer_op(0)
-       , _playlist(0)
 {
        
        set<boost::shared_ptr<Source> > unique_srcs;
@@ -125,7 +123,6 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes
        , _read_data_count(0)
        , _pending_changed(Change (0))
        , _last_layer_op(0)
-       , _playlist(0)
 {
        if (other->_sync_position < offset)
                _sync_position = other->_sync_position;
@@ -167,7 +164,6 @@ Region::Region (boost::shared_ptr<const Region> other)
        , _read_data_count(0)
        , _pending_changed(Change(0))
        , _last_layer_op(other->_last_layer_op)
-       , _playlist(0)
 {
        other->_first_edit = EditChangesName;
 
@@ -209,10 +205,7 @@ Region::Region (SourceList& srcs, const XMLNode& node)
        , _read_data_count(0)
        , _pending_changed(Change(0))
        , _last_layer_op(0)
-       , _playlist(0)
-
 {
-
        set<boost::shared_ptr<Source> > unique_srcs;
 
        for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
@@ -250,7 +243,6 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node)
        , _read_data_count(0)
        , _pending_changed(Change(0))
        , _last_layer_op(0)
-       , _playlist(0)
 {
        _sources.push_back (src);
 
@@ -265,9 +257,11 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node)
 
 Region::~Region ()
 {
-       if (_playlist) {
+       boost::shared_ptr<Playlist> pl (playlist());
+
+       if (pl) {
                for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                       (*i)->remove_playlist (_playlist);
+                       (*i)->remove_playlist (pl);
                }
        }
        
@@ -276,29 +270,30 @@ Region::~Region ()
 }
 
 void
-Region::set_playlist (Playlist* pl)
+Region::set_playlist (boost::weak_ptr<Playlist> wpl)
 {
-       if (pl == _playlist) {
+       boost::shared_ptr<Playlist> old_playlist = (_playlist.lock());
+       boost::shared_ptr<Playlist> pl (wpl.lock());
+
+       if (old_playlist == pl) {
                return;
        }
 
-       Playlist* old_playlist = _playlist;
-
        if (pl) {
                if (old_playlist) {
                        for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                               (*i)->remove_playlist (old_playlist);   
-                               (*i)->add_playlist (_playlist);
+                               (*i)->remove_playlist (_playlist);      
+                               (*i)->add_playlist (pl);
                        }
                } else {
                        for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                               (*i)->add_playlist (_playlist);
+                               (*i)->add_playlist (pl);
                        }
                }
        } else {
                if (old_playlist) {
                        for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                               (*i)->remove_playlist (old_playlist);
+                               (*i)->remove_playlist (_playlist);
                        }
                }
        }
@@ -357,9 +352,11 @@ Region::maybe_uncopy ()
 void
 Region::first_edit ()
 {
-       if (_first_edit != EditChangesNothing && _playlist) {
+       boost::shared_ptr<Playlist> pl (playlist());
+
+       if (_first_edit != EditChangesNothing && pl) {
 
-               _name = _playlist->session().new_region_name (_name);
+               _name = pl->session().new_region_name (_name);
                _first_edit = EditChangesNothing;
 
                send_change (NameChanged);
@@ -370,7 +367,9 @@ Region::first_edit ()
 bool
 Region::at_natural_position () const
 {
-       if (!_playlist) {
+       boost::shared_ptr<Playlist> pl (playlist());
+
+       if (!pl) {
                return false;
        }
        
@@ -388,7 +387,9 @@ Region::at_natural_position () const
 void
 Region::move_to_natural_position (void *src)
 {
-       if (!_playlist) {
+       boost::shared_ptr<Playlist> pl (playlist());
+
+       if (!pl) {
                return;
        }
        
@@ -448,7 +449,11 @@ Region::set_position_on_top (nframes_t pos, void *src)
                _position = pos;
        }
 
-       _playlist->raise_region_to_top (shared_from_this ());
+       boost::shared_ptr<Playlist> pl (playlist());
+
+       if (pl) {
+               pl->raise_region_to_top (shared_from_this ());
+       }
 
        /* do this even if the position is the same. this helps out
           a GUI that has moved its representation already.
@@ -835,42 +840,37 @@ Region::sync_position() const
 void
 Region::raise ()
 {
-       if (_playlist == 0) {
-               return;
+       boost::shared_ptr<Playlist> pl (playlist());
+       if (pl) {
+               pl->raise_region (shared_from_this ());
        }
-
-       _playlist->raise_region (shared_from_this ());
 }
 
 void
 Region::lower ()
 {
-       if (_playlist == 0) {
-               return;
+       boost::shared_ptr<Playlist> pl (playlist());
+       if (pl) {
+               pl->lower_region (shared_from_this ());
        }
-
-       _playlist->lower_region (shared_from_this ());
 }
 
 void
 Region::raise_to_top ()
 {
-
-       if (_playlist == 0) {
-               return;
+       boost::shared_ptr<Playlist> pl (playlist());
+       if (pl) {
+               pl->raise_region_to_top (shared_from_this());
        }
-
-       _playlist->raise_region_to_top (shared_from_this());
 }
 
 void
 Region::lower_to_bottom ()
 {
-       if (_playlist == 0) {
-               return;
+       boost::shared_ptr<Playlist> pl (playlist());
+       if (pl) {
+               pl->lower_region_to_bottom (shared_from_this());
        }
-
-       _playlist->lower_region_to_bottom (shared_from_this());
 }
 
 void
@@ -919,7 +919,7 @@ Region::state (bool full_state)
 
        snprintf (buf, sizeof (buf), "%d", (int) _layer);
        node->add_property ("layer", buf);
-       snprintf (buf, sizeof (buf), "%u", _sync_position);
+       snprintf (buf, sizeof (buf), "%" PRIu32, _sync_position);
        node->add_property ("sync-position", buf);
 
        return *node;
@@ -1230,11 +1230,13 @@ Region::verify_start_mutable (jack_nframes_t& new_start)
 boost::shared_ptr<Region>
 Region::get_parent() const
 {
-       if (_playlist) {
+       boost::shared_ptr<Playlist> pl (playlist());
+
+       if (pl) {
                boost::shared_ptr<Region> r;
                boost::shared_ptr<Region const> grrr2 = boost::dynamic_pointer_cast<Region const> (shared_from_this());
                
-               if (grrr2 && (r = _playlist->session().find_whole_file_parent (grrr2))) {
+               if (grrr2 && (r = pl->session().find_whole_file_parent (grrr2))) {
                        return boost::static_pointer_cast<Region> (r);
                }
        }
index 5314c99632e1ae30e5f06291fda83c6c902856d5..a2bc65407ca6e73a43db976fa871edad30a9dc48 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <sigc++/bind.h>
 #include <pbd/xml++.h>
+#include <pbd/enumwriter.h>
 
 #include <ardour/timestamps.h>
 #include <ardour/audioengine.h>
@@ -889,6 +890,10 @@ Route::clear_redirects (void *src)
 
        {
                Glib::RWLock::WriterLock lm (redirect_lock);
+               RedirectList::iterator i;
+               for (i = _redirects.begin(); i != _redirects.end(); ++i) {
+                       (*i)->drop_references ();
+               }
                _redirects.clear ();
        }
 
@@ -985,6 +990,8 @@ Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_
                reset_panner ();
        }
 
+       redirect->drop_references ();
+
        redirects_changed (src); /* EMIT SIGNAL */
        return 0;
 }
@@ -1317,8 +1324,7 @@ Route::state(bool full_state)
        char buf[32];
 
        if (_flags) {
-               snprintf (buf, sizeof (buf), "0x%x", _flags);
-               node->add_property("flags", buf);
+               node->add_property("flags", enum_2_string (_flags));
        }
        
        node->add_property("default-type", _default_type.to_string());
@@ -1478,9 +1484,7 @@ Route::_set_state (const XMLNode& node, bool call_base)
        }
 
        if ((prop = node.property (X_("flags"))) != 0) {
-               int x;
-               sscanf (prop->value().c_str(), "0x%x", &x);
-               _flags = Flag (x);
+               _flags = Flag (string_2_enum (prop->value(), _flags));
        } else {
                _flags = Flag (0);
        }
index 57306237427ff581a17e352b615d29516ccf3bc0..c2aa59ed8b6db32ea73af708d4e280a1eb5c4ef1 100644 (file)
@@ -26,6 +26,7 @@
 #include <sigc++/bind.h>
 
 #include <pbd/error.h>
+#include <pbd/enumwriter.h>
 
 #include <ardour/route_group.h>
 #include <ardour/audio_track.h>
@@ -125,11 +126,9 @@ RouteGroup::get_max_factor(gain_t factor)
 XMLNode&
 RouteGroup::get_state (void)
 {
-       char buf[32];
        XMLNode *node = new XMLNode ("RouteGroup");
        node->add_property ("name", _name);
-       snprintf (buf, sizeof (buf), "%" PRIu32, (uint32_t) _flags);
-       node->add_property ("flags", buf);
+       node->add_property ("flags", enum_2_string (_flags));
        return *node;
 }
 
@@ -143,7 +142,7 @@ RouteGroup::set_state (const XMLNode& node)
        }
 
        if ((prop = node.property ("flags")) != 0) {
-               _flags = atoi (prop->value().c_str());
+               _flags = Flag (string_2_enum (prop->value(), _flags));
        }
 
        return 0;
@@ -157,9 +156,9 @@ RouteGroup::set_active (bool yn, void *src)
                return;
        }
        if (yn) {
-               _flags |= Active;
+               _flags = Flag (_flags | Active);
        } else {
-               _flags &= ~Active;
+               _flags = Flag (_flags & ~Active);
        }
        _session.set_dirty ();
        FlagsChanged (src); /* EMIT SIGNAL */
@@ -173,9 +172,9 @@ RouteGroup::set_relative (bool yn, void *src)
                return;
        }
        if (yn) {
-               _flags |= Relative;
+               _flags = Flag (_flags | Relative);
        } else {
-               _flags &= ~Relative;
+               _flags = Flag (_flags & ~Relative);
        }
        _session.set_dirty ();
        FlagsChanged (src); /* EMIT SIGNAL */
@@ -189,14 +188,14 @@ RouteGroup::set_hidden (bool yn, void *src)
                return;
        }
        if (yn) {
-               _flags |= Hidden;
+               _flags = Flag (_flags | Hidden);
                if (Config->get_hiding_groups_deactivates_groups()) {
-                       _flags &= ~Active;
+                       _flags = Flag (_flags & ~Active);
                }
        } else {
-               _flags &= ~Hidden;
+               _flags = Flag (_flags & ~Hidden);
                if (Config->get_hiding_groups_deactivates_groups()) {
-                       _flags |= Active;
+                       _flags = Flag (_flags | Active);
                }
        }
        _session.set_dirty ();
index 73dbf11ad58bfa925caa804f72dab81a1907c46a..0141007803bcdf8766e309145dfc6f3a582ab2ae 100644 (file)
@@ -34,7 +34,7 @@ using namespace ARDOUR;
 using namespace PBD;
 
 Send::Send (Session& s, Placement p)
-       : Redirect (s, s.next_send_name(), p)
+       : Redirect (s, string_compose (_("send %1"), (bitslot = s.next_send_id()) + 1), p)
 {
        _metering = false;
        RedirectCreated (this); /* EMIT SIGNAL */
@@ -53,7 +53,7 @@ Send::Send (Session& s, const XMLNode& node)
 }
 
 Send::Send (const Send& other)
-       : Redirect (other._session, other._session.next_send_name(), other.placement())
+       : Redirect (other._session, string_compose (_("send %1"), (bitslot = other._session.next_send_id()) + 1), other.placement())
 {
        _metering = false;
        RedirectCreated (this); /* EMIT SIGNAL */
@@ -74,7 +74,10 @@ XMLNode&
 Send::state(bool full)
 {
        XMLNode *node = new XMLNode("Send");
+       char buf[32];
        node->add_child_nocopy (Redirect::state (full));
+       snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
+       node->add_property ("bitslot", buf);
        return *node;
 }
 
@@ -83,6 +86,14 @@ Send::set_state(const XMLNode& node)
 {
        XMLNodeList nlist = node.children();
        XMLNodeIterator niter;
+       const XMLProperty* prop;
+
+       if ((prop = node.property ("bitslot")) == 0) {
+               bitslot = _session.next_send_id();
+       } else {
+               sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
+               _session.mark_send_id (bitslot);
+       }
 
        /* Send has regular IO automation (gain, pan) */
 
index 1b7c3be6ddc738880cd51c9dfa73ae914fb24319..6ad8f7dbd2fdb871264a4147fe8c9e7d6d606f28 100644 (file)
@@ -40,6 +40,7 @@
 #include <pbd/pathscanner.h>
 #include <pbd/stl_delete.h>
 #include <pbd/basename.h>
+#include <pbd/stacktrace.h>
 
 #include <ardour/audioengine.h>
 #include <ardour/configuration.h>
@@ -290,12 +291,13 @@ Session::Session (AudioEngine &eng,
        if (new_session) {
                if (create (new_session, mix_template, compute_initial_length())) {
                        cerr << "create failed\n";
+                       destroy ();
                        throw failed_constructor ();
                }
        }
        
        if (second_stage_init (new_session)) {
-               cerr << "2nd state failed\n";
+               destroy ();
                throw failed_constructor ();
        }
        
@@ -359,6 +361,7 @@ Session::Session (AudioEngine &eng,
 
        if (new_session) {
                if (create (new_session, 0, initial_length)) {
+                       destroy ();
                        throw failed_constructor ();
                }
        }
@@ -386,6 +389,7 @@ Session::Session (AudioEngine &eng,
        Config->set_output_auto_connect (output_ac);
 
        if (second_stage_init (new_session)) {
+               destroy ();
                throw failed_constructor ();
        }
        
@@ -401,6 +405,12 @@ Session::Session (AudioEngine &eng,
 }
 
 Session::~Session ()
+{
+       destroy ();
+}
+
+void
+Session::destroy ()
 {
        /* if we got to here, leaving pending capture state around
           is a mistake.
@@ -469,10 +479,24 @@ Session::~Session ()
                tmp = i;
                ++tmp;
 
-               delete *i;
+               (*i)->drop_references ();
+               
+               i = tmp;
+       }
+       
+       for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
+               PlaylistList::iterator tmp;
+
+               tmp = i;
+               ++tmp;
+
+               (*i)->drop_references ();
                
                i = tmp;
        }
+       
+       playlists.clear ();
+       unused_playlists.clear ();
 
 #ifdef TRACK_DESTRUCTION
        cerr << "delete regions\n";
@@ -619,8 +643,6 @@ Session::when_engine_running ()
 
        /* we don't want to run execute this again */
 
-       first_time_running.disconnect ();
-
        set_block_size (_engine.frames_per_cycle());
        set_frame_rate (_engine.frame_rate());
 
@@ -685,23 +707,6 @@ Session::when_engine_running ()
                // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
        }
 
-       if (auditioner == 0) {
-
-               /* we delay creating the auditioner till now because
-                  it makes its own connections to ports named
-                  in the ARDOUR_RC config file. the engine has
-                  to be running for this to work.
-               */
-
-               try {
-                       auditioner.reset (new Auditioner (*this));
-               }
-
-               catch (failed_constructor& err) {
-                       warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
-               }
-       }
-
        /* Create a set of Connection objects that map
           to the physical outputs currently available
        */
@@ -841,6 +846,7 @@ Session::when_engine_running ()
                }
        }
 
+       
        _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
 
        /* hook us up to the engine */
@@ -867,6 +873,22 @@ Session::hookup_io ()
 
        _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
 
+       if (auditioner == 0) {
+               
+               /* we delay creating the auditioner till now because
+                  it makes its own connections to ports.
+                  the engine has to be running for this to work.
+               */
+               
+               try {
+                       auditioner.reset (new Auditioner (*this));
+               }
+               
+               catch (failed_constructor& err) {
+                       warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
+               }
+       }
+
        /* Tell all IO objects to create their ports */
 
        IO::enable_ports ();
@@ -918,7 +940,7 @@ Session::hookup_io ()
 }
 
 void
-Session::playlist_length_changed (Playlist* pl)
+Session::playlist_length_changed ()
 {
        /* we can't just increase end_location->end() if pl->get_maximum_extent() 
           if larger. if the playlist used to be the longest playlist,
@@ -932,10 +954,10 @@ Session::playlist_length_changed (Playlist* pl)
 void
 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
 {
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
 
        if ((playlist = dstream->playlist()) != 0) {
-         playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
+               playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
        }
        
        /* see comment in playlist_length_changed () */
@@ -2317,7 +2339,7 @@ Session::get_maximum_extent () const
        boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
 
        for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
-               Playlist* pl = (*i)->playlist();
+               boost::shared_ptr<Playlist> pl = (*i)->playlist();
                if ((me = pl->get_maximum_extent()) > max) {
                        max = me;
                }
@@ -2697,14 +2719,10 @@ Session::add_source (boost::shared_ptr<Source> source)
                result = sources.insert (entry);
        }
 
-       if (!result.second) {
-               cerr << "\tNOT inserted ? " << result.second << endl;
+       if (result.second) {
+               source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
+               set_dirty();
        }
-
-       source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
-       set_dirty();
-       
-       SourceAdded (source); /* EMIT SIGNAL */
 }
 
 void
@@ -2737,8 +2755,6 @@ Session::remove_source (boost::weak_ptr<Source> src)
                
                save_state (_current_snapshot_name);
        }
-       
-       SourceRemoved(source); /* EMIT SIGNAL */
 }
 
 boost::shared_ptr<Source>
@@ -2924,6 +2940,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
                                } else {
                                        snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
                                }
+
                        } else {
 
                                spath += '/';
@@ -2956,6 +2973,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
 
                if (cnt > limit) {
                        error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
+                       destroy ();
                        throw failed_constructor();
                }
        }
@@ -2967,6 +2985,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
        string foo = buf;
 
        spath = discover_best_sound_dir ();
+       spath += '/';
 
        string::size_type pos = foo.find_last_of ('/');
        
@@ -3176,7 +3195,7 @@ Session::create_midi_source_for_session (MidiDiskstream& ds)
 
 /* Playlist management */
 
-Playlist *
+boost::shared_ptr<Playlist>
 Session::playlist_by_name (string name)
 {
        Glib::Mutex::Lock lm (playlist_lock);
@@ -3190,11 +3209,12 @@ Session::playlist_by_name (string name)
                        return* i;
                }
        }
-       return 0;
+
+       return boost::shared_ptr<Playlist>();
 }
 
 void
-Session::add_playlist (Playlist* playlist)
+Session::add_playlist (boost::shared_ptr<Playlist> playlist)
 {
        if (playlist->hidden()) {
                return;
@@ -3204,9 +3224,8 @@ Session::add_playlist (Playlist* playlist)
                Glib::Mutex::Lock lm (playlist_lock);
                if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
                        playlists.insert (playlists.begin(), playlist);
-                       // playlist->ref();
-                       playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
-                       playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
+                       playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
+                       playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
                }
        }
 
@@ -3216,7 +3235,7 @@ Session::add_playlist (Playlist* playlist)
 }
 
 void
-Session::get_playlists (vector<Playlist*>& s)
+Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
 {
        { 
                Glib::Mutex::Lock lm (playlist_lock);
@@ -3230,15 +3249,25 @@ Session::get_playlists (vector<Playlist*>& s)
 }
 
 void
-Session::track_playlist (Playlist* pl, bool inuse)
+Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
 {
+       boost::shared_ptr<Playlist> pl(wpl.lock());
+
+       if (!pl) {
+               return;
+       }
+
        PlaylistList::iterator x;
 
+       if (pl->hidden()) {
+               /* its not supposed to be visible */
+               return;
+       }
+
        { 
                Glib::Mutex::Lock lm (playlist_lock);
 
                if (!inuse) {
-                       //cerr << "shifting playlist to unused: " << pl->name() << endl;
 
                        unused_playlists.insert (pl);
                        
@@ -3248,8 +3277,7 @@ Session::track_playlist (Playlist* pl, bool inuse)
 
                        
                } else {
-                       //cerr << "shifting playlist to used: " << pl->name() << endl;
-                       
+
                        playlists.insert (pl);
                        
                        if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
@@ -3260,20 +3288,24 @@ Session::track_playlist (Playlist* pl, bool inuse)
 }
 
 void
-Session::remove_playlist (Playlist* playlist)
+Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
 {
        if (_state_of_the_state & Deletion) {
                return;
        }
 
+       boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
+
+       if (!playlist) {
+               return;
+       }
+
        { 
                Glib::Mutex::Lock lm (playlist_lock);
-               // cerr << "removing playlist: " << playlist->name() << endl;
 
                PlaylistList::iterator i;
 
                i = find (playlists.begin(), playlists.end(), playlist);
-
                if (i != playlists.end()) {
                        playlists.erase (i);
                }
@@ -3451,6 +3483,12 @@ Session::graph_reordered ()
                return;
        }
        
+       /* every track/bus asked for this to be handled but it was deferred because
+          we were connecting. do it now.
+       */
+
+       request_input_change_handling ();
+
        resort_routes ();
 
        /* force all diskstreams to update their capture offset values to 
@@ -3528,18 +3566,28 @@ Session::remove_redirect (Redirect* redirect)
        Insert* insert;
        PortInsert* port_insert;
        PluginInsert* plugin_insert;
-
+       
        if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
                if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
-                       _port_inserts.remove (port_insert);
+                       list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
+                       if (x != _port_inserts.end()) {
+                               insert_bitset[port_insert->bit_slot()] = false;
+                               _port_inserts.erase (x);
+                       }
                } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
                        _plugin_inserts.remove (plugin_insert);
                } else {
-                       fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
+                       fatal << string_compose (_("programming error: %1"),
+                                                X_("unknown type of Insert deleted!")) 
+                             << endmsg;
                        /*NOTREACHED*/
                }
        } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
-               _sends.remove (send);
+               list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
+               if (x != _sends.end()) {
+                       send_bitset[send->bit_slot()] = false;
+                       _sends.erase (x);
+               }
        } else {
                fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
                /*NOTREACHED*/
@@ -3561,6 +3609,13 @@ Session::available_capture_duration ()
        case FormatInt24:
                sample_bytes_on_disk = 3;
                break;
+
+       default: 
+               /* impossible, but keep some gcc versions happy */
+               fatal << string_compose (_("programming error: %1"),
+                                        X_("illegal native file data format"))
+                     << endmsg;
+               /*NOTREACHED*/
        }
 
        double scale = 4096.0 / sample_bytes_on_disk;
@@ -3642,20 +3697,70 @@ Session::ensure_buffers (ChanCount howmany)
        allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
 }
 
-string
-Session::next_send_name ()
+uint32_t
+Session::next_insert_id ()
 {
-       char buf[32];
-       snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
-       return buf;
+       /* this doesn't really loop forever. just think about it */
+
+       while (true) {
+               for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
+                       if (!insert_bitset[n]) {
+                               insert_bitset[n] = true;
+                               cerr << "Returning " << n << " as insert ID\n";
+                               return n;
+                               
+                       }
+               }
+               
+               /* none available, so resize and try again */
+
+               insert_bitset.resize (insert_bitset.size() + 16, false);
+       }
 }
 
-string
-Session::next_insert_name ()
+uint32_t
+Session::next_send_id ()
 {
-       char buf[32];
-       snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
-       return buf;
+       /* this doesn't really loop forever. just think about it */
+
+       while (true) {
+               for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
+                       if (!send_bitset[n]) {
+                               send_bitset[n] = true;
+                               cerr << "Returning " << n << " as send ID\n";
+                               return n;
+                               
+                       }
+               }
+               
+               /* none available, so resize and try again */
+
+               send_bitset.resize (send_bitset.size() + 16, false);
+       }
+}
+
+void
+Session::mark_send_id (uint32_t id)
+{
+       if (id >= send_bitset.size()) {
+               send_bitset.resize (id+16, false);
+       }
+       if (send_bitset[id]) {
+               warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
+       }
+       send_bitset[id] = true;
+}
+
+void
+Session::mark_insert_id (uint32_t id)
+{
+       if (id >= insert_bitset.size()) {
+               insert_bitset.resize (id+16, false);
+       }
+       if (insert_bitset[id]) {
+               warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
+       }
+       insert_bitset[id] = true;
 }
 
 /* Named Selection management */
@@ -3732,12 +3837,6 @@ Session::route_name_unique (string n) const
        return true;
 }
 
-int
-Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
-{
-       return fs->move_to_trash (dead_sound_dir_name);
-}
-
 uint32_t
 Session::n_playlists () const
 {
@@ -3794,18 +3893,17 @@ int
 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,     
                               bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
 {
+       int ret = -1;
+       boost::shared_ptr<Playlist> playlist;
        boost::shared_ptr<AudioFileSource> fsource;
-       
-       int              ret = -1;
-       Playlist*        playlist = 0;
-       uint32_t         x;
-       char             buf[PATH_MAX+1];
-       string           dir;
-       ChanCount        nchans(track.audio_diskstream()->n_channels());
-       jack_nframes_t   position;
-       jack_nframes_t   this_chunk;
-       jack_nframes_t   to_do;
-       BufferSet        buffers;
+       uint32_t x;
+       char buf[PATH_MAX+1];
+       string dir;
+       ChanCount nchans(track.audio_diskstream()->n_channels());
+       nframes_t position;
+       nframes_t this_chunk;
+       nframes_t to_do;
+       BufferSet buffers;
 
        // any bigger than this seems to cause stack overflows in called functions
        const nframes_t chunk_size = (128 * 1024)/4;
@@ -3915,7 +4013,7 @@ 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()));
+                                                                          region_name_from_path (srcs.front()->name(), true));
 
                ret = 0;
        }
index 832284901c12580fd0e8e5a406206429733c4ae2..bb02eede91cb7677917feea4e919f19e95fe1774 100644 (file)
@@ -157,8 +157,6 @@ Session::_butler_thread_work (void* arg)
        return 0;
 }
 
-#define transport_work_requested() g_atomic_int_get(&butler_should_do_transport_work)
-
 void *
 Session::butler_thread_work ()
 {
index 5816f1c6b7f670a2ece6dd892684496ca7850802..9d054c22fd1228da42107c6834eec3fa5ac5f08e 100644 (file)
 #include <ardour/midi_source.h>
 #include <ardour/midi_region.h>
 #include <pbd/error.h>
-using namespace PBD;
-#include "i18n.h"
+#include <pbd/id.h>
+#include <pbd/statefuldestructible.h>
+#include <pbd/failed_constructor.h>
 
+using namespace PBD;
+using namespace ARDOUR;
 
-namespace ARDOUR {
+#include "i18n.h"
 
 void Session::register_with_memento_command_factory(PBD::ID id, PBD::StatefulThingWithGoingAway *ptr)
 {
     registry[id] = ptr;
 }
     
-Command *Session::memento_command_factory(XMLNode *n)
+Command *
+Session::memento_command_factory(XMLNode *n)
 {
     PBD::ID id;
     XMLNode *before = 0, *after = 0;
@@ -70,8 +74,9 @@ Command *Session::memento_command_factory(XMLNode *n)
     } else if (obj_T == typeid (TempoMap).name()) {
            return new MementoCommand<TempoMap>(*_tempo_map, before, after);
     } else if (obj_T == typeid (Playlist).name() || obj_T == typeid (AudioPlaylist).name()) {
-           if (Playlist *pl = playlist_by_name(child->property("name")->value()))
-                   return new MementoCommand<Playlist>(*pl, before, after);
+           if (boost::shared_ptr<Playlist> pl = playlist_by_name(child->property("name")->value())) {
+                   return new MementoCommand<Playlist>(*(pl.get()), before, after);
+           }
     } else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name()) { 
            return new MementoCommand<Route>(*route_by_id(id), before, after);
     } else if (obj_T == typeid (Curve).name() || obj_T == typeid (AutomationList).name()) {
@@ -86,100 +91,425 @@ Command *Session::memento_command_factory(XMLNode *n)
     return 0 ;
 }
 
+Command *
+Session::global_state_command_factory (const XMLNode& node)
+{
+       const XMLProperty* prop;
+       Command* command = 0;
+
+       if ((prop = node.property ("type")) == 0) {
+               error << _("GlobalRouteStateCommand has no \"type\" node, ignoring") << endmsg;
+               return 0;
+       }
+       
+       try {
+
+               if (prop->value() == "solo") {
+                       command = new GlobalSoloStateCommand (*this, node);
+               } else if (prop->value() == "mute") {
+                       command = new GlobalMuteStateCommand (*this, node);
+               } else if (prop->value() == "rec-enable") {
+                       command = new GlobalRecordEnableStateCommand (*this, node);
+               } else if (prop->value() == "metering") {
+                       command = new GlobalMeteringStateCommand (*this, node);
+               } else {
+                       error << string_compose (_("unknown type of GlobalRouteStateCommand (%1), ignored"), prop->value()) << endmsg;
+               }
+       }
+
+       catch (failed_constructor& err) {
+               return 0;
+       }
+
+       return command;
+}
+
+Session::GlobalRouteStateCommand::GlobalRouteStateCommand (Session& s, void* p)
+       : sess (s), src (p)
+{
+}
+
+Session::GlobalRouteStateCommand::GlobalRouteStateCommand (Session& s, const XMLNode& node)
+       : sess (s), src (this)
+{
+       if (set_state (node)) {
+               throw failed_constructor ();
+       }
+}
+
+int
+Session::GlobalRouteStateCommand::set_state (const XMLNode& node)
+{
+       GlobalRouteBooleanState states;
+       XMLNodeList nlist;
+       const XMLProperty* prop;
+       XMLNode* child;
+       XMLNodeConstIterator niter;
+       int loop;
+
+       before.clear ();
+       after.clear ();
+       
+       for (loop = 0; loop < 2; ++loop) {
+
+               const char *str;
+
+               if (loop) {
+                       str = "after";
+               } else {
+                       str = "before";
+               }
+               
+               if ((child = node.child (str)) == 0) {
+                       warning << string_compose (_("global route state command has no \"%1\" node, ignoring entire command"), str) << endmsg;
+                       return -1;
+               }
+
+               nlist = child->children();
+
+               for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+                       
+                       RouteBooleanState rbs;
+                       boost::shared_ptr<Route> route;
+                       ID id;
+                       
+                       prop = (*niter)->property ("id");
+                       id = prop->value ();
+                       
+                       if ((route = sess.route_by_id (id)) == 0) {
+                               warning << string_compose (_("cannot find track/bus \"%1\" while rebuilding a global route state command, ignored"), id.to_s()) << endmsg;
+                               continue;
+                       }
+                       
+                       rbs.first = boost::weak_ptr<Route> (route);
+                       
+                       prop = (*niter)->property ("yn");
+                       rbs.second = (prop->value() == "1");
+                       
+                       if (loop) {
+                               after.push_back (rbs);
+                       } else {
+                               before.push_back (rbs);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+XMLNode&
+Session::GlobalRouteStateCommand::get_state ()
+{
+       XMLNode* node = new XMLNode (X_("GlobalRouteStateCommand"));
+       XMLNode* nbefore = new XMLNode (X_("before"));
+       XMLNode* nafter = new XMLNode (X_("after"));
+
+       for (Session::GlobalRouteBooleanState::iterator x = before.begin(); x != before.end(); ++x) {
+               XMLNode* child = new XMLNode ("s");
+               boost::shared_ptr<Route> r = x->first.lock();
+
+               if (r) {
+                       child->add_property (X_("id"), r->id().to_s());
+                       child->add_property (X_("yn"), (x->second ? "1" : "0"));
+                       nbefore->add_child_nocopy (*child);
+               }
+       }
+
+       for (Session::GlobalRouteBooleanState::iterator x = after.begin(); x != after.end(); ++x) {
+               XMLNode* child = new XMLNode ("s");
+               boost::shared_ptr<Route> r = x->first.lock();
+
+               if (r) {
+                       child->add_property (X_("id"), r->id().to_s());
+                       child->add_property (X_("yn"), (x->second ? "1" : "0"));
+                       nafter->add_child_nocopy (*child);
+               }
+       }
+
+       node->add_child_nocopy (*nbefore);
+       node->add_child_nocopy (*nafter);
+
+       return *node;
+}
+
 // solo
+
 Session::GlobalSoloStateCommand::GlobalSoloStateCommand(Session &sess, void *src)
-    : sess(sess), src(src)
+       : GlobalRouteStateCommand (sess, src)
 {
     after = before = sess.get_global_route_boolean(&Route::soloed);
 }
-void Session::GlobalSoloStateCommand::mark()
+
+Session::GlobalSoloStateCommand::GlobalSoloStateCommand (Session& sess, const XMLNode& node)
+       : Session::GlobalRouteStateCommand (sess, node)
+{
+}
+
+void 
+Session::GlobalSoloStateCommand::mark()
 {
     after = sess.get_global_route_boolean(&Route::soloed);
 }
-void Session::GlobalSoloStateCommand::operator()()
+
+void 
+Session::GlobalSoloStateCommand::operator()()
 {
     sess.set_global_solo(after, src);
 }
-void Session::GlobalSoloStateCommand::undo()
+
+void 
+Session::GlobalSoloStateCommand::undo()
 {
     sess.set_global_solo(before, src);
 }
-XMLNode &Session::GlobalSoloStateCommand::get_state()
+
+XMLNode&
+Session::GlobalSoloStateCommand::get_state()
 {
-    XMLNode *node = new XMLNode("GlobalSoloStateCommand");
-    return *node;
+       XMLNode& node = GlobalRouteStateCommand::get_state();
+       node.add_property ("type", "solo");
+       return node;
 }
 
 // mute
 Session::GlobalMuteStateCommand::GlobalMuteStateCommand(Session &sess, void *src)
-    : sess(sess), src(src)
+       : GlobalRouteStateCommand (sess, src)
 {
     after = before = sess.get_global_route_boolean(&Route::muted);
 }
-void Session::GlobalMuteStateCommand::mark()
+
+Session::GlobalMuteStateCommand::GlobalMuteStateCommand (Session& sess, const XMLNode& node)
+       : Session::GlobalRouteStateCommand (sess, node)
 {
-    after = sess.get_global_route_boolean(&Route::muted);
 }
-void Session::GlobalMuteStateCommand::operator()()
+
+void 
+Session::GlobalMuteStateCommand::mark()
 {
-    sess.set_global_mute(after, src);
+       after = sess.get_global_route_boolean(&Route::muted);
 }
-void Session::GlobalMuteStateCommand::undo()
+
+void 
+Session::GlobalMuteStateCommand::operator()()
 {
-    sess.set_global_mute(before, src);
+       sess.set_global_mute(after, src);
 }
-XMLNode &Session::GlobalMuteStateCommand::get_state()
+
+void 
+Session::GlobalMuteStateCommand::undo()
 {
-    XMLNode *node = new XMLNode("GlobalMuteStateCommand");
-    return *node;
+       sess.set_global_mute(before, src);
+}
+
+XMLNode&
+Session::GlobalMuteStateCommand::get_state()
+{
+       XMLNode& node = GlobalRouteStateCommand::get_state();
+       node.add_property ("type", "mute");
+       return node;
 }
 
 // record enable
 Session::GlobalRecordEnableStateCommand::GlobalRecordEnableStateCommand(Session &sess, void *src) 
-    : sess(sess), src(src)
+       : GlobalRouteStateCommand (sess, src)
+{
+       after = before = sess.get_global_route_boolean(&Route::record_enabled);
+}
+
+Session::GlobalRecordEnableStateCommand::GlobalRecordEnableStateCommand (Session& sess, const XMLNode& node)
+       : Session::GlobalRouteStateCommand (sess, node)
 {
-    after = before = sess.get_global_route_boolean(&Route::record_enabled);
 }
-void Session::GlobalRecordEnableStateCommand::mark()
+
+void 
+Session::GlobalRecordEnableStateCommand::mark()
 {
-    after = sess.get_global_route_boolean(&Route::record_enabled);
+       after = sess.get_global_route_boolean(&Route::record_enabled);
 }
-void Session::GlobalRecordEnableStateCommand::operator()()
+
+void 
+Session::GlobalRecordEnableStateCommand::operator()()
 {
-    sess.set_global_record_enable(after, src);
+       sess.set_global_record_enable(after, src);
 }
-void Session::GlobalRecordEnableStateCommand::undo()
+
+void 
+Session::GlobalRecordEnableStateCommand::undo()
 {
-    sess.set_global_record_enable(before, src);
+       sess.set_global_record_enable(before, src);
 }
-XMLNode &Session::GlobalRecordEnableStateCommand::get_state()
+
+XMLNode& 
+Session::GlobalRecordEnableStateCommand::get_state()
 {
-    XMLNode *node = new XMLNode("GlobalRecordEnableStateCommand");
-    return *node;
+       XMLNode& node = GlobalRouteStateCommand::get_state();
+       node.add_property ("type", "rec-enable");
+       return node;
 }
 
 // metering
-Session::GlobalMeteringStateCommand::GlobalMeteringStateCommand(Session &sess, void *src
-    : sess(sess), src(src)
+Session::GlobalMeteringStateCommand::GlobalMeteringStateCommand(Session &s, void *p
+       : sess (s), src (p)
 {
-    after = before = sess.get_global_route_metering();
+       after = before = sess.get_global_route_metering();
 }
-void Session::GlobalMeteringStateCommand::mark()
+
+Session::GlobalMeteringStateCommand::GlobalMeteringStateCommand (Session& s, const XMLNode& node)
+       : sess (s), src (this)
 {
-    after = sess.get_global_route_metering();
+       if (set_state (node)) {
+               throw failed_constructor();
+       }
 }
-void Session::GlobalMeteringStateCommand::operator()()
+
+void 
+Session::GlobalMeteringStateCommand::mark()
 {
-    sess.set_global_route_metering(after, src);
+       after = sess.get_global_route_metering();
 }
-void Session::GlobalMeteringStateCommand::undo()
+
+void 
+Session::GlobalMeteringStateCommand::operator()()
 {
-    sess.set_global_route_metering(before, src);
+       sess.set_global_route_metering(after, src);
 }
-XMLNode &Session::GlobalMeteringStateCommand::get_state()
+
+void 
+Session::GlobalMeteringStateCommand::undo()
 {
-    XMLNode *node = new XMLNode("GlobalMeteringStateCommand");
-    return *node;
+       sess.set_global_route_metering(before, src);
 }
 
-} // namespace ARDOUR
+XMLNode&
+Session::GlobalMeteringStateCommand::get_state()
+{
+       XMLNode* node = new XMLNode (X_("GlobalRouteStateCommand"));
+       XMLNode* nbefore = new XMLNode (X_("before"));
+       XMLNode* nafter = new XMLNode (X_("after"));
+
+       for (Session::GlobalRouteMeterState::iterator x = before.begin(); x != before.end(); ++x) {
+               XMLNode* child = new XMLNode ("s");
+               boost::shared_ptr<Route> r = x->first.lock();
+
+               if (r) {
+                       child->add_property (X_("id"), r->id().to_s());
+
+                       const char* meterstr;
+                       
+                       switch (x->second) {
+                       case MeterInput:
+                               meterstr = X_("input");
+                               break;
+                       case MeterPreFader:
+                               meterstr = X_("pre");
+                               break;
+                       case MeterPostFader:
+                               meterstr = X_("post");
+                               break;
+                       }
+
+                       child->add_property (X_("meter"), meterstr);
+                       nbefore->add_child_nocopy (*child);
+               }
+       }
+
+       for (Session::GlobalRouteMeterState::iterator x = after.begin(); x != after.end(); ++x) {
+               XMLNode* child = new XMLNode ("s");
+               boost::shared_ptr<Route> r = x->first.lock();
+
+               if (r) {
+                       child->add_property (X_("id"), r->id().to_s());
+
+                       const char* meterstr;
+                       
+                       switch (x->second) {
+                       case MeterInput:
+                               meterstr = X_("input");
+                               break;
+                       case MeterPreFader:
+                               meterstr = X_("pre");
+                               break;
+                       case MeterPostFader:
+                               meterstr = X_("post");
+                               break;
+                       }
+
+                       child->add_property (X_("meter"), meterstr);
+                       nafter->add_child_nocopy (*child);
+               }
+       }
+
+       node->add_child_nocopy (*nbefore);
+       node->add_child_nocopy (*nafter);
+
+       node->add_property ("type", "metering");
+
+       return *node;
+}
+
+int
+Session::GlobalMeteringStateCommand::set_state (const XMLNode& node)
+{
+       GlobalRouteBooleanState states;
+       XMLNodeList nlist;
+       const XMLProperty* prop;
+       XMLNode* child;
+       XMLNodeConstIterator niter;
+       int loop;
+
+       before.clear ();
+       after.clear ();
+       
+       for (loop = 0; loop < 2; ++loop) {
+
+               const char *str;
+
+               if (loop) {
+                       str = "after";
+               } else {
+                       str = "before";
+               }
+               
+               if ((child = node.child (str)) == 0) {
+                       warning << string_compose (_("global route meter state command has no \"%1\" node, ignoring entire command"), str) << endmsg;
+                       return -1;
+               }
+
+               nlist = child->children();
+
+               for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+                       
+                       RouteMeterState rms;
+                       boost::shared_ptr<Route> route;
+                       ID id;
+                       
+                       prop = (*niter)->property ("id");
+                       id = prop->value ();
+                       
+                       if ((route = sess.route_by_id (id)) == 0) {
+                               warning << string_compose (_("cannot find track/bus \"%1\" while rebuilding a global route state command, ignored"), id.to_s()) << endmsg;
+                               continue;
+                       }
+                       
+                       rms.first = boost::weak_ptr<Route> (route);
+                       
+                       prop = (*niter)->property ("meter");
+
+                       if (prop->value() == X_("pre")) {
+                               rms.second = MeterPreFader;
+                       } else if (prop->value() == X_("post")) {
+                               rms.second = MeterPostFader;
+                       } else {
+                               rms.second = MeterInput;
+                       }
+                       
+                       if (loop) {
+                               after.push_back (rms);
+                       } else {
+                               before.push_back (rms);
+                       }
+               }
+       }
+
+       return 0;
+}
index dc7eabf40f5d4a1863fa7faea95db021399a3704..981f9505d9bf92fa40dd6d77c73c4bdcd1a8d722 100644 (file)
@@ -305,9 +305,14 @@ Session::process_event (Event* ev)
        */
 
        if (non_realtime_work_pending()) {
-               immediate_events.insert (immediate_events.end(), ev);
-               _remove_event (ev);
-               return;
+               
+               /* except locates, which we have the capability to handle */
+
+               if (ev->type != Event::Locate) {
+                       immediate_events.insert (immediate_events.end(), ev);
+                       _remove_event (ev);
+                       return;
+               }
        }
 
        //printf("Processing event: %s\n", event_names[ev->type]);
index b3a5ec6e01b0d87759f906137ba5f63c6633c84c..18bf9b83e13f08c63669eb7efbfb279c3524c9da 100644 (file)
@@ -581,7 +581,7 @@ Session::mmc_step (MIDI::MachineControl &mmc, int steps)
        }
        
        double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
-       double cur_speed = (((steps * 0.5) * Config->get_smpte_frames_per_second()) / diff_secs) / Config->get_smpte_frames_per_second();
+       double cur_speed = (((steps * 0.5) * smpte_frames_per_second()) / diff_secs) / smpte_frames_per_second();
        
        if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
                /* change direction */
@@ -640,6 +640,8 @@ Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
        smpte.minutes = mmc_tc[1];
        smpte.seconds = mmc_tc[2];
        smpte.frames = mmc_tc[3];
+       smpte.rate = smpte_frames_per_second();
+       smpte.drop = smpte_drop_frames();
   
        // Also takes smpte offset into account:
        smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
index c877abdca462232061669d249a48c223164d6577..2de3448cd16d32b9dc724ea71329d445604212f2 100644 (file)
@@ -57,7 +57,7 @@ Session::process (nframes_t nframes)
        }
 
        if (non_realtime_work_pending()) {
-               if (g_atomic_int_get (&butler_should_do_transport_work) == 0) {
+               if (!transport_work_requested ()) {
                        post_transport ();
                } 
        } 
index bcc9b730ba958c31d1d666c82ad9e5e7e24f21e9..097a9e23814d09a9a681599858d7664a8e7ecdd5 100644 (file)
@@ -43,8 +43,8 @@
 #ifdef HAVE_SYS_VFS_H
 #include <sys/vfs.h>
 #else
-#include <sys/mount.h>
 #include <sys/param.h>
+#include <sys/mount.h>
 #endif
 
 #include <glibmm.h>
@@ -57,6 +57,8 @@
 #include <pbd/pathscanner.h>
 #include <pbd/pthread_utils.h>
 #include <pbd/strsplit.h>
+#include <pbd/stacktrace.h>
+#include <pbd/copyfile.h>
 
 #include <ardour/audioengine.h>
 #include <ardour/configuration.h>
@@ -93,6 +95,7 @@
 #include <ardour/control_protocol_manager.h>
 #include <ardour/region_factory.h>
 #include <ardour/source_factory.h>
+#include <ardour/playlist_factory.h>
 
 #include <control_protocol/control_protocol.h>
 
@@ -107,12 +110,14 @@ void
 Session::first_stage_init (string fullpath, string snapshot_name)
 {
        if (fullpath.length() == 0) {
+               destroy ();
                throw failed_constructor();
        }
 
        char buf[PATH_MAX+1];
        if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
                error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
+               destroy ();
                throw failed_constructor();
        }
 
@@ -133,7 +138,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
 
        g_atomic_int_set (&processing_prohibited, 0);
-       send_cnt = 0;
        insert_cnt = 0;
        _transport_speed = 0;
        _last_transport_speed = 0;
@@ -164,7 +168,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        _worst_output_latency = 0;
        _worst_input_latency = 0;
        _worst_track_latency = 0;
-       _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
+       _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
        _slave = 0;
        butler_mixdown_buffer = 0;
        butler_gain_buffer = 0;
@@ -247,7 +251,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
 
        RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
        SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
-       Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
+       PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
        Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
        NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
        AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
@@ -316,10 +320,20 @@ Session::second_stage_init (bool new_session)
        _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
        _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
 
-       if (_engine.running()) {
+       try {
                when_engine_running();
-       } else {
-               first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
+       }
+
+       /* handle this one in a different way than all others, so that its clear what happened */
+       
+       catch (AudioEngine::PortRegistrationFailure& err) {
+               error << _("Unable to create all required ports")
+                     << endmsg;
+               return -1;
+       }
+
+       catch (...) {
+               return -1;
        }
 
        //send_full_time_code ();
@@ -391,6 +405,7 @@ Session::setup_raid_path (string path)
                if (fspath[fspath.length()-1] != '/') {
                        fspath += '/';
                }
+
                fspath += sound_dir (false);
                
                AudioFileSource::set_search_path (fspath);
@@ -604,15 +619,12 @@ Session::save_state (string snapshot_name, bool pending)
                xml_path = _path;
                xml_path += snapshot_name;
                xml_path += _statefile_suffix;
+
                bak_path = xml_path;
                bak_path += ".bak";
                
-               // Make backup of state file
-               
-               if ((access (xml_path.c_str(), F_OK) == 0) &&
-                   (rename(xml_path.c_str(), bak_path.c_str()))) {
-                       error << _("could not backup old state file, current state not saved.") << endmsg;
-                       return -1;
+               if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
+                       copy_file (xml_path, bak_path);
                }
 
        } else {
@@ -623,30 +635,31 @@ Session::save_state (string snapshot_name, bool pending)
 
        }
 
+       string tmp_path;
+
+       tmp_path = _path;
+       tmp_path += snapshot_name;
+       tmp_path += ".tmp";
+
        cerr << "actually writing state\n";
 
-       if (!tree.write (xml_path)) {
-               error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
+       if (!tree.write (tmp_path)) {
+               error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
+               unlink (tmp_path.c_str());
+               return -1;
 
-               /* don't leave a corrupt file lying around if it is
-                  possible to fix.
-               */
+       } else {
 
-               if (unlink (xml_path.c_str())) {
-                       error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
-               } else {
-                       if (!pending) {
-                               if (rename (bak_path.c_str(), xml_path.c_str())) {
-                                       error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
-                               }
-                       }
+               if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
+                       error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
+                       unlink (tmp_path.c_str());
+                       return -1;
                }
-
-               return -1;
        }
 
        if (!pending) {
-                save_history(snapshot_name);
+
+                save_history (snapshot_name);
 
                bool was_dirty = dirty();
 
@@ -715,15 +728,52 @@ Session::load_state (string snapshot_name)
 
        set_dirty();
 
-       if (state_tree->read (xmlpath)) {
-               return 0;
-       } else {
+       if (!state_tree->read (xmlpath)) {
                error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
+               delete state_tree;
+               state_tree = 0;
+               return -1;
        }
 
-       delete state_tree;
-       state_tree = 0;
-       return -1;
+       XMLNode& root (*state_tree->root());
+       
+       if (root.name() != X_("Session")) {
+               error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
+               delete state_tree;
+               state_tree = 0;
+               return -1;
+       }
+
+       const XMLProperty* prop;
+       bool is_old = false;
+
+       if ((prop = root.property ("version")) == 0) {
+               /* no version implies very old version of Ardour */
+               is_old = true;
+       } else {
+               int major_version;
+               major_version = atoi (prop->value()); // grab just the first number before the period
+               if (major_version < 2) {
+                       is_old = true;
+               }
+       }
+
+       if (is_old) {
+               string backup_path;
+
+               backup_path = xmlpath;
+               backup_path += ".1";
+
+               info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
+                                       xmlpath, backup_path) 
+                    << endmsg;
+
+               copy_file (xmlpath, backup_path);
+
+               /* if it fails, don't worry. right? */
+       }
+
+       return 0;
 }
 
 int
@@ -1520,6 +1570,7 @@ Session::load_sources (const XMLNode& node)
                if ((source = XMLSourceFactory (**niter)) == 0) {
                        error << _("Session: cannot create Source from XML description.") << endmsg;
                }
+
        }
 
        return 0;
@@ -1791,7 +1842,7 @@ Session::load_playlists (const XMLNode& node)
 {
        XMLNodeList nlist;
        XMLNodeConstIterator niter;
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
 
        nlist = node.children();
 
@@ -1812,7 +1863,7 @@ Session::load_unused_playlists (const XMLNode& node)
 {
        XMLNodeList nlist;
        XMLNodeConstIterator niter;
-       Playlist *playlist;
+       boost::shared_ptr<Playlist> playlist;
 
        nlist = node.children();
 
@@ -1827,34 +1878,22 @@ Session::load_unused_playlists (const XMLNode& node)
 
                // now manually untrack it
 
-               track_playlist (playlist, false);
+               track_playlist (false, boost::weak_ptr<Playlist> (playlist));
        }
 
        return 0;
 }
 
-Playlist *
+boost::shared_ptr<Playlist>
 Session::XMLPlaylistFactory (const XMLNode& node)
 {
-       const XMLProperty* type = node.property("type");
-
        try {
-       
-       if ( !type || type->value() == "audio" ) {
-
-               return new AudioPlaylist (*this, node);
-       
-       } else if (type->value() == "midi") {
-
-               return new MidiPlaylist (*this, node);
-       
-       }
-       
-       } catch (failed_constructor& err) {
-               return 0;
+               return PlaylistFactory::create (*this, node);
        }
 
-       return 0;
+       catch (failed_constructor& err) {
+               return boost::shared_ptr<Playlist>();
+       }
 }
 
 int
@@ -1913,7 +1952,6 @@ Session::sound_dir (bool with_path) const
        
        old_withpath = _path;
        old_withpath += old_sound_dir_name;
-       old_withpath += '/';
 
        if (stat (old_withpath.c_str(), &statbuf) == 0) {
                if (with_path)
@@ -1933,7 +1971,6 @@ Session::sound_dir (bool with_path) const
        res += legalize_for_path (_name);
        res += '/';
        res += sound_dir_name;
-       res += '/';
 
        return res;
 }
@@ -2265,7 +2302,12 @@ void
 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
 {
        for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
-               i->first->set_meter_point (i->second, arg);
+
+               boost::shared_ptr<Route> r = (i->first.lock());
+
+               if (r) {
+                       r->set_meter_point (i->second, arg);
+               }
        }
 }
 
@@ -2273,8 +2315,13 @@ void
 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
 {
        for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
-               Route* r = i->first.get();
-               (r->*method) (i->second, arg);
+
+               boost::shared_ptr<Route> r = (i->first.lock());
+
+               if (r) {
+                       Route* rp = r.get();
+                       (rp->*method) (i->second, arg);
+               }
        }
 }
 
@@ -2506,11 +2553,20 @@ Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_th
        return 0;
 }
 
+struct RegionCounter {
+    typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
+    AudioSourceList::iterator iter;
+    boost::shared_ptr<Region> region;
+    uint32_t count;
+    
+    RegionCounter() : count (0) {}
+};
+
 int
 Session::cleanup_sources (Session::cleanup_report& rep)
 {
        vector<boost::shared_ptr<Source> > dead_sources;
-       vector<Playlist*> playlists_tbd;
+       vector<boost::shared_ptr<Playlist> > playlists_tbd;
        PathScanner scanner;
        string sound_path;
        vector<space_and_path>::iterator i;
@@ -2549,73 +2605,36 @@ Session::cleanup_sources (Session::cleanup_report& rep)
 
        /* now delete any that were marked for deletion */
 
-       for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
-               PlaylistList::iterator foo;
-
-               if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
-                       unused_playlists.erase (foo);
-               }
-               delete *x;
+       for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
+               (*x)->drop_references ();
        }
 
-       /* step 2: find all un-referenced sources */
+       playlists_tbd.clear ();
+
+       /* step 2: find all un-used sources */
 
        rep.paths.clear ();
        rep.space = 0;
 
        for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
-
+               
                SourceMap::iterator tmp;
 
                tmp = i;
                ++tmp;
 
-               /* only remove files that are not in use and have some size
-                  to them. otherwise we remove the current "nascent"
+               /* do not bother with files that are zero size, otherwise we remove the current "nascent"
                   capture files.
                */
 
-               cerr << "checking out source " << i->second->name() << " use_count = " << i->second.use_count() << endl;
-
-               if (i->second.use_count() == 1 && i->second->length() > 0) {
+               if (!i->second->used() && i->second->length() > 0) {
                        dead_sources.push_back (i->second);
-
-                       /* remove this source from our own list to avoid us
-                          adding it to the list of all sources below
-                       */
-
-                       sources.erase (i);
-               }
+                       i->second->GoingAway();
+               } 
 
                i = tmp;
        }
 
-       /* Step 3: get rid of all regions in the region list that use any dead sources
-          in case the sources themselves don't go away (they might be referenced in
-          other snapshots).
-       */
-               
-       for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
-
-               for (RegionList::iterator r = regions.begin(); r != regions.end(); ) {
-                       RegionList::iterator tmp;
-
-                       tmp = r;
-                       ++tmp;
-                       
-                       boost::shared_ptr<Region> reg = r->second;
-
-                       for (uint32_t n = 0; n < reg->n_channels(); ++n) {
-                               if (reg->source (n) == (*i)) {
-                                       /* this region is dead */
-                                       remove_region (reg);
-                               }
-                       }
-                       
-                       r = tmp;
-               }
-       }
-
        /* build a list of all the possible sound directories for the session */
 
        for (i = session_dirs.begin(); i != session_dirs.end(); ) {
@@ -2624,7 +2643,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                ++nexti;
 
                sound_path += (*i).path;
-               sound_path += sound_dir_name;
+               sound_path += sound_dir (false);
 
                if (nexti != session_dirs.end()) {
                        sound_path += ':';
@@ -2632,7 +2651,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
 
                i = nexti;
        }
-       
+
        /* now do the same thing for the files that ended up in the sounds dir(s) 
           but are not referenced as sources in any snapshot.
        */
@@ -2672,7 +2691,6 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                                used = true;
                                break;
                        }
-
                }
 
                if (!used) {
@@ -2697,11 +2715,31 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                   on whichever filesystem it was already on.
                */
 
-               newpath = Glib::path_get_dirname (*x);
-               newpath = Glib::path_get_dirname (newpath);
+               if (_path.find ("/sounds/")) {
+
+                       /* old school, go up 1 level */
+
+                       newpath = Glib::path_get_dirname (*x);      // "sounds" 
+                       newpath = Glib::path_get_dirname (newpath); // "session-name"
+
+               } else {
+
+                       /* new school, go up 4 levels */
+                       
+                       newpath = Glib::path_get_dirname (*x);      // "audiofiles" 
+                       newpath = Glib::path_get_dirname (newpath); // "session-name"
+                       newpath = Glib::path_get_dirname (newpath); // "interchange"
+                       newpath = Glib::path_get_dirname (newpath); // "session-dir"
+               }
 
                newpath += '/';
                newpath += dead_sound_dir_name;
+
+               if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
+                       error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
+                       return -1;
+               }
+
                newpath += '/';
                newpath += Glib::path_get_basename ((*x));
                
@@ -2741,7 +2779,6 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                              << endmsg;
                        goto out;
                }
-               
 
                /* see if there an easy to find peakfile for this file, and remove it.
                 */
@@ -2759,7 +2796,6 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                                goto out;
                        }
                }
-
        }
 
        ret = 0;
@@ -2865,6 +2901,12 @@ Session::set_clean ()
        }
 }
 
+void
+Session::set_deletion_in_progress ()
+{
+       _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
+}
+
 void
 Session::add_controllable (Controllable* c)
 {
@@ -2916,8 +2958,8 @@ Session::save_history (string snapshot_name)
     XMLTree tree;
     string xml_path;
     string bak_path;
-    
-    tree.set_root (&_history.get_state());
+
+    tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
 
     if (snapshot_name.empty()) {
        snapshot_name = _current_snapshot_name;
@@ -2934,8 +2976,6 @@ Session::save_history (string snapshot_name)
         return -1;
     }
 
-    cerr << "actually writing history\n";
-
     if (!tree.write (xml_path))
     {
         error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
@@ -2965,18 +3005,22 @@ Session::restore_history (string snapshot_name)
     XMLTree tree;
     string xmlpath;
 
+    if (snapshot_name.empty()) {
+           snapshot_name = _current_snapshot_name;
+    }
+
     /* read xml */
     xmlpath = _path + snapshot_name + ".history";
     cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
 
     if (access (xmlpath.c_str(), F_OK)) {
-        error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
-        return 1;
+           info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
+           return 1;
     }
 
     if (!tree.read (xmlpath)) {
-        error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
-        return -1;
+           error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
+           return -1;
     }
 
     /* replace history */
@@ -3005,10 +3049,19 @@ Session::restore_history (string snapshot_name)
                    if (n->name() == "MementoCommand" ||
                        n->name() == "MementoUndoCommand" ||
                        n->name() == "MementoRedoCommand") {
+
                            if ((c = memento_command_factory(n))) {
                                    ut->add_command(c);
                            }
+                           
+                   } else if (n->name() == X_("GlobalRouteStateCommand")) {
+
+                           if ((c = global_state_command_factory (*n))) {
+                                   ut->add_command (c);
+                           }
+                           
                    } else {
+
                            error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
                    }
            }
@@ -3039,7 +3092,6 @@ Session::config_changed (const char* parameter_name)
                        
                        for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
                                if ((*i)->record_enabled ()) {
-                                       //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
                                        (*i)->monitor_input (!Config->get_auto_input());
                                }
                        }
@@ -3099,7 +3151,7 @@ Session::config_changed (const char* parameter_name)
 
                setup_raid_path (Config->get_raid_path());
 
-       } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
+       } else if (PARAM_IS ("smpte-format")) {
 
                sync_time_vars ();
 
index d24bab5ff81f39c9c4f57e8e42bb2b7f0ee7f0b3..585dad6b1a4038fca0ca364ee0989ef8a3e1486e 100644 (file)
@@ -48,43 +48,141 @@ Session::bbt_time (nframes_t when, BBT_Time& bbt)
 }
 
 /* SMPTE TIME */
+float
+Session::smpte_frames_per_second() const
+{
+       switch (Config->get_smpte_format()) {
+               case smpte_23976: 
+                       return 23.976;
+
+                       break;
+               case smpte_24: 
+                       return 24;
+
+                       break;
+               case smpte_24976: 
+                       return 24.976;
+
+                       break;
+               case smpte_25: 
+                       return 25;
+
+                       break;
+               case smpte_2997: 
+                       return 29.97;
+
+                       break;
+               case smpte_2997drop: 
+                       return 29.97;
+
+                       break;
+               case smpte_30: 
+                       return 30;
+
+                       break;
+               case smpte_30drop: 
+                       return 30;
+
+                       break;
+               case smpte_5994: 
+                       return 59.94;
+
+                       break;
+               case smpte_60: 
+                       return 60;
+
+                       break;
+               default:
+                 cerr << "Editor received unexpected smpte type" << endl;
+       }
+       return 30.0;
+}
+bool
+Session::smpte_drop_frames() const
+{
+       switch (Config->get_smpte_format()) {
+               case smpte_23976: 
+                       return false;
+
+                       break;
+               case smpte_24: 
+                       return false;
+
+                       break;
+               case smpte_24976: 
+                       return false;
+
+                       break;
+               case smpte_25: 
+                       return false;
+
+                       break;
+               case smpte_2997: 
+                       return false;
 
+                       break;
+               case smpte_2997drop: 
+                       return true;
+
+                       break;
+               case smpte_30: 
+                       return false;
+
+                       break;
+               case smpte_30drop: 
+                       return true;
+
+                       break;
+               case smpte_5994: 
+                       return false;
+
+                       break;
+               case smpte_60: 
+                       return false;
+
+                       break;
+               default:
+                       cerr << "Editor received unexpected smpte type" << endl;
+       }
+       return false;
+}
 void
 Session::sync_time_vars ()
 {
        _current_frame_rate = (nframes_t) round (_base_frame_rate * (1.0 + (Config->get_video_pullup()/100.0)));
-       _frames_per_hour = _current_frame_rate * 3600;
-       _frames_per_smpte_frame = (double) _current_frame_rate / (double) Config->get_smpte_frames_per_second();
-       _smpte_frames_per_hour = (unsigned long) (Config->get_smpte_frames_per_second() * 3600.0);
+       _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second();
+       if (smpte_drop_frames()) {
+         _frames_per_hour = (long)(107892 * _frames_per_smpte_frame);
+       } else {
+         _frames_per_hour = (long)(3600 * rint(smpte_frames_per_second()) * _frames_per_smpte_frame);
+       }
+       _smpte_frames_per_hour = (nframes_t)rint(smpte_frames_per_second() * 3600.0);
+
 }
 
 int
-Session::set_smpte_type (float fps, bool drop_frames)
+Session::set_smpte_format (SmpteFormat format)
 {
-       Config->set_smpte_frames_per_second (fps);
-       Config->set_smpte_drop_frames (drop_frames);
+
+       Config->set_smpte_format (format);
 
        last_smpte_valid = false;
        // smpte type bits are the middle two in the upper nibble
-       switch ((int) ceil (fps)) {
+       switch ((int) ceil (smpte_frames_per_second())) {
        case 24:
                mtc_smpte_bits = 0;
-               SMPTE::Time::default_rate = SMPTE::MTC_24_FPS;
                break;
 
        case 25:
                mtc_smpte_bits = 0x20;
-               SMPTE::Time::default_rate = SMPTE::MTC_25_FPS;
                break;
 
        case 30:
        default:
-               if (drop_frames) {
+               if (smpte_drop_frames()) {
                        mtc_smpte_bits = 0x40;
-                       SMPTE::Time::default_rate = SMPTE::MTC_30_FPS_DROP;
                } else {
                        mtc_smpte_bits =  0x60;
-                       SMPTE::Time::default_rate = SMPTE::MTC_30_FPS;
                }
                break;
        };
@@ -113,7 +211,8 @@ Session::set_smpte_offset_negative (bool neg)
 void
 Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset, bool use_subframes ) const
 {
-       if (Config->get_smpte_drop_frames()) {
+
+       if (smpte.drop) {
                // The drop frame format was created to better approximate the 30000/1001 = 29.97002997002997....
                // framerate of NTSC color TV. The used frame rate of drop frame is 29.97, which drifts by about
                // 0.108 frame per hour, or about 1.3 frames per 12 hours. This is not perfect, but a lot better
@@ -152,9 +251,10 @@ Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset
                //  0:10:00:00        0.0             0                   600.000         26460000 (accurate)
                //
                //  Per Sigmond <per@sigmond.no>
-    
+
                // Samples inside time dividable by 10 minutes (real time accurate)
-               nframes_t base_samples = ((smpte.hours * 60 * 60) + ((smpte.minutes / 10) * 10 * 60)) * frame_rate();
+               nframes_t base_samples = (nframes_t) (((smpte.hours * 107892) + ((smpte.minutes / 10) * 17982)) * _frames_per_smpte_frame);
+
                // Samples inside time exceeding the nearest 10 minutes (always offset, see above)
                long exceeding_df_minutes = smpte.minutes % 10;
                long exceeding_df_seconds = (exceeding_df_minutes * 60) + smpte.seconds;
@@ -162,12 +262,18 @@ Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset
                nframes_t exceeding_samples = (nframes_t) rint(exceeding_df_frames * _frames_per_smpte_frame);
                sample = base_samples + exceeding_samples;
        } else {
-               // Non drop is easy:
-               sample = (((smpte.hours * 60 * 60) + (smpte.minutes * 60) + smpte.seconds) * frame_rate()) + (nframes_t)rint(smpte.frames * _frames_per_smpte_frame);
+               /* 
+                  Non drop is easy.. just note the use of 
+                  rint(smpte.rate) * _frames_per_smpte_frame
+                  (frames per SMPTE second), which is larger than  
+                  frame_rate() in the non-integer SMPTE rate case.
+               */
+
+               sample = (nframes_t)rint((((smpte.hours * 60 * 60) + (smpte.minutes * 60) + smpte.seconds) * (rint(smpte.rate) * _frames_per_smpte_frame)) + (smpte.frames * _frames_per_smpte_frame));
        }
   
        if (use_subframes) {
-               sample += (long) (((double)smpte.subframes * _frames_per_smpte_frame) / 80.0);
+               sample += (long) (((double)smpte.subframes * _frames_per_smpte_frame) / Config->get_subframes_per_frame());
        }
   
        if (use_offset) {
@@ -190,6 +296,7 @@ Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset
                        }
                }
        }
+
 }
 
 
@@ -224,14 +331,14 @@ Session::sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset,
        // high sample numbers in the calculations that follow.
        smpte.hours = offset_sample / _frames_per_hour;
        offset_sample = offset_sample % _frames_per_hour;
-  
+
        // Calculate exact number of (exceeding) smpte frames and fractional frames
        smpte_frames_left_exact = (double) offset_sample / _frames_per_smpte_frame;
        smpte_frames_fraction = smpte_frames_left_exact - floor( smpte_frames_left_exact );
-       smpte.subframes = (long) rint(smpte_frames_fraction * 80.0);
+       smpte.subframes = (long) rint(smpte_frames_fraction * Config->get_subframes_per_frame());
   
        // XXX Not sure if this is necessary anymore...
-       if (smpte.subframes == 80) {
+       if (smpte.subframes == Config->get_subframes_per_frame()) {
                // This can happen with 24 fps (and 29.97 fps ?)
                smpte_frames_left_exact = ceil( smpte_frames_left_exact );
                smpte.subframes = 0;
@@ -240,7 +347,7 @@ Session::sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset,
        // Extract hour-exceeding frames for minute, second and frame calculations
        smpte_frames_left = ((long) floor( smpte_frames_left_exact ));
 
-       if (Config->get_smpte_drop_frames()) {
+       if (smpte_drop_frames()) {
                // See long explanation in smpte_to_sample()...
 
                // Number of 10 minute chunks
@@ -276,15 +383,18 @@ Session::sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset,
                }
        } else {
                // Non drop is easy
-               smpte.minutes = smpte_frames_left / ((long) Config->get_smpte_frames_per_second () * 60);
-               smpte_frames_left = smpte_frames_left % ((long) Config->get_smpte_frames_per_second () * 60);
-               smpte.seconds = smpte_frames_left / (long) Config->get_smpte_frames_per_second ();
-               smpte.frames = smpte_frames_left % (long) Config->get_smpte_frames_per_second ();
+               smpte.minutes = smpte_frames_left / ((long) rint (smpte_frames_per_second ()) * 60);
+               smpte_frames_left = smpte_frames_left % ((long) rint (smpte_frames_per_second ()) * 60);
+               smpte.seconds = smpte_frames_left / (long) rint(smpte_frames_per_second ());
+               smpte.frames = smpte_frames_left % (long) rint(smpte_frames_per_second ());
        }
 
        if (!use_subframes) {
                smpte.subframes = 0;
        }
+       /* set frame rate and drop frame */
+       smpte.rate = smpte_frames_per_second ();
+       smpte.drop = smpte_drop_frames();
 }
 
 void
@@ -415,7 +525,7 @@ Session::jack_timebase_callback (jack_transport_state_t state,
 
 #ifdef HAVE_JACK_VIDEO_SUPPORT
        //poke audio video ratio so Ardour can track Video Sync
-       pos->audio_frames_per_video_frame = frame_rate() / Config->get_smpte_frames_per_second ();
+       pos->audio_frames_per_video_frame = frame_rate() / smpte_frames_per_second();
        pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio);
 #endif
 
@@ -423,7 +533,7 @@ Session::jack_timebase_callback (jack_transport_state_t state,
        /* SMPTE info */
 
        t.smpte_offset = _smpte_offset;
-       t.smpte_frame_rate = Config->get_smpte_frames_per_second ();
+       t.smpte_frame_rate = smpte_frames_per_second();
 
        if (_transport_speed) {
 
@@ -474,7 +584,7 @@ Session::convert_to_frames_at (nframes_t position, AnyTime& any)
                secs = any.smpte.hours * 60 * 60;
                secs += any.smpte.minutes * 60;
                secs += any.smpte.seconds;
-               secs += any.smpte.frames / Config->get_smpte_frames_per_second ();
+               secs += any.smpte.frames / smpte_frames_per_second();
                if (_smpte_offset_negative) 
                {
                        return (nframes_t) floor (secs * frame_rate()) - _smpte_offset;
index e9c4e3785fc53b228e20200b069c2bc194f17082..ad3573a72e0bd8e61fd7b8775b204b54ed3ebae6 100644 (file)
@@ -52,8 +52,10 @@ using namespace PBD;
 void
 Session::request_input_change_handling ()
 {
-       Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
-       queue_event (ev);
+       if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
+               Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
+               queue_event (ev);
+       }
 }
 
 void
@@ -185,9 +187,14 @@ Session::realtime_stop (bool abort)
 void
 Session::butler_transport_work ()
 {
+  restart:
+       bool finished;
        boost::shared_ptr<RouteList> r = routes.reader ();
        boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
 
+       int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
+       finished = true;
+
        if (post_transport_work & PostTransportCurveRealloc) {
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
                        (*i)->curve_reallocate();
@@ -211,30 +218,48 @@ Session::butler_transport_work ()
                cumulative_rf_motion = 0;
                reset_rf_scale (0);
 
-               for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
-                       if (!(*i)->hidden()) {
-                               if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
-                                       (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
+               /* don't seek if locate will take care of that in non_realtime_stop() */
+
+               if (!(post_transport_work & PostTransportLocate)) {
+                       
+                       for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+                               if (!(*i)->hidden()) {
+                                       if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
+                                               (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
+                                       }
+                                       else {
+                                               (*i)->seek (_transport_frame);
+                                       }
                                }
-                               else {
-                                       (*i)->seek (_transport_frame);
+                               if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
+                                       /* new request, stop seeking, and start again */
+                                       g_atomic_int_dec_and_test (&butler_should_do_transport_work);
+                                       goto restart;
                                }
                        }
                }
        }
 
        if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
-               non_realtime_stop (post_transport_work & PostTransportAbort);
+               non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
+               if (!finished) {
+                       g_atomic_int_dec_and_test (&butler_should_do_transport_work);
+                       goto restart;
+               }
        }
 
        if (post_transport_work & PostTransportOverWrite) {
-               non_realtime_overwrite ();
+               non_realtime_overwrite (on_entry, finished);
+               if (!finished) {
+                       g_atomic_int_dec_and_test (&butler_should_do_transport_work);
+                       goto restart;
+               }
        }
 
        if (post_transport_work & PostTransportAudition) {
                non_realtime_set_audition ();
        }
-
+       
        g_atomic_int_dec_and_test (&butler_should_do_transport_work);
 }
 
@@ -249,7 +274,7 @@ Session::non_realtime_set_speed ()
 }
 
 void
-Session::non_realtime_overwrite ()
+Session::non_realtime_overwrite (int on_entry, bool& finished)
 {
        boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
 
@@ -257,11 +282,15 @@ Session::non_realtime_overwrite ()
                if ((*i)->pending_overwrite) {
                        (*i)->overwrite_existing_buffers ();
                }
+               if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
+                       finished = false;
+                       return;
+               }
        }
 }
 
 void
-Session::non_realtime_stop (bool abort)
+Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 {
        struct tm* now;
        time_t     xnow;
@@ -376,6 +405,11 @@ Session::non_realtime_stop (bool abort)
                                        (*i)->seek (_transport_frame);
                                }
                        }
+                       if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
+                               finished = false;
+                               /* we will be back */
+                               return;
+                       }
                }
 
 #ifdef LEAVE_TRANSPORT_UNADJUSTED
@@ -629,6 +663,8 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
 
        } else {
 
+               cerr << "butler not requested\n";
+
                /* this is functionally what clear_clicks() does but with a tentative lock */
 
                Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
@@ -904,7 +940,6 @@ Session::post_transport ()
        if (post_transport_work & PostTransportLocate) {
 
                if ((Config->get_auto_play() && !_exporting) || (post_transport_work & PostTransportRoll)) {
-                       
                        start_transport ();
                        
                } else {
@@ -1127,7 +1162,7 @@ void
 Session::request_bounded_roll (nframes_t start, nframes_t end)
 {
        request_stop ();
-       Event *ev = new Event (Event::StopOnce, Event::Replace, Event::Immediate, end, 0.0);
+       Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
        queue_event (ev);
        request_locate (start, true);
 }
@@ -1135,6 +1170,8 @@ Session::request_bounded_roll (nframes_t start, nframes_t end)
 void
 Session::engine_halted ()
 {
+       bool ignored;
+
        /* there will be no more calls to process(), so
           we'd better clean up for ourselves, right now.
 
@@ -1147,7 +1184,7 @@ Session::engine_halted ()
        stop_butler ();
        
        realtime_stop (false);
-       non_realtime_stop (false);
+       non_realtime_stop (false, 0, ignored);
        transport_sub_state = 0;
 
        TransportStateChange (); /* EMIT SIGNAL */
index 6fb71e9596dc46caeb887b9f07876c79aad99b52..aca8cf5a2576d5d0bfbe8b0e5ced87eba9a8c7cd 100644 (file)
@@ -49,7 +49,7 @@ uint64_t                              SMFSource::header_position_offset;
 */
 
 SMFSource::SMFSource (Session& s, std::string path, Flag flags)
-       : MidiSource (s, region_name_from_path(path))
+       : MidiSource (s, region_name_from_path(path, false))
        , _channel(0)
        , _flags (Flag(flags | Writable)) // FIXME: this needs to be writable for now
        , _allow_remove_if_empty(true)
index a30bfcf49b928383c23927f27443e0432bece818..8e90eac6ab1be8bbc1b634c57cba47af8da8eceb 100644 (file)
@@ -408,26 +408,25 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt)
                PeakBuildRecord *pbr = 0;
                
                if (pending_peak_builds.size()) {
-                               pbr = pending_peak_builds.back();
-                       }
+                       pbr = pending_peak_builds.back();
+               }
                        
-                       if (pbr && pbr->frame + pbr->cnt == oldlen) {
-                               
-                               /* the last PBR extended to the start of the current write,
-                                  so just extend it again.
-                               */
-
-                               pbr->cnt += cnt;
-                       } else {
-                               pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt));
-                       }
+               if (pbr && pbr->frame + pbr->cnt == oldlen) {
                        
-                       _peaks_built = false;
+                       /* the last PBR extended to the start of the current write,
+                          so just extend it again.
+                       */
+                       pbr->cnt += cnt;
+               } else {
+                       pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt));
+               }
+
+               _peaks_built = false;
        }
        
        
        if (_build_peakfiles) {
-               queue_for_peaks (shared_from_this ());
+               queue_for_peaks (shared_from_this (), false);
        }
 
        _write_data_count = cnt;
@@ -540,7 +539,7 @@ SndFileSource::destructive_write_unlocked (Sample* data, nframes_t cnt)
        }
 
        if (_build_peakfiles) {
-               queue_for_peaks (shared_from_this ());
+               queue_for_peaks (shared_from_this (), true);
        }
        
        return cnt;
index 8f0afd3507d9a416b3dce2f97ea6d4a414222ea3..db2147493aaf971e4ea353e8ed3fa4489a9b8568 100644 (file)
@@ -131,15 +131,22 @@ Source::update_length (jack_nframes_t pos, jack_nframes_t cnt)
 }
 
 void
-Source::add_playlist (Playlist* pl)
+Source::add_playlist (boost::shared_ptr<Playlist> pl)
 {
        _playlists.insert (pl);
+       pl->GoingAway.connect (bind (mem_fun (*this, &Source::remove_playlist), boost::weak_ptr<Playlist> (pl)));
 }
 
 void
-Source::remove_playlist (Playlist* pl)
+Source::remove_playlist (boost::weak_ptr<Playlist> wpl)
 {
-       std::set<Playlist*>::iterator x;
+       boost::shared_ptr<Playlist> pl (wpl.lock());
+
+       if (!pl) {
+               return;
+       }
+
+       std::set<boost::shared_ptr<Playlist> >::iterator x;
 
        if ((x = _playlists.find (pl)) != _playlists.end()) {
                _playlists.erase (x);
index 001af609dc1c20997fe1985de0c2ab7fa1cebbb5..ad01bf617170fefc5e08d0c829389cecf935207d 100644 (file)
@@ -64,47 +64,26 @@ SourceFactory::create (Session& s, const XMLNode& node)
 
        if (type == DataType::AUDIO) {
 
-               if (node.property (X_("destructive")) != 0) {
-
-                       boost::shared_ptr<Source> ret (new DestructiveFileSource (s, node));
+               try {
+                       boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
                        if (setup_peakfile (ret)) {
                                return boost::shared_ptr<Source>();
                        }
                        SourceCreated (ret);
                        return ret;
+               } 
 
-               } else {
-               
-               try {
-                       boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
+               catch (failed_constructor& err) {
+                       boost::shared_ptr<Source> ret (new SndFileSource (s, node));
                        if (setup_peakfile (ret)) {
                                return boost::shared_ptr<Source>();
                        }
                        SourceCreated (ret);
                        return ret;
-               
-               } catch (failed_constructor& err) {
-
-                       try {
-                               boost::shared_ptr<Source> ret (new CoreAudioSource (node));
-                               SourceCreated (ret);
-                               return ret;
-                       } 
-
-
-                       catch (failed_constructor& err) {
-
-                               boost::shared_ptr<Source> ret (new SndFileSource (s, node));
-                               if (setup_peakfile (ret)) {
-                                       return boost::shared_ptr<Source>();
-                               }
-                               SourceCreated (ret);
-                               return ret;
-                       }
                }
 
        } else if (type == DataType::MIDI) {
-               
+
                boost::shared_ptr<Source> ret (new SMFSource (node));
                SourceCreated (ret);
                return ret;
@@ -127,33 +106,24 @@ SourceFactory::create (Session& s, const XMLNode& node)
 
        if (type == DataType::AUDIO) {
                
-               if (node.property (X_("destructive")) != 0) {
-                       
-                       boost::shared_ptr<Source> ret (new DestructiveFileSource (s, node));
-                       if (setup_peakfile (ret)) {
-                               return boost::shared_ptr<Source>();
-                       }
-                       SourceCreated (ret);
-                       return ret;
+               boost::shared_ptr<Source> ret (new SndFileSource (s, node));
 
-               } else {
-                       
-                       boost::shared_ptr<Source> ret (new SndFileSource (s, node));
-                       if (setup_peakfile (ret)) {
-                               return boost::shared_ptr<Source>();
-                       }
-                       SourceCreated (ret);
-                       return ret;
+               if (setup_peakfile (ret)) {
+                       return boost::shared_ptr<Source>();
                }
+               
+               SourceCreated (ret);
+               return ret;
 
        } else if (type == DataType::MIDI) {
 
                boost::shared_ptr<Source> ret (new SMFSource (s, node));
+               
                SourceCreated (ret);
                return ret;
 
        }
-       
+
        return boost::shared_ptr<Source> ();
 }
 
@@ -164,39 +134,53 @@ boost::shared_ptr<Source>
 SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
 {
        if (type == DataType::AUDIO) {
-               if (flags & Destructive) {
-                       boost::shared_ptr<Source> ret (new DestructiveFileSource (s, idstr, flags));
-                       if (setup_peakfile (ret)) {
-                               return boost::shared_ptr<Source>();
-                       }
-                       if (announce) {
-                               SourceCreated (ret);
-                       }
-                       return ret;
-       
+
+               if (!(flags & Destructive)) {
+
                        try {
                                boost::shared_ptr<Source> ret (new CoreAudioSource (s, idstr, flags));
+                               if (setup_peakfile (ret)) {
+                                       return boost::shared_ptr<Source>();
+                               }
                                if (announce) {
                                        SourceCreated (ret);
                                }
                                return ret;
-               
-                       } catch (failed_constructor& err) {
+                       }
+
+                       catch (failed_constructor& err) {
                                boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+                               if (setup_peakfile (ret)) {
+                                       return boost::shared_ptr<Source>();
+                               }
                                if (announce) {
                                        SourceCreated (ret);
                                }
                                return ret;
                        }
 
+               } else {
+
+                       boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+                       if (setup_peakfile (ret)) {
+                               return boost::shared_ptr<Source>();
+                       }
+                       if (announce) {
+                               SourceCreated (ret);
+                       }
+                       return ret;
+               }
+
        } else if (type == DataType::MIDI) {
 
                boost::shared_ptr<Source> ret (new SMFSource (s, node));
-               SourceCreated (ret);
+               if (announce) {
+                       SourceCreated (ret);
+               }
                return ret;
 
        }
-       
+
        return boost::shared_ptr<Source>();
 }
 
@@ -206,27 +190,32 @@ boost::shared_ptr<Source>
 SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
 {
        if (type == DataType::AUDIO) {
-       
+
                boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+
                if (setup_peakfile (ret)) {
                        return boost::shared_ptr<Source>();
                }
+
                if (announce) {
                        SourceCreated (ret);
                }
+
                return ret;
 
        } else if (type == DataType::MIDI) {
 
-               boost::shared_ptr<Source> ret (new SMFSource (s, idstr, SMFSource::Flag(0))); // FIXME: flags?
+               // FIXME: flags?
+               boost::shared_ptr<Source> ret (new SMFSource (s, idstr, SMFSource::Flag(0)));
+
                if (announce) {
                        SourceCreated (ret);
                }
-               return ret;
 
+               return ret;
        }
-       
-       return boost::shared_ptr<Source> ();
+
+       return boost::shared_ptr<Source>();
 }
 
 #endif // HAVE_COREAUDIO
@@ -235,39 +224,33 @@ boost::shared_ptr<Source>
 SourceFactory::createWritable (DataType type, Session& s, std::string path, bool destructive, nframes_t rate, bool announce)
 {
        /* this might throw failed_constructor(), which is OK */
+
        if (type == DataType::AUDIO) {
-       
-               if (destructive) {
-                       boost::shared_ptr<Source> ret (new DestructiveFileSource (s, path,
-                                               Config->get_native_file_data_format(),
-                                               Config->get_native_file_header_format(),
-                                               rate));
-                       if (setup_peakfile (ret)) {
-                               return boost::shared_ptr<Source>();
-                       }
-                       if (announce) {
-                               SourceCreated (ret);
-                       }
-               } else {
-                       boost::shared_ptr<Source> ret (new SndFileSource (s, path, 
-                                               Config->get_native_file_data_format(),
-                                               Config->get_native_file_header_format(),
-                                               rate));
-                       if (setup_peakfile (ret)) {
-                               return boost::shared_ptr<Source>();
-                       }
-                       if (announce) {
-                               SourceCreated (ret);
-                       }
-                       return ret;
+               boost::shared_ptr<Source> ret (new SndFileSource 
+                               (s, path, 
+                                Config->get_native_file_data_format(),
+                                Config->get_native_file_header_format(),
+                                rate,
+                                (destructive ? AudioFileSource::Flag (SndFileSource::default_writable_flags | AudioFileSource::Destructive) :
+                                 SndFileSource::default_writable_flags)));     
+
+               if (setup_peakfile (ret)) {
+                       return boost::shared_ptr<Source>();
+               }
+               if (announce) {
+                       SourceCreated (ret);
                }
+               return ret;
 
        } else if (type == DataType::MIDI) {
 
                boost::shared_ptr<Source> ret (new SMFSource (s, path));
-               SourceCreated (ret);
+               
+               if (announce) {
+                       SourceCreated (ret);
+               }
                return ret;
-       
+
        }
 
        return boost::shared_ptr<Source> ();
index 0ff94324bb088f369c92835006d9335791919708..e86c30dd4d90c7ac843dc0b0d62c4e8e3bcbcb05 100644 (file)
@@ -924,7 +924,10 @@ TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num)
 
        return frame_time (the_beat);
 
-       /* XXX just keeping this for reference
+
+
+       /*****************************  
+       XXX just keeping this for reference
 
         TempoMap::BBTPointList::iterator i;
         TempoMap::BBTPointList *more_zoomed_bbt_points;
@@ -978,7 +981,8 @@ TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num)
         delete more_zoomed_bbt_points;
         return fr ;
 
-       */
+       ******************************/
+
 
 }
 
index 9c94d32241889497f7155e3f5cd704f302846bbe..e0ef8fd0b339e411a36a31f9c9dd8421d7e1a58b 100644 (file)
@@ -40,6 +40,7 @@
 #include <pbd/error.h>
 #include <pbd/stacktrace.h>
 #include <pbd/xml++.h>
+#include <pbd/basename.h>
 #include <ardour/utils.h>
 
 #include "i18n.h"
@@ -47,6 +48,7 @@
 using namespace ARDOUR;
 using namespace std;
 using namespace PBD;
+using Glib::ustring;
 
 void
 elapsed_time_to_str (char *buf, uint32_t seconds)
@@ -90,6 +92,24 @@ elapsed_time_to_str (char *buf, uint32_t seconds)
        }
 }
 
+ustring 
+legalize_for_path (ustring str)
+{
+       ustring::size_type pos;
+       ustring legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=: ";
+       ustring legal;
+
+       legal = str;
+       pos = 0;
+
+       while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
+               legal.replace (pos, 1, "_");
+               pos += 1;
+       }
+
+       return legal;
+}
+#if 0
 string 
 legalize_for_path (string str)
 {
@@ -107,6 +127,7 @@ legalize_for_path (string str)
 
        return legal;
 }
+#endif
 
 ostream&
 operator<< (ostream& o, const BBT_Time& bbt)
@@ -180,7 +201,7 @@ tokenize_fullpath (string fullpath, string& path, string& name)
 }
 
 int
-touch_file (string path)
+touch_file (ustring path)
 {
        int fd = open (path.c_str(), O_RDWR|O_CREAT, 0660);
        if (fd >= 0) {
@@ -190,22 +211,31 @@ touch_file (string path)
        return 1;
 }
 
-string
-placement_as_string (Placement p)
+ustring
+region_name_from_path (ustring path, bool strip_channels)
 {
-       switch (p) {
-       case PreFader:
-               return _("pre");
-       default: /* to get g++ to realize we have all the cases covered */
-       case PostFader:
-               return _("post");
+       path = PBD::basename_nosuffix (path);
+
+       if (strip_channels) {
+
+               /* remove any "?R", "?L" or "?[a-z]" channel identifier */
+               
+               ustring::size_type len = path.length();
+               
+               if (len > 3 && (path[len-2] == '%' || path[len-2] == '?' || path[len-2] == '.') && 
+                   (path[len-1] == 'R' || path[len-1] == 'L' || (islower (path[len-1])))) {
+                       
+                       path = path.substr (0, path.length() - 2);
+               }
        }
-}
 
-string
-region_name_from_path (string path)
+       return path;
+}      
+
+bool
+path_is_paired (ustring path, ustring& pair_base)
 {
-       string::size_type pos;
+       ustring::size_type pos;
 
        /* remove any leading path */
 
@@ -219,21 +249,23 @@ region_name_from_path (string path)
                path = path.substr (0, pos);
        }
 
-       /* remove any "?R", "?L" or "?[a-z]" channel identifier */
-       
-       string::size_type len = path.length();
+       ustring::size_type len = path.length();
+
+       /* look for possible channel identifier: "?R", "%R", ".L" etc. */
 
-       if (len > 3 && (path[len-2] == '%' || path[len-2] == '?') && 
+       if (len > 3 && (path[len-2] == '%' || path[len-2] == '?' || path[len-2] == '.') && 
            (path[len-1] == 'R' || path[len-1] == 'L' || (islower (path[len-1])))) {
                
-               path = path.substr (0, path.length() - 2);
-       }
+               pair_base = path.substr (0, len-2);
+               return true;
 
-       return path;
-}      
+       } 
 
-string
-path_expand (string path)
+       return false;
+}
+
+ustring
+path_expand (ustring path)
 {
 #ifdef HAVE_WORDEXP
        /* Handle tilde and environment variable expansion in session path */
@@ -371,25 +403,65 @@ slave_source_to_string (SlaveSource src)
        }
 }
 
+/* I don't really like hard-coding these falloff rates here
+ * Probably should use a map of some kind that could be configured
+ * These rates are db/sec.
+*/
+
+#define METER_FALLOFF_OFF     0.0f
+#define METER_FALLOFF_SLOWEST 6.6f // BBC standard
+#define METER_FALLOFF_SLOW    8.6f // BBC standard
+#define METER_FALLOFF_MEDIUM  20.0f
+#define METER_FALLOFF_FAST    32.0f
+#define METER_FALLOFF_FASTER  46.0f
+#define METER_FALLOFF_FASTEST 70.0f
+
 float
 meter_falloff_to_float (MeterFalloff falloff)
 {
        switch (falloff) {
        case MeterFalloffOff:
-               return 0.0f;
+               return METER_FALLOFF_OFF;
        case MeterFalloffSlowest:
-               return 1.0f;
+               return METER_FALLOFF_SLOWEST;
        case MeterFalloffSlow:
-               return 2.0f;
+               return METER_FALLOFF_SLOW;
        case MeterFalloffMedium:
-               return 3.0f;
+               return METER_FALLOFF_MEDIUM;
        case MeterFalloffFast:
-               return 4.0f;
+               return METER_FALLOFF_FAST;
        case MeterFalloffFaster:
-               return 5.0f;
+               return METER_FALLOFF_FASTER;
        case MeterFalloffFastest:
+               return METER_FALLOFF_FASTEST;
        default:
-               return 6.0f;
+               return METER_FALLOFF_FAST;
+       }
+}
+
+MeterFalloff
+meter_falloff_from_float (float val)
+{
+       if (val == METER_FALLOFF_OFF) {
+               return MeterFalloffOff;
+       }
+       else if (val <= METER_FALLOFF_SLOWEST) {
+               return MeterFalloffSlowest;
+       }
+       else if (val <= METER_FALLOFF_SLOW) {
+               return MeterFalloffSlow;
+       }
+       else if (val <= METER_FALLOFF_MEDIUM) {
+               return MeterFalloffMedium;
+       }
+       else if (val <= METER_FALLOFF_FAST) {
+               return MeterFalloffFast;
+       }
+       else if (val <= METER_FALLOFF_FASTER) {
+               return MeterFalloffFaster;
+       }
+       else {
+               return MeterFalloffFastest;
        }
 }
 
index 0df20efe56ec977c2fb55727702adb4defa1a03e..110bfe41bef5884095afe8fb29e7b494f61dfc6c 100644 (file)
@@ -1,4 +1,14 @@
+# -*- python -*-
+
 import os.path
+import glob
+
+libclearlooks_files = [
+    'clearlooks_draw.c',
+    'clearlooks_rc_style.c',
+    'clearlooks_style.c',
+    'clearlooks_theme_main.c',
+    'support.c' ]
 
 Import ('env install_prefix')
 
@@ -7,17 +17,17 @@ clearlooks = env.Copy()
 clearlooks.Replace(CCFLAGS = ' `pkg-config --cflags gtk+-2.0` ',
                    LINKFLAGS = ' `pkg-config --libs gtk+-2.0` ')
 
-libclearlooks = clearlooks.SharedLibrary('clearlooks', [
-    'clearlooks_draw.c',
-    'clearlooks_rc_style.c',
-    'clearlooks_style.c',
-    'clearlooks_theme_main.c',
-    'support.c'
-])
+libclearlooks = clearlooks.SharedLibrary('clearlooks', libclearlooks_files) 
 
 usable_libclearlooks = clearlooks.Install ('engines', libclearlooks)
 Default (usable_libclearlooks)
 
 env.Alias('install',
-          env.Install(os.path.join(install_prefix,'lib/ardour2/engines'),
+          env.Install(os.path.join(install_prefix,env['LIBDIR'], 'ardour2', 'engines'),
                       libclearlooks))
+
+env.Alias('tarball', env.Distribute (env['DISTTREE'],
+                                     [ 'SConscript', 'bits.c'] +
+                                    libclearlooks_files +
+                                    glob.glob('*.h')
+                                    ))
index 6394982a20e6e26a800b757965a04e64c9b7beca..18b061ef82512231b19951841be30cafd9f8c513 100644 (file)
@@ -39,7 +39,7 @@ libflowcanvas = flowcanvas.SharedLibrary('flowcanvas', flowcanvas_files)
 
 Default(libflowcanvas)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libflowcanvas))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libflowcanvas))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      ['SConscript'] +
index 771de86dc8a65e3c3fd3ee1fb2e209fdbf6f1396..bdffd959b5745c55ce2a3d8b44036db515f6b991 100644 (file)
@@ -11,24 +11,42 @@ Import('env install_prefix')
 fst = env.Copy(CC="winegcc")
 fst.Append (CPPPATH=".")
 
-hackSDK = fst.Command('vst/aeffectx.h', 'vstsdk2.3/source/common/aeffectx.h', [
-    Delete ('${TARGET.dir}'),
-    Copy ('${TARGET.dir}', '${SOURCE.dir}'),
-    "sed -i '/struct VstFileType\|struct VstFileSelect/,/};/d' $TARGET"
-])
-
-a = fst.Object ('fst', 'fst.c')
-b = fst.Object ('fstinfofile', 'fstinfofile.c')
-c = fst.Object ('vstwin', 'vstwin.c')
-d = fst.Object ('vsti', 'vsti.c')
-
 if fst['VST']:
-    if os.access ('vst/aeffectx.h', os.F_OK):
-        Default([hackSDK,a,b,c,d])
+    vst_dir     = Dir ('libs/vst')
+    vst_sdk_dir = Dir ('vstsdk2.3')
+    #
+    # if it exists, try to use the Steinberg zip package
+    #
+    vst_sdk_zip = File ('vstsdk2.3.zip')
+
+    if os.access (vst_sdk_zip.abspath, os.F_OK):
+        print 'VST package discovered.'
+    elif os.access ('vst_sdk2_3.zip', os.F_OK):
+        #
+        # add a build target that unpacks the zip package the Steinberg "meta" zip package
+        #
+        vst_meta_zip = fst.Command (vst_sdk_zip, 'vst_sdk2_3.zip',  "unzip -o -d ${TARGET.dir} $SOURCES vstsdk2.3.zip" )
+        print 'VST meta-package discovered.'
     else:
-        print 'You have not installed the VST SDK in the correct location.'
-        print 'Please see http://ardour.org/building_vst_support for more information'
-        sys.exit (1)
+        if os.access ('vstsdk2.3.zip', os.F_OK) != 1:
+            print 'Did not find vst_sdk2_3.zip or vstsdk2.3.zip in libs/fst.'
+            print 'Make sure the correct file is in the correct location and correctly named.'
+            print 'Please see http://ardour.org/building_vst_support for more information.'
+            sys.exit (1)    
+
+    vst_headers = fst.Command ([ 'vst/aeffectx.h', 'vst/AEffect.h' ], vst_sdk_zip, [
+        "unzip -qq -d ${SOURCE.dir} -o $SOURCE",
+        Delete ('$TARGET.dir'),
+        Copy ('${TARGET.dir}', 'libs/fst/vstsdk2.3/source/common'),
+        "sed -i '/struct VstFileType\|struct VstFileSelect/,/};/d' $TARGET"
+        ])
+
+    a = fst.Object ('fst', 'fst.c')
+    b = fst.Object ('fstinfofile', 'fstinfofile.c')
+    c = fst.Object ('vstwin', 'vstwin.c')
+    d = fst.Object ('vsti', 'vsti.c')
+
+    Default([vst_headers,a,b,c,d])
     
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      fst_src + ['SConscript',
index 7cc98d2233155a108b850ad7e4104f6237433998..7b0c69d01576eff30298f32e34930defffdb6645 100644 (file)
@@ -227,7 +227,9 @@ FSTInfo *fst_get_info( char *dllpath ) {
        FSTInfo *info;
        char *fstpath;
 
-       if( !(h = fst_load( dllpath )) ) return NULL;
+       if( !(h = fst_load( dllpath )) ) {
+               return NULL;
+       }
        if( !(fst = fst_instantiate( h, simple_master_callback, NULL )) ) {
            fst_unload( h );
            fst_error( "instantiate failed\n" );
index dbc58e64994155884f48e1d690026a99368e9e1d..267f846203b61659d6c504f95aca45ef0ce31449 100644 (file)
@@ -28,7 +28,7 @@ else :
 
 Default([glibmm2_config_h, libglibmm2])
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libglibmm2))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libglibmm2))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript',
index 884ac3cbb08702301eff5ea7e038a75f7b4fbc31..84a5e8251adfe650e8497d4e4bbea57d665765a7 100644 (file)
@@ -13,7 +13,7 @@ atkmm.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'] ])
 libatkmm = atkmm.SharedLibrary('atkmm', atkmm_files)
 Default(libatkmm)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libatkmm))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libatkmm))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript', 'atkmm.h'] + 
index 58f0ebb2e5cc10864a5575b8627776c38b735224..6ea5c7cfef7cc770f4e4b89c1ad0455ff850621e 100644 (file)
@@ -14,7 +14,7 @@ gdkmm2.Append(CXXFLAGS="-Ilibs/gtkmm2/gtk")
 libgdkmm2 = gdkmm2.SharedLibrary('gdkmm2', gdkmm2_files)
 Default(libgdkmm2)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libgdkmm2))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libgdkmm2))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript', 'gdkmmconfig.h', 'gdkmm.h'] + 
index 90e832b010cefd6ab64d4504fac79c299226c930..b4cd99f02369d89fc340975849b30e3504666ff1 100644 (file)
@@ -13,7 +13,7 @@ gtkmm2.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'], libra
 libgtkmm2 = gtkmm2.SharedLibrary('gtkmm2', gtkmm2_files)
 Default(libgtkmm2)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libgtkmm2))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libgtkmm2))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript', 'gtkmmconfig.h', 'gtkmm.h'] + 
index 0ec62a0f0235c5bf63715127425fac49e8f72990..d045cf20435f03c87fcf74b076fc3ac502dbd8de 100644 (file)
@@ -13,7 +13,7 @@ pangomm.Merge([libraries['glibmm2'], libraries['pango'], libraries['sigc2']])
 libpangomm = pangomm.SharedLibrary('pangomm', pangomm_files)
 Default(libpangomm)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libpangomm))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libpangomm))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript', 'pangomm.h'] + 
index e654b6cb521843a6c019b7f1aa1f09401d5416f4..9c7511c85dadcbaec7348a1cf7666f0bdf99c94b 100644 (file)
@@ -39,10 +39,12 @@ choice.cc
 click_box.cc
 dndtreeview.cc
 fastmeter.cc
+focus_entry.cc
 gtk_ui.cc
 hexentry.cc
 idle_adjustment.cc
 pathlist.cc
+pixfader.cc
 pixscroller.cc
 popup.cc
 prompter.cc
@@ -67,7 +69,7 @@ Default(libgtkmm2ext)
 if env['NLS']:
     i18n (gtkmm2ext, gtkmm2ext_files, env)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libgtkmm2ext))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libgtkmm2ext))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript', 'i18n.h', 'gettext.h'] +
index 734c4b77e283874204884d5b6f6fda2a35acd482..f59d192ff1402a78575d74a060f8a64128277699 100644 (file)
@@ -70,8 +70,8 @@ BarController::BarController (Gtk::Adjustment& adj,
 
        darea.signal_expose_event().connect (mem_fun (*this, &BarController::expose));
        darea.signal_motion_notify_event().connect (mem_fun (*this, &BarController::motion));
-       darea.signal_button_press_event().connect (mem_fun (*this, &BarController::button_press));
-       darea.signal_button_release_event().connect (mem_fun (*this, &BarController::button_release));
+       darea.signal_button_press_event().connect (mem_fun (*this, &BarController::button_press), false);
+       darea.signal_button_release_event().connect (mem_fun (*this, &BarController::button_release), false);
        darea.signal_scroll_event().connect (mem_fun (*this, &BarController::scroll));
 
        spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated));
@@ -82,9 +82,21 @@ BarController::BarController (Gtk::Adjustment& adj,
        show_all ();
 }
 
+void
+BarController::drop_grab ()
+{
+       if (grabbed) {
+               grabbed = false;
+               darea.remove_modal_grab();
+               StopGesture ();
+       }
+}
+
 bool
 BarController::button_press (GdkEventButton* ev)
 {
+       double fract;
+
        if (binding_proxy.button_press_handler (ev)) {
                return true;
        }
@@ -93,8 +105,7 @@ BarController::button_press (GdkEventButton* ev)
        case 1:
                if (ev->type == GDK_2BUTTON_PRESS) {
                        switch_on_release = true;
-                       grabbed = false;
-                       darea.remove_modal_grab();
+                       drop_grab ();
                } else {
                        switch_on_release = false;
                        darea.add_modal_grab();
@@ -107,6 +118,9 @@ BarController::button_press (GdkEventButton* ev)
                break;
 
        case 2:
+               fract = ev->x / (darea.get_width() - 2.0);
+               adjustment.set_value (adjustment.get_lower() + fract * (adjustment.get_upper() - adjustment.get_lower()));
+
        case 3:
                break;
 
@@ -121,6 +135,8 @@ BarController::button_press (GdkEventButton* ev)
 bool
 BarController::button_release (GdkEventButton* ev)
 {
+       drop_grab ();
+       
        switch (ev->button) {
        case 1:
                if (switch_on_release) {
@@ -143,23 +159,11 @@ BarController::button_release (GdkEventButton* ev)
 
                        mouse_control (ev->x, ev->window, scale);
                }
-               darea.remove_modal_grab();
-               grabbed = false;
-               StopGesture ();
-               grabbed = false;
                break;
 
        case 2:
-               if (true) { // XXX FIX ME
-                       /* relax */
-               } else {
-                       double fract;
-                       fract = ev->x / (darea.get_width() - 2.0);
-                       adjustment.set_value (adjustment.get_lower() + 
-                                             fract * (adjustment.get_upper() - adjustment.get_lower()));
-               }
-               return true;
-
+               break;
+               
        case 3:
                return false;
                
@@ -204,7 +208,7 @@ BarController::motion (GdkEventMotion* ev)
        double scale;
        
        if (!grabbed) {
-               return TRUE;
+               return true;
        }
 
        if ((ev->state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK)) == GDK_SHIFT_MASK) {
@@ -225,7 +229,7 @@ BarController::motion (GdkEventMotion* ev)
 gint
 BarController::mouse_control (double x, GdkWindow* window, double scaling)
 {
-       double fract;
+       double fract = 0.0;
        double delta;
 
        if (window != grab_window) {
@@ -259,7 +263,7 @@ BarController::expose (GdkEventExpose* event)
 {
        Glib::RefPtr<Gdk::Window> win (darea.get_window());
        Widget* parent;
-       gint x1, x2, y1, y2;
+       gint x1=0, x2=0, y1=0, y2=0;
        gint w, h;
        double fract;
 
@@ -271,6 +275,7 @@ BarController::expose (GdkEventExpose* event)
        
        switch (_style) {
        case Line:
+               h = darea.get_height();
                x1 = (gint) floor (w * fract);
                x2 = x1;
                y1 = 0;
@@ -281,22 +286,18 @@ BarController::expose (GdkEventExpose* event)
                        
                        if (parent) {
                                win->draw_rectangle (parent->get_style()->get_fg_gc (parent->get_state()),
-                                                   true,
-                                                   0, 0, darea.get_width(), darea.get_height());
+                                                    true,
+                                                    0, 0, darea.get_width(), darea.get_height());
                        }
-               } else {
-                       win->draw_rectangle (get_style()->get_bg_gc (get_state()),
-                                           true,
-                                           0, 0, darea.get_width(), darea.get_height());
-               }
 
-               if (fract == 0.0) {
-                       win->draw_rectangle (get_style()->get_fg_gc (get_state()),
-                                           true, x1, 1, 2, darea.get_height() - 2);
                } else {
-                       win->draw_rectangle (get_style()->get_fg_gc (get_state()),
-                                           true, x1 - 1, 1, 3, darea.get_height() - 2);
+
+                       win->draw_rectangle (get_style()->get_bg_gc (get_state()),
+                                            true,
+                                            0, 0, darea.get_width() - ((darea.get_width()+1) % 2), darea.get_height());
                }
+               
+               win->draw_line (get_style()->get_fg_gc (get_state()), x1, 0, x1, h);
                break;
 
        case CenterOut:
@@ -456,3 +457,10 @@ BarController::set_use_parent (bool yn)
        use_parent = yn;
        queue_draw ();
 }
+
+void
+BarController::set_sensitive (bool yn)
+{
+       Frame::set_sensitive (yn);
+       darea.set_sensitive (yn);
+}
diff --git a/libs/gtkmm2ext/focus_entry.cc b/libs/gtkmm2ext/focus_entry.cc
new file mode 100644 (file)
index 0000000..dbe833d
--- /dev/null
@@ -0,0 +1,31 @@
+#include <gtkmm2ext/focus_entry.h>
+
+using namespace Gtkmm2ext;
+
+FocusEntry::FocusEntry ()
+{
+       next_release_selects = false;
+}
+
+bool 
+FocusEntry::on_button_press_event (GdkEventButton* ev)
+{
+       if (!has_focus()) {
+               next_release_selects = true;
+       }
+       return Entry::on_button_press_event (ev);
+}
+
+bool 
+FocusEntry::on_button_release_event (GdkEventButton* ev)
+{
+       if (next_release_selects) {
+               bool ret = Entry::on_button_release_event (ev);
+               select_region (0, -1);
+               next_release_selects = false;
+               return ret;
+       } 
+
+       return Entry::on_button_release_event (ev);
+}
+
index ebce4e2de925e79192a0f6eac8d4149dfb14afa4..e5b8e31b58209912246f4ea098f11f545a1f82ac 100644 (file)
@@ -20,7 +20,8 @@
 #ifndef __gtkmm2ext_bar_controller_h__
 #define __gtkmm2ext_bar_controller_h__
 
-#include <gtkmm.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/drawingarea.h>
 #include <gtkmm2ext/binding_proxy.h>
 
 namespace ARDOUR {
@@ -35,10 +36,6 @@ class BarController : public Gtk::Frame
        BarController (Gtk::Adjustment& adj, PBD::Controllable&, sigc::slot<void,char*,unsigned int>);
        virtual ~BarController () {}
        
-       void set_sensitive (bool yn) {
-               darea.set_sensitive (yn);
-       }
-       
        enum Style {
                LeftToRight,
                RightToLeft,
@@ -53,6 +50,8 @@ class BarController : public Gtk::Frame
        void set_with_text (bool yn);
        void set_use_parent (bool yn);
 
+       void set_sensitive (bool yn);
+
        Gtk::SpinButton& get_spin_button() { return spinner; }
 
        sigc::signal<void> StartGesture;
@@ -79,12 +78,12 @@ class BarController : public Gtk::Frame
        Gtk::SpinButton     spinner;
        bool                use_parent;
 
-       bool button_press (GdkEventButton *);
-       bool button_release (GdkEventButton *);
-       bool motion (GdkEventMotion *);
-       bool expose (GdkEventExpose *);
-       bool scroll (GdkEventScroll *);
-       bool entry_focus_out (GdkEventFocus*);
+       virtual bool button_press (GdkEventButton *);
+       virtual bool button_release (GdkEventButton *);
+       virtual bool motion (GdkEventMotion *);
+       virtual bool expose (GdkEventExpose *);
+       virtual bool scroll (GdkEventScroll *);
+       virtual bool entry_focus_out (GdkEventFocus*);
 
        gint mouse_control (double x, GdkWindow* w, double scaling);
 
@@ -92,6 +91,7 @@ class BarController : public Gtk::Frame
        gint switch_to_spinner ();
 
        void entry_activated ();
+       void drop_grab ();
 };
 
 
diff --git a/libs/gtkmm2ext/gtkmm2ext/focus_entry.h b/libs/gtkmm2ext/gtkmm2ext/focus_entry.h
new file mode 100644 (file)
index 0000000..5d9d7fd
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __gtkmm2ext_focus_entry_h__
+#define __gtkmm2ext_focus_entry_h__
+
+#include <gtkmm/entry.h>
+
+namespace Gtkmm2ext {
+
+class FocusEntry : public Gtk::Entry
+{
+  public:
+       FocusEntry ();
+       
+  protected:
+       bool on_button_press_event (GdkEventButton*);
+       bool on_button_release_event (GdkEventButton*);
+  private:
+       bool next_release_selects;
+};
+
+}
+
+#endif /* __gtkmm2ext_focus_entry_h__ */
diff --git a/libs/gtkmm2ext/gtkmm2ext/pixfader.h b/libs/gtkmm2ext/gtkmm2ext/pixfader.h
new file mode 100644 (file)
index 0000000..bb41762
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+    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.
+
+    $Id: fastmeter.h 570 2006-06-07 21:21:21Z sampo $
+*/
+
+#ifndef __gtkmm2ext_pixfader_h__
+#define __gtkmm2ext_pixfader_h__
+
+#include <cmath>
+
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/adjustment.h>
+#include <gdkmm/pixbuf.h>
+
+namespace Gtkmm2ext {
+
+class PixFader : public Gtk::DrawingArea {
+  public:
+       PixFader (Glib::RefPtr<Gdk::Pixbuf> belt_image, Gtk::Adjustment& adjustment);
+       virtual ~PixFader ();
+       
+  protected:
+       Gtk::Adjustment& adjustment;
+
+       void on_size_request (GtkRequisition*);
+
+       bool on_expose_event (GdkEventExpose*);
+       bool on_button_press_event (GdkEventButton*);
+       bool on_button_release_event (GdkEventButton*);
+       bool on_motion_notify_event (GdkEventMotion*);
+       bool on_scroll_event (GdkEventScroll* ev);
+
+  private:  
+       Glib::RefPtr<Gdk::Pixbuf> pixbuf;
+       gint pixheight;
+
+       GdkRectangle view;
+
+       GdkWindow* grab_window;
+       double grab_y;
+       double grab_start;
+       int last_drawn;
+       bool dragging;
+       float default_value;
+       int unity_y;
+
+       void adjustment_changed ();
+
+       int display_height ();
+};
+
+
+} /* namespace */
+
+ #endif /* __gtkmm2ext_pixfader_h__ */
index f0f645eab7502b402c77344074aa378fb46efd17..c137dbabf5ecb3d755324a05e6d81c023602b171 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <gtkmm.h>
 #include <gtkmm2ext/popup.h>
-#include <gtkmm2ext/pixscroller.h>
+#include <gtkmm2ext/pixfader.h>
 #include <gtkmm2ext/binding_proxy.h>
 
 namespace Gtkmm2ext {
@@ -35,11 +35,10 @@ namespace PBD {
 
 namespace Gtkmm2ext {
 
-class SliderController : public Gtkmm2ext::PixScroller
+class SliderController : public Gtkmm2ext::PixFader
 {
   public:
-       SliderController (Glib::RefPtr<Gdk::Pixbuf> slider,
-                         Glib::RefPtr<Gdk::Pixbuf> rail,
+       SliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                          Gtk::Adjustment* adj,
                          PBD::Controllable&,
                          bool with_numeric = true);
@@ -64,8 +63,7 @@ class SliderController : public Gtkmm2ext::PixScroller
 class VSliderController : public SliderController
 {
   public:
-       VSliderController (Glib::RefPtr<Gdk::Pixbuf> slider,
-                          Glib::RefPtr<Gdk::Pixbuf> rail,
+       VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                           Gtk::Adjustment *adj,
                           PBD::Controllable&,
                           bool with_numeric = true);
@@ -74,8 +72,7 @@ class VSliderController : public SliderController
 class HSliderController : public SliderController
 {
   public:
-       HSliderController (Glib::RefPtr<Gdk::Pixbuf> slider,
-                          Glib::RefPtr<Gdk::Pixbuf> rail,
+       HSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                           Gtk::Adjustment *adj,
                           PBD::Controllable&,
                           bool with_numeric = true);
diff --git a/libs/gtkmm2ext/pixfader.cc b/libs/gtkmm2ext/pixfader.cc
new file mode 100644 (file)
index 0000000..f3a40ff
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+    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.
+
+    $Id: fastmeter.h 570 2006-06-07 21:21:21Z sampo $
+*/
+
+
+#include <iostream>
+#include <gtkmm2ext/pixfader.h>
+
+using namespace Gtkmm2ext;
+using namespace Gtk;
+using namespace Gdk;
+using namespace std;
+
+PixFader::PixFader (Glib::RefPtr<Pixbuf> belt, Gtk::Adjustment& adj)
+       : adjustment (adj),
+         pixbuf (belt)
+{
+       dragging = false;
+       default_value = adjustment.get_value();
+       last_drawn = -1;
+       pixheight = pixbuf->get_height();
+
+       view.x = 0;
+       view.y = 0;
+       view.width = pixbuf->get_width();
+       view.height = pixheight / 2;
+
+       unity_y = (int) rint (view.height - (default_value * view.height)) - 1;
+
+       add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK);
+
+       adjustment.signal_value_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
+       adjustment.signal_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
+}
+
+PixFader::~PixFader ()
+{
+}
+
+bool
+PixFader::on_expose_event (GdkEventExpose* ev)
+{
+       GdkRectangle intersection;
+       int dh = display_height ();
+       int offset_into_pixbuf = (int) floor (view.height / ((float) view.height / dh));
+       Glib::RefPtr<Gdk::GC> fg_gc (get_style()->get_fg_gc(get_state()));
+
+       if (gdk_rectangle_intersect (&view, &ev->area, &intersection)) {
+               get_window()->draw_pixbuf (fg_gc, pixbuf, 
+                                          intersection.x, offset_into_pixbuf + intersection.y,
+                                          intersection.x, intersection.y,
+                                          intersection.width, intersection.height,
+                                          Gdk::RGB_DITHER_NONE, 0, 0);
+               
+               get_window()->draw_line (get_style()->get_bg_gc(STATE_ACTIVE), 0, 0, view.width - 1, 0); /* top */
+               get_window()->draw_line (get_style()->get_bg_gc(STATE_ACTIVE), 0, 0, 0, view.height - 1); /* left */
+               get_window()->draw_line (get_style()->get_bg_gc(STATE_NORMAL), view.width - 1, 0, view.width - 1, view.height - 1); /* right */
+               get_window()->draw_line (get_style()->get_bg_gc(STATE_NORMAL), 0, view.height - 1, view.width - 1, view.height - 1); /* bottom */
+       }
+
+       /* always draw the line */
+
+       get_window()->draw_line (fg_gc, 1, unity_y, view.width - 2, unity_y);
+
+       last_drawn = dh;
+       return true;
+}
+
+void
+PixFader::on_size_request (GtkRequisition* req)
+{
+       req->width = view.width;
+       req->height = view.height;
+}
+
+bool
+PixFader::on_button_press_event (GdkEventButton* ev)
+{
+       switch (ev->button) {
+       case 1:
+       case 2:
+               add_modal_grab();
+               grab_y = ev->y;
+               grab_start = ev->y;
+               grab_window = ev->window;
+               dragging = true;
+               break;
+       default:
+               break;
+       } 
+                              
+
+       return false;
+}
+
+bool
+PixFader::on_button_release_event (GdkEventButton* ev)
+{
+       double fract;
+       
+       switch (ev->button) {
+       case 1:
+               if (dragging) {
+                       remove_modal_grab();
+                       dragging = false;
+
+                       if (ev->y == grab_start) {
+
+                               /* no motion - just a click */
+
+                               if (ev->state & Gdk::SHIFT_MASK) {
+                                       adjustment.set_value (default_value);
+                               } else if (ev->state & GDK_CONTROL_MASK) {
+                                       adjustment.set_value (adjustment.get_lower());
+                               } else if (ev->y < view.height - display_height()) {
+                                       /* above the current display height, remember X Window coords */
+                                       adjustment.set_value (adjustment.get_value() + adjustment.get_step_increment());
+                               } else {
+                                       adjustment.set_value (adjustment.get_value() - adjustment.get_step_increment());
+                               }
+                       }
+
+               } 
+               break;
+               
+       case 2:
+               if (dragging) {
+                       remove_modal_grab();
+                       dragging = false;
+                       
+                       fract = 1.0 - (ev->y / view.height); // inverted X Window coordinates, grrr
+                       
+                       fract = min (1.0, fract);
+                       fract = max (0.0, fract);
+                       
+                       adjustment.set_value (fract * (adjustment.get_upper() - adjustment.get_lower()));
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       return false;
+}
+
+bool
+PixFader::on_scroll_event (GdkEventScroll* ev)
+{
+       double scale;
+       
+       if (ev->state & GDK_CONTROL_MASK) {
+               if (ev->state & GDK_MOD1_MASK) {
+                       scale = 0.05;
+               } else {
+                       scale = 0.1;
+               }
+       } else {
+               scale = 0.5;
+       }
+
+       switch (ev->direction) {
+
+       case GDK_SCROLL_UP:
+               /* wheel up */
+               adjustment.set_value (adjustment.get_value() + (adjustment.get_page_increment() * scale));
+               break;
+       case GDK_SCROLL_DOWN:
+               /* wheel down */
+               adjustment.set_value (adjustment.get_value() - (adjustment.get_page_increment() * scale));
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+bool
+PixFader::on_motion_notify_event (GdkEventMotion* ev)
+{
+       if (dragging) {
+               double fract;
+               double delta;
+               double scale;
+
+               if (ev->window != grab_window) {
+                       grab_y = ev->y;
+                       grab_window = ev->window;
+                       return true;
+               }
+               
+               if (ev->state & GDK_CONTROL_MASK) {
+                       if (ev->state & GDK_MOD1_MASK) {
+                               scale = 0.05;
+                       } else {
+                               scale = 0.1;
+                       }
+               } else {
+                       scale = 1.0;
+               }
+
+               delta = ev->y - grab_y;
+               grab_y = ev->y;
+
+               fract = (delta / view.height);
+
+               fract = min (1.0, fract);
+               fract = max (-1.0, fract);
+
+               // X Window is top->bottom for 0..Y
+               
+               fract = -fract;
+
+               adjustment.set_value (adjustment.get_value() + scale * fract * (adjustment.get_upper() - adjustment.get_lower()));
+       }
+
+       return true;
+}
+
+void
+PixFader::adjustment_changed ()
+{
+       if (display_height() != last_drawn) {
+               queue_draw ();
+       }
+}
+
+int
+PixFader::display_height ()
+{
+       float fract = (adjustment.get_upper() - adjustment.get_value ()) / ((adjustment.get_upper() - adjustment.get_lower()));
+       return (int) floor (view.height * (1.0 - fract));
+}
index c3a04f19a884dea9a92e04f0b9a6006ad74fe210..d06204d35617f1e27a291678db29ffa3348efed1 100644 (file)
@@ -86,7 +86,7 @@ Prompter::get_result (string &str, bool strip)
 {
        str = entry.get_text ();
        if (strip) {
-               strip_whitespace_edges (str);
+               PBD::strip_whitespace_edges (str);
        }
 }
 
index e524eba1cbd4bdd57010351bf3a10bf2feee1e5c..3e2b42f409361011e3e275729b323dc335cf4e25 100644 (file)
@@ -20,7 +20,7 @@
 #include <string>
 
 #include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/pixscroller.h>
+#include <gtkmm2ext/pixfader.h>
 #include <gtkmm2ext/slider_controller.h>
 
 #include "i18n.h"
 using namespace Gtkmm2ext;
 using namespace PBD;
 
-SliderController::SliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
-                                   Glib::RefPtr<Gdk::Pixbuf> rail,
+SliderController::SliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                                    Gtk::Adjustment *adj,
                                    Controllable& c,
                                    bool with_numeric)
 
-       : PixScroller (*adj, slide, rail),
+       : PixFader (image, *adj),
          binding_proxy (c),
          spin (*adj, 0, 2)
 {                        
@@ -47,7 +46,7 @@ SliderController::SliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
 void
 SliderController::set_value (float v)
 {
-       adj.set_value (v);
+       adjustment.set_value (v);
 }
 
 bool 
@@ -56,16 +55,15 @@ SliderController::on_button_press_event (GdkEventButton *ev)
        if (binding_proxy.button_press_handler (ev)) {
                return true;
        }
-       return PixScroller::on_button_press_event (ev);
+       return PixFader::on_button_press_event (ev);
 }
 
-VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
-                                     Glib::RefPtr<Gdk::Pixbuf> rail,
+VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                                      Gtk::Adjustment *adj,
                                      Controllable& control,
                                      bool with_numeric)
 
-       : SliderController (slide, rail, adj, control, with_numeric)
+       : SliderController (image, adj, control, with_numeric)
 {
        if (with_numeric) {
                spin_frame.add (spin);
@@ -76,13 +74,12 @@ VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
        }
 }
 
-HSliderController::HSliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
-                                     Glib::RefPtr<Gdk::Pixbuf> rail,
+HSliderController::HSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
                                      Gtk::Adjustment *adj,
                                      Controllable& control,
                                      bool with_numeric)
        
-       : SliderController (slide, rail, adj, control, with_numeric)
+       : SliderController (image, adj, control, with_numeric)
 {
        if (with_numeric) {
                spin_frame.add (spin);
index e4a9207195275d83db075d8105149a49df856d76..92bde5541e510f778650dbe3b22502950601ec10 100644 (file)
@@ -127,7 +127,7 @@ TearOff::close_click (GdkEventButton* ev)
 gint
 TearOff::window_button_press (GdkEventButton* ev)
 {
-       if (dragging) {
+       if (dragging || ev->button != 1) {
                dragging = false;
                own_window.remove_modal_grab();
                return true;
@@ -172,6 +172,12 @@ TearOff::window_motion (GdkEventMotion* ev)
                return true;
        }
 
+       if (!(ev->state & GDK_BUTTON1_MASK)) {
+               dragging = false;
+               own_window.remove_modal_grab();
+               return true;
+       }
+
        x_delta = ev->x_root - drag_x;
        y_delta = ev->y_root - drag_y;
 
index 1ee69265807d044d01fcbef40dc9f4c0da79604c..0d22ba243fcf322d647e211cd94f1acb925aaa54 100644 (file)
@@ -15,7 +15,7 @@ libglade = libglademm.SharedLibrary('libglademm', libglademm_files)
 
 Default(libglade)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libglade))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libglade))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript', 'libglademmconfig.h', 'libglademm.h'] +
index d9620dc378eb597429f47f7ca15d6653c47cb153..7cab8b707a9a0f952f44de664c442a0c7050ed56 100644 (file)
@@ -20,7 +20,7 @@ gnomecanvasmm.Merge([libraries['glibmm2'],
 libgnomecanvasmm = gnomecanvasmm.SharedLibrary('libgnomecanvasmm', gnomecanvasmm_files)
 Default(libgnomecanvasmm)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libgnomecanvasmm))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libgnomecanvasmm))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript', 'libgnomecanvasmmconfig.h', 'libgnomecanvasmm.h'] +
index f8e9fc5ecbbe379b9a93889c66ac19922186f1c5..9e8ccc93f721a86ea7f09eb3ba2fdd240598cd42 100644 (file)
@@ -6,8 +6,9 @@ import glob
 
 sndfile_files = glob.glob('src/*.c') + glob.glob('src/GSM610/*.c') + glob.glob('src/G72x/*.c')
 
-Import('env install_prefix')
+Import('env install_prefix libraries')
 sndfile = env.Copy()
+sndfile.Merge([libraries['flac'] ])
 
 domain = 'libsndfile'
 
@@ -31,7 +32,7 @@ sndfile_h = sndfile.Command('src/sndfile.h', ['src/sndfile.h.in'], 'cd libs/libs
 
 Default([sndfile_h,libsndfile])
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libsndfile))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libsndfile))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'NEWS', 'README', 'AUTHORS', 'ChangeLog',
index 8aaca4e783e806bb62289cc6c82ac1c87cd48f8f..bfa95c3aac1dda0a09d55888958f5a97052b2cd2 100755 (executable)
@@ -12235,9 +12235,17 @@ rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  cat conftest.$ac_ext > blah1.c
+
+  echo $CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext > blah1
+
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
+  
+  cat conftest.err > blah2
+  
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
         { ac_try='test -z "$ac_c_werror_flag"
index 477d49c6caa34648c40b825af8eb1fb0ac129334..e9fbc0abf599d680e589158440e9dd2d0334ad93 100644 (file)
@@ -57,7 +57,7 @@ libmidi2 = midi2.SharedLibrary('midi++', [ sources, sysdep_src ])
 
 Default(libmidi2)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libmidi2))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libmidi2))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript' ] + sources + sysdep_sources +
index 4fc24e87119e6ab0d3fd504f61419969516e3537..2aad0e072d247b92b186153b797d5ae9512bc58a 100644 (file)
@@ -109,7 +109,7 @@ JACK_MidiPort::create_ports(PortRequest & req)
                _jack_output_port = jack_port_register(_jack_client,
                        string(req.tagname).append("_out").c_str(),
                        JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
-               jack_midi_reset_new_port(
+               jack_midi_clear_buffer(
                        jack_port_get_buffer(_jack_output_port, nframes), nframes);
                ret = ret && (_jack_output_port != NULL);
        }
@@ -118,7 +118,7 @@ JACK_MidiPort::create_ports(PortRequest & req)
                _jack_input_port = jack_port_register(_jack_client,
                        string(req.tagname).append("_in").c_str(),
                        JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
-               jack_midi_reset_new_port(
+               jack_midi_clear_buffer(
                        jack_port_get_buffer(_jack_input_port, nframes), nframes);
                ret = ret && (_jack_input_port != NULL);
        }
index f474834fd8eef7863cd03bf80dce7b5e38e40497..afb24a43117920dd60202fc19af7df2227c9466b 100644 (file)
@@ -20,9 +20,11 @@ pbd.Append(POTFILE=domain + '.pot')
 pbd_files = Split("""
 basename.cc
 base_ui.cc
-convert.cc
 command.cc
+convert.cc
+copyfile.cc
 controllable.cc
+enumwriter.cc
 dmalloc.cc
 error.cc
 id.cc
@@ -66,7 +68,7 @@ mount_env.Program('mountpoint', 'mountpoint.cc')
 if env['NLS']:
     i18n (pbd, pbd_files, env)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libpbd))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libpbd))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'SConscript', 'i18n.h', 'gettext.h', 'pbd/abstract_ui.cc' ] +
index a51e393b78498845a671a60244a888b8a16a9e52..9beed93625cf398a5bf556fc58eaad0fe86c8388 100644 (file)
@@ -1,20 +1,13 @@
-#include <iostream>
-#include <string.h>
 #include <pbd/basename.h>
+#include <glibmm/miscutils.h>
 
+using Glib::ustring;
 
-// implement this using Glib::path_get_basename
-std::string 
-PBD::basename_nosuffix (const std::string& str)
+ustring
+PBD::basename_nosuffix (ustring str)
 {
-       std::string::size_type slash = str.find_last_of ('/');
-       std::string noslash;
+       ustring base = Glib::path_get_basename (str);
 
-       if (slash == std::string::npos) {
-               noslash = str;
-       } else {
-               noslash = str.substr (slash+1);
-       }
+       return base.substr (0, base.find_last_of ('.'));
 
-       return noslash.substr (0, noslash.find_last_of ('.'));
 }
index 2264a955ae1accfda27633482b812beea5f0de35..049ad0aa213543677b907de12146e34e8bd509c8 100644 (file)
@@ -18,8 +18,10 @@ Controllable::Controllable (std::string name)
 XMLNode&
 Controllable::get_state ()
 {
-       XMLNode* node = new XMLNode (_name);
+       XMLNode* node = new XMLNode (X_("controllable"));
        char buf[64];
+
+       node->add_property (X_("name"), _name); // not reloaded from XML state, just there to look at
        _id.print (buf, sizeof (buf));
        node->add_property (X_("id"), buf);
        return *node;
diff --git a/libs/pbd/copyfile.cc b/libs/pbd/copyfile.cc
new file mode 100644 (file)
index 0000000..d36ecef
--- /dev/null
@@ -0,0 +1,38 @@
+#include <fstream>
+#include <unistd.h>
+
+#include <pbd/copyfile.h>
+#include <pbd/error.h>
+#include <pbd/compose.h>
+
+#include "i18n.h"
+
+using namespace PBD;
+using namespace std;
+
+int
+PBD::copy_file (Glib::ustring from, Glib::ustring to)
+{
+       ifstream in (from.c_str());
+       ofstream out (to.c_str());
+       
+       if (!in) {
+               error << string_compose (_("Could not open %1 for copy"), from) << endmsg;
+               return -1;
+       }
+       
+       if (!out) {
+               error << string_compose (_("Could not open %1 as copy"), to) << endmsg;
+               return -1;
+       }
+       
+       out << in.rdbuf();
+       
+       if (!in || !out) {
+               error << string_compose (_("Could not copy existing file %1 to %2"), from, to) << endmsg;
+               unlink (to.c_str());
+               return -1;
+       }
+       
+       return 0;
+}
diff --git a/libs/pbd/enumwriter.cc b/libs/pbd/enumwriter.cc
new file mode 100644 (file)
index 0000000..7674410
--- /dev/null
@@ -0,0 +1,273 @@
+/* 
+    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.
+
+    $Id$
+*/
+
+#include <ctype.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <pbd/enumwriter.h>
+#include <pbd/error.h>
+#include <pbd/compose.h>
+
+using namespace std;
+using namespace PBD;
+
+#include "i18n.h"
+
+EnumWriter* EnumWriter::_instance = 0;
+map<string,string> EnumWriter::hack_table;
+
+static int 
+nocase_cmp(const string & s1, const string& s2) 
+{
+       string::const_iterator it1 = s1.begin();
+       string::const_iterator it2 = s2.begin();
+       
+       while ((it1 != s1.end()) && (it2 != s2.end())) { 
+               if(::toupper(*it1) != ::toupper(*it2))  {//letters differ?
+                       // return -1 to indicate 'smaller than', 1 otherwise
+                       return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1; 
+               }
+
+               ++it1;
+               ++it2;
+       }
+
+       string::size_type size1 = s1.size();
+       string::size_type size2 = s2.size();
+
+       //return -1,0 or 1 according to strings' lengths
+
+       if (size1 == size2) {
+               return 0;
+       }
+
+       return (size1 < size2) ? -1 : 1;
+}
+
+EnumWriter::EnumWriter ()
+{
+       if (_instance == 0) {
+               _instance = this;
+       }
+}
+
+EnumWriter::~EnumWriter ()
+{
+}
+
+void
+EnumWriter::register_distinct (string type, vector<int> v, vector<string> s)
+{
+       pair<string,EnumRegistration> newpair;
+       pair<Registry::iterator,bool> result;
+
+       newpair.first = type;
+       newpair.second = EnumRegistration (v, s, false);
+       
+       result = registry.insert (newpair);
+
+       if (!result.second) {
+               warning << string_compose (_("enum type \"%1\" already registered with the enum writer"), type) << endmsg;
+       }
+}
+
+void
+EnumWriter::register_bits (string type, vector<int> v, vector<string> s)
+{
+       pair<string,EnumRegistration> newpair;
+       pair<Registry::iterator,bool> result;
+
+       newpair.first = type;
+       newpair.second = EnumRegistration (v, s, true);
+       
+       result = registry.insert (newpair);
+
+       if (!result.second) {
+               warning << _("enum type \"%1\" already registered with the enum writer") << endmsg;
+       }
+}
+
+string
+EnumWriter::write (string type, int value)
+{
+       Registry::iterator x = registry.find (type);
+
+       if (x == registry.end()) {
+               error << string_compose (_("EnumWriter: unknown enumeration type \"%1\""), type) << endmsg;
+               throw unknown_enumeration();
+       }
+
+       if (x->second.bitwise) {
+               return write_bits (x->second, value);
+       } else {
+               return write_distinct (x->second, value);
+       }
+}
+
+int
+EnumWriter::read (string type, string value)
+{
+       Registry::iterator x = registry.find (type);
+
+       if (x == registry.end()) {
+               error << string_compose (_("EnumWriter: unknown enumeration type \"%1\""), type) << endmsg;
+               throw unknown_enumeration();
+       }
+
+       if (x->second.bitwise) {
+               return read_bits (x->second, value);
+       } else {
+               return read_distinct (x->second, value);
+       }
+}      
+
+string
+EnumWriter::write_bits (EnumRegistration& er, int value)
+{
+       vector<int>::iterator i;
+       vector<string>::iterator s;
+       string result;
+
+       for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) {
+               if (value & (*i)) {
+                       if (!result.empty()) {
+                               result += ',';
+                       } 
+                       result += (*s);
+               }
+       }
+
+       return result;
+}
+
+string
+EnumWriter::write_distinct (EnumRegistration& er, int value)
+{
+       vector<int>::iterator i;
+       vector<string>::iterator s;
+
+       for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) {
+               if (value == (*i)) {
+                       return (*s);
+               }
+       }
+
+       return string();
+}
+
+int
+EnumWriter::read_bits (EnumRegistration& er, string str)
+{
+       vector<int>::iterator i;
+       vector<string>::iterator s;
+       int result = 0;
+       bool found = false;
+       string::size_type comma;
+
+       /* catch old-style hex numerics */
+
+       if (str.length() > 2 && str[0] == '0' && str[1] == 'x') {
+               return strtol (str.c_str(), (char **) 0, 16);
+       }
+
+       /* catch old style dec numerics */
+
+       if (strspn (str.c_str(), "0123456789") == str.length()) {
+               return strtol (str.c_str(), (char **) 0, 10);
+       }
+
+       do {
+               
+               comma = str.find_first_of (',');
+               string segment = str.substr (0, comma);
+
+               for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) {
+                       if (segment == *s || nocase_cmp (segment, *s) == 0) {
+                               result |= (*i);
+                               found = true;
+                       }
+               }
+
+               if (comma == string::npos) {
+                       break;
+               }
+
+               str = str.substr (comma+1);
+
+       } while (true);
+
+       if (!found) {
+               throw unknown_enumeration();
+       }
+
+       return result;
+}
+
+int
+EnumWriter::read_distinct (EnumRegistration& er, string str)
+{
+       vector<int>::iterator i;
+       vector<string>::iterator s;
+
+       /* catch old-style hex numerics */
+
+       if (str.length() > 2 && str[0] == '0' && str[1] == 'x') {
+               return strtol (str.c_str(), (char **) 0, 16);
+       }
+
+       /* catch old style dec numerics */
+
+       if (strspn (str.c_str(), "0123456789") == str.length()) {
+               return strtol (str.c_str(), (char **) 0, 10);
+       }
+
+       for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) {
+               if (str == (*s) || nocase_cmp (str, *s) == 0) {
+                       return (*i);
+               }
+       }
+
+       /* failed to find it as-is. check to see if there a hack for the name we're looking up */
+
+       map<string,string>::iterator x;
+
+       if ((x  = hack_table.find (str)) != hack_table.end()) {
+
+               cerr << "found hack for " << str << " = " << x->second << endl;
+
+               str = x->second;
+
+               for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) {
+                       if (str == (*s) || nocase_cmp (str, *s) == 0) {
+                               return (*i);
+                       }
+               }
+       }
+
+       throw unknown_enumeration();
+}
+
+void
+EnumWriter::add_to_hack_table (string str, string hacked)
+{
+       hack_table[str] = hacked;
+}
index a7e36acff039f417a59b305043a08af83d771fbd..a62264354181abc8b0d7f30338f9966bc5728100 100644 (file)
@@ -1,13 +1,13 @@
 #ifndef __stupid_basename_h__
 #define __stupid_basename_h__
 
-#include <string>
+#include <glibmm/ustring.h>
 
 namespace PBD
 {
        
-extern std::string basename_nosuffix (const std::string&);
+Glib::ustring basename_nosuffix (Glib::ustring);
 
-} // namespace PBD
+} 
 
 #endif  // __stupid_basename_h__
diff --git a/libs/pbd/pbd/copyfile.h b/libs/pbd/pbd/copyfile.h
new file mode 100644 (file)
index 0000000..8a1bf24
--- /dev/null
@@ -0,0 +1,6 @@
+#include <glibmm/ustring.h>
+
+namespace PBD {
+
+       int copy_file (Glib::ustring from, Glib::ustring to);
+}
diff --git a/libs/pbd/pbd/enumwriter.h b/libs/pbd/pbd/enumwriter.h
new file mode 100644 (file)
index 0000000..f53388f
--- /dev/null
@@ -0,0 +1,77 @@
+/* 
+    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.
+
+    $Id$
+*/
+
+#include <map>
+#include <string>
+#include <vector>
+#include <exception>
+
+
+namespace PBD {
+
+class unknown_enumeration : public std::exception {
+  public:
+       virtual const char *what() const throw() { return "unknown enumerator in PBD::EnumWriter"; }
+};
+
+class EnumWriter {
+  public:
+       EnumWriter ();
+       ~EnumWriter ();
+
+       static EnumWriter& instance() { return *_instance; }
+
+       void register_distinct (std::string type, std::vector<int>, std::vector<std::string>);
+       void register_bits     (std::string type, std::vector<int>, std::vector<std::string>);
+
+       std::string write (std::string type, int value);
+       int         read  (std::string type, std::string value);
+
+       void add_to_hack_table (std::string str, std::string hacked_str);
+
+  private:
+       struct EnumRegistration {
+           std::vector<int> values;
+           std::vector<std::string> names;
+           bool bitwise;
+
+           EnumRegistration() {}
+           EnumRegistration (std::vector<int>& v, std::vector<std::string>& s, bool b) 
+                   : values (v), names (s), bitwise (b) {}
+       };
+
+       typedef std::map<std::string, EnumRegistration> Registry;
+       Registry registry;
+
+       std::string write_bits (EnumRegistration&, int value);
+       std::string write_distinct (EnumRegistration&, int value);
+
+       int read_bits (EnumRegistration&, std::string value);
+       int read_distinct (EnumRegistration&, std::string value);
+
+       static EnumWriter* _instance;
+       static std::map<std::string,std::string> hack_table;
+};
+
+}
+
+#define enum_2_string(e) (PBD::EnumWriter::instance().write (typeid(e).name(), e))
+#define string_2_enum(str,e) (PBD::EnumWriter::instance().read (typeid(e).name(), (str)))
+
index a976b7934118868b1f66f3349467f93cac2ac701..b80e3eac4a4dcd7043c2cdb1320fcb5f021be3df 100644 (file)
@@ -4,18 +4,24 @@
 #include <iterator>
 #include <string>
 
+#include <pbd/whitespace.h>
+
 namespace PBD {
 
 /**
     Tokenize string, this should work for standard
-    strings aswell as Glib::ustring. This is a bit of a hack,
+    strings as well as Glib::ustring. This is a bit of a hack,
     there are much better string tokenizing patterns out there.
+       If strip_whitespace is set to true, tokens will be checked to see
+       that they still have a length after stripping.  If no length, they
+       are discarded.
 */
 template<typename StringType, typename Iter>
 unsigned int
 tokenize(const StringType& str,        
         const StringType& delims,
-        Iter it)
+        Iter it,
+               bool strip_whitespace=false)
 {
     typename StringType::size_type start_pos = 0;
     typename StringType::size_type end_pos = 0;
@@ -28,14 +34,30 @@ tokenize(const StringType& str,
             if (end_pos == str.npos) {
                 end_pos = str.length();
             }
-            *it++ = str.substr(start_pos, end_pos - start_pos);
+               if (strip_whitespace) {
+                               StringType stripped = str.substr(start_pos, end_pos - start_pos);
+                               strip_whitespace_edges (stripped);
+                               if (stripped.length()) {
+                                       *it++ = stripped;
+                               }
+                       } else {
+               *it++ = str.substr(start_pos, end_pos - start_pos);
+                       }
             ++token_count;
             start_pos = str.find_first_not_of(delims, end_pos + 1);
         }
     } while (start_pos != str.npos);
 
     if (start_pos != str.npos) {
-        *it++ = str.substr(start_pos, str.length() - start_pos);
+       if (strip_whitespace) {
+                       StringType stripped = str.substr(start_pos, str.length() - start_pos);
+                       strip_whitespace_edges (stripped);
+                       if (stripped.length()) {
+                               *it++ = stripped;
+                       }
+               } else {
+               *it++ = str.substr(start_pos, str.length() - start_pos);
+               }
         ++token_count;
     }
 
index eb46750e4ffb160c4f0aa224f8d7865377d33934..4dfab5178fcc893122c00de0e87f3b450941e81d 100644 (file)
@@ -94,7 +94,7 @@ class UndoHistory : public sigc::trackable
        void clear_undo ();
        void clear_redo ();
 
-        XMLNode &get_state();
+        XMLNode &get_state(uint32_t depth = 0);
         void save_state();
 
        sigc::signal<void> Changed;
index 6620a8fb50f9fe27b564e4cab6359774815ed9ab..6adb41641c70c879ee416fba73c5524191ddf739 100644 (file)
@@ -3,6 +3,12 @@
 
 #include <string>
 
+namespace PBD {
+
+// returns the empty string if the entire string is whitespace
+// so check length after calling.
 extern void strip_whitespace_edges (std::string& str);
 
+} // namespace PBD
+
 #endif // __pbd_whitespace_h__
index 277b83bfced06c3897421356ba6b5b89c719c3d8..4719d0968eb07cc70301f27ec50f07f291964089 100644 (file)
@@ -236,13 +236,31 @@ UndoHistory::clear ()
        Changed (); /* EMIT SIGNAL */
 }
 
-XMLNode & UndoHistory::get_state()
+XMLNode& 
+UndoHistory::get_state (uint32_t depth)
 {
     XMLNode *node = new XMLNode ("UndoHistory");
 
-    list<UndoTransaction*>::iterator it;
-    for (it = UndoList.begin(); it != UndoList.end(); it++) {
-           node->add_child_nocopy((*it)->get_state());
+    if (depth == 0) {
+           /* everything */
+
+           for (list<UndoTransaction*>::iterator it = UndoList.begin(); it != UndoList.end(); ++it) {
+                   node->add_child_nocopy((*it)->get_state());
+           }
+           
+    } else {
+
+           /* just the last "depth" transactions */
+
+           list<UndoTransaction*> in_order;
+
+           for (list<UndoTransaction*>::reverse_iterator it = UndoList.rbegin(); it != UndoList.rend() && depth; ++it, depth--) {
+                   in_order.push_front (*it);
+           }
+
+           for (list<UndoTransaction*>::iterator it = in_order.begin(); it != in_order.end(); it++) {
+                   node->add_child_nocopy((*it)->get_state());
+           }
     }
 
     return *node;
index 53616133ade362f96c87e2778d1b38b7892fdb93..a719fb169f2af983150620c8f56da841a036a2b3 100644 (file)
@@ -2,6 +2,8 @@
 
 using namespace std;
 
+namespace PBD {
+       
 void
 strip_whitespace_edges (string& str)
 {   
@@ -24,7 +26,8 @@ strip_whitespace_edges (string& str)
     }
 
     if (i == len) {
-           /* its all whitespace, not much we can do */
+           /* it's all whitespace, not much we can do */
+               str = "";
            return;
     }
 
@@ -55,3 +58,4 @@ strip_whitespace_edges (string& str)
     }
 }
 
+} // namespace PBD
index 65833dfb530b628f09aec2b371fb4de2421a1f33..b29aefb0cd807a028e71b621de377ed0f91e1812 100644 (file)
@@ -20,7 +20,7 @@ else :
 
 Default([sigc2_config_h,libsigc2])
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libsigc2))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libsigc2))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                      [ 'NEWS', 'README', 'AUTHORS', 'ChangeLog',
index d37fd1f99b78bf3b023919148bfda5aa53c0e187..9ddee87b0c3457dd6b63cb235b8821f351a2eb6e 100644 (file)
@@ -23,7 +23,7 @@ libst = st.SharedLibrary('soundtouch', soundtouch_files)
 
 Default(libst)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libst))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libst))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
        [ 'SConscript'] + soundtouch_files + glob.glob('*.h')))
index c404675ecdefb7fb4f2b2b354d325d64d878344c..e1ea90d428fedcaa6f125b2d1a9997f143ad0094 100644 (file)
@@ -47,8 +47,12 @@ typedef unsigned long   ulong;
 
     typedef unsigned int    BOOL;
 
+#ifndef FALSE
     #define FALSE   0
+#endif
+#ifndef TRUE
     #define TRUE    1
+#endif
 
 #endif  // _WINDEF_
 
index 88aeeda376c6b3deef62d0927898dad52e71ff34..026698500a55c9502c4c7dd669f2e8f825f89380 100644 (file)
@@ -50,7 +50,7 @@ Default(libardour_cp)
 if env['NLS']:
        i18n (cp, cp_files, env)
              
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libardour_cp))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libardour_cp))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                     [ 'SConscript' ] +
index 09c1c9616a341225380fb95766140bc708998ad2..b25a268aac45009c800885627dbb8b8753dbf5f9 100644 (file)
@@ -31,28 +31,18 @@ enum Wrap {
        HOURS
 };
 
-/** SMPTE frame rate (in frames per second).
- *
- * This should be eliminated in favour of a float to support arbitrary rates.
- */
-enum FPS {
-    MTC_24_FPS = 0,
-    MTC_25_FPS = 1,
-    MTC_30_FPS_DROP = 2,
-    MTC_30_FPS = 3
-};
-
 struct Time {
        bool       negative;
        uint32_t   hours;
        uint32_t   minutes;
        uint32_t   seconds;
-       uint32_t   frames;       ///< SMPTE frames (not audio samples)
-       uint32_t   subframes;    ///< Typically unused
-       FPS        rate;         ///< Frame rate of this Time
-       static FPS default_rate; ///< Rate to use for default constructor
+       uint32_t   frames;        ///< SMPTE frames (not audio samples)
+       uint32_t   subframes;     ///< Typically unused
+       float      rate;          ///< Frame rate of this Time
+       static float default_rate;///< Rate to use for default constructor
+       bool       drop;          ///< Whether this Time uses dropframe SMPTE
 
-       Time(FPS a_rate = default_rate) {
+       Time(float a_rate = default_rate) {
                negative = false;
                hours = 0;
                minutes = 0;
index 55d0660c59203a1924837ab2569afde1629349ab..5df159a52bf45760253cec76258a783e9ce39709 100644 (file)
 #define SMPTE_IS_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours && !(sm.subframes))
 
 #include <control_protocol/smpte.h>
+#include <ardour/configuration.h>
 
 namespace SMPTE {
 
-FPS Time::default_rate = MTC_30_FPS;
+float Time::default_rate = 30.0;
 
 
 /** Increment @a smpte by exactly one frame (keep subframes value).
@@ -38,7 +39,7 @@ increment( Time& smpte )
        if (smpte.negative) {
                if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
                        // We have a zero transition involving only subframes
-                       smpte.subframes = 80 - smpte.subframes;
+                       smpte.subframes = ARDOUR::Config->get_subframes_per_frame() - smpte.subframes;
                        smpte.negative = false;
                        return SECONDS;
                }
@@ -50,34 +51,42 @@ increment( Time& smpte )
                }
                return wrap;
        }
-  
-       switch (smpte.rate) {
-       case MTC_24_FPS:
+
+       switch ((int)ceil(smpte.rate)) {
+       case 24:
                if (smpte.frames == 23) {
                        smpte.frames = 0;
                        wrap = SECONDS;
                }
                break;
-       case MTC_25_FPS:
+       case 25:
                if (smpte.frames == 24) {
                        smpte.frames = 0;
                        wrap = SECONDS;
                }
                break;
-       case MTC_30_FPS_DROP:
-               if (smpte.frames == 29) {
-                       if ( ((smpte.minutes + 1) % 10) && (smpte.seconds == 59) ) {
-                               smpte.frames = 2;
-                       }
-                       else {
-                               smpte.frames = 0;
-                       }
-                       wrap = SECONDS;
+       case 30:
+               if (smpte.drop) {
+                      if (smpte.frames == 29) {
+                             if ( ((smpte.minutes + 1) % 10) && (smpte.seconds == 59) ) {
+                                    smpte.frames = 2;
+                             }
+                             else {
+                                    smpte.frames = 0;
+                             }
+                             wrap = SECONDS;
+                      }
+               } else {
+
+                      if (smpte.frames == 29) {
+                             smpte.frames = 0;
+                             wrap = SECONDS;
+                      }
                }
                break;
-       case MTC_30_FPS:
-               if (smpte.frames == 29) {
-                       smpte.frames = 0;
+       case 60:
+               if (smpte.frames == 59) {
+                       smpte.frames = 0;
                        wrap = SECONDS;
                }
                break;
@@ -121,38 +130,46 @@ decrement( Time& smpte )
                return wrap;
        } else if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
                // We have a zero transition involving only subframes
-               smpte.subframes = 80 - smpte.subframes;
+               smpte.subframes = ARDOUR::Config->get_subframes_per_frame() - smpte.subframes;
                smpte.negative = true;
                return SECONDS;
        }
   
-       switch (smpte.rate) {
-       case MTC_24_FPS:
+       switch ((int)ceil(smpte.rate)) {
+       case 24:
                if (smpte.frames == 0) {
                        smpte.frames = 23;
                        wrap = SECONDS;
                }
                break;
-       case MTC_25_FPS:
+       case 25:
                if (smpte.frames == 0) {
                        smpte.frames = 24;
                        wrap = SECONDS;
                }
                break;
-       case MTC_30_FPS_DROP:
-               if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
-                       if (smpte.frames <= 2) {
-                               smpte.frames = 29;
+       case 30:
+               if (smpte.drop) {
+                       if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
+                               if (smpte.frames <= 2) {
+                                       smpte.frames = 29;
+                                       wrap = SECONDS;
+                               }
+                       } else if (smpte.frames == 0) {
+                               smpte.frames = 29;
+                               wrap = SECONDS;
+                       }
+                       
+               } else {
+                       if (smpte.frames == 0) {
+                               smpte.frames = 29;
                                wrap = SECONDS;
                        }
-               } else if (smpte.frames == 0) {
-                       smpte.frames = 29;
-                       wrap = SECONDS;
                }
                break;
-       case MTC_30_FPS:
-               if (smpte.frames == 0) {
-                       smpte.frames = 29;
+       case 60:
+               if (smpte.frames == 0) {
+                       smpte.frames = 59;
                        wrap = SECONDS;
                }
                break;
@@ -212,7 +229,7 @@ increment_subframes( Time& smpte )
        }
   
        smpte.subframes++;
-       if (smpte.subframes >= 80) {
+       if (smpte.subframes >= ARDOUR::Config->get_subframes_per_frame()) {
                smpte.subframes = 0;
                increment( smpte );
                return FRAMES;
@@ -274,17 +291,19 @@ increment_seconds( Time& smpte )
                }
        } else {
                // Go to highest possible frame in this second
-               switch (smpte.rate) {
-               case MTC_24_FPS:
+         switch ((int)ceil(smpte.rate)) {
+               case 24:
                        smpte.frames = 23;
                        break;
-               case MTC_25_FPS:
+               case 25:
                        smpte.frames = 24;
                        break;
-               case MTC_30_FPS_DROP:
-               case MTC_30_FPS:
+               case 30:
                        smpte.frames = 29;
                        break;
+               case 60:
+                       smpte.frames = 59;
+                       break;
                }
     
                // Increment by one frame
@@ -304,17 +323,20 @@ seconds_floor( Time& smpte )
        frames_floor( smpte );
   
        // Go to lowest possible frame in this second
-       switch (smpte.rate) {
-       case MTC_24_FPS:
-       case MTC_25_FPS:
-       case MTC_30_FPS:
-               smpte.frames = 0;
-               break;
-       case MTC_30_FPS_DROP:
-               if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
-                       smpte.frames = 2;
+       switch ((int)ceil(smpte.rate)) {
+       case 24:
+       case 25:
+       case 30:
+       case 60:
+               if (!(smpte.drop)) {
+                       smpte.frames = 0;
                } else {
-                       smpte.frames = 0;
+
+                       if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
+                               smpte.frames = 2;
+                       } else {
+                               smpte.frames = 0;
+                       }
                }
                break;
        }
index f9c2de08f8da1be37234244a000aa8fdacf9cfdf..6c76e054649b8410ce3a2ac8ba6017968a9a491c 100644 (file)
@@ -34,6 +34,7 @@ genericmidi.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
 genericmidi.Merge ([
        libraries['ardour'],
        libraries['ardour_cp'],
+       libraries['sndfile-ardour'],
        libraries['midi++2'],
        libraries['pbd'],
        libraries['sigc2'],
@@ -50,7 +51,7 @@ Default(libardour_genericmidi)
 if env['NLS']:
        i18n (genericmidi, genericmidi_files, env)
              
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2/surfaces'), libardour_genericmidi))
+env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2', 'surfaces'), libardour_genericmidi))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                     [ 'SConscript' ] +
index 03dbfb353c451344816189281b06031a79468415..0256d5c3597aa15b074f43c392581509e3b34ceb 100644 (file)
@@ -234,7 +234,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
 
        controllables.clear ();
 
-       nlist = node.children();
+       nlist = node.children(); // "controls"
 
        if (nlist.empty()) {
                return 0;
index 6dc9bde8ad23fc51a664b1937ef23139149b93f7..75b5699f18bf7c3e460bce2ab5c810f338ba5c8e 100644 (file)
@@ -32,8 +32,6 @@ using namespace MIDI;
 using namespace PBD;
 using namespace ARDOUR;
 
-bool MIDIControllable::_send_feedback = false;
-
 MIDIControllable::MIDIControllable (Port& p, Controllable& c, bool is_bistate)
        : controllable (c), _port (p), bistate (is_bistate)
 {
@@ -288,7 +286,7 @@ MIDIControllable::send_feedback ()
 {
        byte msg[3];
 
-       if (setting || !_send_feedback || control_type == none) {
+       if (setting || !feedback || control_type == none) {
                return;
        }
        
@@ -302,7 +300,7 @@ MIDIControllable::send_feedback ()
 MIDI::byte*
 MIDIControllable::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool force)
 {
-       if (control_type != none &&_send_feedback && bufsize > 2) {
+       if (control_type != none && feedback && bufsize > 2) {
 
                MIDI::byte gm = (MIDI::byte) (controllable.get_value() * 127.0);
                
@@ -345,6 +343,12 @@ MIDIControllable::set_state (const XMLNode& node)
                return -1;
        }
 
+       if ((prop = node.property ("feedback")) != 0) {
+               feedback = (prop->value() == "yes");
+       } else {
+               feedback = true; // default
+       }
+
        bind_midi (control_channel, control_type, control_additional);
        
        return 0;
@@ -362,6 +366,7 @@ MIDIControllable::get_state ()
        node.add_property ("channel", buf);
        snprintf (buf, sizeof(buf), "0x%x", (int) control_additional);
        node.add_property ("additional", buf);
+       node.add_property ("feedback", (feedback ? "yes" : "no"));
 
        return node;
 }
index ab15f9f4ab3fd6425001e7e582dbffbef043c97c..8b631729161bfdc0a03eb1689b885f556a3b8ca8 100644 (file)
@@ -80,8 +80,6 @@ class MIDIControllable : public Stateful
        std::string     _control_description;
        bool             feedback;
        
-       static bool _send_feedback;
-
        void midi_receiver (MIDI::Parser &p, MIDI::byte *, size_t);
        void midi_sense_note (MIDI::Parser &, MIDI::EventTwoBytes *, bool is_on);
        void midi_sense_note_on (MIDI::Parser &p, MIDI::EventTwoBytes *tb);
index 3f9cc5cc1542633542fb8d88f96881c68f08ff6d..5d390f3e2ffe29b9986f3209f749de846d6029b4 100644 (file)
@@ -44,12 +44,11 @@ tranzport.Merge ([
 
 libardour_tranzport = tranzport.SharedLibrary('ardour_tranzport', tranzport_files)
 
-Default(libardour_tranzport)
-
-if env['NLS']:
-       i18n (tranzport, tranzport_files, env)
-             
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2/surfaces'), libardour_tranzport))
+if tranzport['TRANZPORT']:
+       Default(libardour_tranzport)
+       if env['NLS']:
+               i18n (tranzport, tranzport_files, env)
+       env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2', 'surfaces'), libardour_tranzport))
 
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                     [ 'SConscript' ] +
index ea85a32a778076b36b7a0afe55ef754c1b1df9e1..bbb78d31d159f7172f5b2039e84601676cbd06e9 100644 (file)
     $Id$
 */
 
+/* Design notes: The tranzport is a unique device, basically a 
+   20 lcd gui with 22 shift keys and 8 blinking lights. 
+
+   As such it has several unique constraints. The device exerts flow control
+   by having a usb write fail. It is pointless to retry madly at that point,
+   the device is busy, and it's not going to become unbusy very quickly. 
+
+   So writes need to be either "mandatory" or "unreliable", and therein 
+   lies the rub, as the kernel can also drop writes, and missing an
+   interrupt in userspace is also generally bad.
+
+   It will be good one day, to break the gui, keyboard, and blinking light
+   components into separate parts, but for now, this remains monolithic.
+
+   A more complex surface might have hundreds of lights and several displays.
+
+   mike.taht@gmail.com
+ */
+
+#define DEFAULT_USB_TIMEOUT 10
+#define MAX_RETRY 1
+#define MAX_TRANZPORT_INFLIGHT 4
+#define DEBUG_TRANZPORT 0
+#define HAVE_TRANZPORT_KERNEL_DRIVER 0
+
 #include <iostream>
 #include <algorithm>
 #include <cmath>
@@ -33,6 +58,7 @@
 #include <ardour/route.h>
 #include <ardour/audio_track.h>
 #include <ardour/session.h>
+#include <ardour/tempo.h>
 #include <ardour/location.h>
 #include <ardour/dB.h>
 
@@ -51,6 +77,12 @@ BaseUI::RequestType LEDChange = BaseUI::new_request_type ();
 BaseUI::RequestType Print = BaseUI::new_request_type ();
 BaseUI::RequestType SetCurrentTrack = BaseUI::new_request_type ();
 
+/* Base Tranzport cmd strings */
+
+static const uint8_t cmd_light_on[] =  { 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 };
+static const uint8_t cmd_light_off[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
+static const uint8_t cmd_write_screen[] =  { 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 };
+
 static inline double 
 gain_to_slider_position (ARDOUR::gain_t g)
 {
@@ -74,8 +106,7 @@ TranzportControlProtocol::TranzportControlProtocol (Session& s)
        /* tranzport controls one track at a time */
 
        set_route_table_size (1);
-       
-       timeout = 60000;
+       timeout = 6000; // what is this for?
        buttonmask = 0;
        _datawheel = 0;
        _device_status = STATUS_OFFLINE;
@@ -84,51 +115,212 @@ TranzportControlProtocol::TranzportControlProtocol (Session& s)
        last_where = max_frames;
        wheel_mode = WheelTimeline;
        wheel_shift_mode = WheelShiftGain;
+       wheel_increment = WheelIncrScreen;
+       bling_mode = BlingOff;
        timerclear (&last_wheel_motion);
        last_wheel_dir = 1;
        last_track_gain = FLT_MAX;
        display_mode = DisplayNormal;
        gain_fraction = 0.0;
+       invalidate();
+       screen_init();
+       lights_init();
+       print(0,0,"!!Welcome to Ardour!!");
+       print(1,0,"!Peace through Music!");
+}
 
-       memset (current_screen, 0, sizeof (current_screen));
-       memset (pending_screen, 0, sizeof (pending_screen));
+void TranzportControlProtocol::light_validate (LightID light) 
+{
+       lights_invalid[light] = 0;
+}
+
+void TranzportControlProtocol::light_invalidate (LightID light) 
+{
+       lights_invalid[light] = 1;
+}
 
-       for (uint32_t i = 0; i < sizeof(lights)/sizeof(lights[0]); ++i) {
-               lights[i] = false;
+void TranzportControlProtocol::lights_validate () 
+{
+       memset (lights_invalid, 0, sizeof (lights_invalid)); 
+}
+
+void TranzportControlProtocol::lights_invalidate () 
+{
+       memset (lights_invalid, 1, sizeof (lights_invalid)); 
+}
+
+void TranzportControlProtocol::lights_init()
+{
+       for (uint32_t i = 0; i < sizeof(lights_current)/sizeof(lights_current[0]); i++) {
+               lights_invalid[i] = lights_current[i] = 
+                       lights_pending[i] = lights_flash[i] = false;
+       }
+}
+
+
+
+int
+TranzportControlProtocol::lights_flush ()
+{
+       if ( _device_status == STATUS_OFFLINE) { return (0); }
+
+       //  Figure out iterators one day soon
+       //  for (LightID i = i.start(), i = i.end(); i++) {
+       //  if (lights_pending[i] != lights_current[i] || lights_invalid[i]) {
+       //    if (light_set(i, lights_pending[i])) { 
+       //       return i-1;
+       //    } 
+       //  }
+       //}
+       if ((lights_pending[LightRecord] != lights_current[LightRecord]) || lights_invalid[LightRecord]) {
+               if (light_set(LightRecord,lights_pending[LightRecord])) {
+                       return 1;
+               }
+       }
+       if ((lights_pending[LightTrackrec] != lights_current[LightTrackrec]) || lights_invalid[LightTrackrec]) {
+               if (light_set(LightTrackrec,lights_pending[LightTrackrec])) {
+                       return 1;
+               }
+       }
+
+       if ((lights_pending[LightTrackmute] != lights_current[LightTrackmute]) || lights_invalid[LightTrackmute]) {
+               if (light_set(LightTrackmute,lights_pending[LightTrackmute])) {
+                       return 1;
+               }
        }
 
-       for (uint32_t i = 0; i < sizeof(pending_lights)/sizeof(pending_lights[0]); ++i) {
-               pending_lights[i] = false;
+       if ((lights_pending[LightTracksolo] != lights_current[LightTracksolo]) || lights_invalid[LightTracksolo]) {
+               if (light_set(LightTracksolo,lights_pending[LightTracksolo])) {
+                       return 1;
+               }
+       }
+       if ((lights_pending[LightAnysolo] != lights_current[LightAnysolo]) || lights_invalid[LightAnysolo]) {
+               if (light_set(LightAnysolo,lights_pending[LightAnysolo])) {
+                       return 1;
+               }
+       }
+       if ((lights_pending[LightLoop] != lights_current[LightLoop]) || lights_invalid[LightLoop]) {
+               if (light_set(LightLoop,lights_pending[LightLoop])) {
+                       return 1;
+               }
        }
+       if ((lights_pending[LightPunch] != lights_current[LightPunch]) || lights_invalid[LightPunch]) {
+               if (light_set(LightPunch,lights_pending[LightPunch])) {
+                       return 1;
+               }
+       }
+
+       return 0;
 }
 
-TranzportControlProtocol::~TranzportControlProtocol ()
+// Screen specific commands
+
+void
+TranzportControlProtocol::screen_clear ()
 {
-       set_active (false);
+       const char *blank = "                    ";
+       print(0,0,blank); 
+       print(1,0,blank);
 }
 
-bool
-TranzportControlProtocol::probe ()
+void TranzportControlProtocol::screen_invalidate ()
 {
-       struct usb_bus *bus;
-       struct usb_device *dev;
+       for(int row = 0; row < 2; row++) {
+               for(int col = 0; col < 20; col++) {
+                       screen_invalid[row][col] = true;
+                       screen_current[row][col] = 0x7f;
+                       screen_pending[row][col] = ' ';
+                       // screen_flash[row][col] = ' ';
+               }
+       }
+       // memset (&screen_invalid, 1, sizeof(screen_invalid));
+       // memset (&screen_current, 0x7F, sizeof (screen_current)); // fill cache with a character we otherwise never use
+}
 
-       usb_init();
-       usb_find_busses();
-       usb_find_devices();
+void TranzportControlProtocol::screen_validate ()
+{
+}
 
-       for (bus = usb_busses; bus; bus = bus->next) {
+void TranzportControlProtocol::screen_init ()
+{
+       screen_invalidate();
+}
 
-               for(dev = bus->devices; dev; dev = dev->next) {
-                       if (dev->descriptor.idVendor == VENDORID && dev->descriptor.idProduct == PRODUCTID) {
-                               return true; 
+int
+TranzportControlProtocol::screen_flush ()
+{
+       int cell = 0, row, col_base, col, pending = 0;
+       if ( _device_status == STATUS_OFFLINE) { return (-1); }
+
+       for (row = 0; row < 2 && pending == 0; row++) {
+               for (col_base = 0, col = 0; col < 20 && pending == 0; ) {
+                       if ((screen_pending[row][col] != screen_current[row][col]) 
+                                       || screen_invalid[row][col]) {
+
+                               /* something in this cell is different, so dump the cell to the device. */
+
+                               uint8_t cmd[8]; 
+                               cmd[0] = 0x00; 
+                               cmd[1] = 0x01; 
+                               cmd[2] = cell; 
+                               cmd[3] = screen_pending[row][col_base]; 
+                               cmd[4] = screen_pending[row][col_base+1];
+                               cmd[5] = screen_pending[row][col_base+2]; 
+                               cmd[6] = screen_pending[row][col_base+3];
+                               cmd[7] = 0x00;
+
+                               if(write(cmd) != 0) {
+                                       /* try to update this cell on the next go-round */
+#if DEBUG_TRANZPORT > 4
+                                       printf("usb screen update failed for some reason... why? \ncmd and data were %02x %02x %02x %02x %02x %02x %02x %02x\n", 
+                                                       cmd[0],cmd[1],cmd[2], cmd[3], cmd[4], cmd[5],cmd[6],cmd[7]); 
+#endif
+                                       pending += 1;   
+                                       // Shouldn't need to do this
+                                       // screen_invalid[row][col_base] = screen_invalid[row][col_base+1] = 
+                                       // screen_invalid[row][col_base+2] = screen_invalid[row][col_base+3] = true;
+
+                               } else {
+                                       /* successful write: copy to current cached display */
+                                       screen_invalid[row][col_base] = screen_invalid[row][col_base+1] = 
+                                               screen_invalid[row][col_base+2] = screen_invalid[row][col_base+3] = false;
+                                       memcpy (&screen_current[row][col_base], &screen_pending[row][col_base], 4);
+                               }
+
+                               /* skip the rest of the 4 character cell since we wrote+copied it already */
+
+                               col_base += 4;
+                               col = col_base;
+                               cell++;
+
+                       } else {
+
+                               col++;
+
+                               if (col && col % 4 == 0) {
+                                       cell++;
+                                       col_base += 4;
+                               }
                        }
                }
        }
+       return pending;
+}
 
-       return false;
+
+//  Tranzport specific
+
+void TranzportControlProtocol::invalidate() 
+{
+       lcd_damage(); lights_invalidate(); screen_invalidate(); // one of these days lcds can be fine but screens not
+}
+
+TranzportControlProtocol::~TranzportControlProtocol ()
+{
+       set_active (false);
 }
 
+
 int
 TranzportControlProtocol::set_active (bool yn)
 {
@@ -139,7 +331,7 @@ TranzportControlProtocol::set_active (bool yn)
                        if (open ()) {
                                return -1;
                        }
-                       
+
                        if (pthread_create_and_store (X_("tranzport monitor"), &thread, 0, _monitor_work, this) == 0) {
                                _active = true;
                        } else {
@@ -148,11 +340,12 @@ TranzportControlProtocol::set_active (bool yn)
 
                } else {
                        cerr << "Begin tranzport shutdown\n";
+                       screen_clear ();
+                       lcd_damage();
+                       lights_off ();
+                       for(int x = 0; x < 10 && flush(); x++) { usleep(1000); }
                        pthread_cancel_one (thread);
-                       cerr << "Thread dead\n";
-                       // lcd_clear ();
-                       // lights_off ();
-                       // cerr << "dev reset\n";
+                       cerr << "Tranzport Thread dead\n";
                        close ();
                        _active = false;
                        cerr << "End tranzport shutdown\n";
@@ -167,8 +360,8 @@ TranzportControlProtocol::show_track_gain ()
 {
        if (route_table[0]) {
                gain_t g = route_get_gain (0);
-               if (g != last_track_gain) {
-                       char buf[16];
+               if ((g != last_track_gain) || lcd_isdamaged(0,9,8)) {
+                       char buf[16]; 
                        snprintf (buf, sizeof (buf), "%6.1fdB", coefficient_to_dB (route_get_effective_gain (0)));
                        print (0, 9, buf); 
                        last_track_gain = g;
@@ -191,20 +384,66 @@ void
 TranzportControlProtocol::next_display_mode ()
 {
        switch (display_mode) {
-       case DisplayNormal:
-               display_mode = DisplayBigMeter;
-               break;
 
-       case DisplayBigMeter:
-               display_mode = DisplayNormal;
-               break;
+               case DisplayNormal:
+                       enter_big_meter_mode();
+                       break;
+
+               case DisplayBigMeter:
+                       enter_normal_display_mode();
+                       break;
+
+               case DisplayRecording:
+                       enter_normal_display_mode();
+                       break;
+
+               case DisplayRecordingMeter:
+                       enter_big_meter_mode();
+                       break;
+
+               case DisplayConfig: 
+               case DisplayBling:
+               case DisplayBlingMeter:
+                       enter_normal_display_mode();
+                       break;
        }
 }
 
+// FIXME, these 3 aren't done yet
+
+void
+TranzportControlProtocol::enter_recording_mode ()
+{
+       lcd_damage(); // excessive
+       screen_clear ();
+       lights_off ();
+       display_mode = DisplayRecording;
+}
+
+void
+TranzportControlProtocol::enter_bling_mode ()
+{
+       lcd_damage();
+       screen_clear ();
+       lights_off ();
+       display_mode = DisplayBling;
+}
+
+void
+TranzportControlProtocol::enter_config_mode ()
+{
+       lcd_damage();
+       screen_clear ();
+       lights_off ();
+       display_mode = DisplayConfig;
+}
+
+
 void
 TranzportControlProtocol::enter_big_meter_mode ()
 {
-       lcd_clear ();
+       screen_clear ();
+       lcd_damage();
        lights_off ();
        last_meter_fill = 0;
        display_mode = DisplayBigMeter;
@@ -213,16 +452,11 @@ TranzportControlProtocol::enter_big_meter_mode ()
 void
 TranzportControlProtocol::enter_normal_display_mode ()
 {
-       last_where += 1; /* force time redisplay */
-       last_track_gain = FLT_MAX; /* force gain redisplay */
-
-       lcd_clear ();
+       screen_clear ();
+       lcd_damage();
        lights_off ();
-       show_current_track ();
-       show_wheel_mode ();
-       show_wheel_mode ();
-       show_transport_time ();
        display_mode = DisplayNormal;
+       //  normal_update();
 }
 
 
@@ -230,10 +464,11 @@ float
 log_meter (float db)
 {
        float def = 0.0f; /* Meter deflection %age */
-       if (db < -70.0f) {
-               def = 0.0f;
-       } else if (db < -60.0f) {
+
+       if (db < -70.0f) return 0.0f;
+       if (db > 6.0f) return 1.0f;
+
+       if (db < -60.0f) {
                def = (db + 70.0f) * 0.25f;
        } else if (db < -50.0f) {
                def = (db + 60.0f) * 0.5f + 2.5f;
@@ -245,32 +480,36 @@ log_meter (float db)
                def = (db + 30.0f) * 2.0f + 30.0f;
        } else if (db < 6.0f) {
                def = (db + 20.0f) * 2.5f + 50.0f;
-       } else {
-               def = 115.0f;
        }
-       
+
        /* 115 is the deflection %age that would be 
           when db=6.0. this is an arbitrary
           endpoint for our scaling.
-       */
-       
+          */
+
        return def/115.0f;
 }
 
 void
 TranzportControlProtocol::show_meter ()
 {
+       // you only seem to get a route_table[0] on moving forward - bug elsewhere
        if (route_table[0] == 0) {
+               // Principle of least surprise
+               print (0, 0, "No audio to meter!!!");
+               print (1, 0, "Select another track"); 
                return;
        }
 
        float level = route_get_peak_input_power (0, 0);
        float fraction = log_meter (level);
 
+       /* Someday add a peak bar*/
+
        /* we draw using a choice of a sort of double colon-like character ("::") or a single, left-aligned ":".
           the screen is 20 chars wide, so we can display 40 different levels. compute the level,
           then figure out how many "::" to fill. if the answer is odd, make the last one a ":"
-       */
+          */
 
        uint32_t fill  = (uint32_t) floor (fraction * 40);
        char buf[21];
@@ -285,7 +524,7 @@ TranzportControlProtocol::show_meter ()
 
        bool add_single_level = (fill % 2 != 0);
        fill /= 2;
-       
+
        if (fraction > 0.98) {
                light_on (LightAnysolo);
        }
@@ -310,25 +549,64 @@ TranzportControlProtocol::show_meter ()
        }
 
        /* print() requires this */
-       
+
        buf[21] = '\0';
 
        print (0, 0, buf);
        print (1, 0, buf);
 }
 
+void
+TranzportControlProtocol::show_bbt (nframes_t where)
+{ 
+       if ((where != last_where) || lcd_isdamaged(1,9,8)) {
+               char buf[16];
+               BBT_Time bbt;
+               session->tempo_map().bbt_time (where, bbt);
+               sprintf (buf, "%03" PRIu32 "|%02" PRIu32 "|%04" PRIu32, bbt.bars,bbt.beats,bbt.ticks);
+               last_bars = bbt.bars;
+               last_beats = bbt.beats;
+               last_ticks = bbt.ticks;
+               last_where = where;
+
+               if(last_ticks < 1960) { print (1, 9, buf); } // save a write so we can do leds
+
+               // if displaymode is recordmode show beats but not yet
+               lights_pending[LightRecord] = false;
+               lights_pending[LightAnysolo] = false;
+               switch(last_beats) {
+                       case 1: if(last_ticks < 500 || last_ticks > 1960) lights_pending[LightRecord] = true; break;
+                       default: if(last_ticks < 250) lights_pending[LightAnysolo] = true;
+               }
+
+               // update lights for tempo one day
+               //        if (bbt_upper_info_label) {
+               //     TempoMap::Metric m (session->tempo_map().metric_at (when));
+               //     sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
+               //      bbt_lower_info_label->set_text (buf);
+               //      sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
+               //      bbt_upper_info_label->set_text (buf);
+       }
+       }
+
+
 void
 TranzportControlProtocol::show_transport_time ()
 {
        nframes_t where = session->transport_frame();
-       
-       if (where != last_where) {
+       show_bbt(where);
+}      
+
+void
+TranzportControlProtocol::show_smpte (nframes_t where)
+{
+       if ((where != last_where) || lcd_isdamaged(1,9,10)) {
 
                char buf[5];
                SMPTE::Time smpte;
 
                session->smpte_time (where, smpte);
-               
+
                if (smpte.negative) {
                        sprintf (buf, "-%02" PRIu32 ":", smpte.hours);
                } else {
@@ -343,7 +621,7 @@ TranzportControlProtocol::show_transport_time ()
                print (1, 15, buf);
 
                sprintf (buf, "%02" PRIu32, smpte.frames);
-               print (1, 18, buf);
+               print_noretry (1, 18, buf); 
 
                last_where = where;
        }
@@ -355,6 +633,33 @@ TranzportControlProtocol::_monitor_work (void* arg)
        return static_cast<TranzportControlProtocol*>(arg)->monitor_work ();
 }
 
+// I note that these usb specific open, close, probe, read routines are basically 
+// pure boilerplate and could easily be abstracted elsewhere
+
+#if !HAVE_TRANZPORT_KERNEL_DRIVER
+
+bool
+TranzportControlProtocol::probe ()
+{
+       struct usb_bus *bus;
+       struct usb_device *dev;
+
+       usb_init();
+       usb_find_busses();
+       usb_find_devices();
+
+       for (bus = usb_busses; bus; bus = bus->next) {
+
+               for(dev = bus->devices; dev; dev = dev->next) {
+                       if (dev->descriptor.idVendor == VENDORID && dev->descriptor.idProduct == PRODUCTID) {
+                               return true; 
+                       }
+               }
+       }
+
+       return false;
+}
+
 int
 TranzportControlProtocol::open ()
 {
@@ -424,393 +729,469 @@ TranzportControlProtocol::close ()
 
        return ret;
 }
+
+int TranzportControlProtocol::read(uint8_t *buf, uint32_t timeout_override) 
+{
+       int val;
+       // Get smarter about handling usb errors soon. Like disconnect
+       //  pthread_testcancel();
+       val = usb_interrupt_read (udev, READ_ENDPOINT, (char *) buf, 8, 10);
+       //  pthread_testcancel();
+       return val;
+} 
+
        
 int
-TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override)
+TranzportControlProtocol::write_noretry (uint8_t* cmd, uint32_t timeout_override)
 {
        int val;
-
+       if(inflight > MAX_TRANZPORT_INFLIGHT) { return (-1); }
        val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout);
 
-       if (val < 0)
+       if (val < 0) {
+#if DEBUG_TRANZPORT
+               printf("usb_interrupt_write failed: %d\n", val);
+#endif
                return val;
-       if (val != 8)
+               }
+
+       if (val != 8) {
+#if DEBUG_TRANZPORT
+               printf("usb_interrupt_write failed: %d\n", val);
+#endif
                return -1;
+               }
+       ++inflight;
+
        return 0;
 
 }      
 
-void
-TranzportControlProtocol::lcd_clear ()
+int
+TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override)
 {
-       /* special case this for speed and atomicity */
-
-       uint8_t cmd[8];
+#if MAX_RETRY > 1
+       int val;
+       int retry = 0;
+       if(inflight > MAX_TRANZPORT_INFLIGHT) { return (-1); }
        
-       cmd[0] = 0x00;
-       cmd[1] = 0x01;
-       cmd[3] = ' ';
-       cmd[4] = ' ';
-       cmd[5] = ' ';
-       cmd[6] = ' ';
-       cmd[7] = 0x00;
-
-       for (uint8_t i = 0; i < 10; ++i) {
-               cmd[2] = i;
-               usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, 1000);
+       while((val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout))!=8 && retry++ < MAX_RETRY) {
+               printf("usb_interrupt_write failed, retrying: %d\n", val);
        }
-       
-       memset (current_screen, ' ', sizeof (current_screen));
-       memset (pending_screen, ' ', sizeof (pending_screen));
-}
 
-void
-TranzportControlProtocol::lights_off ()
+       if (retry == MAX_RETRY) {
+               printf("Too many retries on a tranzport write, aborting\n");
+               }
+
+       if (val < 0) {
+               printf("usb_interrupt_write failed: %d\n", val);
+               return val;
+               }
+       if (val != 8) {
+               printf("usb_interrupt_write failed: %d\n", val);
+               return -1;
+               }
+       ++inflight;
+       return 0;
+#else
+       return (write_noretry(cmd,timeout_override));
+#endif
+
+}      
+
+#else
+#error Kernel API not defined yet for Tranzport
+// Something like open(/dev/surface/tranzport/event) for reading and raw for writing)
+#endif
+
+// We have a state "Unknown" - STOP USING SPACES FOR IT - switching to arrow character
+// We have another state - no_retry. Misleading, as we still retry on the next pass
+// I think it's pointless to keep no_retry and instead we should throttle writes 
+// We have an "displayed" screen
+// We always draw into the pending screen, which could be any of several screens
+// We have an active screen
+// Print arg - we have 
+// setactive
+// so someday I think we need a screen object.
+
+/*
+screen_flash.clear();
+screen_flash.print(0,0,"Undone:"); // Someday pull the undo stack from somewhere
+screen_flash.print(1,0,"Nextup:"); 
+
+if(flash_messages && lcd.getactive() != screen_flash) lcd.setactive(screen_flash,2000);
+
+screen::setactive(screen_name,duration); // duration in ms
+screen::getactive();
+*/
+
+
+int
+TranzportControlProtocol::flush ()
 {
-       uint8_t cmd[8];
+       int pending = 0;
+       if(!(pending = lights_flush())) {
+               pending = screen_flush(); 
+       } 
+       return pending;
+}
 
-       cmd[0] = 0x00;
-       cmd[1] = 0x00;
-       cmd[3] = 0x00;
-       cmd[4] = 0x00;
-       cmd[5] = 0x00;
-       cmd[6] = 0x00;
-       cmd[7] = 0x00;
+// doing these functions made me realize that screen_invalid should be lcd_isdamaged FIXME soon
 
-       cmd[2] = LightRecord;
-       if (write (cmd, 1000) == 0) {
-               lights[LightRecord] = false;
-       }
-       cmd[2] = LightTrackrec;
-       if (write (cmd, 1000) == 0) {
-               lights[LightTrackrec] = false;
-       }
-       cmd[2] = LightTrackmute;
-       if (write (cmd, 1000) == 0) {
-               lights[LightTrackmute] = false;
-       }
-       cmd[2] = LightTracksolo;
-       if (write (cmd, 1000) == 0) {
-               lights[LightTracksolo] = false;
-       }
-       cmd[2] = LightAnysolo;
-       if (write (cmd, 1000) == 0) {
-               lights[LightAnysolo] = false;
+bool TranzportControlProtocol::lcd_damage() 
+{
+       screen_invalidate();
+       return true;
+}
+
+bool TranzportControlProtocol::lcd_damage (int row, int col, int length)
+{
+       bool result = false;
+       int endcol = col+length-1;
+       if((endcol > 19)) { endcol = 19; } 
+       if((row >= 0 && row < 2) && (col >=0 && col < 20)) {
+               for(int c = col; c < endcol; c++) {
+                       screen_invalid[row][c] = true;
+               }
+               result = true;
        }
-       cmd[2] = LightLoop;
-       if (write (cmd, 1000) == 0) {
-               lights[LightLoop] = false;
+       return result;
+}
+
+// Gotta switch to bitfields, this is collossally dumb
+// Still working on the layering, arguably screen_invalid should be lcd_invalid
+
+bool TranzportControlProtocol::lcd_isdamaged () 
+{
+       for(int r = 0; r < 2; r++) {
+               for(int c = 0; c < 20; c++) {
+                       if(screen_invalid[r][c]) {
+#if DEBUG_TRANZPORT > 5        
+                               printf("row: %d,col: %d is damaged, should redraw it\n", r,c);
+#endif
+                               return true;
+                       }
+               }
        }
-       cmd[2] = LightPunch;
-       if (write (cmd, 1000) == 0) {
-               lights[LightPunch] = false;
+       return false;
+}
+
+bool TranzportControlProtocol::lcd_isdamaged (int row, int col, int length)
+{
+       bool result = 0;
+       int endcol = col+length;
+       if((endcol > 19)) { endcol = 19; } 
+       if((row >= 0 && row < 2) && (col >=0 && col < 20)) {
+               for(int c = col; c < endcol; c++) {
+                       if(screen_invalid[row][c]) {
+#if DEBUG_TRANZPORT > 5        
+                               printf("row: %d,col: %d is damaged, should redraw it\n", row,c);
+#endif
+                               return true;
+                       }
+               }
        }
+       return result;
 }
 
+// lcd_clear would be a separate function for a smart display
+// here it does nothing, but for the sake of completeness it should
+// probably write the lcd, and while I'm on the topic it should probably
+// take a row, col, length argument....
+
+void
+TranzportControlProtocol::lcd_clear ()
+{
+
+}
+
+// These lcd commands are not universally used yet and may drop out of the api
+
 int
-TranzportControlProtocol::light_on (LightID light)
+TranzportControlProtocol::lcd_flush ()
 {
-       uint8_t cmd[8];
+       return 0; 
+}
 
-       if (!lights[light]) {
+int 
+TranzportControlProtocol::lcd_write(uint8_t* cmd, uint32_t timeout_override)
+{
+       return write(cmd,timeout_override);
+}
 
-               cmd[0] = 0x00;
-               cmd[1] = 0x00;
-               cmd[2] = light;
-               cmd[3] = 0x01;
-               cmd[4] = 0x00;
-               cmd[5] = 0x00;
-               cmd[6] = 0x00;
-               cmd[7] = 0x00;
+void 
+TranzportControlProtocol::lcd_fill (uint8_t fill_char) 
+{
+}
 
-               if (write (cmd, 1000) == 0) {
-                       lights[light] = true;
-                       return 0;
-               } else {
-                       return -1;
-               }
+void 
+TranzportControlProtocol::lcd_print (int row, int col, const char* text) 
+{
+       print(row,col,text);
+}
 
-       } else {
-               return 0;
-       }
+void TranzportControlProtocol::lcd_print_noretry (int row, int col, const char* text)
+{
+       print(row,col,text);
 }
 
-int
-TranzportControlProtocol::light_off (LightID light)
+// Lights are buffered
+
+void
+TranzportControlProtocol::lights_on ()
 {
-       uint8_t cmd[8];
+       lights_pending[LightRecord] = lights_pending[LightTrackrec] = 
+               lights_pending[LightTrackmute] =  lights_pending[LightTracksolo] = 
+               lights_pending[LightAnysolo] =   lights_pending[LightLoop] = 
+               lights_pending[LightPunch] = true;
+}
 
-       if (lights[light]) {
+void
+TranzportControlProtocol::lights_off ()
+{
+       lights_pending[LightRecord] = lights_pending[LightTrackrec] = 
+               lights_pending[LightTrackmute] =  lights_pending[LightTracksolo] = 
+               lights_pending[LightAnysolo] =   lights_pending[LightLoop] = 
+               lights_pending[LightPunch] = false;
+}
 
-               cmd[0] = 0x00;
-               cmd[1] = 0x00;
-               cmd[2] = light;
-               cmd[3] = 0x00;
-               cmd[4] = 0x00;
-               cmd[5] = 0x00;
-               cmd[6] = 0x00;
-               cmd[7] = 0x00;
+int
+TranzportControlProtocol::light_on (LightID light)
+{
+       lights_pending[light] = true;
+       return 0;
+}
 
-               if (write (cmd, 1000) == 0) {
-                       lights[light] = false;
-                       return 0;
-               } else {
-                       return -1;
-               }
+int
+TranzportControlProtocol::light_off (LightID light)
+{
+       lights_pending[light] = false;
+       return 0;
+}
 
-       } else {
+int
+TranzportControlProtocol::light_set (LightID light, bool offon)
+{
+       uint8_t cmd[8];
+       cmd[0] = 0x00;  cmd[1] = 0x00;  cmd[2] = light;  cmd[3] = offon;
+       cmd[4] = 0x00;  cmd[5] = 0x00;  cmd[6] = 0x00;  cmd[7] = 0x00;
+
+       if (write (cmd) == 0) {
+               lights_current[light] = offon;
+               lights_invalid[light] = false;
                return 0;
+       } else {
+               return -1;
        }
 }
 
-void*
-TranzportControlProtocol::monitor_work ()
+int TranzportControlProtocol::rtpriority_set(int priority) 
 {
        struct sched_param rtparam;
        int err;
-       uint8_t buf[8];
-       int val;
-       bool first_time = true;
+       // preallocate and memlock some stack with memlock?
+       char *a = (char*) alloca(4096*2); a[0] = 'a'; a[4096] = 'b';
+       memset (&rtparam, 0, sizeof (rtparam));
+       rtparam.sched_priority = priority; /* XXX should be relative to audio (JACK) thread */
+       // Note - try SCHED_RR with a low limit 
+       // - we don't care if we can't write everything this ms
+       // and it will help if we lose the device
+       if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
+               PBD::info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror (errno)) << endmsg;
+               return 1;
+       } 
+       return 0;
+}
 
-       PBD::ThreadCreated (pthread_self(), X_("Tranzport"));
+// Running with realtime privs is bad when you have problems
 
+int TranzportControlProtocol::rtpriority_unset(int priority) 
+{
+       struct sched_param rtparam;
+       int err;
        memset (&rtparam, 0, sizeof (rtparam));
-       rtparam.sched_priority = 3; /* XXX should be relative to audio (JACK) thread */
-       
+       rtparam.sched_priority = priority;      
        if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
-               // do we care? not particularly.
-               PBD::info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror (errno)) << endmsg;
+               PBD::info << string_compose (_("%1: can't stop realtime scheduling (%2)"), name(), strerror (errno)) << endmsg;
+               return 1;
        } 
+       PBD::info << string_compose (_("%1: realtime scheduling stopped (%2)"), name(), strerror (errno)) << endmsg;
+       return 0;
+}
+
+// Slowly breaking this into where I can make usb processing it's own thread.
+
+void*
+TranzportControlProtocol::monitor_work ()
+{
+       uint8_t buf[8];
+       int val = 0, pending = 0;
+       bool first_time = true;
+       uint8_t offline = 0;
+
 
+       PBD::ThreadCreated (pthread_self(), X_("Tranzport"));
        pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
        pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
-
        next_track ();
+       rtpriority_set();
+       inflight=0;
+       flush();
 
        while (true) {
 
                /* bInterval for this beastie is 10ms */
 
-               /* anything to read ? */
-
                if (_device_status == STATUS_OFFLINE) {
-                       light_off (LightRecord);
-                       first_time = true;
-               }
-
-               pthread_testcancel();
-               val = usb_interrupt_read (udev, READ_ENDPOINT, (char*) buf, 8, 10);
-               pthread_testcancel();
-
-               if (val == 8) {
-                       process (buf);
-               }
-
-               if (_device_status != STATUS_OFFLINE) {
-                       if (first_time) {
-                               lcd_clear ();
-                               lights_off ();
-                               first_time = false;
-                       }
-                       /* update whatever needs updating */
-                       update_state ();
-               }
-       }
-
-       return (void*) 0;
-}
-
-int
-TranzportControlProtocol::update_state ()
-{
-       int row;
-       int col_base;
-       int col;
-       int cell;
-
-       /* do the text updates */
+                       first_time = true;
+                       if(offline++ == 1) { 
+                               cerr << "Transport has gone offline\n";
+                       }
+               } else { 
+                       offline = 0; // hate writing this
+               }
 
-       switch (display_mode) {
-       case DisplayBigMeter:
-               show_meter ();
-               break;
+               val = read(buf);
 
-       case DisplayNormal:
-               normal_update ();
-               break;
-       }
+               if (val == 8) {
+                       process (buf);
+               }
 
-       /* next: flush LCD */
+#if DEBUG_TRANZPORT > 2
+               if(inflight > 1) printf("Inflight: %d\n", inflight);
+#endif
 
-       cell = 0;
-       
-       for (row = 0; row < 2; ++row) {
-
-               for (col_base = 0, col = 0; col < 20; ) {
-                       
-                       if (pending_screen[row][col] != current_screen[row][col]) {
-
-                               /* something in this cell is different, so dump the cell
-                                  to the device.
-                               */
-
-                               uint8_t cmd[8];
-                               
-                               cmd[0] = 0x00;
-                               cmd[1] = 0x01;
-                               cmd[2] = cell;
-                               cmd[3] = pending_screen[row][col_base];
-                               cmd[4] = pending_screen[row][col_base+1];
-                               cmd[5] = pending_screen[row][col_base+2];
-                               cmd[6] = pending_screen[row][col_base+3];
-                               cmd[7] = 0x00;
 
-                               if (usb_interrupt_write (udev, WRITE_ENDPOINT, (char *) cmd, 8, 1000) == 8) {
-                                       /* successful write: copy to current */
-                                       memcpy (&current_screen[row][col_base], &pending_screen[row][col_base], 4);
-                               }
+               if (_device_status != STATUS_OFFLINE) {
+                       if (first_time) {
+                               invalidate();
+                               lcd_clear ();
+                               lights_off ();
+                               first_time = false;
+                               offline = 0;
+                               pending = 3; // Give some time for the device to recover
+                       }
+                       /* update whatever needs updating */
+                       update_state ();
 
-                               /* skip the rest of the 4 character cell since we wrote+copied it already */
-                               
-                               col_base += 4;
-                               col = col_base;
-                               cell++;
+                       /* still struggling with a good means of exerting flow control */
+                       // pending = flush();
 
+                       if(pending == 0) {
+                               pending = flush(); 
                        } else {
-
-                               col++;
-                               
-                               if (col && col % 4 == 0) {
-                                       cell++;
-                                       col_base += 4;
+                               if(inflight > 0) {
+                                       pending = --inflight; // we just did a whole bunch of writes so wait
+                               } else {
+                                       pending = 0;
                                }
                        }
-               }
+                       // pending = 0;
+               } 
        }
 
-       /* now update LED's */
+       return (void*) 0;
+}
 
-       /* per track */
+int TranzportControlProtocol::lights_show_recording() 
+{
+       //   FIXME, flash recording light when recording and transport is moving
+       return     lights_show_normal();
+}
 
-       if (route_table[0]) {
-               boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack> (route_table[0]);
-               if (at && at->record_enabled()) {
-                       pending_lights[LightTrackrec] = true;
-               } else {
-                       pending_lights[LightTrackrec] = false;
-               }
-               if (route_get_muted (0)) {
-                       pending_lights[LightTrackmute] = true;
-               } else {
-                       pending_lights[LightTrackmute] = false;
-               }
-               if (route_get_soloed (0)) {
-                       pending_lights[LightTracksolo] = true;
-               } else {
-                       pending_lights[LightTracksolo] = false;
-               }
+// gotta do bling next!
 
-       } else {
-               pending_lights[LightTrackrec] = false;
-               pending_lights[LightTracksolo] = false;
-               pending_lights[LightTrackmute] = false;
+int TranzportControlProtocol::lights_show_bling() 
+{
+       switch (bling_mode) {
+               case BlingOff: break;
+               case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
+               case BlingRotating: break; // switch between lights
+               case BlingPairs: break; // Show pairs of lights
+               case BlingRows: break; // light each row in sequence
+               case BlingFlashAll: break; // Flash everything randomly
        }
+       return 0;
+}
 
-       /* global */
+int TranzportControlProtocol::lights_show_normal() 
+{
+       /* Track only */
 
-       if (session->get_play_loop()) {
-               pending_lights[LightLoop] = true;
+       if (route_table[0]) {
+               boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack> (route_table[0]);
+               lights_pending[LightTrackrec]  = at && at->record_enabled();
+               lights_pending[LightTrackmute] = route_get_muted(0); 
+               lights_pending[LightTracksolo] = route_get_soloed(0);
        } else {
-               pending_lights[LightLoop] = false;
+               lights_pending[LightTrackrec]  = false;
+               lights_pending[LightTracksolo] = false;
+               lights_pending[LightTrackmute] = false;
        }
 
-       if (Config->get_punch_in() || Config->get_punch_out()) {
-               pending_lights[LightPunch] = true;
-       } else {
-               pending_lights[LightPunch] = false;
-       }
+       /* Global settings */
 
-       if (session->get_record_enabled()) {
-               pending_lights[LightRecord] = true;
-       } else {
-               pending_lights[LightRecord] = false;
-       }
+       lights_pending[LightLoop]        = session->get_play_loop(); 
+       lights_pending[LightPunch]       = Config->get_punch_in() || Config->get_punch_out();
+       lights_pending[LightRecord]      = session->get_record_enabled();
+       lights_pending[LightAnysolo]     = session->soloing();
 
-       if (session->soloing ()) {
-               pending_lights[LightAnysolo] = true;
-       } else {
-               pending_lights[LightAnysolo] = false;
-       }
+       return 0;
+}
 
-       /* flush changed light change */
+int TranzportControlProtocol::lights_show_tempo() 
+{
+       // someday soon fiddle with the lights based on the tempo 
+       return     lights_show_normal();
+}
 
-       if (pending_lights[LightRecord] != lights[LightRecord]) {
-               if (pending_lights[LightRecord]) {
-                       light_on (LightRecord);
-               } else {
-                       light_off (LightRecord);
-               }
-       }
+int
+TranzportControlProtocol::update_state ()
+{
+       /* do the text and light updates */
 
-       if (pending_lights[LightTracksolo] != lights[LightTracksolo]) {
-               if (pending_lights[LightTracksolo]) {
-                       light_on (LightTracksolo);
-               } else {
-                       light_off (LightTracksolo);
-               }
-       }
+       switch (display_mode) {
+               case DisplayBigMeter:
+                       lights_show_tempo();
+                       show_meter ();
+                       break;
 
-       if (pending_lights[LightTrackrec] != lights[LightTrackrec]) {
-               if (pending_lights[LightTrackrec]) {
-                       light_on (LightTrackrec);
-               } else {
-                       light_off (LightTrackrec);
-               }
-       }
+               case DisplayNormal:
+                       lights_show_normal();
+                       normal_update ();
+                       break;
 
-       if (pending_lights[LightTrackmute] != lights[LightTrackmute]) {
-               if (pending_lights[LightTrackmute]) {
-                       light_on (LightTrackmute);
-               } else {
-                       light_off (LightTrackmute);
-               }
-       }
+               case DisplayConfig:
+                       break;
 
-       if (pending_lights[LightTracksolo] != lights[LightTracksolo]) {
-               if (pending_lights[LightTracksolo]) {
-                       light_on (LightTracksolo);
-               } else {
-                       light_off (LightTracksolo);
-               }
-       }
+               case DisplayRecording:
+                       lights_show_recording();
+                       normal_update(); 
+                       break;
 
-       if (pending_lights[LightAnysolo] != lights[LightAnysolo]) {
-               if (pending_lights[LightAnysolo]) {
-                       light_on (LightAnysolo);
-               } else {
-                       light_off (LightAnysolo);
-               }
-       }
+               case DisplayRecordingMeter:
+                       lights_show_recording();
+                       show_meter(); 
+                       break;
 
-       if (pending_lights[LightLoop] != lights[LightLoop]) {
-               if (pending_lights[LightLoop]) {
-                       light_on (LightLoop);
-               } else {
-                       light_off (LightLoop);
-               }
-       }
+               case DisplayBling:
+                       lights_show_bling();
+                       normal_update();
+                       break;
 
-       if (pending_lights[LightPunch] != lights[LightPunch]) {
-               if (pending_lights[LightPunch]) {
-                       light_on (LightPunch);
-               } else {
-                       light_off (LightPunch);
-               }
+               case DisplayBlingMeter:
+                       lights_show_bling();
+                       show_meter();
+                       break;
        }
-
        return 0;
+
 }
 
+#define TRANZPORT_BUTTON_HANDLER(callback, button_arg) if (button_changes & button_arg) { \
+    if (buttonmask & button_arg) { \
+      callback##_press (buttonmask&ButtonShift); } else { callback##_release (buttonmask&ButtonShift); } }
+
 int
 TranzportControlProtocol::process (uint8_t* buf)
 {
@@ -820,6 +1201,7 @@ TranzportControlProtocol::process (uint8_t* buf)
        uint32_t button_changes;
 
        _device_status = buf[1];
+
        this_button_mask = 0;
        this_button_mask |= buf[2] << 24;
        this_button_mask |= buf[3] << 16;
@@ -834,157 +1216,50 @@ TranzportControlProtocol::process (uint8_t* buf)
                datawheel ();
        }
 
-       if (button_changes & ButtonBattery) {
-               if (buttonmask & ButtonBattery) {
-                       button_event_battery_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_battery_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonBacklight) {
-               if (buttonmask & ButtonBacklight) {
-                       button_event_backlight_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_backlight_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonTrackLeft) {
-               if (buttonmask & ButtonTrackLeft) {
-                       button_event_trackleft_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_trackleft_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonTrackRight) {
-               if (buttonmask & ButtonTrackRight) {
-                       button_event_trackright_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_trackright_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonTrackRec) {
-               if (buttonmask & ButtonTrackRec) {
-                       button_event_trackrec_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_trackrec_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonTrackMute) {
-               if (buttonmask & ButtonTrackMute) {
-                       button_event_trackmute_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_trackmute_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonTrackSolo) {
-               if (buttonmask & ButtonTrackSolo) {
-                       button_event_tracksolo_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_tracksolo_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonUndo) {
-               if (buttonmask & ButtonUndo) {
-                       button_event_undo_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_undo_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonIn) {
-               if (buttonmask & ButtonIn) {
-                       button_event_in_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_in_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonOut) {
-               if (buttonmask & ButtonOut) {
-                       button_event_out_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_out_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonPunch) {
-               if (buttonmask & ButtonPunch) {
-                       button_event_punch_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_punch_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonLoop) {
-               if (buttonmask & ButtonLoop) {
-                       button_event_loop_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_loop_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonPrev) {
-               if (buttonmask & ButtonPrev) {
-                       button_event_prev_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_prev_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonAdd) {
-               if (buttonmask & ButtonAdd) {
-                       button_event_add_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_add_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonNext) {
-               if (buttonmask & ButtonNext) {
-                       button_event_next_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_next_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonRewind) {
-               if (buttonmask & ButtonRewind) {
-                       button_event_rewind_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_rewind_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonFastForward) {
-               if (buttonmask & ButtonFastForward) {
-                       button_event_fastforward_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_fastforward_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonStop) {
-               if (buttonmask & ButtonStop) {
-                       button_event_stop_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_stop_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonPlay) {
-               if (buttonmask & ButtonPlay) {
-                       button_event_play_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_play_release (buttonmask&ButtonShift);
-               }
-       }
-       if (button_changes & ButtonRecord) {
-               if (buttonmask & ButtonRecord) {
-                       button_event_record_press (buttonmask&ButtonShift);
-               } else {
-                       button_event_record_release (buttonmask&ButtonShift);
-               }
-       }
-               
+       // SHIFT + STOP + PLAY for bling mode?
+       // if (button_changes & ButtonPlay & ButtonStop) {
+       // bling_mode_toggle();  
+       // } or something like that
+
+       TRANZPORT_BUTTON_HANDLER(button_event_battery,ButtonBattery);
+       TRANZPORT_BUTTON_HANDLER(button_event_backlight,ButtonBacklight);
+       TRANZPORT_BUTTON_HANDLER(button_event_trackleft,ButtonTrackLeft);
+       TRANZPORT_BUTTON_HANDLER(button_event_trackright,ButtonTrackRight);
+       TRANZPORT_BUTTON_HANDLER(button_event_trackrec,ButtonTrackRec);
+       TRANZPORT_BUTTON_HANDLER(button_event_trackmute,ButtonTrackMute);
+       TRANZPORT_BUTTON_HANDLER(button_event_tracksolo,ButtonTrackSolo);
+       TRANZPORT_BUTTON_HANDLER(button_event_undo,ButtonUndo);
+       TRANZPORT_BUTTON_HANDLER(button_event_in,ButtonIn);
+       TRANZPORT_BUTTON_HANDLER(button_event_out,ButtonOut);
+       TRANZPORT_BUTTON_HANDLER(button_event_punch,ButtonPunch);
+       TRANZPORT_BUTTON_HANDLER(button_event_loop,ButtonLoop);
+       TRANZPORT_BUTTON_HANDLER(button_event_prev,ButtonPrev);
+       TRANZPORT_BUTTON_HANDLER(button_event_add,ButtonAdd);
+       TRANZPORT_BUTTON_HANDLER(button_event_next,ButtonNext);
+       TRANZPORT_BUTTON_HANDLER(button_event_rewind,ButtonRewind);
+       TRANZPORT_BUTTON_HANDLER(button_event_fastforward,ButtonFastForward);
+       TRANZPORT_BUTTON_HANDLER(button_event_stop,ButtonStop);
+       TRANZPORT_BUTTON_HANDLER(button_event_play,ButtonPlay);
+       TRANZPORT_BUTTON_HANDLER(button_event_record,ButtonRecord);
        return 0;
 }
 
 void
 TranzportControlProtocol::show_current_track ()
 {
+       char pad[11];
+       char *v;
+       int len;
        if (route_table[0] == 0) {
-               print (0, 0, "--------");
+               print (0, 0, "----------");
+               last_track_gain = FLT_MAX;
        } else {
-               print (0, 0, route_get_name (0).substr (0, 8).c_str());
+               strcpy(pad,"          ");
+               v =  (char *)route_get_name (0).substr (0, 10).c_str();
+               if((len = strlen(v)) > 0) {
+                       strncpy(pad,(char *)v,len);
+               }
+               print (0, 0, pad);
        }
 }
 
@@ -1001,11 +1276,24 @@ TranzportControlProtocol::button_event_battery_release (bool shifted)
 void
 TranzportControlProtocol::button_event_backlight_press (bool shifted)
 {
+#if DEBUG_TRANZPORT
+       printf("backlight pressed\n");
+#endif
 }
 
 void
 TranzportControlProtocol::button_event_backlight_release (bool shifted)
 {
+#if DEBUG_TRANZPORT
+       printf("backlight released\n\n");
+#endif
+       if (shifted) {
+               lcd_damage();
+               lcd_clear();
+               last_where += 1; /* force time redisplay */
+               last_track_gain = FLT_MAX;
+               normal_update(); //  redraw_screen();  
+       }
 }
 
 void
@@ -1048,7 +1336,11 @@ TranzportControlProtocol::button_event_trackrec_release (bool shifted)
 void
 TranzportControlProtocol::button_event_trackmute_press (bool shifted)
 {
-       route_set_muted (0, !route_get_muted (0));
+       if (shifted) {
+         // Mute ALL? Something useful when a phone call comes in. Mute master?
+       } else {
+         route_set_muted (0, !route_get_muted (0));
+       }
 }
 
 void
@@ -1059,6 +1351,9 @@ TranzportControlProtocol::button_event_trackmute_release (bool shifted)
 void
 TranzportControlProtocol::button_event_tracksolo_press (bool shifted)
 {
+#if DEBUG_TRANZPORT
+       printf("solo pressed\n");
+#endif
        if (display_mode == DisplayBigMeter) {
                light_off (LightAnysolo);
                return;
@@ -1074,15 +1369,18 @@ TranzportControlProtocol::button_event_tracksolo_press (bool shifted)
 void
 TranzportControlProtocol::button_event_tracksolo_release (bool shifted)
 {
+#if DEBUG_TRANZPORT
+       printf("solo released\n");
+#endif
 }
 
 void
 TranzportControlProtocol::button_event_undo_press (bool shifted)
 {
        if (shifted) {
-               redo ();
+               redo (); // someday flash the screen with what was redone
        } else {
-               undo ();
+               undo (); // someday flash the screen with what was undone
        }
 }
 
@@ -1235,7 +1533,11 @@ TranzportControlProtocol::button_event_stop_release (bool shifted)
 void
 TranzportControlProtocol::button_event_play_press (bool shifted)
 {
-       transport_play ();
+       if (shifted) {
+         set_transport_speed (1.0f);
+       } else {
+         transport_play ();
+       }
 }
 
 void
@@ -1258,11 +1560,17 @@ TranzportControlProtocol::button_event_record_release (bool shifted)
 {
 }
 
+void button_event_mute (bool pressed, bool shifted)
+{
+       //static int was_pressed = 0;
+       //  if(pressed) { }
+}
+
 void
 TranzportControlProtocol::datawheel ()
 {
        if ((buttonmask & ButtonTrackRight) || (buttonmask & ButtonTrackLeft)) {
-               
+
                /* track scrolling */
 
                if (_datawheel < WheelDirectionThreshold) {
@@ -1274,7 +1582,7 @@ TranzportControlProtocol::datawheel ()
                timerclear (&last_wheel_motion);
 
        } else if ((buttonmask & ButtonPrev) || (buttonmask & ButtonNext)) {
-               
+
                if (_datawheel < WheelDirectionThreshold) {
                        next_marker ();
                } else {
@@ -1289,23 +1597,27 @@ TranzportControlProtocol::datawheel ()
 
                if (route_table[0]) {
                        switch (wheel_shift_mode) {
-                       case WheelShiftGain:
-                               if (_datawheel < WheelDirectionThreshold) {
-                                       step_gain_up ();
-                               } else {
-                                       step_gain_down ();
-                               }
-                               break;
-                       case WheelShiftPan:
-                               if (_datawheel < WheelDirectionThreshold) {
-                                       step_pan_right ();
-                               } else {
-                                       step_pan_left ();
-                               }
-                               break;
+                               case WheelShiftGain:
+                                       if (_datawheel < WheelDirectionThreshold) {
+                                               step_gain_up ();
+                                       } else {
+                                               step_gain_down ();
+                                       }
+                                       break;
+                               case WheelShiftPan:
+                                       if (_datawheel < WheelDirectionThreshold) {
+                                               step_pan_right ();
+                                       } else {
+                                               step_pan_left ();
+                                       }
+                                       break;
+
+                               case WheelShiftMarker:
+                                       break;
+
+                               case WheelShiftMaster:
+                                       break;
 
-                       case WheelShiftMaster:
-                               break;
                        }
                }
 
@@ -1314,17 +1626,17 @@ TranzportControlProtocol::datawheel ()
        } else {
 
                switch (wheel_mode) {
-               case WheelTimeline:
-                       scroll ();
-                       break;
-                       
-               case WheelScrub:
-                       scrub ();
-                       break;
+                       case WheelTimeline:
+                               scroll ();
+                               break;
 
-               case WheelShuttle:
-                       shuttle ();
-                       break;
+                       case WheelScrub:
+                               scrub ();
+                               break;
+
+                       case WheelShuttle:
+                               shuttle ();
+                               break;
                }
        }
 }
@@ -1332,10 +1644,15 @@ TranzportControlProtocol::datawheel ()
 void
 TranzportControlProtocol::scroll ()
 {
+       float m = 1.0;
        if (_datawheel < WheelDirectionThreshold) {
-               ScrollTimeline (0.2);
+               m = 1.0;
        } else {
-               ScrollTimeline (-0.2);
+               m = -1.0;
+       }
+       switch(wheel_increment) {
+               case WheelIncrScreen: ScrollTimeline (0.2*m); break;
+               default: break; // other modes unimplemented as yet
        }
 }
 
@@ -1346,41 +1663,47 @@ TranzportControlProtocol::scrub ()
        struct timeval now;
        struct timeval delta;
        int dir;
-       
+
        gettimeofday (&now, 0);
-       
+
        if (_datawheel < WheelDirectionThreshold) {
                dir = 1;
        } else {
                dir = -1;
        }
-       
+
        if (dir != last_wheel_dir) {
                /* changed direction, start over */
                speed = 0.1f;
        } else {
                if (timerisset (&last_wheel_motion)) {
-                       
+
                        timersub (&now, &last_wheel_motion, &delta);
-                       
+
                        /* 10 clicks per second => speed == 1.0 */
-                       
+
                        speed = 100000.0f / (delta.tv_sec * 1000000 + delta.tv_usec);
-                       
+
                } else {
-                       
+
                        /* start at half-speed and see where we go from there */
-                       
+
                        speed = 0.5f;
                }
        }
-       
+
        last_wheel_motion = now;
        last_wheel_dir = dir;
-       
+
        set_transport_speed (speed * dir);
 }
 
+void
+TranzportControlProtocol::config ()
+{
+  // FIXME
+}
+
 void
 TranzportControlProtocol::shuttle ()
 {
@@ -1453,6 +1776,10 @@ TranzportControlProtocol::next_wheel_shift_mode ()
                break;
        case WheelShiftMaster:
                wheel_shift_mode = WheelShiftGain;
+               break;
+       case WheelShiftMarker: // Not done yet, disabled
+               wheel_shift_mode = WheelShiftGain;
+               break;
        }
 
        show_wheel_mode ();
@@ -1495,36 +1822,48 @@ TranzportControlProtocol::show_wheel_mode ()
        string text;
 
        switch (wheel_mode) {
-       case WheelTimeline:
-               text = "Time";
-               break;
-       case WheelScrub:
-               text = "Scrb";
-               break;
-       case WheelShuttle:
-               text = "Shtl";
-               break;
+               case WheelTimeline:
+                       text = "Time";
+                       break;
+               case WheelScrub:
+                       text = "Scrb";
+                       break;
+               case WheelShuttle:
+                       text = "Shtl";
+                       break;
        }
 
        switch (wheel_shift_mode) {
-       case WheelShiftGain:
-               text += ":Gain";
-               break;
+               case WheelShiftGain:
+                       text += ":Gain";
+                       break;
 
-       case WheelShiftPan:
-               text += ":Pan";
-               break;
+               case WheelShiftPan:
+                       text += ":Pan ";
+                       break;
 
-       case WheelShiftMaster:
-               text += ":Mstr";
-               break;
+               case WheelShiftMaster:
+                       text += ":Mstr";
+                       break;
+
+               case WheelShiftMarker:
+                       text += ":Mrkr";
+                       break;
        }
-       
+
        print (1, 0, text.c_str());
 }
 
+// Was going to keep state around saying to retry or not
+// haven't got to it yet, still not sure it's a good idea
+
+void
+TranzportControlProtocol::print (int row, int col, const char *text) {
+       print_noretry(row,col,text);
+}
+
 void
-TranzportControlProtocol::print (int row, int col, const char *text)
+TranzportControlProtocol::print_noretry (int row, int col, const char *text)
 {
        int cell;
        uint32_t left = strlen (text);
@@ -1564,7 +1903,7 @@ TranzportControlProtocol::print (int row, int col, const char *text)
 
                /* copy current cell contents into tmp */
                
-               memcpy (tmp, &pending_screen[row][base_col], 4);
+               memcpy (tmp, &screen_pending[row][base_col], 4);
                
                /* overwrite with new text */
                
@@ -1574,7 +1913,7 @@ TranzportControlProtocol::print (int row, int col, const char *text)
                
                /* copy it back to pending */
                
-               memcpy (&pending_screen[row][base_col], tmp, 4);
+               memcpy (&screen_pending[row][base_col], tmp, 4);
                
                text += tocopy;
                left -= tocopy;
@@ -1595,3 +1934,17 @@ TranzportControlProtocol::set_state (const XMLNode& node)
 {
        return 0;
 }
+
+int
+TranzportControlProtocol::save (char *name) 
+{
+       // Presently unimplemented
+       return 0;
+}
+
+int
+TranzportControlProtocol::load (char *name) 
+{
+       // Presently unimplemented
+       return 0;
+}
index e5193a761cdfa3d71306b034d5b6ceb672f9899a..f13e4a3a44d57cc7300ddbb87b6c8e5c8ba846f3 100644 (file)
@@ -1,3 +1,4 @@
+
 #ifndef ardour_tranzport_control_protocol_h
 #define ardour_tranzport_control_protocol_h
 
@@ -72,7 +73,8 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
        enum WheelShiftMode {
                WheelShiftGain,
                WheelShiftPan,
-               WheelShiftMaster
+               WheelShiftMaster,
+               WheelShiftMarker
        };
                
        enum WheelMode {
@@ -81,29 +83,68 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
                WheelShuttle
        };
 
+       // FIXME - look at gtk2_ardour for snap settings
+
+       enum WheelIncrement {
+              WheelIncrSlave,
+              WheelIncrScreen,
+              WheelIncrSample,
+              WheelIncrBeat,
+              WheelIncrBar,
+              WheelIncrSecond,
+              WheelIncrMinute
+       };
+         
        enum DisplayMode {
                DisplayNormal,
-               DisplayBigMeter
+               DisplayRecording,
+               DisplayRecordingMeter,
+               DisplayBigMeter,
+               DisplayConfig,
+               DisplayBling,
+               DisplayBlingMeter
+       };
+
+       enum BlingMode {
+               BlingOff,
+               BlingKit,
+               BlingRotating,
+               BlingPairs,
+               BlingRows,
+               BlingFlashAll
        };
        
        pthread_t       thread;
        uint32_t        buttonmask;
        uint32_t        timeout;
+       uint32_t        inflight;
        uint8_t        _datawheel;
        uint8_t        _device_status;
-       usb_dev_handle* udev;
-
        uint32_t        current_track_id;
        WheelMode       wheel_mode;
        WheelShiftMode  wheel_shift_mode;
        DisplayMode     display_mode;
+       BlingMode       bling_mode;
+       WheelIncrement  wheel_increment;
+       usb_dev_handle* udev;
+
        ARDOUR::gain_t  gain_fraction;
 
        Glib::Mutex update_lock;
-       char current_screen[2][20];
-       char pending_screen[2][20];
-       bool lights[7];
-       bool pending_lights[7];
+
+       bool screen_invalid[2][20];
+       char screen_current[2][20];
+       char screen_pending[2][20];
+       char screen_flash[2][20];
+
+       bool lights_invalid[7];
+       bool lights_current[7];
+       bool lights_pending[7];
+       bool lights_flash[7];
+
+       uint32_t       last_bars;
+       uint32_t       last_beats;
+       uint32_t       last_ticks;
 
        bool           last_negative;
        uint32_t       last_hrs;
@@ -119,28 +160,94 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
        Glib::Mutex io_lock;
 
        int open ();
-       int read (uint32_t timeout_override = 0);
+       int read (uint8_t *buf,uint32_t timeout_override = 0);
        int write (uint8_t* cmd, uint32_t timeout_override = 0);
+       int write_noretry (uint8_t* cmd, uint32_t timeout_override = 0);
        int close ();
+       int save(char *name = "default");
+       int load(char *name = "default");
+       void print (int row, int col, const char* text);
+       void print_noretry (int row, int col, const char* text);
+
+       int rtpriority_set(int priority = 52);
+       int rtpriority_unset(int priority = 0);
 
        int open_core (struct usb_device*);
 
+       static void* _monitor_work (void* arg);
+       void* monitor_work ();
+
+       int process (uint8_t *);
+       int update_state();
+       void invalidate();
+       int flush();
+       // bool isuptodate(); // think on this. It seems futile to update more than 30/sec
+
+       // A screen is a cache of what should be on the lcd
+
+       void screen_init();
+       void screen_validate();
+       void screen_invalidate();
+       int  screen_flush();
+       void screen_clear();
+       // bool screen_isuptodate(); // think on this - 
+
+       // Commands to write to the lcd 
+
+       int  lcd_init();
+        bool lcd_damage();
+       bool lcd_isdamaged();
+
+        bool lcd_damage(int row, int col = 0, int length = 20);
+       bool lcd_isdamaged(int row, int col = 0, int length = 20);
+
+       int  lcd_flush();
+       int  lcd_write(uint8_t* cmd, uint32_t timeout_override = 0); // pedantic alias for write
+       void lcd_fill (uint8_t fill_char);
        void lcd_clear ();
-       void print (int row, int col, const char* text);
+       void lcd_print (int row, int col, const char* text);
+       void lcd_print_noretry (int row, int col, const char* text);
+
+       // Commands to write to the lights
+       // FIXME - on some devices lights can have intensity and colors
+
+       void lights_init();
+       void lights_validate();
+       void lights_invalidate();
+       void light_validate(LightID light);
+       void light_invalidate(LightID light);
+       int  lights_flush();
+       int  lights_write(uint8_t* cmd,uint32_t timeout_override = 0); // pedantic alias to write
+
+       // a cache of what should be lit
+
+       void lights_off ();
+       void lights_on ();
+       int  light_set(LightID, bool offon = true);
        int  light_on (LightID);
        int  light_off (LightID);
-       void lights_off ();
+
+       // some modes for the lights, should probably be renamed
+
+       int  lights_show_normal();
+       int  lights_show_recording();
+       int  lights_show_tempo();
+       int  lights_show_bling();
 
        void enter_big_meter_mode ();
        void enter_normal_display_mode ();
+       void enter_config_mode();
+       void enter_recording_mode();
+       void enter_bling_mode();
 
        void next_display_mode ();
-
        void normal_update ();
 
        void show_current_track ();
        void show_track_gain ();
        void show_transport_time ();
+       void show_bbt (nframes_t where);        
+       void show_smpte (nframes_t where);
        void show_wheel_mode ();
        void show_gain ();
        void show_pan ();
@@ -150,6 +257,7 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
        void scrub ();
        void scroll ();
        void shuttle ();
+       void config ();
 
        void next_wheel_mode ();
        void next_wheel_shift_mode ();
@@ -162,8 +270,6 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
        void step_pan_right ();
        void step_pan_left ();
 
-       static void* _monitor_work (void* arg);
-       void* monitor_work ();
 
        void button_event_battery_press (bool shifted);
        void button_event_battery_release (bool shifted);
@@ -206,8 +312,8 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
        void button_event_record_press (bool shifted);
        void button_event_record_release (bool shifted);
 
-       int process (uint8_t *);
-       int update_state();
+       // new api
+       void button_event_mute (bool pressed, bool shifted);
 };
 
 
index 77f72965cd49a01a86bb9fe0a515902a3490c30a..cddf78e774c9fb4e8f69302726960290069c24fa 100644 (file)
@@ -1,4 +1,4 @@
 #ifndef __ardour_svn_revision_h__
 #define __ardour_svn_revision_h__
-static const char* ardour_svn_revision = "1137";
+static const char* ardour_svn_revision = "1266";
 #endif
index 7fa556530b1e083a53a84211d33ed5ef484bf117..60a80c5619c2163f9f6fafe197d0e37e2baf47b7 100644 (file)
@@ -3,6 +3,7 @@
 import os
 import glob
 template_files = glob.glob('*.template.in')
+files = glob.glob('*.template')
 
 Import('env install_prefix subst_dict')
 
@@ -13,5 +14,5 @@ for template in template_files:
 
 Default(template_build)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour2/templates'), template_build))
+env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour2', 'templates'), files))
 env.Alias('tarball', env.Distribute (env['DISTTREE'], [ 'SConscript' ] + template_build))
index 0e345fc1201ce4e83a1b899f97c2a4a6aa079140..2334fab13bf70c7f4bd2c51e1243e8eb14f347b5 100644 (file)
Binary files a/tools/osx_packaging/Ardour2.icns and b/tools/osx_packaging/Ardour2.icns differ
diff --git a/tools/osx_packaging/COPYING b/tools/osx_packaging/COPYING
new file mode 100644 (file)
index 0000000..d60c31a
--- /dev/null
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
index 965d87003d1fd570d3bef1b0d54ff7a23551cc3e..4cab63503497e6b4c65896cabc378d69b20d345b 100755 (executable)
-#!/usr/bin/ruby
+#!/usr/bin/env ruby
 
 # Ruby script for pulling together a MacOSX app bundle.
 
-if File.exist?("lib") then
-    Dir.foreach("lib") {|x| unless x[0] == 46 then File.delete("lib/"+x) end}
+# it will be either powerpc or i386
+versionline = `grep -m 1 '^version =' ../../SConstruct`
+version = versionline.split(" = ")[1].chomp().slice(1..-2)
+$stdout.printf("Version is %s\n", version)
+
+arch = `uname -p`.strip()
+libdir = "lib_" + arch
+bindir = "bin_" + arch
+
+ppc_libdir = "lib_powerpc"
+i386_libdir = "lib_i386"
+ppc_bindir = "bin_powerpc"
+i386_bindir = "bin_i386"
+ppc_binlib = "binlib_powerpc.zip"
+i386_binlib = "binlib_i386.zip"
+
+#$stdout.print("libdir is '" + libdir + "'\n")
+
+# check for the other arch's libbin.zip
+if arch == "i386" then
+  zipfile = ppc_binlib
+  `rm -rf #{ppc_libdir} #{ppc_bindir}`
+else
+  zipfile = i386_binlib
+  `rm -rf #{i386_libdir} #{i386_bindir}`
+end
+
+if File.exist?(zipfile) then
+  $stdout.print("Found #{zipfile} : unpacking...\n")
+  `unzip -aq #{zipfile}`
+end
+
+
+if File.exist?(libdir) then
+  # remove it
+  `rm -rf #{libdir}/*`
+  #Dir.foreach(libdir) {|x| unless ( x[0] == 46 or File.stat(libdir+"/"+x).directory?) then File.delete(libdir + "/" +x) end}
 else
-    Dir.mkdir "lib"
+    Dir.mkdir libdir
 end
 
-result = `otool -L ../../gtk2_ardour/ardour.bin`
+if File.exist?(bindir) then
+    Dir.foreach(bindir) {|x| unless x[0] == 46 then File.delete(bindir + "/" +x) end}
+else
+    Dir.mkdir bindir
+end
+
+if not File.exist?(libdir+"/surfaces") then
+   Dir.mkdir(libdir + "/surfaces")
+end
+
+
+odir = Dir.getwd
+Dir.chdir("../..")
+
+result = `otool -L gtk2_ardour/ardour.bin`
 results = result.split("\n")
 results.delete_at(0)
+
+result =  `otool -L libs/ardour/libardour.dylib`
+results = results + result.split("\n").slice(1,result.size-1)
+
+result =  `otool -L libs/surfaces/*/*.dylib`
+results = results + result.split("\n").slice(1,result.size-1)
+
+results.uniq!
+
+$stdout.print("Copying libs to #{libdir} ...\n");
+
 results.each do |s|
     s = s.split[0]
     # exclude frameworks, system libraries, X11 libraries, and libjack.
-    unless s =~ /System|\/usr\/lib|\/usr\/X11R6|libjack/ then
-        `cp #{s} lib`
+    unless s =~ /System|\/usr\/lib|\/usr\/X11R6|libjack|:$/ then
+       #$stdout.print("Copying #{s}\n")
+        `cp #{s} #{odir}/#{libdir}/`
     end
 end
 
-`/usr/local/bin/platypus -a 'Ardour2' -t 'Shell' -o 'None' -u 'Paul Davis' -i '/bin/sh' -V '1.0' -s 'ArDr' -I 'org.ardour.Ardour2' -f 'bin' -f 'lib' -f 'Ardour2.icns' -f 'MenuBar.nib' -f 'ProgressWindow.nib' -f 'init' -f 'openDoc' 'script' 'Ardour2.app'`
\ No newline at end of file
+# now do it again
+result =  `otool -L #{odir}/#{libdir}/*.dylib`
+results = result.split("\n")
+results.uniq!
+results.each do |s|
+    s = s.split[0]
+    # exclude frameworks, system libraries, X11 libraries, and libjack.
+    unless s =~ /System|\/usr\/lib|\/usr\/X11R6|libjack|:$/ then
+      sbase = File.basename(s)
+      targfile = "#{odir}/#{libdir}/#{sbase}"
+      #$stdout.print("Targ is : " + targfile + "\n")
+      if not File.exist?(targfile) then
+       #$stdout.print("2nd stage Copying #{s}\n")
+        `cp #{s} #{odir}/#{libdir}/`
+      end
+    end
+end
+
+
+Dir.chdir(odir)
+
+# copy ardour.bin to bindir/ardour
+
+
+if File.exist?("../../gtk2_ardour/ardour.bin") then
+   $stdout.print("Copying bin to #{bindir} ...\n");
+   `cp ../../gtk2_ardour/ardour.bin #{bindir}/ardour`
+end
+
+`cp ../../libs/surfaces/*/*.dylib #{libdir}/surfaces`
+# remove the basenames from libdir that are in surfaces (copied earlier)
+`rm -f #{libdir}/surfaces/libardour_cp.dylib`
+begin
+  Dir.foreach(libdir+"/surfaces") {|x| unless ( x[0] == 46 or x.include?("libardour_cp")) then File.delete(libdir + "/" +x) end}
+rescue
+end
+
+
+# copy gtk and pango lib stuff
+`cp -R /opt/local/lib/pango #{libdir}/`
+`cp -R /opt/local/lib/gtk-2.0 #{libdir}/`
+
+# use our clearlooks
+`rm -f #{libdir}/gtk-2.0/2.*/engines/libclearlooks.*`
+# must use .so for it to be found :/
+`cp ../../libs/clearlooks/libclearlooks.dylib #{libdir}/gtk-2.0/2.10.0/engines/libclearlooks.so`
+
+
+def lipo_platforms_recurse(src1, src2, target)
+
+  if not File.stat(src1).directory? then
+    # normal file, lets lipo them if it doesn't already exist there
+    isbin = `file #{src1}`.include?("Mach-O")
+    if (! File.exist?(target)) and isbin then
+      if File.exist?(src2) then
+        $stdout.print("Lipo'ing " + target + "\n")
+        `lipo -create -output #{target} #{src1} #{src2}`
+      else
+        # just copy it
+        $stdout.print("Copying " + src1 + "\n")
+        `cp #{src1} #{target}`
+      end
+    else
+      #$stdout.print("Skipping " + target + "\n")
+    end
+  else
+    # directory, recurse if necessary
+    if File.exist?(src2) then
+      # other dir exists, recurse
+      
+      # make targetdir if necessary
+      if not File.exist?(target) then
+        Dir.mkdir(target)
+      end
+      
+      Dir.foreach(src1) do |file| 
+        if file[0] != 46 then
+          src1file = src1 + '/' + file
+          src2file = src2 + '/' + file
+          targfile = target + '/' + file
+          lipo_platforms_recurse(src1file, src2file, targfile)
+        end
+      end
+    else
+      # just copy it recursively to target
+      $stdout.print("Copying dir " + src1 + "\n")
+      `cp -R #{src1} #{target}`
+    end
+  end
+end
+
+# lipo stuff together if both platforms libs and bins are here
+
+if File.exist?(ppc_libdir) and File.exist?(i386_libdir) then
+  $stdout.print("\nBoth platforms in place, lipo'ing...\n");
+  `rm -rf lib/*`
+  `rm -f bin/ardour`
+  lipo_platforms_recurse(ppc_libdir, i386_libdir, "lib")
+  lipo_platforms_recurse(i386_libdir, ppc_libdir, "lib")
+  lipo_platforms_recurse(i386_bindir+'/ardour', ppc_bindir+'/ardour', "bin/ardour")
+
+  # remove existing Ardour2.app
+  `rm -rf Ardour2.app`
+
+  $stdout.print("\nRunning Playtpus to create Ardour2.app  ...\n");
+
+  `/usr/local/bin/platypus -D -X 'ardour' -a 'Ardour2' -t 'shell' -o 'None' -u 'Paul Davis' -i '/bin/sh' -V "#{version}" -s 'ArDr' -I 'org.ardour.Ardour2' -f 'bin' -f 'lib' -i 'Ardour2.icns' -f 'MenuBar.nib' -f 'ProgressWindow.nib' -f 'init' -f 'openDoc' 'script' 'Ardour2.app'`
+
+  $stdout.print("\nCopying other stuff to Ardour2.app  ...\n");
+
+  if not File.exist?("Ardour2.app/Contents/Resources/etc") then
+    Dir.mkdir "Ardour2.app/Contents/Resources/etc" 
+  end
+
+  if not File.exist?("Ardour2.app/Contents/Resources/etc/ardour2") then
+    Dir.mkdir "Ardour2.app/Contents/Resources/etc/ardour2" 
+  end
+  `cp ../../gtk2_ardour/ardour.bindings ../../gtk2_ardour/ardour.colors ../../gtk2_ardour/ardour.menus Ardour2.app/Contents/Resources/etc/ardour2/`
+  `cp ../../ardour.rc ../../ardour_system.rc Ardour2.app/Contents/Resources/etc/ardour2/`
+  `cp ardour2_mac_ui.rc Ardour2.app/Contents/Resources/etc/ardour2/ardour2_ui.rc`
+
+  # copy other etc stuff
+  if not File.exist?("Ardour2.app/Contents/Resources/etc/gtk-2.0") then
+    `cp -R etc/gtk-2.0 Ardour2.app/Contents/Resources/etc/`
+  end
+  if not File.exist?("Ardour2.app/Contents/Resources/etc/pango") then
+    `cp -R etc/pango Ardour2.app/Contents/Resources/etc/`
+  end
+  if not File.exist?("Ardour2.app/Contents/Resources/etc/fonts") then
+    `cp -R /opt/local/etc/fonts Ardour2.app/Contents/Resources/etc/`
+  end
+
+  if not File.exist?("Ardour2.app/Contents/Resources/etc/profile.d") then
+    `cp -R etc/profile.d Ardour2.app/Contents/Resources/etc/`
+  end
+
+  # share stuff
+
+  if not File.exist?("Ardour2.app/Contents/Resources/share") then
+    Dir.mkdir "Ardour2.app/Contents/Resources/share"
+  end
+
+  if not File.exist?("Ardour2.app/Contents/Resources/share/ardour2") then
+    Dir.mkdir "Ardour2.app/Contents/Resources/share/ardour2"
+    Dir.mkdir "Ardour2.app/Contents/Resources/share/ardour2/templates"
+    `cp -R  ../../gtk2_ardour/icons ../../gtk2_ardour/pixmaps ../../gtk2_ardour/splash.png Ardour2.app/Contents/Resources/share/ardour2/`
+    `cp ../../templates/*.template Ardour2.app/Contents/Resources/share/ardour2/templates/` 
+  end
+
+  # go through and recursively remove any .svn dirs in the bundle
+  svndirs = `find Ardour2.app -name .svn -type dir`.split("\n")
+  svndirs.each do |svndir|
+    `rm -rf #{svndir}`
+  end
+
+  # make DMG
+  `rm -rf macdist`
+  Dir.mkdir("macdist")
+  `cp -r README.rtf COPYING Ardour2.app macdist/`
+  dmgname = "Ardour-#{version}"
+  `rm -f #{dmgname}.dmg`
+  $stdout.print("\nCreating DMG\n")
+  `hdiutil create -fs HFS+ -volname #{dmgname} -srcfolder macdist #{dmgname}.dmg`
+
+
+  $stdout.print("\nDone\n")
+
+else
+  # zip up libdir and bindir
+  zipfile = "binlib_"+`uname -p`.strip() + ".zip" 
+  $stdout.print("Zipping up #{libdir} and #{bindir} into #{zipfile}...\n")
+  `zip -rq #{zipfile} #{libdir} #{bindir}`
+  $stdout.print("Copy #{zipfile} to other platform's osx_packaging dir and run app_build.rb\nthere to complete universal build.\n")
+
+
+end
+
+
index 4731120349cfb146a2432b163d4b704e85e7a0cb..ad456c305f9b395121e40c65858c2a190ec65e25 100644 (file)
@@ -58,6 +58,11 @@ style "plugin_maker_text"
        fg[NORMAL] = { 0.80, 0.80, 0.80 }
 }
 
+style "automation_track_name"
+{
+       font_name = "sans italic 8"
+}
+
 style "first_action_message" 
 {
        font_name = "sans medium 34"
@@ -85,7 +90,7 @@ style "default_base" = "medium_text"
   GtkButton::default_outside_border = { 0, 0, 0, 0 }
   GtkTreeView::vertical-padding = 0
   GtkTreeView::horizontal-padding = 0
-  GtkTreeView::even-row-color = { 0, 0, 0.12 }
+  GtkTreeView::even-row-color = { 0, 0, 0 }
   GtkTreeView::odd-row-color = { 0, 0, 0 }
   
   fg[NORMAL] = { 0.80, 0.80, 0.80 }    
@@ -138,7 +143,7 @@ style "transport_base" = "medium_bold_text"
 
 style "black_mackie_menu_bar" = "medium_bold_text"
 {
-      font_name = "sans bold 12"
+      font_name = "sans bold 11"
       fg[NORMAL] = { 1.0, 1.0, 1.0 }
       bg[NORMAL] = { 0, 0, 0 }
 }
@@ -190,6 +195,12 @@ style "track_rec_enable_button" = "small_button"
        bg[PRELIGHT] =   { 1.0, 0.0, 0.0 }
 }
 
+style "gain_fader"
+{
+       bg[NORMAL] =   { 0.269, 0.269, 0.300}
+       bg[ACTIVE] =   { 0.152, 0.152, 0.168 }
+}
+
 style "mixer_rec_enable_button" = "track_rec_enable_button"
 {
        font_name = "sans 8"
@@ -206,6 +217,15 @@ style "solo_button" = "small_button"
        fg[ACTIVE] = { 0, 0, 0 }
 }
 
+style "safe_solo_button" = "small_button"
+{
+       bg[PRELIGHT] = { 0, 1.0, 0 }
+       bg[ACTIVE] = { 0.19, 0.97, 0.69 }
+
+       fg[PRELIGHT] = { 0, 0, 0 }
+       fg[ACTIVE] = { 0, 0, 0 }
+}
+
 style "mixer_solo_button" = "solo_button"
 {
        font_name = "sans 8"
@@ -214,6 +234,14 @@ style "mixer_solo_button" = "solo_button"
 
 }
 
+style "mixer_safe_solo_button" = "safe_solo_button"
+{
+       font_name = "sans 7"
+       xthickness = 0
+       ythickness = 0
+
+}
+
 
 style "mute_button" = "small_button"
 {
@@ -260,11 +288,6 @@ style "time_button" = "default_buttons_menus"
        font_name = "sans 10"
 }
 
-style "default_menus" = "default_buttons_menus"
-{
-       font_name = "sans 11"
-}
-
 style "transport_button"
 {
        font_name = "sans 9"
@@ -289,7 +312,7 @@ style "shuttle_control" = "very_small_text"
        bg[NORMAL] = { 0.26, 0.26, 0.31 }
        bg[PRELIGHT] = { 0.26, 0.26, 0.31 }
        bg[INSENSITIVE] = { 0.26, 0.26, 0.31 }
-       bg[ACTIVE] = { 0.50, 1.0, 0.50 }
+       bg[ACTIVE] = { 0.70, 0.70, 0.70 }
        bg[SELECTED] = { 1.0, 0.04, 0.04 }
 }
 
@@ -314,8 +337,8 @@ style "options_window"  = "default_base"
 
 style "option_entry"  = "default_base"
 {
-       fg[NORMAL] = { 0.50, 1.0, 1.0 }
-       fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+       fg[NORMAL] = { 1.0, 1.0, 1.0 }
+       fg[ACTIVE] = { 1.0, 1.0, 1.0 }
        fg[INSENSITIVE] = { 0.80, 0.80, 0.80 }
        
        base[INSENSITIVE] = { 0.07, 0.07, 0.12 }
@@ -398,15 +421,15 @@ style "warning_message" = "medium_text"
 
 style "medium_entry" = "medium_text"
 {
-       fg[NORMAL] = { 0.50, 1.0, 1.0 }
-       fg[ACTIVE] = { 0.50, 1.0, 1.0 }
-       fg[SELECTED] = { 0.50, 1.0, 0.50 }
+       fg[NORMAL] = { 0.70, 0.70, 0.70 }
+       fg[ACTIVE] = { 0.70, 0.70, 0.70 }
+       fg[SELECTED] = { 1.0, 1.0, 1.0 }
        
        bg[NORMAL] = { 0.35, 0.35, 0.40 }
        
        base[NORMAL] = { 0, 0, 0 }
        base[ACTIVE] = { 0, 0, 0 }
-       base[SELECTED] = { 0.5, 0.5, 1.0 }
+       base[SELECTED] = { 0.70, 0.70, 0.70 }
 }
 
 style "medium_entry_noselection_fg" = "medium_entry"
@@ -416,13 +439,13 @@ style "medium_entry_noselection_fg" = "medium_entry"
 
 style "medium_entry_noselection_bg" = "medium_entry"
 {
-       bg[SELECTED] = { 0.50, 1.0, 1.0 }
+       bg[SELECTED] = { 1.0, 1.0, 1.0 }
 }
 
 style "medium_bold_entry"  = "medium_bold_text"
 {
-       fg[NORMAL] = { 0.50, 1.0, 1.0 }
-       fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+       fg[NORMAL] = { 0.70, 0.70, 0.70 }
+       fg[ACTIVE] = { 0.70, 0.70, 0.70 }
        
        bg[NORMAL] = { 0.35, 0.35, 0.40 }
        
@@ -431,12 +454,17 @@ style "medium_bold_entry"  = "medium_bold_text"
        base[SELECTED] = { 0, 0, 0 }
 }
 
-
 style "small_entry" = "small_text"
 {
-       fg[NORMAL] = { 0.50, 1.0, 1.0 }
-       fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+       fg[NORMAL] = { 0.70, 0.70, 0.70 }
+       fg[ACTIVE] = { 0, 1.0, 0 }
+       fg[SELECTED] = { 0, 1.0, 0 }
+       text[NORMAL] = { 0.70, 0.70, 0.70 }
+       text[ACTIVE] = { 0, 1.0, 0 }
+       text[SELECTED] = { 0, 1.0, 0 }
        bg[NORMAL] = { 0.0, 0.0, 0.0 }
+       bg[SELECTED] = { 0.0, 0.0, 0.0 }
+       bg[SELECTED] = { 0.0, 0.0, 0.0 }
        base[NORMAL] = { 0, 0, 0 }
        base[ACTIVE] = { 0, 0, 0 }
        base[SELECTED] = { 0, 0, 0 }
@@ -450,8 +478,8 @@ style "red_active_small_entry" = "small_entry"
 
 style "small_bold_entry" = "small_bold_text"
 {
-       fg[NORMAL] = { 0.50, 1.0, 1.0 }
-       fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+       fg[NORMAL] = { 0.70, 0.70, 0.70 }
+       fg[ACTIVE] = { 0.70, 0.70, 0.70 }
        
        bg[NORMAL] = { 0.35, 0.35, 0.40 }
        
@@ -470,9 +498,25 @@ style "small_red_on_black_entry"  = "small_bold_text"
        bg[ACTIVE] = { 0.0, 0.0, 0.0 }
 }
 
-style "big_clock_display" = "medium_entry"
+style "non_recording_big_clock_display" = "medium_entry"
+{
+       font_name = "sans 60"
+
+       fg[NORMAL] = { 0.50, 1.0, 0.50 }
+       fg[ACTIVE] = { 1.0, 0, 0.0 }
+       fg[SELECTED] = { 1.0, 0, 0 }
+       fg[PRELIGHT] = { 1.0, 0, 0.0 }
+       fg[INSENSITIVE] = { 1.0, 0, 0.0 }
+       
+       base[NORMAL] = { 0.0, 0.0, 0.0 }
+       base[ACTIVE] = { 0.0, 0.0, 0.0 }
+       bg[NORMAL] = { 0.0, 0.0, 0.0 }
+       bg[ACTIVE] = { 0.7, 0.0, 0.0 }  
+}
+
+style "recording_big_clock_display" = "non_recording_big_clock_display"
 {
-       font_name = "courier bold 34"
+       fg[NORMAL] = { 1.0, 0, 0 }
 }
 
 style "transport_clock_display"
@@ -618,7 +662,7 @@ style "region_list_display" = "small_bold_text"
 {
        fg[NORMAL] = { 0.80, 0.80, 0.80 }
        fg[ACTIVE] = { 0.80, 0.80, 0.80 }
-       fg[SELECTED] = { 0.50, 1.0, 1.0 }
+       fg[SELECTED] = { 0.70, 0.70, 0.70 }
        bg[NORMAL] = { 0, 0, 0 }
        bg[ACTIVE] = { 0, 0, 0 }
        bg[SELECTED] = { 0, 0, 0 }
@@ -630,11 +674,11 @@ style "region_list_display" = "small_bold_text"
 
 style "main_canvas_area"
 {
-       bg[NORMAL] = { 0.32, 0.32, 0.36 }
-       bg[ACTIVE] = { 0.38, 0.38, 0.42 }
-       bg[INSENSITIVE] = { 0.38, 0.38, 0.42 }
-       bg[SELECTED] = { 0.38, 0.38, 0.42 }
-       bg[PRELIGHT] = { 0.38, 0.38, 0.42 }
+       bg[NORMAL] = { 0.20, 0.20, 0.25 }
+       bg[ACTIVE] = { 0.20, 0.20, 0.25 }
+       bg[INSENSITIVE] = { 0.20, 0.20, 0.25 }
+       bg[SELECTED] = { 0.20, 0.20, 0.25 }
+       bg[PRELIGHT] = { 0.20, 0.20, 0.25 }
 }
 
 style "track_controls_inactive"
@@ -728,7 +772,7 @@ style "redirect_list_display"
 
        font_name = "sans 10"
        text[NORMAL] = { 0.80, 0.80, 0.80 }
-       text[ACTIVE] = { 0.5, 0.5, 0.9 }
+       text[ACTIVE] = { 0.70, 0.70, 0.70 }
        text[INSENSITIVE] = { 0, 0, 0 }
        text[SELECTED] = { 0.9, 0.3, 0.3 }
 
@@ -741,7 +785,7 @@ style "redirect_list_display"
         # text
 
        fg[NORMAL] = { 0.5, 0.5, 0.5 }  # used for inactive
-       fg[ACTIVE] = { 0.5, 1.0, 1.0 }  # used for active
+       fg[ACTIVE] = { 1.0, 1.0, 1.0 }  # used for active
 }
 
 style "inspector_redirect_list_display" = "redirect_list_display"
@@ -806,16 +850,17 @@ style "flashing_alert" = "very_small_text"
 
 style "selected_io_selector_port_list" = "medium_bold_text"
 {
-       GtkTreeView::even-row-color = { 0.64, 0.68, 0.54 }
-       GtkTreeView::odd-row-color = { 0.64, 0.68, 0.54 }
+
+       GtkTreeView::even-row-color = { 0, 0, 0 }
+       GtkTreeView::odd-row-color = { 0, 0, 0 }
 
 # fg is used to color the fg (text) of the column header button
 
-       fg[NORMAL] = { 0.80, 0.80, 0.70 }
-       fg[SELECTED] = { 0.80, 0.80, 0.70 }
-       fg[ACTIVE] = { 0.80, 0.80, 0.70 }
-       fg[PRELIGHT] = { 0.80, 0.80, 0.70 }
-       fg[INSENSITIVE] = { 0.80, 0.80, 0.70 }
+       fg[NORMAL] = { 0.85, 0.85, 0.85 }
+       fg[SELECTED] = { 0.85, 0.85, 0.85 }
+       fg[ACTIVE] = { 0.85, 0.85, 0.85 }
+       fg[PRELIGHT] = { 0.85, 0.85, 0.85 }
+       fg[INSENSITIVE] = { 0.85, 0.85, 0.85 }
 
 # bg is used used to color the background of the column header button
 
@@ -827,28 +872,30 @@ style "selected_io_selector_port_list" = "medium_bold_text"
 
 # text is used to color the treeview row text
 
-       text[NORMAL] = { 0.80, 0.80, 0.70 }
-       text[SELECTED] = { 0.80, 0.80, 0.70 }
+       text[NORMAL] = { 0.85, 0.85, 0.85 }
+       text[SELECTED] = { 0.85, 0.85, 0.85 }
 
 # base is used to color a treeview with no rows
 
-       base[NORMAL] = { 0.64, 0.68, 0.54 }
-       base[ACTIVE] = { 0.64, 0.68, 0.54 }
-       base[PRELIGHT] = { 0.64, 0.68, 0.54 }
-       base[INSENSITIVE] = { 0.64, 0.68, 0.54 }
-       base[SELECTED] = { 0.64, 0.68, 0.54 }
+       base[NORMAL] = { 0.20, 0.20, 0.25 }
+       base[ACTIVE] = { 0.20, 0.20, 0.25 }
+       base[PRELIGHT] = { 0.20, 0.20, 0.25 }
+       base[INSENSITIVE] = { 0.20, 0.20, 0.25 }
+       base[SELECTED] = { 0.20, 0.20, 0.25 }
+
 }
 
 style "io_selector_port_list" = "medium_text"
 {
-
+       GtkTreeView::even-row-color = { 0.20, 0.20, 0.25 }
+       GtkTreeView::odd-row-color = { 0.20, 0.20, 0.25 }
 # fg is used to color the fg (text) of the column header button
 
-       fg[NORMAL] = { 0.80, 0.80, 0.70 }
-       fg[SELECTED] = { 0.80, 0.80, 0.70 }
-       fg[ACTIVE] = { 0.80, 0.80, 0.70 }
-       fg[PRELIGHT] = { 0.80, 0.80, 0.70 }
-       fg[INSENSITIVE] = { 0.80, 0.80, 0.70 }
+       fg[NORMAL] = { 0.70, 0.70, 0.70 }
+       fg[SELECTED] = { 0.70, 0.70, 0.70 }
+       fg[ACTIVE] = { 0.70, 0.70, 0.70 }
+       fg[PRELIGHT] = { 0.70, 0.70, 0.70 }
+       fg[INSENSITIVE] = { 0.70, 0.70, 0.70 }
 
 # bg is used used to color the background of the column header button
 
@@ -860,22 +907,22 @@ style "io_selector_port_list" = "medium_text"
 
 # text is used to color the treeview row text
 
-       text[NORMAL] = { 0.80, 0.80, 0.70 }
-       text[SELECTED] = { 0.80, 0.80, 0.70 }
+       text[NORMAL] = { 0.80, 0.80, 0.80 }
+       text[SELECTED] = { 0.80, 0.80, 0.80 }
 
 # base is used to color a treeview with no rows
 
-       base[NORMAL] = { 0, 0, 0 }
-       base[ACTIVE] = { 0, 0, 0 }
-       base[PRELIGHT] = { 0, 0, 0 }
-       base[INSENSITIVE] = { 0, 0, 0 }
-       base[SELECTED] = { 0, 0, 0 }
+       base[NORMAL] = { 0.20, 0.20, 0.25 }
+       base[ACTIVE] = { 0.20, 0.20, 0.25 }
+       base[PRELIGHT] = { 0.20, 0.20, 0.25 }
+       base[INSENSITIVE] = { 0.20, 0.20, 0.25 }
+       base[SELECTED] = { 0.20, 0.20, 0.25 }
 }
 
 style "io_selector_notebook" = "default_base"
 {
-       fg[NORMAL] = { 0.50, 1.0, 1.0 }
-        font_name ="sans bold 10"
+       fg[NORMAL] = { 1.0, 1.0, 1.0 }
+        font_name ="sans bold 8"
 }
 
 style "tearoff_arrow" = "medium_bold_entry"
@@ -906,23 +953,32 @@ style "pan_slider"
 {
        font_name = "sans 8"
 
-       fg[NORMAL] = { 0.67, 0.23, 0.22 }
-       fg[ACTIVE] = { 0.67, 0.23, 0.22 }
-       fg[INSENSITIVE] = {0.32, 0.39, 0.45 } # matches default_base
+       fg[NORMAL] = { 0.22, 0.73, 0.22 }
+       fg[ACTIVE] = { 0.22, 0.73, 0.22 }
+       fg[INSENSITIVE] = {0.22, 0.53, 0.22 }
        fg[SELECTED] = { 0.67, 0.23, 0.22 }
        fg[PRELIGHT] = { 0.67, 0.23, 0.22 }
 
-       bg[NORMAL] = { 0, 0, 0 }
+       bg[NORMAL] = { 0.05, 0.05, 0.05 }
        bg[ACTIVE] = { 0, 0, 0 }
-       bg[INSENSITIVE] = {0.32, 0.39, 0.45 } # matches default_base
+       bg[INSENSITIVE] = {0.12, 0.19, 0.25 }
        bg[SELECTED] = { 0, 0, 0 }
        bg[PRELIGHT] = { 0, 0, 0 }
 
-       text[NORMAL] = { 0.85, 0.92, 0.98 }
-       text[ACTIVE] = { 0.85, 0.92, 0.98 }
-       text[INSENSITIVE] = { 0.85, 0.92, 0.98 }
-       text[SELECTED] = { 0.85, 0.92, 0.98 }
-       text[PRELIGHT] = { 0.85, 0.92, 0.98 }
+       text[NORMAL] = { 0.70, 0.70, 0.70 }
+       text[ACTIVE] = { 0.70, 0.70, 0.70 }
+       text[INSENSITIVE] = { 0.70, 0.70, 0.70 }
+       text[SELECTED] = { 0.70, 0.70, 0.70 }
+       text[PRELIGHT] = { 0.70, 0.70, 0.70 }
+
+       # used to draw the triangular indicators 
+
+       base[NORMAL] = { 0.80, 0.80, 0.80 }
+       base[ACTIVE] =  { 0.80, 0.80, 0.80 }
+       base[INSENSITIVE] = {0.32, 0.39, 0.45 } # matches default_base
+       base[SELECTED] = { 0.80, 0.80, 0.80 }
+       base[PRELIGHT] = { 0.80, 0.80, 0.80 }
+
 }
 
 style "region_list_whole_file"
@@ -940,7 +996,7 @@ style "ardour_button" ="default_buttons_menus"
 widget "*FirstActionMessage" style "first_action_message"
 widget "*VerboseCanvasCursor" style "verbose_canvas_cursor"
 widget "*MarkerText" style "marker_text"
-widget "*TimeAxisViewItemName" style "time_axis_view_item_name"
+widget "*TimeAxisViewItemName*" style "time_axis_view_item_name"
 #widget "*ExportProgress" style "default_buttons_menus"
 widget "*ExportFileLabel" style "small_bold_text"
 widget "*ExportFormatLabel" style "medium_bold_text"
@@ -953,7 +1009,7 @@ widget "*EditModeSelector" style "medium_bold_entry"
 widget "*SnapTypeSelector" style "medium_bold_entry"
 widget "*SnapModeSelector" style "medium_bold_entry"
 widget "*ZoomFocusSelector" style "medium_bold_entry"
-widget "*ArdourContextMenu*" style "default_menus"
+widget "*ArdourContextMenu*" style "default_buttons_menus"
 widget "*EditGroupTitleButton*" style "default_buttons_menus"
 widget "*MixerGroupTitleButton*" style "default_buttons_menus"
 widget "*ErrorLogCloseButton" style "default_buttons_menus"
@@ -1008,8 +1064,8 @@ widget "*EditorTimeButton*" style "time_button"
 widget "*EditorMixerButton*" style "default_buttons_menus"
 widget "*SoloButton*" style "solo_button"
 widget "*SoloButton.*" style "solo_button"
-widget "*SafeSoloButton*" style "solo_button"
-widget "*SafeSoloButton.*" style "solo_button"
+widget "*SafeSoloButton*" style "safe_solo_button"
+widget "*SafeSoloButton.*" style "safe_solo_button"
 widget "*MixerPhaseInvertButton*" style "very_small_button"
 widget "*MixerPhaseInvertButton.*" style "very_small_button"
 widget "*MixerAutomationRecordingButton*" style "very_small_button"
@@ -1046,11 +1102,16 @@ widget "*ErrorMessage" style "error_message"
 widget "*FatalMessage" style "fatal_message"
 widget "*InfoMessage" style "info_message"
 widget "*WarningMessage" style "warning_message"
-widget "*BigClockDisplay" style "big_clock_display"
+widget "*BigClockNonRecording" style "non_recording_big_clock_display"
+widget "*BigClockRecording" style "recording_big_clock_display"
 widget "*TransportClockDisplay" style "transport_clock_display"
 widget "*SecondaryClockDisplay" style "transport_clock_display"
-widget "*BBTTempoLabel" style "tempo_meter_clock_display"
-widget "*BBTMeterLabel" style "tempo_meter_clock_display"
+widget "*AudioClockFramesUpperInfo" style "tempo_meter_clock_display"
+widget "*AudioClockFramesLowerInfo" style "tempo_meter_clock_display"
+widget "*AudioClockSMPTEUpperInfo" style "tempo_meter_clock_display"
+widget "*AudioClockSMPTELowerInfo" style "tempo_meter_clock_display"
+widget "*AudioClockBBTUpperInfo" style "tempo_meter_clock_display"
+widget "*AudioClockBBTLowerInfo" style "tempo_meter_clock_display"
 widget "*SelectionStartClock" style "default_clock_display"
 widget "*SelectionEndClock" style "default_clock_display"
 widget "*EditCursorClock" style "default_clock_display"
@@ -1084,10 +1145,10 @@ widget "*BaseFrame" style "base_frame"
 widget "*AudioTrackStripBase" style "audio_track_base"
 widget "*TimeAxisViewControlsBaseUnselected" style "audio_track_base"
 widget "*AudioTrackControlsBaseUnselected" style "audio_track_base"
-widget "*AudioTrackFader" style "audio_track_base"
+widget "*AudioTrackFader" style "gain_fader"
 widget "*AudioBusStripBase" style "audio_bus_base"
 widget "*BusControlsBaseUnselected" style "audio_bus_base"
-widget "*AudioBusFader" style "audio_bus_base"
+widget "*AudioBusFader" style "gain_fader"
 widget "*TrackSeparator" style "track_separator"
 widget "*TrackEditIndicator0*" style "edit_group_0"
 widget "*TrackEditIndicator1*" style "edit_group_1"
@@ -1114,6 +1175,7 @@ widget "*EditorMainCanvas" style "main_canvas_area"
 widget "*AudioTrackControlsBaseInactiveUnselected" style "track_controls_inactive"
 widget "*BusControlsBaseInactiveUnselected" style "track_controls_inactive"
 widget "*AutomationTrackControlsBaseInactiveUnselected" style "track_controls_inactive"
+widget "*AutomationTrackName" style "automation_track_name"
 widget "*AudioTrackControlsBaseInactiveSelected" style "track_controls_inactive"
 widget "*BusControlsBaseInactiveSelected" style "track_controls_inactive"
 widget "*AutomationTrackControlsBaseInactiveSelected" style "track_controls_inactive"
@@ -1159,6 +1221,7 @@ widget "*MixerStripSpeedBase*" style "small_entry"
 widget "*MixerStripSpeedBaseNotOne" style "small_red_on_black_entry"
 widget "*MixerStripSpeedBaseNotOne*" style "small_red_on_black_entry"
 widget "*MixerStripGainDisplay" style "small_entry"
+widget "*MixerStripGainDisplay*" style "small_entry"
 widget "*MixerStripGainUnitButton" style "very_small_button"
 widget "*MixerStripGainUnitButton*" style "very_small_button"
 widget "*MixerStripMeterPreButton" style "very_small_button"
index 5a2ce0d307f8d540cc4576af8f614b0340707dc4..41a2904ff93cd06350270c7474d963671025416a 100755 (executable)
@@ -20,6 +20,7 @@ export LANG=`grep '\b'\`defaults read .GlobalPreferences AppleCollationOrder\`_\
 
 export ARDOUR2_UI_RC=ardour2_ui.rc
 export ARDOUR_CONFIG_PATH="$TOP/etc"
+export ARDOUR_MODULE_PATH="$TOP/lib/"
 export ARDOUR_DATA_PATH="$TOP/share"
 export ARDOUR_GLADE_PATH="$TOP/share/ardour2/glade"
 
@@ -36,4 +37,7 @@ sed 's|${CWD}|'"$TOP|g" "$TOP/etc/gtk-2.0/gtk.immodules" > "$ETC/gtk.immodules"
 sed 's|${CWD}|'"$TOP|g" "$TOP/etc/gtk-2.0/gdk-pixbuf.loaders" \
     > "$ETC/gdk-pixbuf.loaders"
 
+# to prevent complaining
+mkdir -p "$HOME/.ardour2/templates"
+
 exec "$CWD/ardour" "$@"
diff --git a/tools/osx_packaging/etc/gtk-2.0/gdk-pixbuf.loaders b/tools/osx_packaging/etc/gtk-2.0/gdk-pixbuf.loaders
new file mode 100644 (file)
index 0000000..00c931d
--- /dev/null
@@ -0,0 +1,113 @@
+# GdkPixbuf Image Loader Modules file
+# Automatically generated file, do not edit
+#
+# LoaderDir = ${CWD}/lib/gtk-2.0/2.10.0/loaders
+#
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/io-wmf.so"
+"wmf" 0 "gtk20" "Windows Metafile"
+"image/x-wmf" ""
+"wmf" ""
+"\327\315\306\232" "" 100
+"\001" "" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-ani.so"
+"ani" 0 "gtk20" "The ANI image format"
+"application/x-navi-animation" ""
+"ani" ""
+"RIFF    ACON" "    xxxx    " 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-bmp.so"
+"bmp" 0 "gtk20" "The BMP image format"
+"image/bmp" "image/x-bmp" "image/x-MS-bmp" ""
+"bmp" ""
+"BM" "" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-gif.so"
+"gif" 0 "gtk20" "The GIF image format"
+"image/gif" ""
+"gif" ""
+"GIF8" "" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-ico.so"
+"ico" 1 "gtk20" "The ICO image format"
+"image/x-icon" ""
+"ico" "cur" ""
+"  \001   " "zz znz" 100
+"  \002   " "zz znz" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-jpeg.so"
+"jpeg" 1 "gtk20" "The JPEG image format"
+"image/jpeg" ""
+"jpeg" "jpe" "jpg" ""
+"\377\330" "" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-pcx.so"
+"pcx" 0 "gtk20" "The PCX image format"
+"image/x-pcx" ""
+"pcx" ""
+"\n \001" "" 100
+"\n\002\001" "" 100
+"\n\003\001" "" 100
+"\n\004\001" "" 100
+"\n\005\001" "" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-png.so"
+"png" 1 "gtk20" "The PNG image format"
+"image/png" ""
+"png" ""
+"\211PNG\r\n\032\n" "" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-pnm.so"
+"pnm" 0 "gtk20" "The PNM/PBM/PGM/PPM image format family"
+"image/x-portable-anymap" "image/x-portable-bitmap" "image/x-portable-graymap" "image/x-portable-pixmap" ""
+"pnm" "pbm" "pgm" "ppm" ""
+"P1" "" 100
+"P2" "" 100
+"P3" "" 100
+"P4" "" 100
+"P5" "" 100
+"P6" "" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-ras.so"
+"ras" 0 "gtk20" "The Sun raster image format"
+"image/x-cmu-raster" "image/x-sun-raster" ""
+"ras" ""
+"Y\246j\225" "" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-tga.so"
+"tga" 0 "gtk20" "The Targa image format"
+"image/x-tga" ""
+"tga" "targa" ""
+" \001\001" "x  " 100
+" \001\t" "x  " 100
+"  \002" "xz " 99
+"  \003" "xz " 100
+"  \n" "xz " 100
+"  \013" "xz " 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-tiff.so"
+"tiff" 0 "gtk20" "The TIFF image format"
+"image/tiff" ""
+"tiff" "tif" ""
+"MM *" "  z " 100
+"II* " "   z" 100
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-wbmp.so"
+"wbmp" 0 "gtk20" "The WBMP image format"
+"image/vnd.wap.wbmp" ""
+"wbmp" ""
+" " "z" 1
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-xbm.so"
+"xbm" 0 "gtk20" "The XBM image format"
+"image/x-xbitmap" ""
+"xbm" ""
+"#define " "" 100
+"/*" "" 50
+
+"${CWD}/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-xpm.so"
+"xpm" 0 "gtk20" "The XPM image format"
+"image/x-xpixmap" ""
+"xpm" ""
+"/* XPM */" "" 100
+
diff --git a/tools/osx_packaging/etc/gtk-2.0/gtk.immodules b/tools/osx_packaging/etc/gtk-2.0/gtk.immodules
new file mode 100644 (file)
index 0000000..e8a9900
--- /dev/null
@@ -0,0 +1,35 @@
+# GTK+ Input Method Modules file
+# Automatically generated file, do not edit
+#
+# ModulesPath = /var/root/.gtk-2.0/2.4.0/powerpc-apple-darwin7.6.0/immodules:/var/root/.gtk-2.0/2.4.0/immodules:/var/root/.gtk-2.0/powerpc-apple-darwin7.6.0/immodules:/var/root/.gtk-2.0/immodules:${CWD}/lib/gtk-2.0/2.4.0/powerpc-apple-darwin7.6.0/immodules:${CWD}/lib/gtk-2.0/2.4.0/immodules:${CWD}/lib/gtk-2.0/powerpc-apple-darwin7.6.0/immodules:${CWD}/lib/gtk-2.0/immodules
+#
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-am-et.so" 
+"am_et" "Amharic (EZ+)" "gtk20" "${CWD}/share/locale" "am" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-cedilla.so" 
+"cedilla" "Cedilla" "gtk+" "${CWD}/share/locale" "az:ca:co:fr:gv:oc:pt:sq:tr:wa" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-cyrillic-translit.so" 
+"cyrillic_translit" "Cyrillic (Transliterated)" "gtk20" "${CWD}/share/locale" "" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-inuktitut.so" 
+"inuktitut" "Inukitut (Transliterated)" "gtk20" "${CWD}/share/locale" "iu" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-ipa.so" 
+"ipa" "IPA" "gtk20" "${CWD}/share/locale" "" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-thai-broken.so" 
+"thai_broken" "Thai (Broken)" "gtk20" "${CWD}/share/locale" "" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-ti-er.so" 
+"ti_er" "Tigrigna-Eritrean (EZ+)" "gtk20" "${CWD}/share/locale" "ti" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-ti-et.so" 
+"ti_et" "Tigrigna-Ethiopian (EZ+)" "gtk20" "${CWD}/share/locale" "ti" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-viqr.so" 
+"viqr" "Vietnamese (VIQR)" "gtk20" "${CWD}/share/locale" "vi" 
+
+"${CWD}/lib/gtk-2.0/2.10.0/immodules/im-xim.so" 
+"xim" "X Input Method" "gtk20" "${CWD}/share/locale" "ko:ja:th:zh" 
+
diff --git a/tools/osx_packaging/etc/pango/pango.modules b/tools/osx_packaging/etc/pango/pango.modules
new file mode 100644 (file)
index 0000000..c635b8b
--- /dev/null
@@ -0,0 +1,24 @@
+# Pango Modules file
+# Automatically generated file, do not edit
+#
+# ModulesPath = "${CWD}/lib/pango/1.5.0/modules"
+#
+${CWD}/lib/pango/1.5.0/modules/pango-arabic-fc.so ArabicScriptEngineFc PangoEngineShape PangoRenderFc arabic:*
+${CWD}/lib/pango/1.5.0/modules/pango-basic-fc.so BasicScriptEngineFc PangoEngineShape PangoRenderFc armenian:* bopomofo:* cherokee:* coptic:* cyrillic:* deseret:* ethiopic:* georgian:* gothic:* greek:* han:* hiragana:* katakana:* latin:* ogham:* old-italic:* runic:* canadian-aboriginal:* yi:* braille:* cypriot:* limbu:* osmanya:* shavian:* linear-b:* ugaritic:* glagolitic:* common:
+${CWD}/lib/pango/1.5.0/modules/pango-basic-x.so BasicScriptEngineX PangoEngineShape PangoRenderX common:
+${CWD}/lib/pango/1.5.0/modules/pango-hangul-fc.so HangulScriptEngineFc PangoEngineShape PangoRenderFc hangul:*
+${CWD}/lib/pango/1.5.0/modules/pango-hebrew-fc.so HebrewScriptEngineFc PangoEngineShape PangoRenderFc hebrew:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so devaScriptEngineFc PangoEngineShape PangoRenderFc devanagari:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so bengScriptEngineFc PangoEngineShape PangoRenderFc bengali:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so guruScriptEngineFc PangoEngineShape PangoRenderFc gurmukhi:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so gujrScriptEngineFc PangoEngineShape PangoRenderFc gujarati:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so oryaScriptEngineFc PangoEngineShape PangoRenderFc oriya:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so tamlScriptEngineFc PangoEngineShape PangoRenderFc tamil:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so teluScriptEngineFc PangoEngineShape PangoRenderFc telugu:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so kndaScriptEngineFc PangoEngineShape PangoRenderFc kannada:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so mlymScriptEngineFc PangoEngineShape PangoRenderFc malayalam:*
+${CWD}/lib/pango/1.5.0/modules/pango-indic-fc.so sinhScriptEngineFc PangoEngineShape PangoRenderFc sinhala:*
+${CWD}/lib/pango/1.5.0/modules/pango-khmer-fc.so KhmerScriptEngineFc PangoEngineShape PangoRenderFc khmer:*
+${CWD}/lib/pango/1.5.0/modules/pango-syriac-fc.so SyriacScriptEngineFc PangoEngineShape PangoRenderFc syriac:*
+${CWD}/lib/pango/1.5.0/modules/pango-thai-fc.so ThaiScriptEngineFc PangoEngineShape PangoRenderFc thai:* lao:*
+${CWD}/lib/pango/1.5.0/modules/pango-tibetan-fc.so TibetanScriptEngineFc PangoEngineShape PangoRenderFc tibetan:*
diff --git a/tools/osx_packaging/etc/pango/pangorc b/tools/osx_packaging/etc/pango/pangorc
new file mode 100644 (file)
index 0000000..a4152dd
--- /dev/null
@@ -0,0 +1,5 @@
+[Pango]
+ModuleFiles = ${HOME}/Library/Application Support/Ardour/pango.modules
+
+[PangoX]
+AliasFiles = ${HOME}/Library/Application Support/Ardour/pangox.aliases
diff --git a/tools/osx_packaging/etc/pango/pangox.aliases b/tools/osx_packaging/etc/pango/pangox.aliases
new file mode 100644 (file)
index 0000000..9b41aa7
--- /dev/null
@@ -0,0 +1,220 @@
+# File defining aliases of PangoFontDescription to X font set
+#
+# family style variant weight stretch   XLFD
+
+sans normal normal normal normal \
+  "-*-helvetica-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -*-gulim-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+sans italic normal normal normal \
+  "-*-helvetica-medium-o-normal--*-*-*-*-*-*-*-*,\
+   -*-gulim-medium-o-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+sans normal normal bold normal \
+  "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*,\
+   -*-gulim-bold-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+sans italic normal bold normal \
+  "-*-helvetica-bold-o-normal--*-*-*-*-*-*-*-*,\
+   -*-gulim-bold-o-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+
+serif normal normal normal normal \
+  "-*-times-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -*-batang-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+serif italic normal normal normal \
+  "-*-times-medium-i-normal--*-*-*-*-*-*-*-*,\
+   -*-batang-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+serif normal normal bold normal \
+  "-*-times-bold-r-normal--*-*-*-*-*-*-*-*,\
+   -*-batang-bold-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+serif italic normal bold normal \
+  "-*-times-bold-i-normal--*-*-*-*-*-*-*-*,\
+   -*-batang-bold-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+monospace normal normal normal normal \
+  "-*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -*-dotum-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+monospace italic normal normal normal \
+  "-*-fixed-medium-i-normal--*-*-*-*-*-*-*-*,\
+   -*-dotum-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+monospace normal normal bold normal \
+  "-*-fixed-bold-r-normal--*-*-*-*-*-*-*-*,\
+   -*-dotum-bold-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
+
+monospace italic normal bold normal \
+  "-*-fixed-bold-i-normal--*-*-*-*-*-*-*-*,\
+   -*-dotum-bold-r-normal--*-*-*-*-*-*-ksc5601.1987-0,\
+   -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\
+   -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\
+   -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\
+   -freetype-unitamil-medium-r-normal--*-*-*-*-*-*-iso10646-tam,\
+   -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\
+   -*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\
+   -*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\
+   -*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\
+   -*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\
+   -*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\
+   -*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\
+   -*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori,\
+   -daewoo-mincho-medium-r-normal--*-*-*-*-*-*-ksc5601.1987-0"
diff --git a/tools/osx_packaging/etc/profile.d/gtk+2-shlibs.csh b/tools/osx_packaging/etc/profile.d/gtk+2-shlibs.csh
new file mode 100644 (file)
index 0000000..8dcc7a5
--- /dev/null
@@ -0,0 +1 @@
+setenv GDK_USE_XFT '1'
diff --git a/tools/osx_packaging/etc/profile.d/gtk+2-shlibs.sh b/tools/osx_packaging/etc/profile.d/gtk+2-shlibs.sh
new file mode 100644 (file)
index 0000000..9aeffa2
--- /dev/null
@@ -0,0 +1 @@
+export GDK_USE_XFT='1'
diff --git a/tools/osx_packaging/etc/profile.d/libxml2-bin.csh b/tools/osx_packaging/etc/profile.d/libxml2-bin.csh
new file mode 100644 (file)
index 0000000..b27efb8
--- /dev/null
@@ -0,0 +1,2 @@
+setenv XML_CATALOG_FILES '/sw/etc/xml/catalog'
+setenv SGML_CATALOG_FILES '/sw/etc/sgml/catalog'
diff --git a/tools/osx_packaging/etc/profile.d/libxml2-bin.sh b/tools/osx_packaging/etc/profile.d/libxml2-bin.sh
new file mode 100644 (file)
index 0000000..29ca69f
--- /dev/null
@@ -0,0 +1,2 @@
+export XML_CATALOG_FILES='/sw/etc/xml/catalog'
+export SGML_CATALOG_FILES='/sw/etc/sgml/catalog'
index d689320d205f82ca7fd2443b20d3efe53ed4c424..ec6ad4feecd536b85cc4f30f4a25176a401b0505 100755 (executable)
@@ -24,4 +24,5 @@ export "DISPLAY=`cat $TMP/display`"
 ps -wx -ocommand | grep -e '[X]11' > /dev/null || exit 11
 
 cd ~/
-exec "$CWD/bin/exporter" "$@"
+shift
+exec "$CWD/bin/exporter" "$*"
index 2a4d492f8a6b5ff676cbc768e3760583a29dc4dd..eb4dd6683b0fa3d0dcf630be2732da47d4699ff8 100644 (file)
@@ -74,7 +74,7 @@ if ardour_vst['VST']:
     # the wine script - into the bin dir
     env.Alias('install', env.Install(os.path.join(install_prefix, 'bin'), wine_executable))
     # the win32 executable - into the lib dir since the wine script will look for it there
-    env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), 'ardour_vst.exe.so'))
+    env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), 'ardour_vst.exe.so'))
 
 env.Alias ('tarball', env.Distribute (env['DISTTREE'],
                                       [ 'SConscript',