summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DOCUMENTATION/AUTHORS3
-rw-r--r--PACKAGER_README2
-rw-r--r--SConstruct463
-rw-r--r--gtk2_ardour/SConscript24
-rw-r--r--gtk2_ardour/about.cc2
-rw-r--r--gtk2_ardour/analysis_window.cc8
-rwxr-xr-xgtk2_ardour/ardbg2
-rwxr-xr-xgtk2_ardour/ardev2
-rwxr-xr-xgtk2_ardour/ardev_common.sh1
-rw-r--r--gtk2_ardour/ardev_common.sh.in16
-rw-r--r--gtk2_ardour/ardour.bindings405
-rw-r--r--gtk2_ardour/ardour.menus42
-rw-r--r--gtk2_ardour/ardour.sh.in6
-rw-r--r--gtk2_ardour/ardour2_ui.rc140
-rw-r--r--gtk2_ardour/ardour_ui.cc154
-rw-r--r--gtk2_ardour/ardour_ui.h27
-rw-r--r--gtk2_ardour/ardour_ui2.cc4
-rw-r--r--gtk2_ardour/ardour_ui_dependents.cc29
-rw-r--r--gtk2_ardour/ardour_ui_dialogs.cc35
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc20
-rw-r--r--gtk2_ardour/ardour_ui_options.cc18
-rwxr-xr-xgtk2_ardour/arprof4
-rwxr-xr-xgtk2_ardour/arval2
-rw-r--r--gtk2_ardour/audio_clock.cc247
-rw-r--r--gtk2_ardour/audio_clock.h28
-rw-r--r--gtk2_ardour/audio_region_editor.cc18
-rw-r--r--gtk2_ardour/audio_region_view.cc41
-rw-r--r--gtk2_ardour/audio_region_view.h5
-rw-r--r--gtk2_ardour/audio_streamview.cc51
-rw-r--r--gtk2_ardour/audio_streamview.h6
-rw-r--r--gtk2_ardour/audio_time_axis.cc45
-rw-r--r--gtk2_ardour/audio_time_axis.h3
-rw-r--r--gtk2_ardour/automation_line.cc257
-rw-r--r--gtk2_ardour/automation_line.h12
-rw-r--r--gtk2_ardour/automation_time_axis.cc36
-rw-r--r--gtk2_ardour/automation_time_axis.h3
-rw-r--r--gtk2_ardour/canvas-waveview.c49
-rw-r--r--gtk2_ardour/canvas-waveview.h3
-rw-r--r--gtk2_ardour/crossfade_edit.cc4
-rw-r--r--gtk2_ardour/crossfade_view.cc4
-rw-r--r--gtk2_ardour/editor.cc248
-rw-r--r--gtk2_ardour/editor.h32
-rw-r--r--gtk2_ardour/editor_actions.cc204
-rw-r--r--gtk2_ardour/editor_audio_import.cc278
-rw-r--r--gtk2_ardour/editor_canvas.cc26
-rw-r--r--gtk2_ardour/editor_canvas_events.cc8
-rw-r--r--gtk2_ardour/editor_edit_groups.cc2
-rw-r--r--gtk2_ardour/editor_export_audio.cc2
-rw-r--r--gtk2_ardour/editor_imageframe.cc12
-rw-r--r--gtk2_ardour/editor_markers.cc124
-rw-r--r--gtk2_ardour/editor_mixer.cc7
-rw-r--r--gtk2_ardour/editor_mouse.cc122
-rw-r--r--gtk2_ardour/editor_ops.cc124
-rw-r--r--gtk2_ardour/editor_region_list.cc32
-rw-r--r--gtk2_ardour/editor_route_list.cc2
-rw-r--r--gtk2_ardour/editor_rulers.cc8
-rw-r--r--gtk2_ardour/editor_selection_list.cc8
-rw-r--r--gtk2_ardour/editor_timefx.cc2
-rw-r--r--gtk2_ardour/editor_xpms52
-rw-r--r--gtk2_ardour/enums.cc29
-rw-r--r--gtk2_ardour/enums.h7
-rw-r--r--gtk2_ardour/export_dialog.cc2
-rw-r--r--gtk2_ardour/fft_graph.cc4
-rw-r--r--gtk2_ardour/gain_meter.cc189
-rw-r--r--gtk2_ardour/gain_meter.h19
-rw-r--r--gtk2_ardour/icons/ardour_icon_16px.pngbin0 -> 630 bytes
-rw-r--r--gtk2_ardour/icons/ardour_icon_22px.pngbin0 -> 1025 bytes
-rw-r--r--gtk2_ardour/icons/ardour_icon_32px.pngbin0 -> 1759 bytes
-rw-r--r--gtk2_ardour/icons/ardour_icon_48px.pngbin0 -> 3135 bytes
-rw-r--r--gtk2_ardour/icons/fader_belt.pngbin0 -> 3854 bytes
-rw-r--r--gtk2_ardour/io_selector.cc5
-rw-r--r--gtk2_ardour/ladspa_pluginui.cc2
-rw-r--r--gtk2_ardour/location_ui.cc21
-rw-r--r--gtk2_ardour/logmeter.h4
-rw-r--r--gtk2_ardour/main.cc50
-rw-r--r--gtk2_ardour/meter_bridge.cc2
-rw-r--r--gtk2_ardour/mixer_strip.cc9
-rw-r--r--gtk2_ardour/mixer_strip.h1
-rw-r--r--gtk2_ardour/mixer_ui.cc13
-rw-r--r--gtk2_ardour/new_session_dialog.cc18
-rw-r--r--gtk2_ardour/option_editor.cc64
-rw-r--r--gtk2_ardour/option_editor.h5
-rw-r--r--gtk2_ardour/opts.cc12
-rw-r--r--gtk2_ardour/opts.h1
-rw-r--r--gtk2_ardour/panner.cc104
-rw-r--r--gtk2_ardour/panner.h18
-rw-r--r--gtk2_ardour/panner2d.cc2
-rw-r--r--gtk2_ardour/panner_ui.cc63
-rw-r--r--gtk2_ardour/panner_ui.h6
-rw-r--r--gtk2_ardour/pixmaps/SConscript2
-rw-r--r--gtk2_ardour/playlist_selection.h3
-rw-r--r--gtk2_ardour/playlist_selector.cc45
-rw-r--r--gtk2_ardour/playlist_selector.h11
-rw-r--r--gtk2_ardour/plugin_ui.cc1
-rw-r--r--gtk2_ardour/po/de_DE.po6009
-rw-r--r--gtk2_ardour/po/sv_SE.po119
-rw-r--r--gtk2_ardour/public_editor.h5
-rw-r--r--gtk2_ardour/redirect_box.cc156
-rw-r--r--gtk2_ardour/redirect_box.h24
-rw-r--r--gtk2_ardour/region_gain_line.cc4
-rw-r--r--gtk2_ardour/region_gain_line.h2
-rw-r--r--gtk2_ardour/region_view.cc2
-rw-r--r--gtk2_ardour/route_params_ui.cc4
-rw-r--r--gtk2_ardour/route_time_axis.cc133
-rw-r--r--gtk2_ardour/route_time_axis.h8
-rw-r--r--gtk2_ardour/route_ui.cc2
-rw-r--r--gtk2_ardour/selection.cc30
-rw-r--r--gtk2_ardour/selection.h16
-rw-r--r--gtk2_ardour/sfdb_ui.cc324
-rw-r--r--gtk2_ardour/sfdb_ui.h185
-rw-r--r--gtk2_ardour/time_axis_view.cc24
-rw-r--r--gtk2_ardour/time_axis_view.h17
-rw-r--r--gtk2_ardour/time_axis_view_item.cc2
-rw-r--r--gtk2_ardour/utils.cc127
-rw-r--r--gtk2_ardour/utils.h4
-rw-r--r--gtk2_ardour/visual_time_axis.cc6
-rw-r--r--gtk2_ardour/waveview.cc8
-rw-r--r--gtk2_ardour/waveview.h2
-rw-r--r--libs/appleutility/SConscript2
-rw-r--r--libs/ardour/SConscript51
-rw-r--r--libs/ardour/ardour/audio_diskstream.h58
-rw-r--r--libs/ardour/ardour/audio_library.h50
-rw-r--r--libs/ardour/ardour/audioengine.h5
-rw-r--r--libs/ardour/ardour/audiofilesource.h2
-rw-r--r--libs/ardour/ardour/audioplaylist.h9
-rw-r--r--libs/ardour/ardour/audiosource.h5
-rw-r--r--libs/ardour/ardour/automation_event.h6
-rw-r--r--libs/ardour/ardour/configuration_vars.h18
-rw-r--r--libs/ardour/ardour/crossfade.h5
-rw-r--r--libs/ardour/ardour/cycles.h2
-rw-r--r--libs/ardour/ardour/diskstream.h16
-rw-r--r--libs/ardour/ardour/insert.h11
-rw-r--r--libs/ardour/ardour/io.h6
-rw-r--r--libs/ardour/ardour/location.h5
-rw-r--r--libs/ardour/ardour/meter.h10
-rw-r--r--libs/ardour/ardour/midi_diskstream.h4
-rw-r--r--libs/ardour/ardour/midi_playlist.h9
-rw-r--r--libs/ardour/ardour/named_selection.h5
-rw-r--r--libs/ardour/ardour/playlist.h54
-rw-r--r--libs/ardour/ardour/playlist_factory.h25
-rw-r--r--libs/ardour/ardour/redirect.h2
-rw-r--r--libs/ardour/ardour/region.h7
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/ardour/route_group.h2
-rw-r--r--libs/ardour/ardour/send.h8
-rw-r--r--libs/ardour/ardour/session.h181
-rw-r--r--libs/ardour/ardour/session_playlist.h2
-rw-r--r--libs/ardour/ardour/source.h6
-rw-r--r--libs/ardour/ardour/track.h5
-rw-r--r--libs/ardour/ardour/types.h15
-rw-r--r--libs/ardour/ardour/utils.h12
-rw-r--r--libs/ardour/audio_diskstream.cc215
-rw-r--r--libs/ardour/audio_library.cc459
-rw-r--r--libs/ardour/audio_playlist.cc39
-rw-r--r--libs/ardour/audio_track.cc77
-rw-r--r--libs/ardour/audioengine.cc91
-rw-r--r--libs/ardour/audiofilesource.cc43
-rw-r--r--libs/ardour/audioregion.cc147
-rw-r--r--libs/ardour/audiosource.cc116
-rw-r--r--libs/ardour/auditioner.cc32
-rw-r--r--libs/ardour/automation_event.cc93
-rw-r--r--libs/ardour/configuration.cc4
-rw-r--r--libs/ardour/control_protocol_manager.cc6
-rw-r--r--libs/ardour/crossfade.cc2
-rw-r--r--libs/ardour/diskstream.cc39
-rw-r--r--libs/ardour/enums.cc327
-rw-r--r--libs/ardour/globals.cc102
-rw-r--r--libs/ardour/import.cc32
-rw-r--r--libs/ardour/insert.cc120
-rw-r--r--libs/ardour/io.cc43
-rw-r--r--libs/ardour/location.cc48
-rw-r--r--libs/ardour/meter.cc16
-rw-r--r--libs/ardour/midi_diskstream.cc46
-rw-r--r--libs/ardour/midi_playlist.cc15
-rw-r--r--libs/ardour/midi_port.cc2
-rw-r--r--libs/ardour/midi_track.cc6
-rw-r--r--libs/ardour/named_selection.cc18
-rw-r--r--libs/ardour/panner.cc8
-rw-r--r--libs/ardour/playlist.cc180
-rw-r--r--libs/ardour/playlist_factory.cc91
-rw-r--r--libs/ardour/plugin_manager.cc3
-rw-r--r--libs/ardour/redirect.cc31
-rw-r--r--libs/ardour/region.cc88
-rw-r--r--libs/ardour/route.cc14
-rw-r--r--libs/ardour/route_group.cc23
-rw-r--r--libs/ardour/send.cc15
-rw-r--r--libs/ardour/session.cc258
-rw-r--r--libs/ardour/session_butler.cc2
-rw-r--r--libs/ardour/session_command.cc424
-rw-r--r--libs/ardour/session_events.cc11
-rw-r--r--libs/ardour/session_midi.cc4
-rw-r--r--libs/ardour/session_process.cc2
-rw-r--r--libs/ardour/session_state.cc302
-rw-r--r--libs/ardour/session_time.cc168
-rw-r--r--libs/ardour/session_transport.cc69
-rw-r--r--libs/ardour/smf_source.cc2
-rw-r--r--libs/ardour/sndfilesource.cc29
-rw-r--r--libs/ardour/source.cc13
-rw-r--r--libs/ardour/source_factory.cc161
-rw-r--r--libs/ardour/tempo.cc8
-rw-r--r--libs/ardour/utils.cc132
-rw-r--r--libs/clearlooks/SConscript26
-rw-r--r--libs/flowcanvas/SConscript2
-rw-r--r--libs/fst/SConscript50
-rw-r--r--libs/fst/fstinfofile.c4
-rw-r--r--libs/glibmm2/SConscript2
-rw-r--r--libs/gtkmm2/atk/SConscript2
-rw-r--r--libs/gtkmm2/gdk/SConscript2
-rw-r--r--libs/gtkmm2/gtk/SConscript2
-rw-r--r--libs/gtkmm2/pango/SConscript2
-rw-r--r--libs/gtkmm2ext/SConscript4
-rw-r--r--libs/gtkmm2ext/barcontroller.cc74
-rw-r--r--libs/gtkmm2ext/focus_entry.cc31
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/barcontroller.h22
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/focus_entry.h22
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/pixfader.h70
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/slider_controller.h13
-rw-r--r--libs/gtkmm2ext/pixfader.cc249
-rw-r--r--libs/gtkmm2ext/prompter.cc2
-rw-r--r--libs/gtkmm2ext/slider_controller.cc21
-rw-r--r--libs/gtkmm2ext/tearoff.cc8
-rw-r--r--libs/libglademm/SConscript2
-rw-r--r--libs/libgnomecanvasmm/SConscript2
-rw-r--r--libs/libsndfile/SConscript5
-rwxr-xr-xlibs/libsndfile/configure8
-rw-r--r--libs/midi++2/SConscript2
-rw-r--r--libs/midi++2/jack_midiport.cc4
-rw-r--r--libs/pbd/SConscript6
-rw-r--r--libs/pbd/basename.cc19
-rw-r--r--libs/pbd/controllable.cc4
-rw-r--r--libs/pbd/copyfile.cc38
-rw-r--r--libs/pbd/enumwriter.cc273
-rw-r--r--libs/pbd/pbd/basename.h6
-rw-r--r--libs/pbd/pbd/copyfile.h6
-rw-r--r--libs/pbd/pbd/enumwriter.h77
-rw-r--r--libs/pbd/pbd/tokenizer.h30
-rw-r--r--libs/pbd/pbd/undo.h2
-rw-r--r--libs/pbd/pbd/whitespace.h6
-rw-r--r--libs/pbd/undo.cc26
-rw-r--r--libs/pbd/whitespace.cc6
-rw-r--r--libs/sigc++2/SConscript2
-rw-r--r--libs/soundtouch/SConscript2
-rw-r--r--libs/soundtouch/STTypes.h4
-rw-r--r--libs/surfaces/control_protocol/SConscript2
-rw-r--r--libs/surfaces/control_protocol/control_protocol/smpte.h22
-rw-r--r--libs/surfaces/control_protocol/smpte.cc118
-rw-r--r--libs/surfaces/generic_midi/SConscript3
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc2
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.cc13
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.h2
-rw-r--r--libs/surfaces/tranzport/SConscript11
-rw-r--r--libs/surfaces/tranzport/tranzport_control_protocol.cc1455
-rw-r--r--libs/surfaces/tranzport/tranzport_control_protocol.h138
-rw-r--r--svn_revision.h2
-rw-r--r--templates/SConscript3
-rw-r--r--tools/osx_packaging/Ardour2.icnsbin53885 -> 41196 bytes
-rw-r--r--tools/osx_packaging/COPYING340
-rwxr-xr-xtools/osx_packaging/app_build.rb254
-rw-r--r--tools/osx_packaging/ardour2_mac_ui.rc223
-rwxr-xr-xtools/osx_packaging/bin/exporter4
-rw-r--r--tools/osx_packaging/etc/gtk-2.0/gdk-pixbuf.loaders113
-rw-r--r--tools/osx_packaging/etc/gtk-2.0/gtk.immodules35
-rw-r--r--tools/osx_packaging/etc/pango/pango.modules24
-rw-r--r--tools/osx_packaging/etc/pango/pangorc5
-rw-r--r--tools/osx_packaging/etc/pango/pangox.aliases220
-rw-r--r--tools/osx_packaging/etc/profile.d/gtk+2-shlibs.csh1
-rw-r--r--tools/osx_packaging/etc/profile.d/gtk+2-shlibs.sh1
-rw-r--r--tools/osx_packaging/etc/profile.d/libxml2-bin.csh2
-rw-r--r--tools/osx_packaging/etc/profile.d/libxml2-bin.sh2
-rwxr-xr-xtools/osx_packaging/script3
-rw-r--r--vst/SConscript2
271 files changed, 12749 insertions, 7604 deletions
diff --git a/DOCUMENTATION/AUTHORS b/DOCUMENTATION/AUTHORS
index a406deac66..027521670b 100644
--- a/DOCUMENTATION/AUTHORS
+++ b/DOCUMENTATION/AUTHORS
@@ -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
diff --git a/PACKAGER_README b/PACKAGER_README
index 36017496be..303df707f0 100644
--- a/PACKAGER_README
+++ b/PACKAGER_README
@@ -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.
diff --git a/SConstruct b/SConstruct
index 27e04b2ee1..f1a9a5e707 100644
--- a/SConstruct
+++ b/SConstruct
@@ -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
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index bf8e4f560e..dfd94ea5af 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -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'], []))
diff --git a/gtk2_ardour/about.cc b/gtk2_ardour/about.cc
index 959830725e..34bb98199c 100644
--- a/gtk2_ardour/about.cc
+++ b/gtk2_ardour/about.cc
@@ -145,6 +145,8 @@ static const char* authors[] = {
N_("Stefan Kersten"),
N_("Christopher George"),
N_("Robert Jordens"),
+ N_("Brian Ahr"),
+ N_("Nimal Ratnayake"),
0
};
diff --git a/gtk2_ardour/analysis_window.cc b/gtk2_ardour/analysis_window.cc
index 163ac981b9..3752726c04 100644
--- a/gtk2_ardour/analysis_window.cc
+++ b/gtk2_ardour/analysis_window.cc
@@ -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;
diff --git a/gtk2_ardour/ardbg b/gtk2_ardour/ardbg
index 933b5ba720..95466a42b8 100755
--- a/gtk2_ardour/ardbg
+++ b/gtk2_ardour/ardbg
@@ -1,4 +1,4 @@
#!/bin/sh
dir=`dirname "$0"`
. $dir/ardev_common.sh
-exec gdb gtk2_ardour/ardour.bin $*
+exec gdb $EXECUTABLE $*
diff --git a/gtk2_ardour/ardev b/gtk2_ardour/ardev
index 04719908b4..3b65b2ec79 100755
--- a/gtk2_ardour/ardev
+++ b/gtk2_ardour/ardev
@@ -1,3 +1,3 @@
#!/bin/sh
. `dirname "$0"`/ardev_common.sh
-exec gtk2_ardour/ardour.bin --novst $*
+exec $EXECUTABLE "$*"
diff --git a/gtk2_ardour/ardev_common.sh b/gtk2_ardour/ardev_common.sh
index d4109de8bb..3cef2254d2 100755
--- a/gtk2_ardour/ardev_common.sh
+++ b/gtk2_ardour/ardev_common.sh
@@ -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
index 0000000000..6017dcdba4
--- /dev/null
+++ b/gtk2_ardour/ardev_common.sh.in
@@ -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%
diff --git a/gtk2_ardour/ardour.bindings b/gtk2_ardour/ardour.bindings
index 5a0eb469b7..8d280b536d 100644
--- a/gtk2_ardour/ardour.bindings
+++ b/gtk2_ardour/ardour.bindings
@@ -1,114 +1,311 @@
-; 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" "")
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus
index 97441e5023..cf56e2ad9f 100644
--- a/gtk2_ardour/ardour.menus
+++ b/gtk2_ardour/ardour.menus
@@ -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'/>
@@ -122,6 +123,21 @@
<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'>
@@ -214,13 +230,11 @@
<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'>
@@ -240,10 +254,10 @@
<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>
@@ -258,6 +272,10 @@
<menuitem action='PullupMinus4'/>
<menuitem action='PullupMinus4Minus1'/>
</menu>
+ <menu action='Subframes'>
+ <menuitem action='Subframes80'/>
+ <menuitem action='Subframes100'/>
+ </menu>
<separator/>
<menu action='Autoconnect'>
<menuitem action='InputAutoConnectPhysical'/>
@@ -324,21 +342,7 @@
<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>
diff --git a/gtk2_ardour/ardour.sh.in b/gtk2_ardour/ardour.sh.in
index 107321024b..1bf1ffa94b 100644
--- a/gtk2_ardour/ardour.sh.in
+++ b/gtk2_ardour/ardour.sh.in
@@ -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% $*
diff --git a/gtk2_ardour/ardour2_ui.rc b/gtk2_ardour/ardour2_ui.rc
index d015340868..249edddbf4 100644
--- a/gtk2_ardour/ardour2_ui.rc
+++ b/gtk2_ardour/ardour2_ui.rc
@@ -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"
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 58e60f7627..b85278b8b5 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -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 ();
+}
+
+
+
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 60b3b309b9..92f2cc103d 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -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__ */
diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc
index 25fe144233..27b852982a 100644
--- a/gtk2_ardour/ardour_ui2.cc
+++ b/gtk2_ardour/ardour_ui2.cc
@@ -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
diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc
index bf096f86c1..9c6daa8952 100644
--- a/gtk2_ardour/ardour_ui_dependents.cc
+++ b/gtk2_ardour/ardour_ui_dependents.cc
@@ -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
diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc
index fe5963c535..a9a61176a9 100644
--- a/gtk2_ardour/ardour_ui_dialogs.cc
+++ b/gtk2_ardour/ardour_ui_dialogs.cc
@@ -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)
{
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index d1931a22d5..df2fda78c9 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -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;
diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc
index 707d3109f7..d0f523481f 100644
--- a/gtk2_ardour/ardour_ui_options.cc
+++ b/gtk2_ardour/ardour_ui_options.cc
@@ -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
diff --git a/gtk2_ardour/arprof b/gtk2_ardour/arprof
index 8af65b5fe3..05a469cb17 100755
--- a/gtk2_ardour/arprof
+++ b/gtk2_ardour/arprof
@@ -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 $*
diff --git a/gtk2_ardour/arval b/gtk2_ardour/arval
index a1dc501d3f..920e7cb1a8 100755
--- a/gtk2_ardour/arval
+++ b/gtk2_ardour/arval
@@ -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 $*
diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc
index 4ec8c1b89f..7ad7e4df65 100644
--- a/gtk2_ardour/audio_clock.cc
+++ b/gtk2_ardour/audio_clock.cc
@@ -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:
diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h
index e0431ba16e..662cb949e6 100644
--- a/gtk2_ardour/audio_clock.h
+++ b/gtk2_ardour/audio_clock.h
@@ -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;
diff --git a/gtk2_ardour/audio_region_editor.cc b/gtk2_ardour/audio_region_editor.cc
index c5645d479c..b7106a0796 100644
--- a/gtk2_ardour/audio_region_editor.cc
+++ b/gtk2_ardour/audio_region_editor.cc
@@ -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();
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 6543907bc8..e91dd529e3 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -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)
{
diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h
index 977c0e3aae..1d51cb7172 100644
--- a/gtk2_ardour/audio_region_view.h
+++ b/gtk2_ardour/audio_region_view.h
@@ -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;
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index bef35c572c..14b93c7182 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -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 ()
{
diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h
index 79aef2c042..ba0767a5e4 100644
--- a/gtk2_ardour/audio_streamview.h
+++ b/gtk2_ardour/audio_streamview.h
@@ -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__ */
diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc
index 7f6bc50222..11d151fb91 100644
--- a/gtk2_ardour/audio_time_axis.cc
+++ b/gtk2_ardour/audio_time_axis.cc
@@ -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,7 +337,7 @@ AudioTimeAxisView::set_waveform_shape (WaveformShape shape)
{
AudioStreamView* asv = audio_view();
- if (asv) {
+ if (asv && !ignore_toggle) {
asv->set_waveform_shape (shape);
}
@@ -318,6 +345,18 @@ AudioTimeAxisView::set_waveform_shape (WaveformShape shape)
}
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 ()
{
XMLProperty* prop;
diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h
index 2162771285..95bd8c0955 100644
--- a/gtk2_ardour/audio_time_axis.h
+++ b/gtk2_ardour/audio_time_axis.h
@@ -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;
};
diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc
index 44c100fd37..1dc62f1f42 100644
--- a/gtk2_ardour/automation_line.cc
+++ b/gtk2_ardour/automation_line.cc
@@ -21,6 +21,7 @@
#include <cmath>
#include <climits>
#include <vector>
+#include <fstream>
#include <pbd/stl_delete.h>
#include <pbd/memento_command.h>
@@ -348,13 +349,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)
{
double delta = 0.0;
@@ -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.
*/
@@ -567,98 +553,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)
{
uint32_t view_index, pi, n;
@@ -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
diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h
index b73a1c548a..1349efac4b 100644
--- a/gtk2_ardour/automation_line.h
+++ b/gtk2_ardour/automation_line.h
@@ -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 ();
diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc
index 2efb621b37..776dff37f2 100644
--- a/gtk2_ardour/automation_time_axis.cc
+++ b/gtk2_ardour/automation_time_axis.cc
@@ -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());
}
diff --git a/gtk2_ardour/automation_time_axis.h b/gtk2_ardour/automation_time_axis.h
index 30fa71bea9..0eb525f6c1 100644
--- a/gtk2_ardour/automation_time_axis.h
+++ b/gtk2_ardour/automation_time_axis.h
@@ -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__ */
diff --git a/gtk2_ardour/canvas-waveview.c b/gtk2_ardour/canvas-waveview.c
index 080f6871fa..747761ea9a 100644
--- a/gtk2_ardour/canvas-waveview.c
+++ b/gtk2_ardour/canvas-waveview.c
@@ -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;
diff --git a/gtk2_ardour/canvas-waveview.h b/gtk2_ardour/canvas-waveview.h
index 75281f69eb..81cf35910e 100644
--- a/gtk2_ardour/canvas-waveview.h
+++ b/gtk2_ardour/canvas-waveview.h
@@ -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().
diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc
index 6032bfa561..cf1994eb06 100644
--- a/gtk2_ardour/crossfade_edit.cc
+++ b/gtk2_ardour/crossfade_edit.cc
@@ -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) {
diff --git a/gtk2_ardour/crossfade_view.cc b/gtk2_ardour/crossfade_view.cc
index 42a1a47227..7567b04282 100644
--- a/gtk2_ardour/crossfade_view.cc
+++ b/gtk2_ardour/crossfade_view.cc
@@ -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;
}
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index bb87204916..3c1c89f927 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -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);
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 9a18516588..63f8adaf48 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -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;
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index a55aee6232..f99a828203 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -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);
}
}
}
@@ -979,6 +966,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 ()
{
ActionManager::toggle_config_state ("Editor", "toggle-auto-xfades", &Configuration::set_auto_xfade, &Configuration::get_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
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 426ff57a2a..48edb52756 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -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"));
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 07fe56573d..973598561a 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -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 {
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index 249a65ae01..4e0d6d5fe3 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -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));
diff --git a/gtk2_ardour/editor_edit_groups.cc b/gtk2_ardour/editor_edit_groups.cc
index 8df76fef25..2ee1773646 100644
--- a/gtk2_ardour/editor_edit_groups.cc
+++ b/gtk2_ardour/editor_edit_groups.cc
@@ -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;
}
diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc
index 4526862f79..43977f1577 100644
--- a/gtk2_ardour/editor_export_audio.cc
+++ b/gtk2_ardour/editor_export_audio.cc
@@ -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;
diff --git a/gtk2_ardour/editor_imageframe.cc b/gtk2_ardour/editor_imageframe.cc
index adb64125fc..a2606175df 100644
--- a/gtk2_ardour/editor_imageframe.cc
+++ b/gtk2_ardour/editor_imageframe.cc
@@ -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
diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc
index 6da479bafe..238a45c4d1 100644
--- a/gtk2_ardour/editor_markers.cc
+++ b/gtk2_ardour/editor_markers.cc
@@ -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());
@@ -527,26 +543,6 @@ Editor::build_new_transport_marker_menu ()
}
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 ()
{
Marker* marker;
@@ -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 ()
{
diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc
index 8b100afae5..8139e91ca7 100644
--- a/gtk2_ardour/editor_mixer.cc
+++ b/gtk2_ardour/editor_mixer.cc
@@ -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) {
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 76357070a7..fc76c6a43c 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -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
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 93e90f4c2c..ea4848b882 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -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;
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index b30a3092ec..bc95cb0d14 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -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 */
diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc
index 06bf7da625..216e3a8e1b 100644
--- a/gtk2_ardour/editor_route_list.cc
+++ b/gtk2_ardour/editor_route_list.cc
@@ -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
diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc
index 9834ce16db..bc2328b524 100644
--- a/gtk2_ardour/editor_rulers.cc
+++ b/gtk2_ardour/editor_rulers.cc
@@ -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;
diff --git a/gtk2_ardour/editor_selection_list.cc b/gtk2_ardour/editor_selection_list.cc
index 959da1ad2d..8e88ee497b 100644
--- a/gtk2_ardour/editor_selection_list.cc
+++ b/gtk2_ardour/editor_selection_list.cc
@@ -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) {
diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc
index 188960c962..bfc5ee85cd 100644
--- a/gtk2_ardour/editor_timefx.cc
+++ b/gtk2_ardour/editor_timefx.cc
@@ -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(); ) {
diff --git a/gtk2_ardour/editor_xpms b/gtk2_ardour/editor_xpms
index cb63e2403a..95a51a8213 100644
--- a/gtk2_ardour/editor_xpms
+++ b/gtk2_ardour/editor_xpms
@@ -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
index 0000000000..68b2751ffb
--- /dev/null
+++ b/gtk2_ardour/enums.cc
@@ -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);
+}
diff --git a/gtk2_ardour/enums.h b/gtk2_ardour/enums.h
index 15ba874366..987c49fe06 100644
--- a/gtk2_ardour/enums.h
+++ b/gtk2_ardour/enums.h
@@ -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__ */
diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc
index 5a269ffbef..921e6776aa 100644
--- a/gtk2_ardour/export_dialog.cc
+++ b/gtk2_ardour/export_dialog.cc
@@ -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);
diff --git a/gtk2_ardour/fft_graph.cc b/gtk2_ardour/fft_graph.cc
index 5d2f383a80..e7a0fd75b6 100644
--- a/gtk2_ardour/fft_graph.cc
+++ b/gtk2_ardour/fft_graph.cc
@@ -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);
}
diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc
index fc8e183d96..cedded1d9b 100644
--- a/gtk2_ardour/gain_meter.cc
+++ b/gtk2_ardour/gain_meter.cc
@@ -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);
}
diff --git a/gtk2_ardour/gain_meter.h b/gtk2_ardour/gain_meter.h
index bbc12ccb6c..88105ce846 100644
--- a/gtk2_ardour/gain_meter.h
+++ b/gtk2_ardour/gain_meter.h
@@ -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
index 0000000000..7f21711d4b
--- /dev/null
+++ b/gtk2_ardour/icons/ardour_icon_16px.png
Binary files differ
diff --git a/gtk2_ardour/icons/ardour_icon_22px.png b/gtk2_ardour/icons/ardour_icon_22px.png
new file mode 100644
index 0000000000..bdf723edbd
--- /dev/null
+++ b/gtk2_ardour/icons/ardour_icon_22px.png
Binary files differ
diff --git a/gtk2_ardour/icons/ardour_icon_32px.png b/gtk2_ardour/icons/ardour_icon_32px.png
new file mode 100644
index 0000000000..d906f35d68
--- /dev/null
+++ b/gtk2_ardour/icons/ardour_icon_32px.png
Binary files differ
diff --git a/gtk2_ardour/icons/ardour_icon_48px.png b/gtk2_ardour/icons/ardour_icon_48px.png
new file mode 100644
index 0000000000..298a56556a
--- /dev/null
+++ b/gtk2_ardour/icons/ardour_icon_48px.png
Binary files differ
diff --git a/gtk2_ardour/icons/fader_belt.png b/gtk2_ardour/icons/fader_belt.png
new file mode 100644
index 0000000000..eefed15c76
--- /dev/null
+++ b/gtk2_ardour/icons/fader_belt.png
Binary files differ
diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc
index 366e2c2769..00d24287ed 100644
--- a/gtk2_ardour/io_selector.cc
+++ b/gtk2_ardour/io_selector.cc
@@ -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) {
diff --git a/gtk2_ardour/ladspa_pluginui.cc b/gtk2_ardour/ladspa_pluginui.cc
index 9465b12c23..51fc20c457 100644
--- a/gtk2_ardour/ladspa_pluginui.cc
+++ b/gtk2_ardour/ladspa_pluginui.cc
@@ -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
diff --git a/gtk2_ardour/location_ui.cc b/gtk2_ardour/location_ui.cc
index 13dd95b47d..b77c3a5561 100644
--- a/gtk2_ardour/location_ui.cc
+++ b/gtk2_ardour/location_ui.cc
@@ -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);
diff --git a/gtk2_ardour/logmeter.h b/gtk2_ardour/logmeter.h
index f7ed1dd2be..8d9f0b9d82 100644
--- a/gtk2_ardour/logmeter.h
+++ b/gtk2_ardour/logmeter.h
@@ -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);
}
diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc
index a1d85cdb69..51a29bbb17 100644
--- a/gtk2_ardour/main.cc
+++ b/gtk2_ardour/main.cc
@@ -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);
diff --git a/gtk2_ardour/meter_bridge.cc b/gtk2_ardour/meter_bridge.cc
index b871561563..0e88eff5e0 100644
--- a/gtk2_ardour/meter_bridge.cc
+++ b/gtk2_ardour/meter_bridge.cc
@@ -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)));
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 289fb45536..edc66c92bb 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -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 ();
}
diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h
index 92da4c13fe..430f774eb6 100644
--- a/gtk2_ardour/mixer_strip.h
+++ b/gtk2_ardour/mixer_strip.h
@@ -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 ();
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc
index d8e5fc6988..f20171f9fb 100644
--- a/gtk2_ardour/mixer_ui.cc
+++ b/gtk2_ardour/mixer_ui.cc
@@ -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;
}
diff --git a/gtk2_ardour/new_session_dialog.cc b/gtk2_ardour/new_session_dialog.cc
index 4c486eaaf8..9e094c9ad0 100644
--- a/gtk2_ardour/new_session_dialog.cc
+++ b/gtk2_ardour/new_session_dialog.cc
@@ -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"));
diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc
index 3e461a85d7..1c76f8079b 100644
--- a/gtk2_ardour/option_editor.cc
+++ b/gtk2_ardour/option_editor.cc
@@ -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,24 +222,10 @@ 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 ()
{
click_path_entry.set_sensitive (true);
@@ -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);
}
}
}
diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h
index 2076da3935..cc28a74e60 100644
--- a/gtk2_ardour/option_editor.h
+++ b/gtk2_ardour/option_editor.h
@@ -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 */
diff --git a/gtk2_ardour/opts.cc b/gtk2_ardour/opts.cc
index fcd62de512..792fde3a10 100644
--- a/gtk2_ardour/opts.cc
+++ b/gtk2_ardour/opts.cc
@@ -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);
}
diff --git a/gtk2_ardour/opts.h b/gtk2_ardour/opts.h
index 0516c3aa98..710621ac65 100644
--- a/gtk2_ardour/opts.h
+++ b/gtk2_ardour/opts.h
@@ -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
index 0000000000..bb9b432184
--- /dev/null
+++ b/gtk2_ardour/panner.cc
@@ -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
index 0000000000..d06a4c21e3
--- /dev/null
+++ b/gtk2_ardour/panner.h
@@ -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__ */
diff --git a/gtk2_ardour/panner2d.cc b/gtk2_ardour/panner2d.cc
index 1fb94a1321..1e6e4c16c9 100644
--- a/gtk2_ardour/panner2d.cc
+++ b/gtk2_ardour/panner2d.cc
@@ -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
diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc
index 250f1e146e..af5379b40f 100644
--- a/gtk2_ardour/panner_ui.cc
+++ b/gtk2_ardour/panner_ui.cc
@@ -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;
diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h
index 7658978233..79a8085488 100644
--- a/gtk2_ardour/panner_ui.h
+++ b/gtk2_ardour/panner_ui.h
@@ -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);
diff --git a/gtk2_ardour/pixmaps/SConscript b/gtk2_ardour/pixmaps/SConscript
index c532d3551a..194031c44f 100644
--- a/gtk2_ardour/pixmaps/SConscript
+++ b/gtk2_ardour/pixmaps/SConscript
@@ -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))
diff --git a/gtk2_ardour/playlist_selection.h b/gtk2_ardour/playlist_selection.h
index af0031fec9..813f8a9211 100644
--- a/gtk2_ardour/playlist_selection.h
+++ b/gtk2_ardour/playlist_selection.h
@@ -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__ */
diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc
index ffeaf8f5e9..d02c5a88de 100644
--- a/gtk2_ardour/playlist_selector.cc
+++ b/gtk2_ardour/playlist_selector.cc
@@ -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;
}
diff --git a/gtk2_ardour/playlist_selector.h b/gtk2_ardour/playlist_selector.h
index 2829ba54bb..071f82c616 100644
--- a/gtk2_ardour/playlist_selector.h
+++ b/gtk2_ardour/playlist_selector.h
@@ -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;
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index 56b9e34d35..26f38250a5 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -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)));
diff --git a/gtk2_ardour/po/de_DE.po b/gtk2_ardour/po/de_DE.po
index edd8394611..f8ac19f833 100644
--- a/gtk2_ardour/po/de_DE.po
+++ b/gtk2_ardour/po/de_DE.po
@@ -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)"
-#: actions.cc:261
+#: 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"
+
+#: 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"
+msgstr "Kanaleinstellungen"
-#: 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"
-
-#. 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"
+msgstr "Konnte die aktuelle Sitzung nicht starten"
-#: ardour_ui.cc:1426
-msgid "No Stream"
-msgstr "Kein Datenstrom"
-
-#: 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?"
+
+#: gtk2_ardour/ardour_ui.cc:1713
+#, fuzzy
+msgid "existing_session"
+msgstr "Stellen"
-#: ardour_ui.cc:1809
+#: 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 ""
+msgstr "Zum Ende Springen"
-#. 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 ""
-
-#: ardour_ui_ed.cc:275
-msgid ""
-"Punch\n"
-"out"
-msgstr ""
+#: gtk2_ardour/ardour_ui_ed.cc:287
+msgid "Auto Play"
+msgstr "Auto Play"
-#: ardour_ui_ed.cc:278 option_editor.cc:129
-msgid "Click"
-msgstr ""
+#: gtk2_ardour/ardour_ui_ed.cc:294
+msgid "Sync startup to video"
+msgstr "Mit Video synchronisieren"
-#: ardour_ui_ed.cc:281
-#, fuzzy
-msgid ""
-"Auto\n"
-"input"
-msgstr "Port hinzufügen"
+#: gtk2_ardour/ardour_ui_ed.cc:295
+msgid "Time master"
+msgstr "Time Master"
-#: ardour_ui_ed.cc:284
-msgid ""
-"Auto\n"
-"play"
-msgstr ""
-
-#: ardour_ui_ed.cc:287
-msgid ""
-"Auto\n"
-"return"
-msgstr ""
-
-#: ardour_ui_ed.cc:291
-msgid ""
-"Time\n"
-"master"
-msgstr ""
-
-#: 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 ""
+msgstr "Plugins"
-#: audio_time_axis.cc:747
-#, fuzzy
-msgid "Show waveforms"
-msgstr "Wellenform zeigen"
-
-#: 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"
-#: 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:458
+msgid "Normal mode"
+msgstr "Normaler Modus"
+
+#: 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"
+#: 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: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 ""
-
-#: 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"
-
-#: 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
+#: gtk2_ardour/editor.cc:1466
+#: gtk2_ardour/editor.cc:1474
msgid "Freeze"
-msgstr ""
+msgstr "Einfrieren"
-#: 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"
-#: editor.cc:1907
+#: gtk2_ardour/editor.cc:1795
+#: gtk2_ardour/editor.cc:1959
+#: gtk2_ardour/editor.cc:2015
+msgid "Nudge"
+msgstr "Verschieben"
+
+#: 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"
+msgstr "Spur auffüllen"
-#: editor.cc:1924
-msgid "Destroy"
-msgstr ""
-
-#: 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"
+
+#: gtk2_ardour/editor.cc:1917
+#: gtk2_ardour/editor.cc:1993
+msgid "Select"
+msgstr "Auswahl"
-#. standard editing stuff
-#: editor.cc:2032 editor.cc:2108 editor.cc:3483 editor_actions.cc:214
-#: redirect_box.cc:1060
+#: 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 ""
+
+#: gtk2_ardour/editor.cc:2623
+msgid "Zoom focus"
+msgstr "Zoom-Mittelpunkt"
-#: editor.cc:2747
-msgid "End:"
-msgstr "Ende:"
+#: 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 ""
-"Sie können keine Audio-Daten importieren, solange keine Sitzung geladen ist."
-#: editor_audio_import.cc:77
+#: 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 ""
+
+#: 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."
+
+#: gtk2_ardour/main.cc:316
+msgid "could not load command line session \"%1\""
+msgstr "Konnte die per Kommandozeile übergebene Sitzung nicht laden: \"%1\""
-#: main.cc:335
+#: 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"
+msgstr "Aufnahme"
-#: mixer_strip.cc:418 region_editor.cc:47
-msgid "mute"
-msgstr "mute"
-
-#: mixer_strip.cc:419
-msgid "solo"
-msgstr "solo"
-
-#: 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 ""
-
-#: new_session_dialog.cc:55
-#, fuzzy
-msgid "Automatically Connect Inputs"
-msgstr "Verfügbare Verbindungen"
+msgstr "Master Bus erstellen"
-#: new_session_dialog.cc:56 new_session_dialog.cc:67
-#, fuzzy
-msgid "Port Limit"
-msgstr "Abbrechen"
+#: 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: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 ""
-
-#: new_session_dialog.cc:76
-msgid "Connect to Physical Outputs"
-msgstr ""
+#: gtk2_ardour/new_session_dialog.cc:105
+msgid "... to Master Bus"
+msgstr "... mit Master Bus"
-#: new_session_dialog.cc:80
-#, fuzzy
-msgid "<b>Track/Bus Outputs</b>"
-msgstr "Ausgänge"
+#: gtk2_ardour/new_session_dialog.cc:106
+msgid "... to Physical Outputs"
+msgstr "... mit Soundkartenausgängen"
-#: 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 ""
+msgstr "MIDI"
-#: option_editor.cc:177
-msgid "24 FPS"
-msgstr ""
-
-#: 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 ""
+msgstr "L"
-#: panner_ui.cc:335
+#: gtk2_ardour/panner_ui.cc:328
#, c-format
-msgid "panner for channel %lu"
-msgstr ""
-
-#: panner_ui.cc:337
-#, 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"
+msgstr "Alle 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 ""
-
-#: 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 ""
-
-#: region_editor.cc:193 region_editor.cc:227
-msgid "msecs"
-msgstr ""
-
-#: region_editor.cc:225
-msgid "FADE OUT"
-msgstr ""
+msgstr "LÄNGE:"
-#: 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"
-#: region_editor.cc:414
+#: gtk2_ardour/audio_region_editor.cc:219
#, fuzzy
-msgid "fade out edit"
+msgid "change region end position"
+msgstr "Regionen"
+
+#: gtk2_ardour/audio_region_editor.cc:240
+#, fuzzy
+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"
+
+#: gtk2_ardour/sfdb_ui.cc:151
+#, fuzzy
+msgid "Timecode: %1"
+msgstr "Timecode"
-#: sfdb_ui.cc:161
+#: 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 ""
-
-#: sfdb_ui.cc:414
-msgid "programming error: %1"
-msgstr ""
+msgstr "Kopiert eine Datei in das Verzeichnis der Sitzung"
-#: 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"
diff --git a/gtk2_ardour/po/sv_SE.po b/gtk2_ardour/po/sv_SE.po
index 6dbef3b7eb..107e3d36ad 100644
--- a/gtk2_ardour/po/sv_SE.po
+++ b/gtk2_ardour/po/sv_SE.po
@@ -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"
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index 6039e089e9..8f307f61f2 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -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;
diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc
index f2ee2a5b8f..fac6ede6f3 100644
--- a/gtk2_ardour/redirect_box.cc
+++ b/gtk2_ardour/redirect_box.cc
@@ -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().
@@ -156,6 +158,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)
{
if (type != "redirects" || cnt == 0 || !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
diff --git a/gtk2_ardour/redirect_box.h b/gtk2_ardour/redirect_box.h
index 27ba950899..7ab7d03cac 100644
--- a/gtk2_ardour/redirect_box.h
+++ b/gtk2_ardour/redirect_box.h
@@ -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);
};
diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc
index 3374d44655..1241a1b3a7 100644
--- a/gtk2_ardour/region_gain_line.cc
+++ b/gtk2_ardour/region_gain_line.cc
@@ -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);
diff --git a/gtk2_ardour/region_gain_line.h b/gtk2_ardour/region_gain_line.h
index 3781fe60bb..e98627f814 100644
--- a/gtk2_ardour/region_gain_line.h
+++ b/gtk2_ardour/region_gain_line.h
@@ -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&);
diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc
index 49e7872f49..a9315bb76f 100644
--- a/gtk2_ardour/region_view.cc
+++ b/gtk2_ardour/region_view.cc
@@ -367,7 +367,7 @@ void
RegionView::set_frame_color ()
{
if (_region->opaque()) {
- fill_opacity = 180;
+ fill_opacity = 230;
} else {
fill_opacity = 100;
}
diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc
index 5f61b0528c..14d9fa02cb 100644
--- a/gtk2_ardour/route_params_ui.cc
+++ b/gtk2_ardour/route_params_ui.cc
@@ -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());
}
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 7195c83a99..9684f74024 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -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);
}
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index cefe954c9a..c597f2893c 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -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__ */
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 851c45aaa0..070ad42037 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -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 */
}
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index 06475aa1d4..38a0cdd8e2 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -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);
diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h
index c4336fba21..a2997cd7b5 100644
--- a/gtk2_ardour/selection.h
+++ b/gtk2_ardour/selection.h
@@ -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);
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index c4d6d7edfc..5d3be0399b 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -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,16 +15,17 @@
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,57 +238,22 @@ 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)
{
ENSURE_GUI_THREAD(bind (mem_fun (*this, &SoundFileBox::audition_status_changed), 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
diff --git a/gtk2_ardour/sfdb_ui.h b/gtk2_ardour/sfdb_ui.h
index d7c2c14014..fb0b7da600 100644
--- a/gtk2_ardour/sfdb_ui.h
+++ b/gtk2_ardour/sfdb_ui.h
@@ -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__
@@ -30,14 +28,12 @@
#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>
@@ -48,117 +44,118 @@
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__
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index ce0b6a4250..53a0ee4553 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -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;
+}
diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h
index 0ba4dc1938..96437a9991 100644
--- a/gtk2_ardour/time_axis_view.h
+++ b/gtk2_ardour/time_axis_view.h
@@ -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&);
diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc
index b23e7972ae..6af38deaee 100644
--- a/gtk2_ardour/time_axis_view_item.cc
+++ b/gtk2_ardour/time_axis_view_item.cc
@@ -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 ;
diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc
index 4d7c133770..887494829e 100644
--- a/gtk2_ardour/utils.cc
+++ b/gtk2_ardour/utils.cc
@@ -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;
+}
+
diff --git a/gtk2_ardour/utils.h b/gtk2_ardour/utils.h
index bb2a21d6c3..6d5ff0702d 100644
--- a/gtk2_ardour/utils.h
+++ b/gtk2_ardour/utils.h
@@ -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__ */
diff --git a/gtk2_ardour/visual_time_axis.cc b/gtk2_ardour/visual_time_axis.cc
index 24cafdbe67..20fe13603e 100644
--- a/gtk2_ardour/visual_time_axis.cc
+++ b/gtk2_ardour/visual_time_axis.cc
@@ -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);
}
}
diff --git a/gtk2_ardour/waveview.cc b/gtk2_ardour/waveview.cc
index 05cc97701d..92e4fdd24a 100644
--- a/gtk2_ardour/waveview.cc
+++ b/gtk2_ardour/waveview.cc
@@ -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
diff --git a/gtk2_ardour/waveview.h b/gtk2_ardour/waveview.h
index 15efbbcef5..56d0ed7675 100644
--- a/gtk2_ardour/waveview.h
+++ b/gtk2_ardour/waveview.h
@@ -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 */
diff --git a/libs/appleutility/SConscript b/libs/appleutility/SConscript
index c8bab03a87..68b731c78e 100644
--- a/libs/appleutility/SConscript
+++ b/libs/appleutility/SConscript
@@ -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') ))
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 98a1b362bb..68d9112caf 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -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'], []))
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 4a95e094a9..1da8903a41 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -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 */
diff --git a/libs/ardour/ardour/audio_library.h b/libs/ardour/ardour/audio_library.h
index f5ac6da654..8c01f0e3dc 100644
--- a/libs/ardour/ardour/audio_library.h
+++ b/libs/ardour/ardour/audio_library.h
@@ -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__
@@ -26,64 +24,30 @@
#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;
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 207e3c6428..3dbd30f841 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -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;
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
index bd609a7d80..c1dc7d1e93 100644
--- a/libs/ardour/ardour/audiofilesource.h
+++ b/libs/ardour/ardour/audiofilesource.h
@@ -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();
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
index 383ec73531..c0d5ed6e75 100644
--- a/libs/ardour/ardour/audioplaylist.h
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -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;
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index 2ada255236..0734a66319 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -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 {
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
index e5c194e683..a2cfb23e61 100644
--- a/libs/ardour/ardour/automation_event.h
+++ b/libs/ardour/ardour/automation_event.h
@@ -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;
diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h
index 8044190066..c520477c55 100644
--- a/libs/ardour/ardour/configuration_vars.h
+++ b/libs/ardour/ardour/configuration_vars.h
@@ -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)
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
index d29ba47056..0422698c5e 100644
--- a/libs/ardour/ardour/crossfade.h
+++ b/libs/ardour/ardour/crossfade.h
@@ -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&);
diff --git a/libs/ardour/ardour/cycles.h b/libs/ardour/ardour/cycles.h
index ad3e512669..a6f34d59be 100644
--- a/libs/ardour/ardour/cycles.h
+++ b/libs/ardour/ardour/cycles.h
@@ -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;
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index eb6d936222..a81921b9f1 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -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 */
diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h
index 217fd89885..31e59e6704 100644
--- a/libs/ardour/ardour/insert.h
+++ b/libs/ardour/ardour/insert.h
@@ -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
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index f7e1993bb2..c4df46415b 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -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 */
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
index 94f70bb4e8..57e13de5af 100644
--- a/libs/ardour/ardour/location.h
+++ b/libs/ardour/ardour/location.h
@@ -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);
diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h
index f18a2e6de9..17379c3baa 100644
--- a/libs/ardour/ardour/meter.h
+++ b/libs/ardour/ardour/meter.h
@@ -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;
};
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index 583cc23de5..ee11b5e133 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -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 ();
diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h
index 6f89d23404..492241d6b5 100644
--- a/libs/ardour/ardour/midi_playlist.h
+++ b/libs/ardour/ardour/midi_playlist.h
@@ -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;
diff --git a/libs/ardour/ardour/named_selection.h b/libs/ardour/ardour/named_selection.h
index 87b71e73ff..fd5777ccf6 100644
--- a/libs/ardour/ardour/named_selection.h
+++ b/libs/ardour/ardour/named_selection.h
@@ -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);
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 831c9b3905..9893f7391a 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -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
index 0000000000..23aad3cd78
--- /dev/null
+++ b/libs/ardour/ardour/playlist_factory.h
@@ -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__ */
diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h
index 79ae4516c5..8c3de09c10 100644
--- a/libs/ardour/ardour/redirect.h
+++ b/libs/ardour/ardour/redirect.h
@@ -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;
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 88bb294e5d..46865d8357 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -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;
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 6bc37ee51e..2f94e0c80a 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -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.
diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h
index e9fad1aa2b..d87d3fa3a4 100644
--- a/libs/ardour/ardour/route_group.h
+++ b/libs/ardour/ardour/route_group.h
@@ -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*);
};
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h
index 12a0cba3ec..eceb301bf8 100644
--- a/libs/ardour/ardour/send.h
+++ b/libs/ardour/ardour/send.h
@@ -33,12 +33,15 @@
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
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 039bf92362..1c1ea9e62c 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -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 *);
diff --git a/libs/ardour/ardour/session_playlist.h b/libs/ardour/ardour/session_playlist.h
index 6f1b8dbd12..20cf4d8f2e 100644
--- a/libs/ardour/ardour/session_playlist.h
+++ b/libs/ardour/ardour/session_playlist.h
@@ -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++) {
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index e94b1af54f..8eaab14ec5 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -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;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index d7a2da2f46..eee04d9bfa 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -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;
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 1138b5208f..30cdcd8232 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -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;
diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h
index d926f52f82..de97a5c150 100644
--- a/libs/ardour/ardour/utils.h
+++ b/libs/ardour/ardour/utils.h
@@ -34,10 +34,9 @@
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)
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 9c5f5233b7..7165a58b27 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -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>
@@ -96,34 +98,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)
{
Diskstream::init(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;
+ }
+}
diff --git a/libs/ardour/audio_library.cc b/libs/ardour/audio_library.cc
index 3aa6d05be1..2ed4739a96 100644
--- a/libs/ardour/audio_library.cc
+++ b/libs/ardour/audio_library.cc
@@ -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,25 +15,16 @@
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>
@@ -42,16 +32,11 @@
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,23 +44,6 @@ 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 ()
@@ -83,56 +51,96 @@ 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;
-}
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 335cb020ae..91bed1a4fa 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -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(); ) {
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index f2681aceba..b0ac7a4bd7 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -17,11 +17,14 @@
$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;
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index b0cd64c8d1..be070c74e6 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -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;
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 16cb990ec2..af41094748 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -22,12 +22,14 @@
#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);
+}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 939f9c02dd..8b533deda3 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -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 */
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index 93165b7fe4..203590a4e1 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -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;
}
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 34cf5637b6..7bbc4cd0ba 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -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 ("");
}
}
}
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index 5cc2f50e38..af6fffdeb9 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -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,9 +521,18 @@ 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 ();
}
@@ -522,6 +540,25 @@ AutomationList::move_range (iterator start, iterator end, double xdelta, double
}
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)
{
/* note: we assume higher level logic is in place to avoid this
@@ -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;
}
diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc
index e84e92fa26..eb3d879447 100644
--- a/libs/ardour/configuration.cc
+++ b/libs/ardour/configuration.cc
@@ -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);
}
}
diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc
index a715254747..de177d0e3d 100644
--- a/libs/ardour/control_protocol_manager.cc
+++ b/libs/ardour/control_protocol_manager.cc
@@ -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
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index 739ea1cc0e..fd2fced83c 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -759,7 +759,7 @@ Crossfade::set_state (const XMLNode& node)
/* fade out */
- _fade_in.freeze ();
+ _fade_out.freeze ();
_fade_out.clear ();
children = fo->children();
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 5f6f3956cf..09c5b75b86 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -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
index 0000000000..0460df43d8
--- /dev/null
+++ b/libs/ardour/enums.cc
@@ -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);
+
+}
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index f92660470c..515d9e1c2f 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -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); }
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index f16a6e7d8c..4466c40a32 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -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))));
}
}
diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc
index 034b043763..d109642fd4 100644
--- a/libs/ardour/insert.cc
+++ b/libs/ardour/insert.cc
@@ -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);
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 60e7ec3f42..7ed6158b85 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -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();
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index e09a59d42f..bec87e5dd6 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -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) {
@@ -404,6 +404,40 @@ Locations::set_current (Location *loc, bool want_lock)
}
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)
{
if (find (locations.begin(), locations.end(), loc) == locations.end()) {
diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc
index 1ce610d13c..66e0a98dd3 100644
--- a/libs/ardour/meter.cc
+++ b/libs/ardour/meter.cc
@@ -57,6 +57,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)
{
uint32_t limit = in.get(DataType::AUDIO);
@@ -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 {
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index b1ec7da965..f3de214791 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -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) {
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index b2318bbe96..0352e1e910 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -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) */
diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc
index f4d1912061..d7ce12d411 100644
--- a/libs/ardour/midi_port.cc
+++ b/libs/ardour/midi_port.cc
@@ -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());
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index a18d0c20ce..26441203a3 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -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;
}
diff --git a/libs/ardour/named_selection.cc b/libs/ardour/named_selection.cc
index 605d7cae13..ecce09692f 100644
--- a/libs/ardour/named_selection.cc
+++ b/libs/ardour/named_selection.cc
@@ -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());
diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc
index ee8e100e4a..c69bd84402 100644
--- a/libs/ardour/panner.cc
+++ b/libs/ardour/panner.cc
@@ -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();
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index d439cf1265..2becdc19b4 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -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;
diff --git a/libs/ardour/playlist_factory.cc b/libs/ardour/playlist_factory.cc
index 4461783874..862f85a402 100644
--- a/libs/ardour/playlist_factory.cc
+++ b/libs/ardour/playlist_factory.cc
@@ -22,24 +22,91 @@
#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;
}
diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc
index b24b2619d3..09da4c9ca7 100644
--- a/libs/ardour/plugin_manager.cc
+++ b/libs/ardour/plugin_manager.cc
@@ -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;
}
diff --git a/libs/ardour/redirect.cc b/libs/ardour/redirect.cc
index adad79e2a3..dbdd3d1ddd 100644
--- a/libs/ardour/redirect.cc
+++ b/libs/ardour/redirect.cc
@@ -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;
}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 6d8c71b563..973e14fd31 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -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);
}
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 5314c99632..a2bc65407c 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -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);
}
diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc
index 5730623742..c2aa59ed8b 100644
--- a/libs/ardour/route_group.cc
+++ b/libs/ardour/route_group.cc
@@ -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 ();
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 73dbf11ad5..0141007803 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -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) */
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 1b7c3be6dd..6ad8f7dbd2 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -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 ();
}
@@ -402,6 +406,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;
}
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index 832284901c..bb02eede91 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -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 ()
{
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
index 5816f1c6b7..9d054c22fd 100644
--- a/libs/ardour/session_command.cc
+++ b/libs/ardour/session_command.cc
@@ -11,18 +11,22 @@
#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;
+}
diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc
index dc7eabf40f..981f9505d9 100644
--- a/libs/ardour/session_events.cc
+++ b/libs/ardour/session_events.cc
@@ -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]);
diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc
index b3a5ec6e01..18bf9b83e1 100644
--- a/libs/ardour/session_midi.cc
+++ b/libs/ardour/session_midi.cc
@@ -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 */ );
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index c877abdca4..2de3448cd1 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -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 ();
}
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index bcc9b730ba..097a9e2381 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -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;
@@ -2866,6 +2902,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)
{
Glib::Mutex::Lock lm (controllables_lock);
@@ -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 ();
diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc
index d24bab5ff8..585dad6b1a 100644
--- a/libs/ardour/session_time.cc
+++ b/libs/ardour/session_time.cc
@@ -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;
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index e9c4e3785f..ad3573a72e 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -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 */
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 6fb71e9596..aca8cf5a25 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -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)
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index a30bfcf49b..8e90eac6ab 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -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;
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 8f0afd3507..db2147493a 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -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);
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index 001af609dc..ad01bf6171 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -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> ();
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index 0ff94324bb..e86c30dd4d 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -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 ;
- */
+ ******************************/
+
}
diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc
index 9c94d32241..e0ef8fd0b3 100644
--- a/libs/ardour/utils.cc
+++ b/libs/ardour/utils.cc
@@ -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;
}
}
diff --git a/libs/clearlooks/SConscript b/libs/clearlooks/SConscript
index 0df20efe56..110bfe41be 100644
--- a/libs/clearlooks/SConscript
+++ b/libs/clearlooks/SConscript
@@ -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')
+ ))
diff --git a/libs/flowcanvas/SConscript b/libs/flowcanvas/SConscript
index 6394982a20..18b061ef82 100644
--- a/libs/flowcanvas/SConscript
+++ b/libs/flowcanvas/SConscript
@@ -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'] +
diff --git a/libs/fst/SConscript b/libs/fst/SConscript
index 771de86dc8..bdffd959b5 100644
--- a/libs/fst/SConscript
+++ b/libs/fst/SConscript
@@ -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',
diff --git a/libs/fst/fstinfofile.c b/libs/fst/fstinfofile.c
index 7cc98d2233..7b0c69d015 100644
--- a/libs/fst/fstinfofile.c
+++ b/libs/fst/fstinfofile.c
@@ -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" );
diff --git a/libs/glibmm2/SConscript b/libs/glibmm2/SConscript
index dbc58e6499..267f846203 100644
--- a/libs/glibmm2/SConscript
+++ b/libs/glibmm2/SConscript
@@ -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',
diff --git a/libs/gtkmm2/atk/SConscript b/libs/gtkmm2/atk/SConscript
index 884ac3cbb0..84a5e8251a 100644
--- a/libs/gtkmm2/atk/SConscript
+++ b/libs/gtkmm2/atk/SConscript
@@ -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'] +
diff --git a/libs/gtkmm2/gdk/SConscript b/libs/gtkmm2/gdk/SConscript
index 58f0ebb2e5..6ea5c7cfef 100644
--- a/libs/gtkmm2/gdk/SConscript
+++ b/libs/gtkmm2/gdk/SConscript
@@ -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'] +
diff --git a/libs/gtkmm2/gtk/SConscript b/libs/gtkmm2/gtk/SConscript
index 90e832b010..b4cd99f023 100644
--- a/libs/gtkmm2/gtk/SConscript
+++ b/libs/gtkmm2/gtk/SConscript
@@ -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'] +
diff --git a/libs/gtkmm2/pango/SConscript b/libs/gtkmm2/pango/SConscript
index 0ec62a0f02..d045cf2043 100644
--- a/libs/gtkmm2/pango/SConscript
+++ b/libs/gtkmm2/pango/SConscript
@@ -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'] +
diff --git a/libs/gtkmm2ext/SConscript b/libs/gtkmm2ext/SConscript
index e654b6cb52..9c7511c85d 100644
--- a/libs/gtkmm2ext/SConscript
+++ b/libs/gtkmm2ext/SConscript
@@ -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'] +
diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc
index 734c4b77e2..f59d192ff1 100644
--- a/libs/gtkmm2ext/barcontroller.cc
+++ b/libs/gtkmm2ext/barcontroller.cc
@@ -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
index 0000000000..dbe833d06b
--- /dev/null
+++ b/libs/gtkmm2ext/focus_entry.cc
@@ -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);
+}
+
diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
index ebce4e2de9..e5b8e31b58 100644
--- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
@@ -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
index 0000000000..5d9d7fdac7
--- /dev/null
+++ b/libs/gtkmm2ext/gtkmm2ext/focus_entry.h
@@ -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
index 0000000000..bb4176240a
--- /dev/null
+++ b/libs/gtkmm2ext/gtkmm2ext/pixfader.h
@@ -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__ */
diff --git a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
index f0f645eab7..c137dbabf5 100644
--- a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
@@ -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
index 0000000000..f3a40ffc69
--- /dev/null
+++ b/libs/gtkmm2ext/pixfader.cc
@@ -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));
+}
diff --git a/libs/gtkmm2ext/prompter.cc b/libs/gtkmm2ext/prompter.cc
index c3a04f19a8..d06204d356 100644
--- a/libs/gtkmm2ext/prompter.cc
+++ b/libs/gtkmm2ext/prompter.cc
@@ -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);
}
}
diff --git a/libs/gtkmm2ext/slider_controller.cc b/libs/gtkmm2ext/slider_controller.cc
index e524eba1cb..3e2b42f409 100644
--- a/libs/gtkmm2ext/slider_controller.cc
+++ b/libs/gtkmm2ext/slider_controller.cc
@@ -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"
@@ -28,13 +28,12 @@
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);
diff --git a/libs/gtkmm2ext/tearoff.cc b/libs/gtkmm2ext/tearoff.cc
index e4a9207195..92bde5541e 100644
--- a/libs/gtkmm2ext/tearoff.cc
+++ b/libs/gtkmm2ext/tearoff.cc
@@ -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;
diff --git a/libs/libglademm/SConscript b/libs/libglademm/SConscript
index 1ee6926580..0d22ba243f 100644
--- a/libs/libglademm/SConscript
+++ b/libs/libglademm/SConscript
@@ -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'] +
diff --git a/libs/libgnomecanvasmm/SConscript b/libs/libgnomecanvasmm/SConscript
index d9620dc378..7cab8b707a 100644
--- a/libs/libgnomecanvasmm/SConscript
+++ b/libs/libgnomecanvasmm/SConscript
@@ -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'] +
diff --git a/libs/libsndfile/SConscript b/libs/libsndfile/SConscript
index f8e9fc5ecb..9e8ccc93f7 100644
--- a/libs/libsndfile/SConscript
+++ b/libs/libsndfile/SConscript
@@ -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',
diff --git a/libs/libsndfile/configure b/libs/libsndfile/configure
index 8aaca4e783..bfa95c3aac 100755
--- a/libs/libsndfile/configure
+++ b/libs/libsndfile/configure
@@ -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"
diff --git a/libs/midi++2/SConscript b/libs/midi++2/SConscript
index 477d49c6ca..e9fbc0abf5 100644
--- a/libs/midi++2/SConscript
+++ b/libs/midi++2/SConscript
@@ -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 +
diff --git a/libs/midi++2/jack_midiport.cc b/libs/midi++2/jack_midiport.cc
index 4fc24e8711..2aad0e072d 100644
--- a/libs/midi++2/jack_midiport.cc
+++ b/libs/midi++2/jack_midiport.cc
@@ -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);
}
diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript
index f474834fd8..afb24a4311 100644
--- a/libs/pbd/SConscript
+++ b/libs/pbd/SConscript
@@ -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' ] +
diff --git a/libs/pbd/basename.cc b/libs/pbd/basename.cc
index a51e393b78..9beed93625 100644
--- a/libs/pbd/basename.cc
+++ b/libs/pbd/basename.cc
@@ -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 ('.'));
}
diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc
index 2264a955ae..049ad0aa21 100644
--- a/libs/pbd/controllable.cc
+++ b/libs/pbd/controllable.cc
@@ -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
index 0000000000..d36ecef58a
--- /dev/null
+++ b/libs/pbd/copyfile.cc
@@ -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
index 0000000000..7674410ec9
--- /dev/null
+++ b/libs/pbd/enumwriter.cc
@@ -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;
+}
diff --git a/libs/pbd/pbd/basename.h b/libs/pbd/pbd/basename.h
index a7e36acff0..a622643541 100644
--- a/libs/pbd/pbd/basename.h
+++ b/libs/pbd/pbd/basename.h
@@ -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
index 0000000000..8a1bf242bb
--- /dev/null
+++ b/libs/pbd/pbd/copyfile.h
@@ -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
index 0000000000..f53388f3cc
--- /dev/null
+++ b/libs/pbd/pbd/enumwriter.h
@@ -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)))
+
diff --git a/libs/pbd/pbd/tokenizer.h b/libs/pbd/pbd/tokenizer.h
index a976b79341..b80e3eac4a 100644
--- a/libs/pbd/pbd/tokenizer.h
+++ b/libs/pbd/pbd/tokenizer.h
@@ -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;
}
diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h
index eb46750e4f..4dfab5178f 100644
--- a/libs/pbd/pbd/undo.h
+++ b/libs/pbd/pbd/undo.h
@@ -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;
diff --git a/libs/pbd/pbd/whitespace.h b/libs/pbd/pbd/whitespace.h
index 6620a8fb50..6adb41641c 100644
--- a/libs/pbd/pbd/whitespace.h
+++ b/libs/pbd/pbd/whitespace.h
@@ -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__
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index 277b83bfce..4719d0968e 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -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;
diff --git a/libs/pbd/whitespace.cc b/libs/pbd/whitespace.cc
index 53616133ad..a719fb169f 100644
--- a/libs/pbd/whitespace.cc
+++ b/libs/pbd/whitespace.cc
@@ -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
diff --git a/libs/sigc++2/SConscript b/libs/sigc++2/SConscript
index 65833dfb53..b29aefb0cd 100644
--- a/libs/sigc++2/SConscript
+++ b/libs/sigc++2/SConscript
@@ -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',
diff --git a/libs/soundtouch/SConscript b/libs/soundtouch/SConscript
index d37fd1f99b..9ddee87b0c 100644
--- a/libs/soundtouch/SConscript
+++ b/libs/soundtouch/SConscript
@@ -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')))
diff --git a/libs/soundtouch/STTypes.h b/libs/soundtouch/STTypes.h
index c404675ecd..e1ea90d428 100644
--- a/libs/soundtouch/STTypes.h
+++ b/libs/soundtouch/STTypes.h
@@ -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_
diff --git a/libs/surfaces/control_protocol/SConscript b/libs/surfaces/control_protocol/SConscript
index 88aeeda376..026698500a 100644
--- a/libs/surfaces/control_protocol/SConscript
+++ b/libs/surfaces/control_protocol/SConscript
@@ -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' ] +
diff --git a/libs/surfaces/control_protocol/control_protocol/smpte.h b/libs/surfaces/control_protocol/control_protocol/smpte.h
index 09c1c9616a..b25a268aac 100644
--- a/libs/surfaces/control_protocol/control_protocol/smpte.h
+++ b/libs/surfaces/control_protocol/control_protocol/smpte.h
@@ -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;
diff --git a/libs/surfaces/control_protocol/smpte.cc b/libs/surfaces/control_protocol/smpte.cc
index 55d0660c59..5df159a52b 100644
--- a/libs/surfaces/control_protocol/smpte.cc
+++ b/libs/surfaces/control_protocol/smpte.cc
@@ -20,10 +20,11 @@
#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;
}
diff --git a/libs/surfaces/generic_midi/SConscript b/libs/surfaces/generic_midi/SConscript
index f9c2de08f8..6c76e05464 100644
--- a/libs/surfaces/generic_midi/SConscript
+++ b/libs/surfaces/generic_midi/SConscript
@@ -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' ] +
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index 03dbfb353c..0256d5c359 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -234,7 +234,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
controllables.clear ();
- nlist = node.children();
+ nlist = node.children(); // "controls"
if (nlist.empty()) {
return 0;
diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc
index 6dc9bde8ad..75b5699f18 100644
--- a/libs/surfaces/generic_midi/midicontrollable.cc
+++ b/libs/surfaces/generic_midi/midicontrollable.cc
@@ -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;
}
diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h
index ab15f9f4ab..8b63172916 100644
--- a/libs/surfaces/generic_midi/midicontrollable.h
+++ b/libs/surfaces/generic_midi/midicontrollable.h
@@ -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);
diff --git a/libs/surfaces/tranzport/SConscript b/libs/surfaces/tranzport/SConscript
index 3f9cc5cc15..5d390f3e2f 100644
--- a/libs/surfaces/tranzport/SConscript
+++ b/libs/surfaces/tranzport/SConscript
@@ -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' ] +
diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.cc b/libs/surfaces/tranzport/tranzport_control_protocol.cc
index ea85a32a77..bbb78d31d1 100644
--- a/libs/surfaces/tranzport/tranzport_control_protocol.cc
+++ b/libs/surfaces/tranzport/tranzport_control_protocol.cc
@@ -18,6 +18,31 @@
$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;
+}
+
+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(lights)/sizeof(lights[0]); ++i) {
- 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;
+}
- for (uint32_t i = 0; i < sizeof(pending_lights)/sizeof(pending_lights[0]); ++i) {
- pending_lights[i] = false;
+// Screen specific commands
+
+void
+TranzportControlProtocol::screen_clear ()
+{
+ const char *blank = " ";
+ print(0,0,blank);
+ print(1,0,blank);
+}
+
+void TranzportControlProtocol::screen_invalidate ()
+{
+ 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
}
-TranzportControlProtocol::~TranzportControlProtocol ()
+void TranzportControlProtocol::screen_validate ()
{
- set_active (false);
}
-bool
-TranzportControlProtocol::probe ()
+void TranzportControlProtocol::screen_init ()
{
- struct usb_bus *bus;
- struct usb_device *dev;
+ screen_invalidate();
+}
- usb_init();
- usb_find_busses();
- usb_find_devices();
+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;
- for (bus = usb_busses; bus; bus = bus->next) {
+ 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;
- for(dev = bus->devices; dev; dev = dev->next) {
- if (dev->descriptor.idVendor == VENDORID && dev->descriptor.idProduct == PRODUCTID) {
- return 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,7 +549,7 @@ TranzportControlProtocol::show_meter ()
}
/* print() requires this */
-
+
buf[21] = '\0';
print (0, 0, buf);
@@ -318,17 +557,56 @@ TranzportControlProtocol::show_meter ()
}
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;
+ if(offline++ == 1) {
+ cerr << "Transport has gone offline\n";
+ }
+ } else {
+ offline = 0; // hate writing this
}
- pthread_testcancel();
- val = usb_interrupt_read (udev, READ_ENDPOINT, (char*) buf, 8, 10);
- pthread_testcancel();
+ val = read(buf);
if (val == 8) {
process (buf);
}
+#if DEBUG_TRANZPORT > 2
+ if(inflight > 1) printf("Inflight: %d\n", inflight);
+#endif
+
+
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 ();
- }
- }
-
- return (void*) 0;
-}
-
-int
-TranzportControlProtocol::update_state ()
-{
- int row;
- int col_base;
- int col;
- int cell;
- /* do the text updates */
-
- switch (display_mode) {
- case DisplayBigMeter:
- show_meter ();
- break;
-
- case DisplayNormal:
- normal_update ();
- break;
- }
-
- /* next: flush LCD */
-
- 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);
- }
-
- /* 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,42 +1663,48 @@ 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 ()
{
if (_datawheel < WheelDirectionThreshold) {
@@ -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)
+TranzportControlProtocol::print (int row, int col, const char *text) {
+ print_noretry(row,col,text);
+}
+
+void
+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;
+}
diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.h b/libs/surfaces/tranzport/tranzport_control_protocol.h
index e5193a761c..f13e4a3a44 100644
--- a/libs/surfaces/tranzport/tranzport_control_protocol.h
+++ b/libs/surfaces/tranzport/tranzport_control_protocol.h
@@ -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);
};
diff --git a/svn_revision.h b/svn_revision.h
index 77f72965cd..cddf78e774 100644
--- a/svn_revision.h
+++ b/svn_revision.h
@@ -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
diff --git a/templates/SConscript b/templates/SConscript
index 7fa556530b..60a80c5619 100644
--- a/templates/SConscript
+++ b/templates/SConscript
@@ -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))
diff --git a/tools/osx_packaging/Ardour2.icns b/tools/osx_packaging/Ardour2.icns
index 0e345fc120..2334fab13b 100644
--- a/tools/osx_packaging/Ardour2.icns
+++ b/tools/osx_packaging/Ardour2.icns
Binary files differ
diff --git a/tools/osx_packaging/COPYING b/tools/osx_packaging/COPYING
new file mode 100644
index 0000000000..d60c31a97a
--- /dev/null
+++ b/tools/osx_packaging/COPYING
@@ -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.
+
+ 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.)
+
+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.
+
+ 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.
+
+ 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
+
+ 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.
diff --git a/tools/osx_packaging/app_build.rb b/tools/osx_packaging/app_build.rb
index 965d87003d..4cab635034 100755
--- a/tools/osx_packaging/app_build.rb
+++ b/tools/osx_packaging/app_build.rb
@@ -1,22 +1,260 @@
-#!/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
+
+
diff --git a/tools/osx_packaging/ardour2_mac_ui.rc b/tools/osx_packaging/ardour2_mac_ui.rc
index 4731120349..ad456c305f 100644
--- a/tools/osx_packaging/ardour2_mac_ui.rc
+++ b/tools/osx_packaging/ardour2_mac_ui.rc
@@ -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"
diff --git a/tools/osx_packaging/bin/exporter b/tools/osx_packaging/bin/exporter
index 5a2ce0d307..41a2904ff9 100755
--- a/tools/osx_packaging/bin/exporter
+++ b/tools/osx_packaging/bin/exporter
@@ -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
index 0000000000..00c931d069
--- /dev/null
+++ b/tools/osx_packaging/etc/gtk-2.0/gdk-pixbuf.loaders
@@ -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
index 0000000000..e8a9900917
--- /dev/null
+++ b/tools/osx_packaging/etc/gtk-2.0/gtk.immodules
@@ -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
index 0000000000..c635b8b6a6
--- /dev/null
+++ b/tools/osx_packaging/etc/pango/pango.modules
@@ -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
index 0000000000..a4152dd731
--- /dev/null
+++ b/tools/osx_packaging/etc/pango/pangorc
@@ -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
index 0000000000..9b41aa7521
--- /dev/null
+++ b/tools/osx_packaging/etc/pango/pangox.aliases
@@ -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
index 0000000000..8dcc7a5865
--- /dev/null
+++ b/tools/osx_packaging/etc/profile.d/gtk+2-shlibs.csh
@@ -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
index 0000000000..9aeffa2d87
--- /dev/null
+++ b/tools/osx_packaging/etc/profile.d/gtk+2-shlibs.sh
@@ -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
index 0000000000..b27efb89f4
--- /dev/null
+++ b/tools/osx_packaging/etc/profile.d/libxml2-bin.csh
@@ -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
index 0000000000..29ca69f842
--- /dev/null
+++ b/tools/osx_packaging/etc/profile.d/libxml2-bin.sh
@@ -0,0 +1,2 @@
+export XML_CATALOG_FILES='/sw/etc/xml/catalog'
+export SGML_CATALOG_FILES='/sw/etc/sgml/catalog'
diff --git a/tools/osx_packaging/script b/tools/osx_packaging/script
index d689320d20..ec6ad4feec 100755
--- a/tools/osx_packaging/script
+++ b/tools/osx_packaging/script
@@ -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" "$*"
diff --git a/vst/SConscript b/vst/SConscript
index 2a4d492f8a..eb4dd6683b 100644
--- a/vst/SConscript
+++ b/vst/SConscript
@@ -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',