From 532f6aad4ac79ca15d69deccd18fca90e444c437 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 9 Jan 2007 23:24:54 +0000 Subject: Merged with trunk R1283. NOTE: Compiles, but broken (crash on adding MIDI track). git-svn-id: svn://localhost/ardour2/branches/midi@1292 d708f5d6-7413-0410-9779-e7cbd77b26cf --- DOCUMENTATION/AUTHORS | 3 + PACKAGER_README | 2 +- SConstruct | 463 +- gtk2_ardour/SConscript | 24 +- gtk2_ardour/about.cc | 2 + gtk2_ardour/analysis_window.cc | 8 +- gtk2_ardour/ardbg | 2 +- gtk2_ardour/ardev | 2 +- gtk2_ardour/ardev_common.sh | 1 + gtk2_ardour/ardev_common.sh.in | 16 + gtk2_ardour/ardour.bindings | 405 +- gtk2_ardour/ardour.menus | 42 +- gtk2_ardour/ardour.sh.in | 6 +- gtk2_ardour/ardour2_ui.rc | 140 +- gtk2_ardour/ardour_ui.cc | 154 +- gtk2_ardour/ardour_ui.h | 27 +- gtk2_ardour/ardour_ui2.cc | 4 +- gtk2_ardour/ardour_ui_dependents.cc | 29 +- gtk2_ardour/ardour_ui_dialogs.cc | 35 +- gtk2_ardour/ardour_ui_ed.cc | 20 +- gtk2_ardour/ardour_ui_options.cc | 18 +- gtk2_ardour/arprof | 4 +- gtk2_ardour/arval | 2 +- gtk2_ardour/audio_clock.cc | 247 +- gtk2_ardour/audio_clock.h | 28 +- gtk2_ardour/audio_region_editor.cc | 18 +- gtk2_ardour/audio_region_view.cc | 41 +- gtk2_ardour/audio_region_view.h | 5 +- gtk2_ardour/audio_streamview.cc | 51 +- gtk2_ardour/audio_streamview.h | 6 + gtk2_ardour/audio_time_axis.cc | 45 +- gtk2_ardour/audio_time_axis.h | 3 + gtk2_ardour/automation_line.cc | 257 +- gtk2_ardour/automation_line.h | 12 +- gtk2_ardour/automation_time_axis.cc | 36 +- gtk2_ardour/automation_time_axis.h | 3 + gtk2_ardour/canvas-waveview.c | 49 +- gtk2_ardour/canvas-waveview.h | 3 +- gtk2_ardour/crossfade_edit.cc | 4 +- gtk2_ardour/crossfade_view.cc | 4 +- gtk2_ardour/editor.cc | 248 +- gtk2_ardour/editor.h | 32 +- gtk2_ardour/editor_actions.cc | 204 +- gtk2_ardour/editor_audio_import.cc | 278 +- gtk2_ardour/editor_canvas.cc | 26 +- gtk2_ardour/editor_canvas_events.cc | 8 +- gtk2_ardour/editor_edit_groups.cc | 2 +- gtk2_ardour/editor_export_audio.cc | 2 +- gtk2_ardour/editor_imageframe.cc | 12 +- gtk2_ardour/editor_markers.cc | 124 +- gtk2_ardour/editor_mixer.cc | 7 +- gtk2_ardour/editor_mouse.cc | 122 +- gtk2_ardour/editor_ops.cc | 124 +- gtk2_ardour/editor_region_list.cc | 32 +- gtk2_ardour/editor_route_list.cc | 2 +- gtk2_ardour/editor_rulers.cc | 8 +- gtk2_ardour/editor_selection_list.cc | 8 +- gtk2_ardour/editor_timefx.cc | 2 +- gtk2_ardour/editor_xpms | 52 + gtk2_ardour/enums.cc | 29 + gtk2_ardour/enums.h | 7 + gtk2_ardour/export_dialog.cc | 2 +- gtk2_ardour/fft_graph.cc | 4 +- gtk2_ardour/gain_meter.cc | 189 +- gtk2_ardour/gain_meter.h | 19 +- gtk2_ardour/icons/ardour_icon_16px.png | Bin 0 -> 630 bytes gtk2_ardour/icons/ardour_icon_22px.png | Bin 0 -> 1025 bytes gtk2_ardour/icons/ardour_icon_32px.png | Bin 0 -> 1759 bytes gtk2_ardour/icons/ardour_icon_48px.png | Bin 0 -> 3135 bytes gtk2_ardour/icons/fader_belt.png | Bin 0 -> 3854 bytes gtk2_ardour/io_selector.cc | 5 +- gtk2_ardour/ladspa_pluginui.cc | 2 +- gtk2_ardour/location_ui.cc | 21 +- gtk2_ardour/logmeter.h | 4 +- gtk2_ardour/main.cc | 50 +- gtk2_ardour/meter_bridge.cc | 2 +- gtk2_ardour/mixer_strip.cc | 9 +- gtk2_ardour/mixer_strip.h | 1 + gtk2_ardour/mixer_ui.cc | 13 +- gtk2_ardour/new_session_dialog.cc | 18 +- gtk2_ardour/option_editor.cc | 64 +- gtk2_ardour/option_editor.h | 5 - gtk2_ardour/opts.cc | 12 +- gtk2_ardour/opts.h | 1 + gtk2_ardour/panner.cc | 104 + gtk2_ardour/panner.h | 18 + gtk2_ardour/panner2d.cc | 2 +- gtk2_ardour/panner_ui.cc | 63 +- gtk2_ardour/panner_ui.h | 6 +- gtk2_ardour/pixmaps/SConscript | 2 +- gtk2_ardour/playlist_selection.h | 3 +- gtk2_ardour/playlist_selector.cc | 45 +- gtk2_ardour/playlist_selector.h | 11 +- gtk2_ardour/plugin_ui.cc | 1 + gtk2_ardour/po/de_DE.po | 6011 ++++++++++---------- gtk2_ardour/po/sv_SE.po | 119 +- gtk2_ardour/public_editor.h | 5 +- gtk2_ardour/redirect_box.cc | 156 +- gtk2_ardour/redirect_box.h | 24 +- gtk2_ardour/region_gain_line.cc | 4 +- gtk2_ardour/region_gain_line.h | 2 +- gtk2_ardour/region_view.cc | 2 +- gtk2_ardour/route_params_ui.cc | 4 +- gtk2_ardour/route_time_axis.cc | 133 +- gtk2_ardour/route_time_axis.h | 8 +- gtk2_ardour/route_ui.cc | 2 +- gtk2_ardour/selection.cc | 30 +- gtk2_ardour/selection.h | 16 +- gtk2_ardour/sfdb_ui.cc | 324 +- gtk2_ardour/sfdb_ui.h | 185 +- gtk2_ardour/time_axis_view.cc | 24 +- gtk2_ardour/time_axis_view.h | 17 +- gtk2_ardour/time_axis_view_item.cc | 2 +- gtk2_ardour/utils.cc | 127 +- gtk2_ardour/utils.h | 4 +- gtk2_ardour/visual_time_axis.cc | 6 +- gtk2_ardour/waveview.cc | 8 + gtk2_ardour/waveview.h | 2 + libs/appleutility/SConscript | 2 +- libs/ardour/SConscript | 51 +- libs/ardour/ardour/audio_diskstream.h | 58 +- libs/ardour/ardour/audio_library.h | 50 +- libs/ardour/ardour/audioengine.h | 5 +- libs/ardour/ardour/audiofilesource.h | 2 + libs/ardour/ardour/audioplaylist.h | 9 +- libs/ardour/ardour/audiosource.h | 5 +- libs/ardour/ardour/automation_event.h | 6 +- libs/ardour/ardour/configuration_vars.h | 18 +- libs/ardour/ardour/crossfade.h | 5 +- libs/ardour/ardour/cycles.h | 2 +- libs/ardour/ardour/diskstream.h | 16 +- libs/ardour/ardour/insert.h | 11 +- libs/ardour/ardour/io.h | 6 +- libs/ardour/ardour/location.h | 5 +- libs/ardour/ardour/meter.h | 10 + libs/ardour/ardour/midi_diskstream.h | 4 +- libs/ardour/ardour/midi_playlist.h | 9 +- libs/ardour/ardour/named_selection.h | 5 +- libs/ardour/ardour/playlist.h | 54 +- libs/ardour/ardour/playlist_factory.h | 25 + libs/ardour/ardour/redirect.h | 2 - libs/ardour/ardour/region.h | 7 +- libs/ardour/ardour/route.h | 2 +- libs/ardour/ardour/route_group.h | 2 +- libs/ardour/ardour/send.h | 8 +- libs/ardour/ardour/session.h | 181 +- libs/ardour/ardour/session_playlist.h | 2 +- libs/ardour/ardour/source.h | 6 +- libs/ardour/ardour/track.h | 5 +- libs/ardour/ardour/types.h | 15 +- libs/ardour/ardour/utils.h | 12 +- libs/ardour/audio_diskstream.cc | 215 +- libs/ardour/audio_library.cc | 459 +- libs/ardour/audio_playlist.cc | 39 +- libs/ardour/audio_track.cc | 77 +- libs/ardour/audioengine.cc | 91 +- libs/ardour/audiofilesource.cc | 43 +- libs/ardour/audioregion.cc | 147 +- libs/ardour/audiosource.cc | 116 +- libs/ardour/auditioner.cc | 32 +- libs/ardour/automation_event.cc | 93 +- libs/ardour/configuration.cc | 4 - libs/ardour/control_protocol_manager.cc | 6 +- libs/ardour/crossfade.cc | 2 +- libs/ardour/diskstream.cc | 39 +- libs/ardour/enums.cc | 327 ++ libs/ardour/globals.cc | 102 +- libs/ardour/import.cc | 32 +- libs/ardour/insert.cc | 120 +- libs/ardour/io.cc | 43 +- libs/ardour/location.cc | 48 +- libs/ardour/meter.cc | 16 +- libs/ardour/midi_diskstream.cc | 46 +- libs/ardour/midi_playlist.cc | 15 +- libs/ardour/midi_port.cc | 2 +- libs/ardour/midi_track.cc | 6 +- libs/ardour/named_selection.cc | 18 +- libs/ardour/panner.cc | 8 +- libs/ardour/playlist.cc | 180 +- libs/ardour/playlist_factory.cc | 91 +- libs/ardour/plugin_manager.cc | 3 +- libs/ardour/redirect.cc | 31 +- libs/ardour/region.cc | 88 +- libs/ardour/route.cc | 14 +- libs/ardour/route_group.cc | 23 +- libs/ardour/send.cc | 15 +- libs/ardour/session.cc | 258 +- libs/ardour/session_butler.cc | 2 - libs/ardour/session_command.cc | 424 +- libs/ardour/session_events.cc | 11 +- libs/ardour/session_midi.cc | 4 +- libs/ardour/session_process.cc | 2 +- libs/ardour/session_state.cc | 302 +- libs/ardour/session_time.cc | 168 +- libs/ardour/session_transport.cc | 69 +- libs/ardour/smf_source.cc | 2 +- libs/ardour/sndfilesource.cc | 29 +- libs/ardour/source.cc | 13 +- libs/ardour/source_factory.cc | 161 +- libs/ardour/tempo.cc | 8 +- libs/ardour/utils.cc | 132 +- libs/clearlooks/SConscript | 26 +- libs/flowcanvas/SConscript | 2 +- libs/fst/SConscript | 50 +- libs/fst/fstinfofile.c | 4 +- libs/glibmm2/SConscript | 2 +- libs/gtkmm2/atk/SConscript | 2 +- libs/gtkmm2/gdk/SConscript | 2 +- libs/gtkmm2/gtk/SConscript | 2 +- libs/gtkmm2/pango/SConscript | 2 +- libs/gtkmm2ext/SConscript | 4 +- libs/gtkmm2ext/barcontroller.cc | 74 +- libs/gtkmm2ext/focus_entry.cc | 31 + libs/gtkmm2ext/gtkmm2ext/barcontroller.h | 22 +- libs/gtkmm2ext/gtkmm2ext/focus_entry.h | 22 + libs/gtkmm2ext/gtkmm2ext/pixfader.h | 70 + libs/gtkmm2ext/gtkmm2ext/slider_controller.h | 13 +- libs/gtkmm2ext/pixfader.cc | 249 + libs/gtkmm2ext/prompter.cc | 2 +- libs/gtkmm2ext/slider_controller.cc | 21 +- libs/gtkmm2ext/tearoff.cc | 8 +- libs/libglademm/SConscript | 2 +- libs/libgnomecanvasmm/SConscript | 2 +- libs/libsndfile/SConscript | 5 +- libs/libsndfile/configure | 8 + libs/midi++2/SConscript | 2 +- libs/midi++2/jack_midiport.cc | 4 +- libs/pbd/SConscript | 6 +- libs/pbd/basename.cc | 19 +- libs/pbd/controllable.cc | 4 +- libs/pbd/copyfile.cc | 38 + libs/pbd/enumwriter.cc | 273 + libs/pbd/pbd/basename.h | 6 +- libs/pbd/pbd/copyfile.h | 6 + libs/pbd/pbd/enumwriter.h | 77 + libs/pbd/pbd/tokenizer.h | 30 +- libs/pbd/pbd/undo.h | 2 +- libs/pbd/pbd/whitespace.h | 6 + libs/pbd/undo.cc | 26 +- libs/pbd/whitespace.cc | 6 +- libs/sigc++2/SConscript | 2 +- libs/soundtouch/SConscript | 2 +- libs/soundtouch/STTypes.h | 4 + libs/surfaces/control_protocol/SConscript | 2 +- .../control_protocol/control_protocol/smpte.h | 22 +- libs/surfaces/control_protocol/smpte.cc | 118 +- libs/surfaces/generic_midi/SConscript | 3 +- .../generic_midi/generic_midi_control_protocol.cc | 2 +- libs/surfaces/generic_midi/midicontrollable.cc | 13 +- libs/surfaces/generic_midi/midicontrollable.h | 2 - libs/surfaces/tranzport/SConscript | 11 +- .../tranzport/tranzport_control_protocol.cc | 1477 +++-- .../tranzport/tranzport_control_protocol.h | 138 +- svn_revision.h | 2 +- templates/SConscript | 3 +- tools/osx_packaging/Ardour2.icns | Bin 53885 -> 41196 bytes tools/osx_packaging/COPYING | 340 ++ tools/osx_packaging/app_build.rb | 254 +- tools/osx_packaging/ardour2_mac_ui.rc | 223 +- tools/osx_packaging/bin/exporter | 4 + tools/osx_packaging/etc/gtk-2.0/gdk-pixbuf.loaders | 113 + tools/osx_packaging/etc/gtk-2.0/gtk.immodules | 35 + tools/osx_packaging/etc/pango/pango.modules | 24 + tools/osx_packaging/etc/pango/pangorc | 5 + tools/osx_packaging/etc/pango/pangox.aliases | 220 + tools/osx_packaging/etc/profile.d/gtk+2-shlibs.csh | 1 + tools/osx_packaging/etc/profile.d/gtk+2-shlibs.sh | 1 + tools/osx_packaging/etc/profile.d/libxml2-bin.csh | 2 + tools/osx_packaging/etc/profile.d/libxml2-bin.sh | 2 + tools/osx_packaging/script | 3 +- vst/SConscript | 2 +- 271 files changed, 12761 insertions(+), 7616 deletions(-) create mode 100644 gtk2_ardour/ardev_common.sh.in create mode 100644 gtk2_ardour/enums.cc create mode 100644 gtk2_ardour/icons/ardour_icon_16px.png create mode 100644 gtk2_ardour/icons/ardour_icon_22px.png create mode 100644 gtk2_ardour/icons/ardour_icon_32px.png create mode 100644 gtk2_ardour/icons/ardour_icon_48px.png create mode 100644 gtk2_ardour/icons/fader_belt.png create mode 100644 gtk2_ardour/panner.cc create mode 100644 gtk2_ardour/panner.h create mode 100644 libs/ardour/ardour/playlist_factory.h create mode 100644 libs/ardour/enums.cc create mode 100644 libs/gtkmm2ext/focus_entry.cc create mode 100644 libs/gtkmm2ext/gtkmm2ext/focus_entry.h create mode 100644 libs/gtkmm2ext/gtkmm2ext/pixfader.h create mode 100644 libs/gtkmm2ext/pixfader.cc create mode 100644 libs/pbd/copyfile.cc create mode 100644 libs/pbd/enumwriter.cc create mode 100644 libs/pbd/pbd/copyfile.h create mode 100644 libs/pbd/pbd/enumwriter.h create mode 100644 tools/osx_packaging/COPYING create mode 100644 tools/osx_packaging/etc/gtk-2.0/gdk-pixbuf.loaders create mode 100644 tools/osx_packaging/etc/gtk-2.0/gtk.immodules create mode 100644 tools/osx_packaging/etc/pango/pango.modules create mode 100644 tools/osx_packaging/etc/pango/pangorc create mode 100644 tools/osx_packaging/etc/pango/pangox.aliases create mode 100644 tools/osx_packaging/etc/profile.d/gtk+2-shlibs.csh create mode 100644 tools/osx_packaging/etc/profile.d/gtk+2-shlibs.sh create mode 100644 tools/osx_packaging/etc/profile.d/libxml2-bin.csh create mode 100644 tools/osx_packaging/etc/profile.d/libxml2-bin.sh 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((*i)->playlist()); + boost::shared_ptr pl + = boost::dynamic_pointer_cast((*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::iterator j = ts.begin(); j != ts.end(); ++j) { + for (std::list::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 "/Transport/ToggleRoll" "space") -(gtk_accel_path "/Transport/ToggleRollForgetCapture" "space") -(gtk_accel_path "/Transport/Forward" "Right") -(gtk_accel_path "/Transport/Rewind" "Left") -(gtk_accel_path "/Transport/GotoZero" "KP_Insert") -(gtk_accel_path "/Transport/GotoStart" "Home") -(gtk_accel_path "/Transport/GotoEnd" "End") - -(gtk_accel_path "/Editor/align-regions-sync-relative" "a") -(gtk_accel_path "/Editor/crop" "c") -(gtk_accel_path "/Editor/duplicate-region" "d") -(gtk_accel_path "/Editor/set-edit-cursor" "e") -(gtk_accel_path "/MouseMode/set-mouse-mode-gain" "g") -(gtk_accel_path "/Editor/split-region" "s") -(gtk_accel_path "/Editor/set-region-sync-position" "v") -(gtk_accel_path "/Editor/mute-unmute-region" "m") -(gtk_accel_path "/Editor/insert-region" "i") -(gtk_accel_path "/Editor/normalize-region" "n") -(gtk_accel_path "/MouseMode/set-mouse-mode-object" "o") -(gtk_accel_path "/Transport/loop" "l") -(gtk_accel_path "/Editor/set-playhead" "p") +; ardour-2.0beta10 GtkAccelMap rc-file -*- scheme -*- +; this file is an automated accelerator map dump +; +; (gtk_accel_path "/RegionList/RegionListSort" "") +(gtk_accel_path "/Common/Quit" "q") +(gtk_accel_path "/Common/Save" "s") +; (gtk_accel_path "/Editor/Pullup" "") +; (gtk_accel_path "/Editor/zoom-to-session" "") +; (gtk_accel_path "/JACK/JACKReconnect" "") +; (gtk_accel_path "/Editor/Autoconnect" "") +; (gtk_accel_path "/Editor/Edit" "") +(gtk_accel_path "/Editor/playhead-to-previous-region-end" "grave") +; (gtk_accel_path "/redirectmenu/copy" "") +; (gtk_accel_path "/options/MeterFalloffFaster" "") +(gtk_accel_path "/Transport/ToggleRollForgetCapture" "space") +(gtk_accel_path "/Transport/Record" "r") +; (gtk_accel_path "/RegionList/SortByRegionLength" "") +; (gtk_accel_path "/options/MeterFalloffSlowest" "") +; (gtk_accel_path "/Editor/playhead-to-previous-region-sync" "") +; (gtk_accel_path "/redirectmenu/deactivate_all" "") +; (gtk_accel_path "/RegionList/SortByRegionPosition" "") +; (gtk_accel_path "/Editor/ZoomFocus" "") +; (gtk_accel_path "/options/MeterFalloffSlow" "") +; (gtk_accel_path "/RegionList/rlHide" "") +; (gtk_accel_path "/Main/Metering" "") +(gtk_accel_path "/Editor/playhead-to-next-region-end" "Tab") +; (gtk_accel_path "/Zoom/zoom-focus-playhead" "") +; (gtk_accel_path "/Editor/center-edit-cursor" "") +; (gtk_accel_path "/Editor/Monitoring" "") +; (gtk_accel_path "/redirectmenu/deactivate" "") +; (gtk_accel_path "/options/LatchedRecordEnable" "") +; (gtk_accel_path "/Transport/TogglePunchIn" "") +; (gtk_accel_path "/ShuttleActions/SetShuttleUnitsPercentage" "") +(gtk_accel_path "/Editor/edit-cursor-to-previous-region-start" "bracketleft") +; (gtk_accel_path "/Main/Close" "") +; (gtk_accel_path "/Main/New" "") +(gtk_accel_path "/Editor/nudge-next-backward" "KP_Subtract") +; (gtk_accel_path "/Editor/EditSelectRangeOptions" "") +; (gtk_accel_path "/Transport/ToggleTimeMaster" "") +; (gtk_accel_path "/Snap/snap-to-thirds" "") +(gtk_accel_path "/Editor/align-regions-start-relative" "a") +; (gtk_accel_path "/Main/Export" "") +(gtk_accel_path "/Editor/jump-forward-to-mark" "KP_Right") +; (gtk_accel_path "/Editor/Smpte30" "") +; (gtk_accel_path "/Editor/playhead-to-range-start" "") +; (gtk_accel_path "/Editor/Subframes" "") +; (gtk_accel_path "/Editor/Smpte2997drop" "") +; (gtk_accel_path "/Main/AddTrackBus" "") +(gtk_accel_path "/Editor/align-regions-end" "a") +; (gtk_accel_path "/JACK/JACKDisconnect" "") +; (gtk_accel_path "/options/MeterFalloffFast" "") +; (gtk_accel_path "/options/FileDataFormatFloat" "") +; (gtk_accel_path "/Snap/snap-to-region-end" "") +(gtk_accel_path "/Editor/edit-cursor-to-next-region-sync" "semicolon") +; (gtk_accel_path "/options/StopRecordingOnXrun" "") +; (gtk_accel_path "/Editor/addExternalAudioToRegionList" "") +; (gtk_accel_path "/RegionList/SortDescending" "") +; (gtk_accel_path "/options/DoNotRunPluginsWhileRecording" "") +; (gtk_accel_path "/Editor/PullupNone" "") (gtk_accel_path "/MouseMode/set-mouse-mode-range" "r") -(gtk_accel_path "/MouseMode/set-mouse-mode-timefx" "t") -(gtk_accel_path "/MouseMode/set-mouse-mode-zoom" "z") - -(gtk_accel_path "/Transport/Record" "r") - - +(gtk_accel_path "/Editor/jump-backward-to-mark" "KP_Left") +; (gtk_accel_path "/Main/AudioFileFormatData" "") +; (gtk_accel_path "/options/MeterFalloffFastest" "") +(gtk_accel_path "/Editor/audition-at-mouse" "period") +(gtk_accel_path "/Transport/Forward" "Right") +; (gtk_accel_path "/Snap/snap-to-smpte-seconds" "") +; (gtk_accel_path "/Snap/snap-to-smpte-frame" "") +; (gtk_accel_path "/Main/ExportSelection" "") +; (gtk_accel_path "/options/StopPluginsWithTransport" "") +(gtk_accel_path "/Editor/editor-paste" "v") +(gtk_accel_path "/Editor/scroll-tracks-down" "Page_Down") +; (gtk_accel_path "/Snap/snap-to-smpte-minutes" "") +(gtk_accel_path "/Editor/normalize-region" "n") (gtk_accel_path "/Editor/nudge-forward" "KP_Add") -(gtk_accel_path "/Editor/nudge-next-forward" "KP_Add") +; (gtk_accel_path "/Main/FlushWastebasket" "") +; (gtk_accel_path "/RegionList/SortByRegionEndinFile" "") +; (gtk_accel_path "/Editor/ToggleMeasureVisibility" "") +; (gtk_accel_path "/Zoom/zoom-focus-center" "") (gtk_accel_path "/Editor/nudge-backward" "KP_Subtract") -(gtk_accel_path "/Editor/nudge-next-backward" "KP_Subtract") - -(gtk_accel_path "/Editor/show-editor-mixer" "e") - -(gtk_accel_path "/Common/goto-editor" "e") -(gtk_accel_path "/Common/goto-mixer" "m") -(gtk_accel_path "/Common/ToggleSoundFileBrowser" "f") -(gtk_accel_path "/Common/ToggleLocations" "l") -(gtk_accel_path "/Common/ToggleBigClock" "b") -(gtk_accel_path "/Common/ToggleColorManager" "c") - -(gtk_accel_path "/Editor/editor-copy" "c") -(gtk_accel_path "/Common/Quit" "q") -(gtk_accel_path "/Editor/redo" "r") -(gtk_accel_path "/Common/Save" "s") -(gtk_accel_path "/Editor/editor-paste" "v") -(gtk_accel_path "/Editor/editor-cut" "x") -(gtk_accel_path "/Editor/editor-delete" "Delete") -(gtk_accel_path "/Editor/undo" "z") - -(gtk_accel_path "/Editor/scroll-tracks-down" "Page_Down") +; (gtk_accel_path "/options/LatchedSolo" "") +; (gtk_accel_path "/options/MeterHoldOff" "") +; (gtk_accel_path "/options/OutputAutoConnectMaster" "") +; (gtk_accel_path "/JACK/JACKLatency64" "") +(gtk_accel_path "/Editor/undo" "z") +(gtk_accel_path "/Editor/insert-region" "i") +; (gtk_accel_path "/Editor/center-playhead" "") +(gtk_accel_path "/Editor/edit-cursor-to-next-region-start" "bracketright") +; (gtk_accel_path "/Snap/snap-to-region-start" "") +; (gtk_accel_path "/Editor/View" "") +; (gtk_accel_path "/Editor/Layering" "") +; (gtk_accel_path "/JACK/JACKLatency4096" "") (gtk_accel_path "/Editor/scroll-tracks-up" "Page_Up") -(gtk_accel_path "/Editor/scroll-backward" "leftarrow") -(gtk_accel_path "/Editor/scroll-forward" "rightarrow") +(gtk_accel_path "/Editor/set-edit-cursor" "e") +; (gtk_accel_path "/Editor/Smpte30drop" "") +; (gtk_accel_path "/Zoom/zoom-focus-edit" "") +(gtk_accel_path "/Editor/playhead-to-previous-region-start" "grave") +; (gtk_accel_path "/Editor/EditCursorMovementOptions" "") +; (gtk_accel_path "/redirectmenu/activate_all" "") +; (gtk_accel_path "/Editor/addExternalAudioAsTapeTrack" "") +; (gtk_accel_path "/redirectmenu/paste" "") +; (gtk_accel_path "/Editor/Smpte25" "") +; (gtk_accel_path "/Main/MeteringFallOffRate" "") +; (gtk_accel_path "/options/UseHardwareMonitoring" "") +; (gtk_accel_path "/Editor/Smpte24" "") +; (gtk_accel_path "/Snap/snap-to-mark" "") +; (gtk_accel_path "/Editor/CrossfadesShort" "") +; (gtk_accel_path "/Editor/Smpte5994" "") +; (gtk_accel_path "/JACK/JACKLatency8192" "") (gtk_accel_path "/Editor/step-tracks-down" "downarrow") -(gtk_accel_path "/Editor/step-tracks-up" "uparrow") -(gtk_accel_path "/Editor/playhead-to-edit" "Return") +; (gtk_accel_path "/Editor/toggle-xfades-visible" "") +(gtk_accel_path "/Editor/extend-range-to-end-of-region" "rightanglebracket") +(gtk_accel_path "/Editor/scroll-backward" "leftarrow") +(gtk_accel_path "/Editor/start-range" "KP_Down") +; (gtk_accel_path "/ShuttleActions/SetShuttleUnitsSemitones" "") +; (gtk_accel_path "/JACK/JACKLatency128" "") +; (gtk_accel_path "/Snap/snap-to-beat" "") +; (gtk_accel_path "/Editor/RegionEditOps" "") +; (gtk_accel_path "/Editor/snap-magnetic" "") +; (gtk_accel_path "/Editor/playhead-to-range-end" "") +(gtk_accel_path "/Editor/align-regions-sync-relative" "a") +; (gtk_accel_path "/Editor/EditSelectRegionOptions" "") +(gtk_accel_path "/Editor/crop" "c") +; (gtk_accel_path "/redirectmenu/newsend" "") +; (gtk_accel_path "/Editor/ToggleGeneric MIDISurfaceSubMenu" "") +; (gtk_accel_path "/Editor/MeterFalloff" "") +; (gtk_accel_path "/RegionList/rlRemove" "") +(gtk_accel_path "/Transport/GotoStart" "Home") +(gtk_accel_path "/Editor/split-region" "s") +; (gtk_accel_path "/Transport/ToggleAutoInput" "") +; (gtk_accel_path "/Snap/snap-to-thirtyseconds" "") +; (gtk_accel_path "/Snap/snap-to-minutes" "") +(gtk_accel_path "/Editor/align-regions-sync" "a") +; (gtk_accel_path "/Main/Windows" "") +; (gtk_accel_path "/Main/CleanupUnused" "") +; (gtk_accel_path "/redirectmenu/deselectall" "") +; (gtk_accel_path "/options/SoloViaBus" "") +(gtk_accel_path "/MouseMode/set-mouse-mode-zoom" "z") +; (gtk_accel_path "/RegionList/rlAudition" "") +(gtk_accel_path "/Editor/set-region-sync-position" "v") +; (gtk_accel_path "/Editor/PullupPlus4Plus1" "") +; (gtk_accel_path "/Snap/snap-to-region-boundary" "") +; (gtk_accel_path "/JACK/JACK" "") +(gtk_accel_path "/Editor/editor-cut" "x") +; (gtk_accel_path "/RegionList/SortAscending" "") +; (gtk_accel_path "/Main/Help" "") +; (gtk_accel_path "/options/UseExternalMonitoring" "") +; (gtk_accel_path "/Editor/Smpte23976" "") +(gtk_accel_path "/Common/goto-editor" "e") +(gtk_accel_path "/Editor/select-all" "a") +(gtk_accel_path "/Editor/nudge-next-forward" "KP_Add") +; (gtk_accel_path "/Snap/snap-to-eighths" "") +(gtk_accel_path "/Editor/select-all-after-playhead" "p") +(gtk_accel_path "/Common/ToggleMaximalEditor" "F11") +; (gtk_accel_path "/RegionList/SortBySourceFileLength" "") +; (gtk_accel_path "/Editor/Timecode" "") +; (gtk_accel_path "/Transport/PlaySelection" "") +; (gtk_accel_path "/Editor/PullupMinus4Minus1" "") +(gtk_accel_path "/Editor/select-all-after-edit-cursor" "e") +; (gtk_accel_path "/RegionList/SortBySourceFileName" "") +(gtk_accel_path "/Editor/finish-range" "KP_Up") +(gtk_accel_path "/Transport/Loop" "l") +; (gtk_accel_path "/Editor/CrossfadesFull" "") +(gtk_accel_path "/Editor/finish-add-range" "KP_Up") +; (gtk_accel_path "/Transport/ToggleClick" "") +; (gtk_accel_path "/options/SendMTC" "") +; (gtk_accel_path "/Transport/TogglePunchOut" "") +(gtk_accel_path "/Editor/select-all-in-loop-range" "l") +(gtk_accel_path "/Editor/show-editor-mixer" "e") +; (gtk_accel_path "/options/SoloInPlace" "") +; (gtk_accel_path "/Main/Options" "") +; (gtk_accel_path "/options/MeterFalloffMedium" "") +(gtk_accel_path "/Editor/toggle-follow-playhead" "f") +; (gtk_accel_path "/Main/SaveTemplate" "") +; (gtk_accel_path "/RegionList/SortByRegionStartinFile" "") +; (gtk_accel_path "/options/GainReduceFastTransport" "") +; (gtk_accel_path "/Common/ToggleInspector" "") +; (gtk_accel_path "/Transport/ToggleAutoPlay" "") +; (gtk_accel_path "/Editor/playhead-to-next-region-sync" "") (gtk_accel_path "/Editor/edit-to-playhead" "Return") - +; (gtk_accel_path "/Editor/LayerMoveAddHigher" "") +; (gtk_accel_path "/Editor/Smpte60" "") +; (gtk_accel_path "/Main/Open" "") +(gtk_accel_path "/Editor/scroll-forward" "rightarrow") +; (gtk_accel_path "/Zoom/zoom-focus-left" "") +; (gtk_accel_path "/Main/TransportOptions" "") +; (gtk_accel_path "/Main/ControlSurfaces" "") +; (gtk_accel_path "/options/FileHeaderFormatBWF" "") +; (gtk_accel_path "/Transport/ToggleAutoReturn" "") +; (gtk_accel_path "/Editor/Smpte2997" "") +; (gtk_accel_path "/Editor/ToggleWaveformVisibility" "") +(gtk_accel_path "/Editor/redo" "r") +; (gtk_accel_path "/Editor/addExternalAudioAsRegion" "") +; (gtk_accel_path "/Main/ExportSession" "") +; (gtk_accel_path "/options/InputAutoConnectPhysical" "") +; (gtk_accel_path "/Snap/snap-to-edit-cursor" "") (gtk_accel_path "/Editor/temporal-zoom-in" "minus") -(gtk_accel_path "/Editor/temporal-zoom-out" "equal") - -(gtk_accel_path "/Editor/select-all" "a") -(gtk_accel_path "/Editor/select-all-after-edit-cursor" "e") -(gtk_accel_path "/Editor/select-all-before-edit-cursor" "e") -(gtk_accel_path "/Editor/select-all-after-playhead" "p") -(gtk_accel_path "/Editor/select-all-before-playhead" "p") -(gtk_accel_path "/Editor/select-all-between-cursors" "u") -(gtk_accel_path "/Editor/select-all-in-punch-range" "d") -(gtk_accel_path "/Editor/select-all-in-loop-range" "l") - +; (gtk_accel_path "/JACK/Latency" "") +(gtk_accel_path "/Editor/edit-cursor-to-range-end" "F2") +; (gtk_accel_path "/redirectmenu/rename" "") +; (gtk_accel_path "/RegionList/rlShowAuto" "") +(gtk_accel_path "/Editor/select-all-before-playhead" "p") +; (gtk_accel_path "/Editor/addExistingAudioFiles" "") +; (gtk_accel_path "/Main/Session" "") +(gtk_accel_path "/Editor/edit-cursor-to-range-start" "F1") +; (gtk_accel_path "/Main/AudioFileFormat" "") +(gtk_accel_path "/MouseMode/set-mouse-mode-timefx" "t") +; (gtk_accel_path "/Transport/Transport" "") +; (gtk_accel_path "/RegionList/SortByRegionName" "") +; (gtk_accel_path "/Main/KeyMouse Actions" "") +(gtk_accel_path "/MouseMode/set-mouse-mode-gain" "g") +; (gtk_accel_path "/Snap/snap-to-frame" "") +; (gtk_accel_path "/Editor/SnapTo" "") +; (gtk_accel_path "/Editor/Crossfades" "") +; (gtk_accel_path "/Editor/PullupPlus4" "") +(gtk_accel_path "/Editor/add-location-from-playhead" "KP_Enter") +(gtk_accel_path "/Editor/edit-cursor-to-previous-region-end" "bracketleft") +; (gtk_accel_path "/Main/MeteringHoldTime" "") +; (gtk_accel_path "/Editor/PullupPlus1" "") +; (gtk_accel_path "/Editor/Smpte24976" "") +; (gtk_accel_path "/options/FileDataFormat24bit" "") +; (gtk_accel_path "/Editor/SnapMode" "") +(gtk_accel_path "/Common/ToggleOptionsEditor" "o") +; (gtk_accel_path "/Editor/PullupMinus4" "") +(gtk_accel_path "/Common/goto-mixer" "m") +; (gtk_accel_path "/Editor/addExternalAudioToTrack" "") +; (gtk_accel_path "/RegionList/SortBySourceFileCreationDate" "") +; (gtk_accel_path "/redirectmenu/activate" "") (gtk_accel_path "/Editor/extend-range-to-start-of-region" "leftanglebracket") -(gtk_accel_path "/Editor/extend-range-to-end-of-region" "rightanglebracket") - -(gtk_accel_path "/Editor/align-regions-sync" "a") -(gtk_accel_path "/Editor/align-regions-end" "a") -(gtk_accel_path "/Editor/align-regions-start-relative" "a") - -(gtk_accel_path "/Editor/brush-at-mouse" "b") -(gtk_accel_path "/Editor/audition-at-mouse" "period") - +; (gtk_accel_path "/Editor/PullupMinus1" "") +; (gtk_accel_path "/Editor/snap-normal" "") +; (gtk_accel_path "/Editor/addExternalAudioAsTrack" "") +(gtk_accel_path "/Common/ToggleBigClock" "b") +; (gtk_accel_path "/Snap/snap-to-asixteenthbeat" "") +(gtk_accel_path "/Editor/select-all-in-punch-range" "d") +; (gtk_accel_path "/redirectmenu/edit" "") +(gtk_accel_path "/Editor/duplicate-region" "d") +; (gtk_accel_path "/JACK/JACKLatency2048" "") +; (gtk_accel_path "/Editor/ToggleWaveformsWhileRecording" "") +; (gtk_accel_path "/Zoom/zoom-focus-right" "") +(gtk_accel_path "/Editor/remove-last-capture" "Delete") +; (gtk_accel_path "/options/FileHeaderFormatWAVE" "") +(gtk_accel_path "/Transport/GotoZero" "KP_Insert") +(gtk_accel_path "/Transport/GotoEnd" "End") +; (gtk_accel_path "/redirectmenu/cut" "") +; (gtk_accel_path "/redirectmenu/newinsert" "") +; (gtk_accel_path "/options/UseMMC" "") +; (gtk_accel_path "/options/MeterFalloffOff" "") +(gtk_accel_path "/MouseMode/set-mouse-mode-object" "o") +; (gtk_accel_path "/Editor/PullupMinus4Plus1" "") +; (gtk_accel_path "/Editor/MeterHold" "") +; (gtk_accel_path "/Snap/snap-to-cd-frame" "") +; (gtk_accel_path "/options/StopTransportAtEndOfSession" "") +; (gtk_accel_path "/Main/Cleanup" "") +; (gtk_accel_path "/Main/Snapshot" "") +; (gtk_accel_path "/Transport/ToggleVideoSync" "") +(gtk_accel_path "/Transport/ToggleRoll" "space") +; (gtk_accel_path "/RegionList/SortBySourceFilesystem" "") +(gtk_accel_path "/Common/ToggleColorManager" "c") +; (gtk_accel_path "/Common/About" "") +; (gtk_accel_path "/JACK/JACKLatency32" "") +(gtk_accel_path "/Editor/playhead-to-edit" "Return") +; (gtk_accel_path "/options/FileHeaderFormatWAVE64" "") +(gtk_accel_path "/Editor/brush-at-mouse" "b") +; (gtk_accel_path "/RegionList/rlShowAll" "") +(gtk_accel_path "/Transport/Rewind" "Left") +; (gtk_accel_path "/RegionList/SortByRegionTimestamp" "") +; (gtk_accel_path "/options/VerifyRemoveLastCapture" "") +; (gtk_accel_path "/options/OutputAutoConnectPhysical" "") +(gtk_accel_path "/Editor/step-tracks-up" "uparrow") (gtk_accel_path "/Editor/playhead-to-next-region-start" "Tab") -(gtk_accel_path "/Editor/playhead-to-next-region-end" "Tab") - -(gtk_accel_path "/Editor/playhead-to-previous-region-start" "grave") -(gtk_accel_path "/Editor/playhead-to-previous-region-end" "grave") - -(gtk_accel_path "/Editor/edit-cursor-to-previous-region-start" "bracketleft") -(gtk_accel_path "/Editor/edit-cursor-to-previous-region-end" "bracketleft") - -(gtk_accel_path "/Editor/edit-cursor-to-next-region-start" "bracketright") -(gtk_accel_path "/Editor/edit-cursor-to-next-region-end" "bracketright") - +; (gtk_accel_path "/options/SendMMC" "") +; (gtk_accel_path "/Editor/toggle-auto-xfades" "") +; (gtk_accel_path "/Main/AudioFileFormatHeader" "") +; (gtk_accel_path "/options/MeterHoldShort" "") +; (gtk_accel_path "/options/MeterHoldMedium" "") +(gtk_accel_path "/Editor/select-all-before-edit-cursor" "e") +; (gtk_accel_path "/Editor/Subframes80" "") +; (gtk_accel_path "/options/FileHeaderFormatCAF" "") +(gtk_accel_path "/Common/ToggleLocations" "l") +; (gtk_accel_path "/Editor/ToggleGeneric MIDISurface" "") +(gtk_accel_path "/Editor/editor-delete" "Delete") +; (gtk_accel_path "/JACK/JACKLatency256" "") +(gtk_accel_path "/Editor/select-all-between-cursors" "u") +; (gtk_accel_path "/Editor/LayerAddHigher" "") +; (gtk_accel_path "/Editor/Solo" "") +; (gtk_accel_path "/JACK/JACKLatency1024" "") +; (gtk_accel_path "/Main/ExportRangeMarkers" "") +(gtk_accel_path "/Editor/set-playhead" "p") +; (gtk_accel_path "/Editor/toggle-xfades-active" "") +; (gtk_accel_path "/Snap/snap-to-bar" "") +; (gtk_accel_path "/Editor/LayerLaterHigher" "") +; (gtk_accel_path "/redirectmenu/selectall" "") +(gtk_accel_path "/Editor/editor-copy" "c") +; (gtk_accel_path "/Snap/snap-to-quarters" "") +(gtk_accel_path "/Editor/temporal-zoom-out" "equal") +; (gtk_accel_path "/options/UseSoftwareMonitoring" "") +; (gtk_accel_path "/Editor/Subframes100" "") +(gtk_accel_path "/Editor/mute-unmute-region" "m") +; (gtk_accel_path "/options/OutputAutoConnectManual" "") +; (gtk_accel_path "/Snap/snap-to-region-sync" "") (gtk_accel_path "/Editor/edit-cursor-to-previous-region-sync" "apostrophe") -(gtk_accel_path "/Editor/edit-cursor-to-next-region-sync" "semicolon") - -(gtk_accel_path "/Editor/edit-cursor-to-range-start" "F1") -(gtk_accel_path "/Editor/edit-cursor-to-range-end" "F2") -(gtk_accel_path "/Common/ToggleMaximalEditor" "F11") - -(gtk_accel_path "/Editor/jump-forward-to-mark" "KP_Right") -(gtk_accel_path "/Editor/jump-backward-to-mark" "KP_Left") - -(gtk_accel_path "/Editor/start-range" "KP_Down") -(gtk_accel_path "/Editor/finish-range" "KP_Up") -(gtk_accel_path "/Editor/finish-add-range" "KP_Up") - - -(gtk_accel_path "/Editor/add-location-from-playhead" "KP_Enter") - - +; (gtk_accel_path "/redirectmenu/clear" "") +; (gtk_accel_path "/Editor/ToggleGeneric MIDISurfaceFeedback" "") +; (gtk_accel_path "/Editor/PullupPlus4Minus1" "") +; (gtk_accel_path "/JACK/JACKLatency512" "") +(gtk_accel_path "/Editor/edit-cursor-to-next-region-end" "bracketright") +; (gtk_accel_path "/Main/Recent" "") +; (gtk_accel_path "/redirectmenu/newplugin" "") +; (gtk_accel_path "/options/InputAutoConnectManual" "") +; (gtk_accel_path "/options/MeterHoldLong" "") +; (gtk_accel_path "/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 @@ + @@ -122,6 +123,21 @@ + + + + + + + + + + + + + + + @@ -214,13 +230,11 @@ - - @@ -240,10 +254,10 @@ - - + + @@ -258,6 +272,10 @@ + + + + @@ -324,21 +342,7 @@ - - - - - - - - - - - - - - - + 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 #include #include +#include #include #include #include @@ -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::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 (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 #include + #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(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_("/Common/ToggleSoundFileBrowser"))); - } - return 0; -} - -void -ARDOUR_UI::toggle_sound_file_browser () -{ - if (create_sound_file_browser()) { - return; - } - - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleSoundFileBrowser")); - if (act) { - RefPtr tact = RefPtr::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 act = ActionManager::get_action (group, action); + Glib::RefPtr act = ActionManager::get_action (group, action.c_str()); if (act) { Glib::RefPtr tact = Glib::RefPtr::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 += "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 ValueChanged; + static sigc::signal ModeChanged; + static std::vector 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 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 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 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 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 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::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 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 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(*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 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 ds) StreamView::playlist_changed(ds); - AudioPlaylist* apl = dynamic_cast(ds->playlist()); + boost::shared_ptr apl = boost::dynamic_pointer_cast(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(this), &StreamView::add_region_view); - AudioPlaylist* apl = dynamic_cast(_trackview.get_diskstream()->playlist()); + boost::shared_ptr apl = boost::dynamic_pointer_cast(_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(*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 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 #include -#include #include #include @@ -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 (&waveform_items.back()); waveform_items.push_back (RadioMenuElem (group, _("Rectified"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Rectified))); rectified_item = static_cast (&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 (&waveform_items.back()); + + waveform_items.push_back (RadioMenuElem (group2, _("Logarithmic"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_scale), LogWaveform))); + logscale_item = static_cast (&waveform_items.back()); + + // setting initial item state + AudioStreamView* asv = audio_view(); + if (asv) { + ignore_toggle = true; + if (asv->get_waveform_shape() == Rectified) + rectified_item->set_active(true); + else traditional_item->set_active(true); + + if (asv->get_waveform_scale() == LogWaveform) + logscale_item->set_active(true); + else linearscale_item->set_active(true); + ignore_toggle = false; + } + items.push_back (MenuElem (_("Waveform"), *waveform_menu)); } @@ -310,13 +337,25 @@ AudioTimeAxisView::set_waveform_shape (WaveformShape shape) { AudioStreamView* asv = audio_view(); - if (asv) { + if (asv && !ignore_toggle) { asv->set_waveform_shape (shape); } map_frozen (); } +void +AudioTimeAxisView::set_waveform_scale (WaveformScale scale) +{ + AudioStreamView* asv = audio_view(); + + if (asv && !ignore_toggle) { + asv->set_waveform_scale (scale); + } + + map_frozen (); +} + void AudioTimeAxisView::add_gain_automation_child () { 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 #include #include +#include #include #include @@ -347,13 +348,6 @@ AutomationLine::nth (uint32_t n) } } -void -AutomationLine::modify_view (ControlPoint& cp, double x, double y, bool with_push) -{ - modify_view_point (cp, x, y, with_push); - update_line (); -} - void AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool with_push) { @@ -416,7 +410,7 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi ControlPoint* after; /* find the first point that can't move */ - + for (uint32_t n = cp.view_index + 1; (after = nth (n)) != 0; ++n) { if (!after->can_slide) { x_limit = after->get_x() - 1.0; @@ -471,14 +465,10 @@ AutomationLine::modify_view_point (ControlPoint& cp, double x, double y, bool wi void AutomationLine::reset_line_coords (ControlPoint& cp) { - line_points[cp.view_index].set_x (cp.get_x()); - line_points[cp.view_index].set_y (cp.get_y()); -} - -void -AutomationLine::update_line () -{ - line->property_points() = line_points; + if (cp.view_index < line_points.size()) { + line_points[cp.view_index].set_x (cp.get_x()); + line_points[cp.view_index].set_y (cp.get_y()); + } } void @@ -491,10 +481,8 @@ AutomationLine::sync_model_with_view_line (uint32_t start, uint32_t end) for (uint32_t i = start; i <= end; ++i) { p = nth(i); - sync_model_with_view_point(*p); + sync_model_with_view_point (*p, false, 0); } - - } void @@ -508,7 +496,6 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) mr.xval = (nframes_t) floor (cp.get_x()); mr.yval = 1.0 - (cp.get_y() / _height); - /* if xval has not changed, set it directly from the model to avoid rounding errors */ if (mr.xval == trackview.editor.frame_to_unit((*cp.model)->when)) { @@ -517,7 +504,6 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) mr.xval = trackview.editor.unit_to_frame (mr.xval); } - /* virtual call: this will do the right thing for whatever particular type of line we are. */ @@ -566,98 +552,6 @@ AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr) } } -void -AutomationLine::sync_model_from (ControlPoint& cp) -{ - ControlPoint* p; - uint32_t lasti; - - sync_model_with_view_point (cp); - - /* we might have moved all points after `cp' by some amount - if we pressed the with_push modifyer some of the time during the drag - so all subsequent points have to be resynced - */ - - lasti = control_points.size() - 1; - p = nth (lasti); - - update_pending = true; - - while (p != &cp && lasti) { - sync_model_with_view_point (*p); - --lasti; - p = nth (lasti); - } -} - -void -AutomationLine::sync_model_with_view_point (ControlPoint& cp) -{ - ModelRepresentation mr; - double ydelta; - - model_representation (cp, mr); - - /* part 4: how much are we changing the central point by */ - - ydelta = mr.yval - mr.ypos; - - /* IMPORTANT: changing the model when the x-coordinate changes - may invalidate the iterators that we are using. this means that we have - to change the points before+after the one corresponding to the visual CP - first (their x-coordinate doesn't change). then we change the - "main" point. - - apply the full change to the central point, and interpolate - in each direction to cover all model points represented - by the control point. - */ - - /* part 5: change all points before the primary point */ - - for (AutomationList::iterator i = mr.start; i != cp.model; ++i) { - - double delta; - - delta = ydelta * ((*i)->when - mr.xmin) / (mr.xpos - mr.xmin); - - /* x-coordinate (generally time) stays where it is, - y-coordinate moves by a certain amount. - */ - - update_pending = true; - change_model (i, (*i)->when, mr.yval + delta); - } - - /* part 6: change later points */ - - AutomationList::iterator i = cp.model; - - ++i; - - while (i != mr.end) { - - double delta; - - delta = ydelta * (mr.xmax - (*i)->when) / (mr.xmax - mr.xpos); - - /* x-coordinate (generally time) stays where it is, - y-coordinate moves by a certain amount. - */ - - update_pending = true; - change_model (i, (*i)->when, (*i)->value + delta); - - ++i; - } - - /* part 7: change the primary point */ - - update_pending = true; - change_model (cp.model, mr.xval, mr.yval); -} - void AutomationLine::determine_visible_control_points (ALPoints& points) { @@ -748,7 +642,8 @@ AutomationLine::determine_visible_control_points (ALPoints& points) if (view_index && pi != npoints && /* not the first, not the last */ (((this_rx == prev_rx) && (this_ry == prev_ry)) || /* same point */ - (((this_rx - prev_rx) < (box_size + 2)) && /* too close horizontally */ + (this_rx == prev_rx) || /* identical x coordinate */ + (((this_rx - prev_rx) < (box_size + 2)) && /* not identical, but still too close horizontally */ ((abs ((int)(this_ry - prev_ry)) < (int) (box_size + 2)))))) { /* too close vertically */ continue; } @@ -810,7 +705,7 @@ AutomationLine::determine_visible_control_points (ALPoints& points) view_index++; } - + /* discard extra CP's to avoid confusing ourselves */ while (control_points.size() > view_index) { @@ -849,9 +744,11 @@ AutomationLine::determine_visible_control_points (ALPoints& points) if (_visible) { line->show (); } + } set_selected_points (trackview.editor.get_selection().points); + } string @@ -886,7 +783,7 @@ AutomationLine::invalidate_point (ALPoints& p, uint32_t index) } void -AutomationLine::start_drag (ControlPoint* cp, float fraction) +AutomationLine::start_drag (ControlPoint* cp, nframes_t x, float fraction) { if (trackview.editor.current_session() == 0) { /* how? */ return; @@ -901,24 +798,43 @@ AutomationLine::start_drag (ControlPoint* cp, float fraction) } trackview.editor.current_session()->begin_reversible_command (str); - trackview.editor.current_session()->add_command (new MementoCommand(*this, &get_state(), 0)); + trackview.editor.current_session()->add_command (new MementoCommand(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(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(*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(*this, &before, &get_state())); + trackview.editor.current_session()->add_command(new MementoCommand(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::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 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 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 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_ptrget_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 +#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 > window_icons; + Glib::RefPtr 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 ds; - Playlist* pl; + boost::shared_ptr 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 ds; - Playlist* pl; - AudioPlaylist* apl; + boost::shared_ptr pl; + boost::shared_ptr apl; - if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()) != 0) && ((apl = dynamic_cast (pl)) != 0)) { + if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()) != 0) && ((apl = boost::dynamic_pointer_cast (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* all_equivs) { - Playlist* pl; + boost::shared_ptr pl; vector > results; RegionView* marv; boost::shared_ptr ds; @@ -2991,7 +3123,7 @@ Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32 } - if ((pl = dynamic_cast(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 regi if ((tatv = dynamic_cast (*i)) != 0) { - Playlist* pl; + boost::shared_ptr pl; vector > results; RegionView* marv; boost::shared_ptr ds; @@ -3201,8 +3333,8 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr regi /* bus */ continue; } - - if ((pl = dynamic_cast(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 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); 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 paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool); void do_embed (vector 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 paths, Editing::ImportMode mode, ARDOUR::AudioTrack* track, nframes_t& pos); + int embed_sndfile (vector 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 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 paths, bool split, bool as_tracks); + void do_import (vector 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 motion_frozen_playlists; + std::set > 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); vector 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 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 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 ract = RefPtr::cast_dynamic(act); if (ract && ract->get_active()) { - session->set_smpte_type (fps, drop); + session->set_smpte_format (format); } } } @@ -978,6 +965,70 @@ Editor::video_pullup_chosen (Session::PullupFormat pullup) } } +void +Editor::update_subframes_per_frame () +{ + ENSURE_GUI_THREAD (mem_fun(*this, &Editor::update_subframes_per_frame)); + + RefPtr 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 ract = RefPtr::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 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 ract = RefPtr::cast_dynamic(act); + if (ract && ract->get_active()) { + Config->set_subframes_per_frame ((uint32_t) rint (sfpf)); + } + + } else { + error << string_compose (_("programming error: %1"), "Editor::subframes_per_frame_chosen could not find action to match value.") << endmsg; + } +} + void Editor::toggle_auto_xfade () { @@ -1011,8 +1062,8 @@ Editor::parameter_changed (const char* parameter_name) update_punch_range_view (true); } else if (PARAM_IS ("layer-model")) { update_layering_model (); - } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) { - update_smpte_mode (); + } else if (PARAM_IS ("smpte-format")) { + update_smpte_mode (); update_just_smpte (); } else if (PARAM_IS ("video-pullup")) { update_video_pullup (); @@ -1026,6 +1077,9 @@ Editor::parameter_changed (const char* parameter_name) update_crossfade_model (); } else if (PARAM_IS ("edit-mode")) { edit_mode_selector.set_active_text (edit_mode_to_string (Config->get_edit_mode())); + } else if (PARAM_IS ("subframes-per-frame")) { + update_subframes_per_frame (); + update_just_smpte (); } #undef PARAM_IS 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 paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) +Editor::do_import (vector 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 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::iterator i = paths.begin(); i != paths.end(); ++i ) { - import_sndfile (*i, mode, track, pos); + vector to_import; + + for (vector::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 paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) +Editor::do_embed (vector paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) { bool multiple_files = paths.size() > 1; bool check_sample_rate = true; - vector::iterator i; + vector::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 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::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 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 foo; + + for (vector::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 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 paths, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) { boost::shared_ptr 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::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 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 (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 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 (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 (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 region, uint32_ case ImportToTrack: if (track) { - Playlist* playlist = track->diskstream()->playlist(); + boost::shared_ptr playlist = track->diskstream()->playlist(); boost::shared_ptr copy (boost::dynamic_pointer_cast (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& 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 (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 (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 (atv->get_diskstream()->playlist())) != 0) { + boost::shared_ptr pl; + if ((pl = boost::dynamic_pointer_cast (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(atv->get_diskstream()->playlist()); + boost::shared_ptr playlist = boost::dynamic_pointer_cast(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()); @@ -526,26 +542,6 @@ Editor::build_new_transport_marker_menu () new_transport_marker_menu->signal_unmap_event().connect ( mem_fun(*this, &Editor::new_transport_marker_menu_popdown)); } -void -Editor::build_transport_marker_menu () -{ - using namespace Menu_Helpers; - - transport_marker_menu = new Menu; - MenuList& items = transport_marker_menu->items(); - transport_marker_menu->set_name ("ArdourContextMenu"); - - items.push_back (MenuElem (_("Locate to Range Mark"), mem_fun(*this, &Editor::marker_menu_set_playhead))); - items.push_back (MenuElem (_("Play from Range Mark"), mem_fun(*this, &Editor::marker_menu_play_from))); - items.push_back (MenuElem (_("Set Range Mark from Playhead"), mem_fun(*this, &Editor::marker_menu_set_from_playhead))); - items.push_back (MenuElem (_("Set Range from Range Selection"), mem_fun(*this, &Editor::marker_menu_set_from_selection))); - items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Hide Range"), mem_fun(*this, &Editor::marker_menu_hide))); - items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Separate Regions in Range"), mem_fun(*this, &Editor::marker_menu_separate_regions_using_location))); - items.push_back (MenuElem (_("Select All in Range"), mem_fun(*this, &Editor::marker_menu_select_all_selectables_using_range))); -} - void Editor::marker_menu_hide () { @@ -726,6 +722,32 @@ Editor::marker_menu_set_from_selection () } } + +void +Editor::marker_menu_play_range () +{ + Marker* marker; + + if ((marker = reinterpret_cast (marker_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 height_list(512) ; vector::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 new_regionviews; - set affected_playlists; - pair::iterator,bool> insert_result; + set > affected_playlists; + pair >::iterator,bool> insert_result; + // TODO: Crossfades need to be copied! for (list::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 to_playlist = rv->region()->playlist(); RouteTimeAxisView* rtv = dynamic_cast(&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::iterator,bool> insert_result; + pair >::iterator,bool> insert_result; const list& layered_regions = selection->regions.by_layer(); for (list::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 (&rv->get_time_axis_view()); - if (rtv && rtv->is_track()) { - Playlist* pl = dynamic_cast(rtv->get_diskstream()->playlist()); + if (rtv && rtv->is_audio_track()) { + boost::shared_ptr pl = boost::dynamic_pointer_cast(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 (drag_info.data); - pair::iterator,bool> insert_result; + pair >::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::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) { - Playlist* from_playlist; - Playlist* to_playlist; + boost::shared_ptr from_playlist; + boost::shared_ptr 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(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::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) { - Playlist* from_playlist; - Playlist* to_playlist; + boost::shared_ptr from_playlist; + boost::shared_ptr 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::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) { + for (set >::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) { (*p)->thaw (); - session->add_command (new MementoCommand(*(*p), 0, & (*p)->get_state())); + session->add_command (new MementoCommand(*((*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 = 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(tvp); - pair::iterator,bool> insert_result; + pair >::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::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(*i); if (arv) arv->temporarily_hide_envelope (); - Playlist * pl = (*i)->region()->playlist(); + boost::shared_ptr pl = (*i)->region()->playlist(); insert_result = motion_frozen_playlists.insert (pl); if (insert_result.second) { session->add_command(new MementoCommand(*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::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) { + for (set >::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) { //(*p)->thaw (); - session->add_command (new MementoCommand(*(*p), 0, &(*p)->get_state())); + session->add_command (new MementoCommand(*(*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 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(*pl, &before, &after)); + session->add_command(new MementoCommand(*pl.get(), &before, &after)); } } } else { if (!rv->region()->locked()) { - Playlist *pl = rv->region()->playlist(); + boost::shared_ptr 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(*pl, &before, &after)); + session->add_command(new MementoCommand(*pl.get(), &before, &after)); } } @@ -4265,22 +4297,22 @@ Editor::point_trim (GdkEvent* event) for (list::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 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(*pl, &before, &after)); + session->add_command(new MementoCommand(*pl.get(), &before, &after)); } } } else { if (!rv->region()->locked()) { - Playlist *pl = rv->region()->playlist(); + boost::shared_ptr 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(*pl, &before, &after)); + session->add_command (new MementoCommand(*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(*(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 = atv->playlist(); double speed = atv->get_diskstream()->speed(); XMLNode &before = playlist->get_state(); playlist->add_region (boost::dynamic_pointer_cast (RegionFactory::create (arv->audio_region())), (nframes_t) (pos * speed)); XMLNode &after = playlist->get_state(); - session->add_command(new MementoCommand(*playlist, &before, &after)); + session->add_command(new MementoCommand(*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 #include #include +#include #include #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 pl = (*a)->region()->playlist(); AudioRegionView* const arv = dynamic_cast(*a); if (arv) @@ -149,7 +149,7 @@ Editor::remove_clicked_region () return; } - Playlist* playlist = clicked_routeview->playlist(); + boost::shared_ptr 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 (*tv)) != 0) { - Playlist *pl; + boost::shared_ptr 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 = 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, int x, int y) TimeAxisView *tv; nframes_t where; AudioTimeAxisView *atv = 0; - Playlist *playlist; + boost::shared_ptr 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, 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, &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; 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 current; boost::shared_ptr current_r; - Playlist *pl; + boost::shared_ptr pl; nframes_t internal_start; string new_name; @@ -2134,7 +2170,7 @@ Editor::create_region_from_selection (vector >& n boost::shared_ptr current; boost::shared_ptr current_r; - Playlist* playlist; + boost::shared_ptr playlist; nframes_t internal_start; string new_name; @@ -2191,7 +2227,7 @@ Editor::separate_region_from_selection () return; } - Playlist *playlist; + boost::shared_ptr 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; /* 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 playlists; - Playlist *playlist; + vector > playlists; + boost::shared_ptr playlist; if (clicked_axisview != 0) { @@ -2322,7 +2358,7 @@ Editor::crop_region_to_selection () begin_reversible_command (_("trim to selection")); - for (vector::iterator i = playlists.begin(); i != playlists.end(); ++i) { + for (vector >::iterator i = playlists.begin(); i != playlists.end(); ++i) { boost::shared_ptr region; @@ -2371,7 +2407,7 @@ Editor::region_fill_track () boost::shared_ptr ar = boost::dynamic_pointer_cast(region); assert(ar); - Playlist* pl = region->playlist(); + boost::shared_ptr 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; if (selection->tracks.empty()) { return; @@ -2781,7 +2817,7 @@ Editor::bounce_range_selection () continue; } - Playlist* playlist; + boost::shared_ptr 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; XMLNode* before; }; @@ -2910,7 +2946,7 @@ struct lt_playlist { void Editor::cut_copy_regions (CutCopyOp op) { - typedef std::map PlaylistMapping; + typedef std::map,boost::shared_ptr > 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((*x)->region()->playlist()); + boost::shared_ptr pl = boost::dynamic_pointer_cast((*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((*x)->region()->playlist()); - AudioPlaylist* npl; + boost::shared_ptr pl = boost::dynamic_pointer_cast((*x)->region()->playlist()); + boost::shared_ptr 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 (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 foo; + list > 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::iterator chunk; - list::iterator tmp; + list >::iterator chunk; + list >::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 pl; + boost::shared_ptr apl; if ((atv = dynamic_cast (*t)) == 0) { continue; @@ -3100,8 +3138,8 @@ Editor::paste_named_selection (float times) if ((pl = atv->playlist()) == 0) { continue; } - - if ((apl = dynamic_cast (pl)) == 0) { + + if ((apl = boost::dynamic_pointer_cast (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(*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; 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; vector > new_regions; vector >::iterator ri; @@ -3227,20 +3265,20 @@ Editor::center_edit_cursor () } void -Editor::clear_playlist (Playlist& playlist) +Editor::clear_playlist (boost::shared_ptr playlist) { begin_reversible_command (_("clear playlist")); - XMLNode &before = playlist.get_state(); - playlist.clear (); - XMLNode &after = playlist.get_state(); - session->add_command (new MementoCommand(playlist, &before, &after)); + XMLNode &before = playlist->get_state(); + playlist->clear (); + XMLNode &after = playlist->get_state(); + session->add_command (new MementoCommand(*playlist.get(), &before, &after)); commit_reversible_command (); } void Editor::nudge_track (bool use_edit_cursor, bool forwards) { - Playlist *playlist; + boost::shared_ptr 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 = 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 #include -#include +#include #include #include @@ -101,7 +101,8 @@ Editor::add_region_to_region_display (boost::shared_ptr region) parent = *(region_list_model->append()); parent[region_list_columns.name] = _("Hidden"); - /// XXX FIX ME parent[region_list_columns.region]->reset (); + boost::shared_ptr proxy = parent[region_list_columns.region]; + proxy.reset (); } else { @@ -109,7 +110,8 @@ Editor::add_region_to_region_display (boost::shared_ptr 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 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) if (region->whole_file()) { str = ".../"; - str += PBD::basename_nosuffix (region->source()->name()); - + + boost::shared_ptr afs = boost::dynamic_pointer_cast(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 thelist; + boost::shared_ptr what_we_found; + list > thelist; for (TrackViewList::iterator i = views->begin(); i != views->end(); ++i) { - Playlist *pl = (*i)->playlist(); + boost::shared_ptr 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; boost::shared_ptr 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 + +#include "audio_clock.h" + +using namespace std; +using namespace PBD; +using namespace ARDOUR; + +void +setup_gtk_ardour_enums () +{ + EnumWriter& enum_writer (EnumWriter::instance()); + vector i; + vector 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 > 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, 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, 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, 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, Session& s) Route* r; if ((r = dynamic_cast (_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, 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::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 (_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(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 #include +#include #include #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 Binary files /dev/null and b/gtk2_ardour/icons/ardour_icon_16px.png differ diff --git a/gtk2_ardour/icons/ardour_icon_22px.png b/gtk2_ardour/icons/ardour_icon_22px.png new file mode 100644 index 0000000000..bdf723edbd Binary files /dev/null and b/gtk2_ardour/icons/ardour_icon_22px.png differ diff --git a/gtk2_ardour/icons/ardour_icon_32px.png b/gtk2_ardour/icons/ardour_icon_32px.png new file mode 100644 index 0000000000..d906f35d68 Binary files /dev/null and b/gtk2_ardour/icons/ardour_icon_32px.png differ diff --git a/gtk2_ardour/icons/ardour_icon_48px.png b/gtk2_ardour/icons/ardour_icon_48px.png new file mode 100644 index 0000000000..298a56556a Binary files /dev/null and b/gtk2_ardour/icons/ardour_icon_48px.png differ diff --git a/gtk2_ardour/icons/fader_belt.png b/gtk2_ardour/icons/fader_belt.png new file mode 100644 index 0000000000..eefed15c76 Binary files /dev/null and b/gtk2_ardour/icons/fader_belt.png 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 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 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(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 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(&rhs_pane1))); - list_hpane.signal_button_release_event().connect (bind (sigc::ptr_fun (pane_handler), static_cast(&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 -#include #include #include #include @@ -60,7 +59,6 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui) /* Paths */ path_table (11, 2), - sfdb_path_view(), /* Fades */ @@ -71,7 +69,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui) /* Sync */ - smpte_offset_clock (X_("SMPTEOffsetClock"), true, true), + smpte_offset_clock (X_("smpteoffset"), false, X_("SMPTEOffsetClock"), true, true), smpte_offset_negative_button (_("SMPTE offset is negative")), /* MIDI */ @@ -99,7 +97,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui) set_default_size (300, 300); set_title (_("ardour: options editor")); - set_wmclass (_("ardour_option_editor"), "Ardour"); + set_wmclass (X_("ardour_option_editor"), "Ardour"); set_name ("OptionsWindow"); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); @@ -224,23 +222,9 @@ OptionEditor::setup_path_options() path_table.attach (*label, 0, 1, 0, 1, FILL|EXPAND, FILL); path_table.attach (session_raid_entry, 1, 3, 0, 1, Gtk::FILL|Gtk::EXPAND, FILL); - label = manage(new Label(_("Soundfile Search Paths"))); - label->set_name("OptionsLabel"); - path_table.attach(*label, 0, 1, 2, 3, FILL|EXPAND, FILL); - path_table.attach(sfdb_path_view, 1, 3, 2, 3, Gtk::FILL|Gtk::EXPAND, FILL); - - sfdb_path_view.set_paths(Library->get_paths()); - sfdb_path_view.PathsUpdated.connect (mem_fun(*this, &OptionEditor::sfdb_paths_changed)); - path_table.show_all(); } -void -OptionEditor::sfdb_paths_changed () -{ - Library->set_paths (sfdb_path_view.get_paths()); -} - void OptionEditor::add_session_paths () { @@ -549,7 +533,7 @@ void OptionEditor::port_online_toggled (MIDI::Port* port, ToggleButton* tb) { bool wanted = tb->get_active(); - + if (wanted != port->input()->offline()) { port->input()->set_offline (wanted); } @@ -558,12 +542,16 @@ OptionEditor::port_online_toggled (MIDI::Port* port, ToggleButton* tb) void OptionEditor::map_port_online (MIDI::Port* port, ToggleButton* tb) { - if (port->input()->offline()) { - tb->set_label (_("offline")); - tb->set_active (false); - } else { - tb->set_label (_("online")); - tb->set_active (true); + bool bstate = tb->get_active (); + + if (bstate != port->input()->offline()) { + if (port->input()->offline()) { + tb->set_label (_("offline")); + tb->set_active (false); + } else { + tb->set_label (_("online")); + tb->set_active (true); + } } } @@ -659,19 +647,12 @@ OptionEditor::click_sound_changed () return; } - if (path.empty()) { + strip_whitespace_edges (path); + if (path == _("internal")) { Config->set_click_sound (""); - } else { - - strip_whitespace_edges (path); - - if (path == _("internal")) { - Config->set_click_sound (""); - } else { - Config->set_click_sound (path); - } + Config->set_click_sound (path); } } } @@ -686,19 +667,12 @@ OptionEditor::click_emphasis_sound_changed () return; } - if (path.empty()) { + strip_whitespace_edges (path); + if (path == _("internal")) { Config->set_click_emphasis_sound (""); - } else { - - strip_whitespace_edges (path); - - if (path == _("internal")) { - Config->set_click_emphasis_sound (""); - } else { - Config->set_click_emphasis_sound (path); - } + Config->set_click_emphasis_sound (path); } } } 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 #include -#include - #include #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 + +#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 win (darea.get_window()); + Glib::RefPtr 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 + +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 @@ -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, Session& s) : _io (io), @@ -71,7 +73,7 @@ PannerUI::PannerUI (boost::shared_ptr 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, 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::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) { - (*i)->set_size_request (61, 15); + for (vector::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::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) { - (*i)->set_size_request (31, 15); + for (vector::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::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) { + for (vector::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::iterator i = pan_bars.begin(); i != pan_bars.end(); ++i) { + for (vector::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 pan_adjustments; - vector pan_bars; + vector 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 +#include namespace ARDOUR { class Playlist; } -struct PlaylistSelection : list {}; +struct PlaylistSelection : list > {}; #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 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 proxy = row[columns.playlist]; + proxy.reset (); } else { row = *(model->append (others.children())); row[columns.text] = nodename; - row[columns.playlist] = 0; + boost::shared_ptr proxy = row[columns.playlist]; + proxy.reset (); } /* Now insert all the playlists for this diskstream/track in a subtree */ - list *pls = x->second; + list > *pls = x->second; - for (list::iterator p = pls->begin(); p != pls->end(); ++p) { + for (list >::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 pl) { - AudioPlaylist* apl; + boost::shared_ptr apl; if (pl->frozen()) { return; } - - if ((apl = dynamic_cast (pl)) == 0) { + + if ((apl = boost::dynamic_pointer_cast (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*> newp (apl->get_orig_diskstream_id(), new list); + pair >*> newp (apl->get_orig_diskstream_id(), new list >); 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; 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 apl; if ((at = rui->audio_track()) == 0) { /* eh? */ return; } - if ((apl = dynamic_cast (playlist)) == 0) { + if ((apl = boost::dynamic_pointer_cast (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 + #include #include #include @@ -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*> DSPL_Map; + typedef std::map >*> 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); void clear_map (); void close_button_click (); void selection_changed (); @@ -66,7 +71,7 @@ class PlaylistSelector : public ArdourDialog add (playlist); } Gtk::TreeModelColumn text; - Gtk::TreeModelColumn playlist; + Gtk::TreeModelColumn > 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 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 (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 \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 \n" "Language-Team: Deutsch \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 \n" +"\tChristophe Combelles \n" msgstr "" -#: about.cc:147 +#: gtk2_ardour/about.cc:153 msgid "" "German:\n" "\tKarsten Petersen \n" msgstr "" +"German:\n" +"\tKarsten Petersen \n" +"\tSebastian Arnold \n" -#: about.cc:148 +#: gtk2_ardour/about.cc:154 msgid "" "Italian:\n" "\tFilippo Pappalardo \n" msgstr "" -#: about.cc:149 +#: gtk2_ardour/about.cc:155 msgid "" "Portuguese:\n" "\tRui Nuno Capela \n" msgstr "" -#: about.cc:150 +#: gtk2_ardour/about.cc:156 msgid "" "Brazilian Portuguese:\n" "\tAlexander da Franca Fernandes \n" "\tChris Ross \n" msgstr "" -#: about.cc:152 +#: gtk2_ardour/about.cc:158 msgid "" "Spanish:\n" "\t Alex Krohn \n" msgstr "" -#: about.cc:153 +#: gtk2_ardour/about.cc:159 msgid "" "Russian:\n" "\t Igor Blinov \n" msgstr "" -#: about.cc:181 -msgid "Copyright (C) 1999-2005 Paul Davis\n" +#: gtk2_ardour/about.cc:187 +msgid "Copyright (C) 1999-2006 Paul Davis\n" msgstr "" -#: about.cc:182 +#: gtk2_ardour/about.cc:188 msgid "" "Ardour comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; see the file COPYING for details.\n" msgstr "" -#: about.cc:188 +#: gtk2_ardour/about.cc:193 +msgid "visit http://www.ardour.org/" +msgstr "" + +#: gtk2_ardour/about.cc:194 msgid "" "%1\n" -"(built with ardour/gtk %2.%3.%4 libardour: %5.%6.%7)" +"(built from revision %2)" msgstr "" +"%1\n" +"(built from revision %2)" + +#: gtk2_ardour/actions.cc:77 +msgid "badly formatted UI definition file" +msgstr "die UI Definitionsdatei ist falsch formatiert" + +#: gtk2_ardour/actions.cc:79 +msgid "Ardour menu definition file not found" +msgstr "Konnte die Ardour Menü-Definition nicht finden" -#: actions.cc:261 +#: gtk2_ardour/actions.cc:83 +msgid "ardour will not work without a valid ardour.menus file" +msgstr "Ardour benötigt eine gültige ardour.menus Datei" + +#: gtk2_ardour/actions.cc:235 msgid "programmer error: %1 %2" +msgstr "Programmierfehler: %1 %2" + +#: gtk2_ardour/actions.cc:254 +msgid "Unknown action name: %1" +msgstr "Unbekannte Aktionsbezeichnung: %1" + +#: gtk2_ardour/add_route_dialog.cc:41 +#: gtk2_ardour/add_route_dialog.cc:196 +msgid "Mono" +msgstr "Mono" + +#: gtk2_ardour/add_route_dialog.cc:42 +#: gtk2_ardour/add_route_dialog.cc:198 +msgid "Stereo" +msgstr "Stereo" + +#: gtk2_ardour/add_route_dialog.cc:43 +msgid "3 Channels" +msgstr "3 Kanäle" + +#: gtk2_ardour/add_route_dialog.cc:44 +msgid "4 Channels" +msgstr "4 Kanäle" + +#: gtk2_ardour/add_route_dialog.cc:45 +msgid "6 Channels" +msgstr "6 Kanäle" + +#: gtk2_ardour/add_route_dialog.cc:46 +msgid "8 Channels" +msgstr "8 Kanäle" + +#: gtk2_ardour/add_route_dialog.cc:47 +msgid "Manual Setup" +msgstr "Manuell" + +#: gtk2_ardour/add_route_dialog.cc:52 +#: gtk2_ardour/add_route_dialog.cc:177 +#: gtk2_ardour/editor.cc:126 +#: gtk2_ardour/editor.cc:3485 +#: gtk2_ardour/editor_actions.cc:286 +#: gtk2_ardour/time_axis_view.cc:586 +msgid "Normal" +msgstr "Normal" + +#: gtk2_ardour/add_route_dialog.cc:53 +#: gtk2_ardour/add_route_dialog.cc:179 +msgid "Tape" msgstr "" -#: add_route_dialog.cc:62 -#, fuzzy +#: gtk2_ardour/add_route_dialog.cc:62 msgid "ardour: add track/bus" -msgstr "Ardour: Editor" +msgstr "Ardour: Füge Spur/Bus hinzu" -#. path = "1" -#: add_route_dialog.cc:63 editor_route_list.cc:73 +#: gtk2_ardour/add_route_dialog.cc:63 +#: gtk2_ardour/editor_route_list.cc:71 msgid "Tracks" msgstr "Spuren" -#. path = "0" -#: add_route_dialog.cc:64 editor_route_list.cc:70 +#: gtk2_ardour/add_route_dialog.cc:64 +#: gtk2_ardour/editor_route_list.cc:68 msgid "Busses" -msgstr "" +msgstr "Busse" -#: add_route_dialog.cc:96 plugin_ui.cc:833 +#: gtk2_ardour/add_route_dialog.cc:96 +#: gtk2_ardour/plugin_ui.cc:150 msgid "Add" msgstr "Hinzufügen" -#: add_route_dialog.cc:114 -#, fuzzy +#: gtk2_ardour/add_route_dialog.cc:114 msgid "Name (template)" -msgstr "Name für Mixer-Voreinstellung" +msgstr "Name für Mixer-Vorlage" -#: add_route_dialog.cc:120 -#, fuzzy +#: gtk2_ardour/add_route_dialog.cc:120 msgid "Channel Configuration" -msgstr "Importieren Abbrechen" - -#: add_route_dialog.cc:177 editor.cc:134 editor.cc:3688 time_axis_view.cc:552 -msgid "Normal" -msgstr "" - -#: add_route_dialog.cc:179 -#, fuzzy -msgid "Tape" -msgstr "Anfang" - -#: add_route_dialog.cc:196 -msgid "Mono" -msgstr "" - -#: add_route_dialog.cc:198 -#, fuzzy -msgid "Stereo" -msgstr "Stop" +msgstr "Kanaleinstellungen" -#. preroll stuff -#: ardour_ui.cc:106 +#: gtk2_ardour/ardour_ui.cc:106 msgid "" "pre\n" "roll" msgstr "" -#: ardour_ui.cc:107 +#: gtk2_ardour/ardour_ui.cc:107 msgid "" "post\n" "roll" msgstr "" -#. transport -#: ardour_ui.cc:115 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:115 msgid "" "time\n" "master" -msgstr "Ardour: Mixer" +msgstr "" +"Time\n" +"Master" -#: ardour_ui.cc:117 +#: gtk2_ardour/ardour_ui.cc:117 msgid "% " msgstr "" -#: ardour_ui.cc:119 -msgid "" -"punch\n" -"in" -msgstr "" +#: gtk2_ardour/ardour_ui.cc:119 +#: gtk2_ardour/ardour_ui_ed.cc:275 +msgid "Punch In" +msgstr "Punch In" -#: ardour_ui.cc:120 -msgid "" -"punch\n" -"out" -msgstr "" +#: gtk2_ardour/ardour_ui.cc:120 +#: gtk2_ardour/ardour_ui_ed.cc:278 +msgid "Punch Out" +msgstr "Punch Out" -#: ardour_ui.cc:121 -msgid "" -"auto\n" -"return" -msgstr "" +#: gtk2_ardour/ardour_ui.cc:121 +#: gtk2_ardour/ardour_ui_ed.cc:290 +msgid "Auto Return" +msgstr "Auto Return" -#: ardour_ui.cc:122 -msgid "" -"auto\n" -"play" -msgstr "" +#: gtk2_ardour/ardour_ui.cc:122 +msgid "Autuo Play" +msgstr "Auto Play" -#: ardour_ui.cc:123 -#, fuzzy -msgid "" -"auto\n" -"input" -msgstr "Port hinzufügen" +#: gtk2_ardour/ardour_ui.cc:123 +#: gtk2_ardour/ardour_ui_ed.cc:284 +msgid "Auto Input" +msgstr "Auto Input" -#: ardour_ui.cc:124 -msgid "click" -msgstr "" +#: gtk2_ardour/ardour_ui.cc:124 +#: gtk2_ardour/ardour_ui_ed.cc:281 +#: gtk2_ardour/option_editor.cc:128 +msgid "Click" +msgstr "Click" -#: ardour_ui.cc:125 -msgid "AUDITIONING" -msgstr "" +#: gtk2_ardour/ardour_ui.cc:125 +msgid "AUDITION" +msgstr "VORHÖREN" -#: ardour_ui.cc:126 +#: gtk2_ardour/ardour_ui.cc:126 msgid "SOLO" -msgstr "" +msgstr "SOLO" -#: ardour_ui.cc:375 +#: gtk2_ardour/ardour_ui.cc:370 msgid "quit" -msgstr "Verlassen" +msgstr "Beenden" -#: ardour_ui.cc:384 +#: gtk2_ardour/ardour_ui.cc:379 msgid "" "Ardour was unable to save your session.\n" "\n" @@ -297,35 +360,37 @@ msgid "" "\n" "\"Just quit\" option." msgstr "" +"Ardour konnte die Sitzung nicht speichern.\n" +"\n" +"Wenn Sie trotzdem beenden wollen, wählen Sie bitte\n" +"\n" +"\"Trotzdem beenden\"." -#: ardour_ui.cc:403 +#: gtk2_ardour/ardour_ui.cc:398 msgid "ardour: save session?" msgstr "Ardour: Sitzung speichern?" -#: ardour_ui.cc:410 +#: gtk2_ardour/ardour_ui.cc:405 msgid "Don't %1" -msgstr "Ohne %1" +msgstr "Nicht %1" -#: ardour_ui.cc:412 +#: gtk2_ardour/ardour_ui.cc:407 msgid "Just %1" -msgstr "Nur %1" +msgstr "%1 ohne zu Speichern" -#: ardour_ui.cc:414 +#: gtk2_ardour/ardour_ui.cc:409 msgid "Save and %1" msgstr "Speichern und %1" -#: ardour_ui.cc:426 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:421 msgid "session" msgstr "Sitzung" -#: ardour_ui.cc:428 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:423 msgid "snapshot" -msgstr "Schnappschuß" +msgstr "Schnappschuss..." -#: ardour_ui.cc:430 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:425 msgid "" "The %1\"%2\"\n" "has not been saved.\n" @@ -335,7 +400,7 @@ msgid "" "\n" "What do you want to do?" msgstr "" -"Die Sitzung \"%1\"\n" +"Die Sitzung %1\"%2\"\n" "wurde nicht gespeichert.\n" "\n" "Alle Änderungen werden verloren\n" @@ -343,159 +408,179 @@ msgstr "" "\n" "Was wollen Sie machen?" -#: ardour_ui.cc:444 +#: gtk2_ardour/ardour_ui.cc:439 msgid "Prompter" msgstr "" -#: ardour_ui.cc:503 -#, fuzzy, c-format +#: gtk2_ardour/ardour_ui.cc:498 +#, c-format msgid "disconnected" -msgstr "Trennen" +msgstr "getrennt" -#: ardour_ui.cc:510 +#: gtk2_ardour/ardour_ui.cc:505 #, c-format -msgid "SR: %.1f kHz / %4.1f msecs" +msgid "%.1f kHz / %4.1f msecs" msgstr "" -#: ardour_ui.cc:514 +#: gtk2_ardour/ardour_ui.cc:509 #, c-format -msgid "SR: %u kHz / %4.1f msecs" +msgid "%u kHz / %4.1f msecs" msgstr "" -#: ardour_ui.cc:527 -#, fuzzy, c-format -msgid "DSP Load: %.1f%%" -msgstr "Auslastung der CPU: %.1f%%" +#: gtk2_ardour/ardour_ui.cc:522 +#, c-format +msgid "DSP: %.1f%%" +msgstr "CPU Auslastung: %.1f%%" -#: ardour_ui.cc:537 +#: gtk2_ardour/ardour_ui.cc:532 #, c-format msgid "Buffers p:%%% c:%%%" -msgstr "" +msgstr "Buffer p:%%% c:%%%" -#: ardour_ui.cc:564 -msgid "space: 24hrs+" +#: gtk2_ardour/ardour_ui.cc:560 +msgid "Disk: 24hrs+" msgstr "Platz: >24 Stunden" -#: ardour_ui.cc:594 +#: gtk2_ardour/ardour_ui.cc:580 #, c-format -msgid "space: %02dh:%02dm:%02ds" +msgid "Disk: %02dh:%02dm:%02ds" msgstr "Platz: %02dh:%02dm:%02ds" -#: ardour_ui.cc:633 +#: gtk2_ardour/ardour_ui.cc:619 msgid "programming error: impossible control method" -msgstr "" +msgstr "Programmierfehler: ungültige Kontrollmethode" -#: ardour_ui.cc:741 new_session_dialog.cc:294 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:727 +#: gtk2_ardour/new_session_dialog.cc:355 msgid "Recent Sessions" -msgstr "Sitzung" +msgstr "Zuletzt verwendete Sitzungen" -#. ardour sessions are folders -#: ardour_ui.cc:834 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:820 msgid "open session" -msgstr "Sitzung" +msgstr "Sitzung öffnen" -#: ardour_ui.cc:840 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:826 msgid "Ardour sessions" -msgstr "Ardour: Neue Sitzung" +msgstr "Ardour-Sitzungen" -#: ardour_ui.cc:873 +#: gtk2_ardour/ardour_ui.cc:859 msgid "Patience is a virtue.\n" msgstr "Geduld ist eine Tugend.\n" -#: ardour_ui.cc:882 -msgid "You cannot add a track without a session already loaded." -msgstr "Sie können erst eine Spur hinzufügen, wenn eine Sitzung geladen wurde." +#: gtk2_ardour/ardour_ui.cc:869 +msgid "You cannot add a track or bus without a session already loaded." +msgstr "Sie können erst Spuren oder Busse hinzufügen, wenn eine Sitzung geladen wurde." -#: ardour_ui.cc:889 -msgid "could not create new audio track" +#: gtk2_ardour/ardour_ui.cc:879 +#: gtk2_ardour/ardour_ui.cc:891 +msgid "could not create a new audio track" msgstr "Konnte neue Spur nicht erstellen." -#: ardour_ui.cc:893 -msgid "could not create new audio bus" -msgstr "Konnte neuen Audiokanal nicht erstellen." +#: gtk2_ardour/ardour_ui.cc:881 +#: gtk2_ardour/ardour_ui.cc:893 +msgid "could not create %1 new audio tracks" +msgstr "Konnte %1 neue Spuren nicht erstellen." -#: ardour_ui.cc:912 +#: gtk2_ardour/ardour_ui.cc:913 msgid "" "There are insufficient JACK ports available\n" "to create a new track or bus.\n" "You should save Ardour, exit and\n" "restart JACK with more ports." msgstr "" +"Es sind nicht genügend JACK Ports verfügbar\n" +"um neue Spuren oder Busse zu erstellen.\n" +"Speichern Sie Ihre Sitzung und starten Sie\n" +"Ardour sowie JACK mit einer größeren\n" +"Anzahl Ports erneut." -#: ardour_ui.cc:1036 +#: gtk2_ardour/ardour_ui.cc:1033 msgid "" "Please create 1 or more track\n" "before trying to record.\n" "Check the Session menu." msgstr "" +"Bitte fügen Sie mindestens eine weitere Spur hinzu,\n" +"bevor Sie aufnehmen.\n" +"Weitere Einstellungen finden Sie im Sitzungsmenü." -#: ardour_ui.cc:1265 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:1253 msgid "" "JACK has either been shutdown or it\n" "disconnected Ardour because Ardour\n" "was not fast enough. You can save the\n" "session and/or try to reconnect to JACK ." msgstr "" -"JACK wurde entweder beendet oder es\n" -"hat Ardour abgekoppelt weil Ardour nicht\n" +"JACK wurde entweder beendet oder\n" +"hat Ardour getrennt weil Ardour nicht\n" "schnell genug war. Sie sollten die Sitzung\n" -"speichern und JACK sowie Ardour neu starten." +"speichern versuchen, erneut zu JACK zu verbinden." -#: ardour_ui.cc:1282 +#: gtk2_ardour/ardour_ui.cc:1270 msgid "Unable to create all required ports" -msgstr "" +msgstr "Ardour konnte nicht alle benötigten Ports erstellen." -#: ardour_ui.cc:1290 +#: gtk2_ardour/ardour_ui.cc:1278 #, fuzzy msgid "Unable to start the session running" -msgstr "An den Anfang der Sitzung springen" - -#: ardour_ui.cc:1426 -msgid "No Stream" -msgstr "Kein Datenstrom" +msgstr "Konnte die aktuelle Sitzung nicht starten" -#: ardour_ui.cc:1453 ardour_ui.cc:1472 +#: gtk2_ardour/ardour_ui.cc:1384 +#: gtk2_ardour/ardour_ui.cc:1403 +#: gtk2_ardour/audio_clock.cc:448 msgid "none" msgstr "keine" -#: ardour_ui.cc:1462 ardour_ui.cc:1481 +#: gtk2_ardour/ardour_ui.cc:1393 +#: gtk2_ardour/ardour_ui.cc:1412 msgid "off" msgstr "aus" -#: ardour_ui.cc:1505 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:1435 msgid "Name of New Snapshot" -msgstr "Name für Schnappschuß" +msgstr "Name für neuen Schnappschuss" -#: ardour_ui.cc:1651 +#: gtk2_ardour/ardour_ui.cc:1581 msgid "Name for mix template:" -msgstr "Name für Mixer-Voreinstellung" +msgstr "Name für Mixer-Vorlage" -#: ardour_ui.cc:1652 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:1582 msgid "-template" -msgstr "Voreinstellung" +msgstr "Vorlage" + +#: gtk2_ardour/ardour_ui.cc:1703 +msgid "" +"This session\n" +"%1\n" +"already exists. Do you want to open it?" +msgstr "" +"Die Sitzung\n" +"%1\n" +"existiert bereits. Wollen Sie sie öffnen?" -#: ardour_ui.cc:1809 +#: gtk2_ardour/ardour_ui.cc:1713 +#, fuzzy +msgid "existing_session" +msgstr "Stellen" + +#: gtk2_ardour/ardour_ui.cc:1819 msgid "" "You do not have write access to this session.\n" "This prevents the session from being loaded." msgstr "" +"Sie haben keinen Schreibzugriff auf diese Sitzung.\n" +"Dadurch kann die Sitzung nicht geladen werden." -#: ardour_ui.cc:1822 ardour_ui.cc:1877 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:1832 +#: gtk2_ardour/ardour_ui.cc:1889 msgid "Session \"%1 (snapshot %2)\" did not load successfully" -msgstr "Sitzung \"%1\" konnte nicht geladen werden." +msgstr "Sitzung \"%1 (Schnappschuss %2)\" konnte nicht geladen werden." -#: ardour_ui.cc:1933 +#: gtk2_ardour/ardour_ui.cc:1948 msgid "No audio files were ready for cleanup" -msgstr "" +msgstr "Keine Audiodateien zum Aufräumen vorhanden" -#: ardour_ui.cc:1937 +#: gtk2_ardour/ardour_ui.cc:1952 msgid "" "If this seems suprising, \n" "check for any existing snapshots.\n" @@ -503,51 +588,53 @@ msgid "" "require some unused files to continue to exist." msgstr "" -#: ardour_ui.cc:1946 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:1961 msgid "ardour: cleanup" -msgstr "Ardour: Uhr" +msgstr "Ardour: Aufräumen" -#: ardour_ui.cc:1982 ardour_ui.cc:1988 +#: gtk2_ardour/ardour_ui.cc:1997 +#: gtk2_ardour/ardour_ui.cc:2003 msgid "files were" -msgstr "" +msgstr "folgenden Dateien wurden" -#: ardour_ui.cc:1984 ardour_ui.cc:1990 +#: gtk2_ardour/ardour_ui.cc:1999 +#: gtk2_ardour/ardour_ui.cc:2005 msgid "file was" -msgstr "" +msgstr "folgende Datei wurde" -#: ardour_ui.cc:2031 +#: gtk2_ardour/ardour_ui.cc:2046 msgid "Are you sure you want to cleanup?" -msgstr "" +msgstr "Sind Sie sicher, dass Sie aufräumen wollen?" -#: ardour_ui.cc:2036 +#: gtk2_ardour/ardour_ui.cc:2051 msgid "" "Cleanup is a destructive operation.\n" "ALL undo/redo information will be lost if you cleanup.\n" -"After cleanup, unused audio files will be moved to a \"dead sounds\" " -"location." +"After cleanup, unused audio files will be moved to a \"dead sounds\" location." msgstr "" +"Das Aufräumen ist eine destruktive Operation.\n" +"Sämtliche Wiederherstellungsinformationen gehen verloren, wenn Sie aufräumen.\n" +"Nach dem Aufräumen werden alle nicht benötigten Audiodateien in einen \"dead sounds\" Ordner verschoben." -#: ardour_ui.cc:2042 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:2057 msgid "Clean Up" -msgstr "leeren" +msgstr "Aufräumen" -#: ardour_ui.cc:2045 +#: gtk2_ardour/ardour_ui.cc:2060 #, fuzzy msgid "CleanupDialog" msgstr "leeren" -#: ardour_ui.cc:2046 +#: gtk2_ardour/ardour_ui.cc:2061 #, fuzzy msgid "ardour_cleanup" msgstr "Ardour: Uhr" -#: ardour_ui.cc:2065 +#: gtk2_ardour/ardour_ui.cc:2080 msgid "cleaned files" -msgstr "" +msgstr "aufgeräumte Dateien" -#: ardour_ui.cc:2066 +#: gtk2_ardour/ardour_ui.cc:2081 msgid "" "The following %1 %2 not in use and \n" "have been moved to:\n" @@ -557,24 +644,32 @@ msgid "" "release an additional\n" "%4 %5bytes of disk space.\n" msgstr "" +"Die %1 %2 nicht benötigt und\n" +"verschoben nach:\n" +"%3. \n" +"\n" +"Wenn Sie den Müll leeren werden weitere\n" +"%4 %5byte Speicherplatz frei.\n" -#: ardour_ui.cc:2091 -#, fuzzy +#: gtk2_ardour/ardour_ui.cc:2106 msgid "deleted file" -msgstr "entfernen" +msgstr "gelöschte Datei" -#: ardour_ui.cc:2092 +#: gtk2_ardour/ardour_ui.cc:2107 msgid "" "The following %1 %2 deleted from\n" "%3,\n" "releasing %4 %5bytes of disk space" msgstr "" +"Die %1 %2 gelöscht aus\n" +"%3,\n" +"und machten %4 %5byte Speicherplatz frei" -#: ardour_ui.cc:2215 +#: gtk2_ardour/ardour_ui.cc:2223 msgid "Recording was stopped because your system could not keep up." msgstr "" -#: ardour_ui.cc:2238 +#: gtk2_ardour/ardour_ui.cc:2234 msgid "" "The disk system on your computer\n" "was not able to keep up with Ardour.\n" @@ -583,7 +678,7 @@ msgid "" "quickly enough to keep up with recording.\n" msgstr "" -#: ardour_ui.cc:2257 +#: gtk2_ardour/ardour_ui.cc:2253 msgid "" "The disk system on your computer\n" "was not able to keep up with Ardour.\n" @@ -592,7 +687,7 @@ msgid "" "quickly enough to keep up with playback.\n" msgstr "" -#: ardour_ui.cc:2283 +#: gtk2_ardour/ardour_ui.cc:2279 msgid "" "This session appears to have been in\n" "middle of recording when ardour or\n" @@ -603,3482 +698,3564 @@ msgid "" "what you would like to do.\n" msgstr "" -#: ardour_ui.cc:2293 +#: gtk2_ardour/ardour_ui.cc:2289 msgid "Recover from crash" msgstr "" -#: ardour_ui.cc:2294 +#: gtk2_ardour/ardour_ui.cc:2290 msgid "Ignore crash data" msgstr "" -#: ardour_ui.cc:2312 +#: gtk2_ardour/ardour_ui.cc:2308 msgid "Could not disconnect from JACK" msgstr "" -#: ardour_ui.cc:2325 +#: gtk2_ardour/ardour_ui.cc:2321 msgid "Could not reconnect to JACK" msgstr "" -#: ardour_ui2.cc:60 +#: gtk2_ardour/ardour_ui2.cc:60 msgid "UI: cannot setup editor" msgstr "Der Editor konnte nicht initialisiert werden." -#: ardour_ui2.cc:65 +#: gtk2_ardour/ardour_ui2.cc:65 msgid "UI: cannot setup mixer" msgstr "Der Mixer konnte nicht initialisiert werden." -#: ardour_ui2.cc:91 +#: gtk2_ardour/ardour_ui2.cc:91 msgid "MMC + Local" msgstr "" -#: ardour_ui2.cc:92 +#: gtk2_ardour/ardour_ui2.cc:92 msgid "MMC" msgstr "" -#: ardour_ui2.cc:93 +#: gtk2_ardour/ardour_ui2.cc:93 msgid "Local" msgstr "" -#: ardour_ui2.cc:110 +#: gtk2_ardour/ardour_ui2.cc:110 msgid "MMC ID" msgstr "" -#: ardour_ui2.cc:291 +#: gtk2_ardour/ardour_ui2.cc:295 msgid "Play from playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Wiedergabe ab Positionszeiger" -#: ardour_ui2.cc:292 +#: gtk2_ardour/ardour_ui2.cc:296 msgid "Stop playback" msgstr "Wiedergabe anhalten" -#: ardour_ui2.cc:293 -#, fuzzy +#: gtk2_ardour/ardour_ui2.cc:297 msgid "Play range/selection" -msgstr "Auswahl wiedergeben" +msgstr "Bereich/Auswahl wiedergeben" -#: ardour_ui2.cc:294 +#: gtk2_ardour/ardour_ui2.cc:298 msgid "Go to start of session" msgstr "An den Anfang der Sitzung springen" -#: ardour_ui2.cc:295 +#: gtk2_ardour/ardour_ui2.cc:299 msgid "Go to end of session" msgstr "Ans Ende der Sitzung springen" -#: ardour_ui2.cc:296 -#, fuzzy +#: gtk2_ardour/ardour_ui2.cc:300 msgid "Play loop range" -msgstr "Bereich" +msgstr "Schleife wiedergeben" -#: ardour_ui2.cc:297 +#: gtk2_ardour/ardour_ui2.cc:301 msgid "Return to last playback start when stopped" -msgstr "Bei Stopp zum Wiedergabeanfang springen" +msgstr "Bei Stop zum letzten Wiedergabeanfang springen" -#: ardour_ui2.cc:298 +#: gtk2_ardour/ardour_ui2.cc:302 msgid "Start playback after any locate" -msgstr "" +msgstr "Startet die Wiedergabe nach setzen des Positionszeigers" -#: ardour_ui2.cc:299 +#: gtk2_ardour/ardour_ui2.cc:303 msgid "Be sensible about input monitoring" -msgstr "" +msgstr "Automatisches Input Monitoring aktivieren" -#: ardour_ui2.cc:300 +#: gtk2_ardour/ardour_ui2.cc:304 msgid "Start recording at auto-punch start" -msgstr "" +msgstr "Beginnt die Aufnahme bei Auto-Punch Start" -#: ardour_ui2.cc:301 +#: gtk2_ardour/ardour_ui2.cc:305 msgid "Stop recording at auto-punch end" -msgstr "" +msgstr "Beginnt die Aufnahme bei Auto-Punch Ende" -#: ardour_ui2.cc:302 +#: gtk2_ardour/ardour_ui2.cc:306 msgid "Enable/Disable audio click" -msgstr "" +msgstr "Aktiviert/Deaktiviert Audio Click" -#: ardour_ui2.cc:303 +#: gtk2_ardour/ardour_ui2.cc:307 msgid "Positional sync source" msgstr "" -#: ardour_ui2.cc:304 +#: gtk2_ardour/ardour_ui2.cc:308 msgid "Does Ardour control the time?" -msgstr "" +msgstr "Bestimmt Ardour die Time?" -#: ardour_ui2.cc:305 +#: gtk2_ardour/ardour_ui2.cc:309 msgid "Shuttle speed control" -msgstr "" +msgstr "Shuttle-Geschwindigkeit" -#: ardour_ui2.cc:306 +#: gtk2_ardour/ardour_ui2.cc:310 #, c-format msgid "Select semitones or %%-age for speed display" -msgstr "" +msgstr "Geschwindigkeitsanzeige als Prozent oder Halbtöne einstellen" -#: ardour_ui2.cc:307 +#: gtk2_ardour/ardour_ui2.cc:311 msgid "Current transport speed" -msgstr "" +msgstr "Geschwindigkeitsanzeige" -#: ardour_ui2.cc:330 -#, fuzzy +#: gtk2_ardour/ardour_ui2.cc:334 msgid "Primary clock" -msgstr "Ardour: Uhr" +msgstr "" -#: ardour_ui2.cc:331 +#: gtk2_ardour/ardour_ui2.cc:335 msgid "secondary clock" msgstr "" -#. XXX: this should really be saved in instant.xml or something similar and restored from there -#. Combo's are stupid - they steal space from the entry for the button -#: ardour_ui2.cc:388 ardour_ui2.cc:833 ardour_ui2.cc:846 ardour_ui2.cc:909 -#: ardour_ui2.cc:911 -msgid "sprung" +#: gtk2_ardour/ardour_ui2.cc:366 +msgid "" +"When active, something is soloed.\n" +"Click to de-solo everything" msgstr "" +"Wird aktiv, wenn eine Spur Solo läuft.\n" +"Schaltet bei Klick Solo aus." -#: ardour_ui2.cc:389 ardour_ui2.cc:835 ardour_ui2.cc:857 -msgid "wheel" +#: gtk2_ardour/ardour_ui2.cc:367 +msgid "" +"When active, auditioning is taking place\n" +"Click to stop the audition" msgstr "" +"Wird beim Vorhören aktiv.\n" +"Klicken stoppt das Vorhören." -#: ardour_ui2.cc:451 -msgid "ardour: clock" -msgstr "Ardour: Uhr" +#: gtk2_ardour/ardour_ui2.cc:395 +#: gtk2_ardour/ardour_ui2.cc:826 +#: gtk2_ardour/ardour_ui2.cc:882 +#: gtk2_ardour/ardour_ui_options.cc:804 +msgid "sprung" +msgstr "Feder" -#: ardour_ui2.cc:596 +#: gtk2_ardour/ardour_ui2.cc:396 +#: gtk2_ardour/ardour_ui2.cc:828 +#: gtk2_ardour/ardour_ui_options.cc:815 +msgid "wheel" +msgstr "Drehrad" + +#: gtk2_ardour/ardour_ui2.cc:602 msgid "Maximum speed" msgstr "" -#: ardour_ui2.cc:823 -#, fuzzy -msgid "st" -msgstr "bestmöglich" +#: gtk2_ardour/ardour_ui2.cc:838 +#: gtk2_ardour/ardour_ui2.cc:861 +msgid "stop" +msgstr "Stop" -#: ardour_ui2.cc:867 ardour_ui2.cc:890 ardour_ui2.cc:907 -msgid "stopped" +#: gtk2_ardour/ardour_ui2.cc:880 +msgid "-0.55" msgstr "" -#: ardour_ui_dialogs.cc:153 playlist_selector.cc:70 -#, fuzzy +#: gtk2_ardour/ardour_ui_dialogs.cc:146 +#: gtk2_ardour/playlist_selector.cc:70 msgid "close" msgstr "Schließen" -#: ardour_ui_dialogs.cc:360 ardour_ui_ed.cc:184 -#, fuzzy +#: gtk2_ardour/ardour_ui_dialogs.cc:353 +#: gtk2_ardour/ardour_ui_ed.cc:192 msgid "Sound File Browser" -msgstr "Ardour: Audio Bibliothek" +msgstr "Audio-Browser" -#. menus + submenus that need action items -#: ardour_ui_ed.cc:72 +#: gtk2_ardour/ardour_ui_ed.cc:77 msgid "Session" msgstr "Sitzung" -#: ardour_ui_ed.cc:73 ardour_ui_ed.cc:130 editor.cc:1836 export_dialog.cc:350 -#: export_dialog.cc:1059 export_dialog.cc:1063 +#: gtk2_ardour/ardour_ui_ed.cc:78 +#: gtk2_ardour/ardour_ui_ed.cc:138 +#: gtk2_ardour/editor.cc:1713 +#: gtk2_ardour/export_dialog.cc:348 +#: gtk2_ardour/export_dialog.cc:1057 +#: gtk2_ardour/export_dialog.cc:1061 msgid "Export" msgstr "Exportieren" -#: ardour_ui_ed.cc:74 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:79 msgid "Cleanup" -msgstr "leeren" +msgstr "Aufräumen" -#: ardour_ui_ed.cc:75 option_editor.cc:126 +#: gtk2_ardour/ardour_ui_ed.cc:80 +#: gtk2_ardour/option_editor.cc:125 msgid "Sync" msgstr "" -#: ardour_ui_ed.cc:76 ardour_ui_ed.cc:77 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:81 +#: gtk2_ardour/ardour_ui_ed.cc:82 msgid "Options" -msgstr "Geschwindigkeitseditor" +msgstr "Optionen" -#: ardour_ui_ed.cc:78 +#: gtk2_ardour/ardour_ui_ed.cc:83 msgid "Help" -msgstr "" +msgstr "Hilfe" -#: ardour_ui_ed.cc:79 +#: gtk2_ardour/ardour_ui_ed.cc:84 msgid "KeyMouse Actions" -msgstr "" +msgstr "Tastatur/Maus-Befehle" -#: ardour_ui_ed.cc:80 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:85 msgid "Audio File Format" -msgstr "Ardour: Audio Bibliothek" +msgstr "Audio-Dateiformat" -#: ardour_ui_ed.cc:81 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:86 msgid "Header" -msgstr "Verbergen" +msgstr "Header" -#: ardour_ui_ed.cc:82 +#: gtk2_ardour/ardour_ui_ed.cc:87 msgid "Data" -msgstr "" +msgstr "Datenformat" -#: ardour_ui_ed.cc:83 +#: gtk2_ardour/ardour_ui_ed.cc:88 msgid "Control Surfaces" -msgstr "" +msgstr "Eingabegeräte" -#. the real actions -#: ardour_ui_ed.cc:87 audio_time_axis.cc:1854 new_session_dialog.cc:529 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:89 +msgid "Metering" +msgstr "Pegelanzeige" + +#: gtk2_ardour/ardour_ui_ed.cc:90 +msgid "Fall off rate" +msgstr "Abfall der Pegelanzeige" + +#: gtk2_ardour/ardour_ui_ed.cc:91 +msgid "Hold Time" +msgstr "Pegelanzeige halten" + +#: gtk2_ardour/ardour_ui_ed.cc:95 +#: gtk2_ardour/route_time_axis.cc:1288 +#: gtk2_ardour/new_session_dialog.cc:600 msgid "New" msgstr "Neu..." -#: ardour_ui_ed.cc:89 new_session_dialog.cc:517 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:97 +#: gtk2_ardour/new_session_dialog.cc:587 msgid "Open" msgstr "Öffnen..." -#: ardour_ui_ed.cc:90 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:98 msgid "Recent" -msgstr "Zurücksetzen" +msgstr "Zuletzt verwendet..." -#: ardour_ui_ed.cc:91 io_selector.cc:58 io_selector.cc:792 +#: gtk2_ardour/ardour_ui_ed.cc:99 +#: gtk2_ardour/io_selector.cc:60 +#: gtk2_ardour/io_selector.cc:749 +#: gtk2_ardour/connection_editor.cc:59 msgid "Close" msgstr "Schließen" -#: ardour_ui_ed.cc:94 route_params_ui.cc:514 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:102 +#: gtk2_ardour/route_params_ui.cc:510 msgid "Add Track/Bus" -msgstr "MIDI Spur(en) hinzufügen" +msgstr "Spur/Bus hinzufügen..." -#: ardour_ui_ed.cc:105 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:113 msgid "Connect" -msgstr "Verbindungen" +msgstr "Verbinden" -#. -#: ardour_ui_ed.cc:113 +#: gtk2_ardour/ardour_ui_ed.cc:121 msgid "Snapshot" -msgstr "Schnappschuß" +msgstr "Schnappschuss" -#: ardour_ui_ed.cc:116 +#: gtk2_ardour/ardour_ui_ed.cc:124 msgid "Save Template..." -msgstr "Speichern als Voreinstellung..." +msgstr "Als Vorlage Speichern..." -#: ardour_ui_ed.cc:119 +#: gtk2_ardour/ardour_ui_ed.cc:127 msgid "Export session to audiofile..." -msgstr "Export als Audio-Datei..." +msgstr "Exportiere Sitzung als Audio-Datei..." -#: ardour_ui_ed.cc:122 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:130 msgid "Export selection to audiofile..." -msgstr "Export als Audio-Datei..." +msgstr "Exportiere Auswahl als Audio-Datei..." -#: ardour_ui_ed.cc:126 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:134 msgid "Export range markers to audiofile..." -msgstr "Export als Audio-Datei..." +msgstr "Exportiere Bereich als Audio-Datei..." -#: ardour_ui_ed.cc:133 +#: gtk2_ardour/ardour_ui_ed.cc:141 msgid "Cleanup unused sources" -msgstr "" +msgstr "Nicht benutzte Dateien entfernen" -#: ardour_ui_ed.cc:135 +#: gtk2_ardour/ardour_ui_ed.cc:143 msgid "Flush wastebasket" -msgstr "" +msgstr "Müll leeren" -#: ardour_ui_ed.cc:141 ardour_ui_options.cc:408 ardour_ui_options.cc:417 -#: ardour_ui_options.cc:489 +#: gtk2_ardour/ardour_ui_ed.cc:149 msgid "JACK" msgstr "" -#: ardour_ui_ed.cc:142 +#: gtk2_ardour/ardour_ui_ed.cc:150 msgid "Latency" -msgstr "" +msgstr "Latenz" -#: ardour_ui_ed.cc:144 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:152 msgid "Reconnect" -msgstr "Verbindungen" +msgstr "Neu Verbinden" -#: ardour_ui_ed.cc:147 mixer_strip.cc:497 mixer_strip.cc:565 +#: gtk2_ardour/ardour_ui_ed.cc:155 +#: gtk2_ardour/mixer_strip.cc:517 +#: gtk2_ardour/mixer_strip.cc:579 msgid "Disconnect" msgstr "Trennen" -#: ardour_ui_ed.cc:174 +#: gtk2_ardour/ardour_ui_ed.cc:182 msgid "Windows" msgstr "Fenster" -#: ardour_ui_ed.cc:175 +#: gtk2_ardour/ardour_ui_ed.cc:183 msgid "start prefix" msgstr "" -#: ardour_ui_ed.cc:176 +#: gtk2_ardour/ardour_ui_ed.cc:184 msgid "Quit" msgstr "Beenden" -#. windows visibility actions -#: ardour_ui_ed.cc:180 +#: gtk2_ardour/ardour_ui_ed.cc:188 msgid "Maximise Editor Space" -msgstr "" +msgstr "Editor Maximieren" -#: ardour_ui_ed.cc:182 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:190 msgid "Show Editor" -msgstr "Geschwindigkeitseditor" +msgstr "Editor anzeigen" -#: ardour_ui_ed.cc:183 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:191 msgid "Show Mixer" -msgstr "Mixer" +msgstr "Mixer anzeigen" -#: ardour_ui_ed.cc:185 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:193 msgid "Options Editor" -msgstr "Geschwindigkeitseditor" +msgstr "Optionen" -#: ardour_ui_ed.cc:186 +#: gtk2_ardour/ardour_ui_ed.cc:194 msgid "Track/Bus Inspector" -msgstr "" +msgstr "Verbindungen" -#: ardour_ui_ed.cc:188 +#: gtk2_ardour/ardour_ui_ed.cc:196 +#: gtk2_ardour/connection_editor.cc:147 +#: gtk2_ardour/connection_editor.cc:148 msgid "Connections" msgstr "Verbindungen" -#: ardour_ui_ed.cc:190 +#: gtk2_ardour/ardour_ui_ed.cc:198 msgid "Locations" -msgstr "Stellen" +msgstr "Lokatoren" -#: ardour_ui_ed.cc:192 +#: gtk2_ardour/ardour_ui_ed.cc:200 msgid "Big Clock" msgstr "Große Uhr" -#: ardour_ui_ed.cc:194 +#: gtk2_ardour/ardour_ui_ed.cc:202 msgid "About" -msgstr "" +msgstr "Ãœber Ardour..." -#: ardour_ui_ed.cc:195 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:203 msgid "Colors" -msgstr "solo" +msgstr "Farben" -#: ardour_ui_ed.cc:197 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:205 msgid "Add Audio Track" -msgstr "MIDI Spur(en) hinzufügen" +msgstr "Audiospur hinzufügen" -#: ardour_ui_ed.cc:199 +#: gtk2_ardour/ardour_ui_ed.cc:207 msgid "Add Audio Bus" msgstr "" -#: ardour_ui_ed.cc:201 +#: gtk2_ardour/ardour_ui_ed.cc:209 msgid "Save" msgstr "Speichern" -#: ardour_ui_ed.cc:203 editor_actions.cc:255 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:211 +#: gtk2_ardour/editor_actions.cc:256 msgid "Remove Last Capture" -msgstr "Synchronisationspunkt entfernen" +msgstr "Letzte Aufnahme entfernen" -#. do-nothing action for the "transport" menu bar item -#: ardour_ui_ed.cc:210 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:218 msgid "Transport" -msgstr "dreieckig" +msgstr "Transport" -#. these two are not used by key bindings, instead use ToggleRoll for that. these two do show up in -#. menus and via button proxies. -#. -#: ardour_ui_ed.cc:216 sfdb_ui.cc:57 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:224 +#: gtk2_ardour/sfdb_ui.cc:60 msgid "Stop" msgstr "Stop" -#: ardour_ui_ed.cc:219 +#: gtk2_ardour/ardour_ui_ed.cc:227 msgid "Roll" msgstr "" -#: ardour_ui_ed.cc:223 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:231 msgid "Start/Stop" -msgstr "Anfang:" +msgstr "Start/Stop" -#: ardour_ui_ed.cc:226 +#: gtk2_ardour/ardour_ui_ed.cc:234 msgid "Stop + Forget Capture" -msgstr "" +msgstr "Stop + Aufnahme verwerfen" -#: ardour_ui_ed.cc:229 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:237 msgid "Play Loop Range" -msgstr "Bereich" +msgstr "Schleife wiedergeben" -#: ardour_ui_ed.cc:232 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:240 msgid "Play Selection" -msgstr "Wiedergabe der ausgewählten Region" +msgstr "Auswahl wiedergeben" -#: ardour_ui_ed.cc:236 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:244 msgid "Enable Record" -msgstr "Wiederherstellen" +msgstr "Aufnahme aktivieren" -#: ardour_ui_ed.cc:239 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:247 msgid "Rewind" -msgstr "Suchen" +msgstr "Rückwärts" -#: ardour_ui_ed.cc:242 +#: gtk2_ardour/ardour_ui_ed.cc:250 msgid "Rewind (Slow)" msgstr "" -#: ardour_ui_ed.cc:245 +#: gtk2_ardour/ardour_ui_ed.cc:253 msgid "Rewind (Fast)" msgstr "" -#: ardour_ui_ed.cc:248 +#: gtk2_ardour/ardour_ui_ed.cc:256 msgid "Forward" -msgstr "" +msgstr "Vorwärts" -#: ardour_ui_ed.cc:251 +#: gtk2_ardour/ardour_ui_ed.cc:259 msgid "Forward (Slow)" msgstr "" -#: ardour_ui_ed.cc:254 +#: gtk2_ardour/ardour_ui_ed.cc:262 msgid "Forward (Fast)" msgstr "" -#: ardour_ui_ed.cc:257 +#: gtk2_ardour/ardour_ui_ed.cc:265 msgid "Goto Zero" -msgstr "" +msgstr "Zum Nullpunkt springen" -#: ardour_ui_ed.cc:260 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:268 msgid "Goto Start" -msgstr "Anfang:" +msgstr "Zum Anfang springen" -#: ardour_ui_ed.cc:263 +#: gtk2_ardour/ardour_ui_ed.cc:271 msgid "Goto End" -msgstr "" - -#. XXX the newline in the displayed names of these action is really wrong, but its because we want the button -#. that proxies for these action to be more compact. It would be nice to find a way to override the action -#. name appearance on the buttons. -#. -#: ardour_ui_ed.cc:272 -msgid "" -"Punch\n" -"in" -msgstr "" +msgstr "Zum Ende Springen" -#: ardour_ui_ed.cc:275 -msgid "" -"Punch\n" -"out" -msgstr "" - -#: ardour_ui_ed.cc:278 option_editor.cc:129 -msgid "Click" -msgstr "" - -#: ardour_ui_ed.cc:281 -#, fuzzy -msgid "" -"Auto\n" -"input" -msgstr "Port hinzufügen" - -#: ardour_ui_ed.cc:284 -msgid "" -"Auto\n" -"play" -msgstr "" +#: gtk2_ardour/ardour_ui_ed.cc:287 +msgid "Auto Play" +msgstr "Auto Play" -#: ardour_ui_ed.cc:287 -msgid "" -"Auto\n" -"return" -msgstr "" +#: gtk2_ardour/ardour_ui_ed.cc:294 +msgid "Sync startup to video" +msgstr "Mit Video synchronisieren" -#: ardour_ui_ed.cc:291 -msgid "" -"Time\n" -"master" -msgstr "" +#: gtk2_ardour/ardour_ui_ed.cc:295 +msgid "Time master" +msgstr "Time Master" -#: ardour_ui_ed.cc:294 +#: gtk2_ardour/ardour_ui_ed.cc:298 msgid "Toggle Record Enable Track1" msgstr "" -#: ardour_ui_ed.cc:296 +#: gtk2_ardour/ardour_ui_ed.cc:300 msgid "Toggle Record Enable Track2" msgstr "" -#: ardour_ui_ed.cc:298 +#: gtk2_ardour/ardour_ui_ed.cc:302 msgid "Toggle Record Enable Track3" msgstr "" -#: ardour_ui_ed.cc:300 +#: gtk2_ardour/ardour_ui_ed.cc:304 msgid "Toggle Record Enable Track4" msgstr "" -#: ardour_ui_ed.cc:302 +#: gtk2_ardour/ardour_ui_ed.cc:306 msgid "Toggle Record Enable Track5" msgstr "" -#: ardour_ui_ed.cc:304 +#: gtk2_ardour/ardour_ui_ed.cc:308 msgid "Toggle Record Enable Track6" msgstr "" -#: ardour_ui_ed.cc:306 +#: gtk2_ardour/ardour_ui_ed.cc:310 msgid "Toggle Record Enable Track7" msgstr "" -#: ardour_ui_ed.cc:308 +#: gtk2_ardour/ardour_ui_ed.cc:312 msgid "Toggle Record Enable Track8" msgstr "" -#: ardour_ui_ed.cc:310 +#: gtk2_ardour/ardour_ui_ed.cc:314 msgid "Toggle Record Enable Track9" msgstr "" -#: ardour_ui_ed.cc:312 +#: gtk2_ardour/ardour_ui_ed.cc:316 msgid "Toggle Record Enable Track10" msgstr "" -#: ardour_ui_ed.cc:314 +#: gtk2_ardour/ardour_ui_ed.cc:318 msgid "Toggle Record Enable Track11" msgstr "" -#: ardour_ui_ed.cc:316 +#: gtk2_ardour/ardour_ui_ed.cc:320 msgid "Toggle Record Enable Track12" msgstr "" -#: ardour_ui_ed.cc:318 +#: gtk2_ardour/ardour_ui_ed.cc:322 msgid "Toggle Record Enable Track13" msgstr "" -#: ardour_ui_ed.cc:320 +#: gtk2_ardour/ardour_ui_ed.cc:324 msgid "Toggle Record Enable Track14" msgstr "" -#: ardour_ui_ed.cc:322 +#: gtk2_ardour/ardour_ui_ed.cc:326 msgid "Toggle Record Enable Track15" msgstr "" -#: ardour_ui_ed.cc:324 +#: gtk2_ardour/ardour_ui_ed.cc:328 msgid "Toggle Record Enable Track16" msgstr "" -#: ardour_ui_ed.cc:326 +#: gtk2_ardour/ardour_ui_ed.cc:330 msgid "Toggle Record Enable Track17" msgstr "" -#: ardour_ui_ed.cc:328 +#: gtk2_ardour/ardour_ui_ed.cc:332 msgid "Toggle Record Enable Track18" msgstr "" -#: ardour_ui_ed.cc:330 +#: gtk2_ardour/ardour_ui_ed.cc:334 msgid "Toggle Record Enable Track19" msgstr "" -#: ardour_ui_ed.cc:332 +#: gtk2_ardour/ardour_ui_ed.cc:336 msgid "Toggle Record Enable Track20" msgstr "" -#: ardour_ui_ed.cc:334 +#: gtk2_ardour/ardour_ui_ed.cc:338 msgid "Toggle Record Enable Track21" msgstr "" -#: ardour_ui_ed.cc:336 +#: gtk2_ardour/ardour_ui_ed.cc:340 msgid "Toggle Record Enable Track22" msgstr "" -#: ardour_ui_ed.cc:338 +#: gtk2_ardour/ardour_ui_ed.cc:342 msgid "Toggle Record Enable Track23" msgstr "" -#: ardour_ui_ed.cc:340 +#: gtk2_ardour/ardour_ui_ed.cc:344 msgid "Toggle Record Enable Track24" msgstr "" -#: ardour_ui_ed.cc:342 +#: gtk2_ardour/ardour_ui_ed.cc:346 msgid "Toggle Record Enable Track25" msgstr "" -#: ardour_ui_ed.cc:344 +#: gtk2_ardour/ardour_ui_ed.cc:348 msgid "Toggle Record Enable Track26" msgstr "" -#: ardour_ui_ed.cc:346 +#: gtk2_ardour/ardour_ui_ed.cc:350 msgid "Toggle Record Enable Track27" msgstr "" -#: ardour_ui_ed.cc:348 +#: gtk2_ardour/ardour_ui_ed.cc:352 msgid "Toggle Record Enable Track28" msgstr "" -#: ardour_ui_ed.cc:350 +#: gtk2_ardour/ardour_ui_ed.cc:354 msgid "Toggle Record Enable Track29" msgstr "" -#: ardour_ui_ed.cc:352 +#: gtk2_ardour/ardour_ui_ed.cc:356 msgid "Toggle Record Enable Track30" msgstr "" -#: ardour_ui_ed.cc:354 +#: gtk2_ardour/ardour_ui_ed.cc:358 msgid "Toggle Record Enable Track31" msgstr "" -#: ardour_ui_ed.cc:356 +#: gtk2_ardour/ardour_ui_ed.cc:360 msgid "Toggle Record Enable Track32" msgstr "" -#: ardour_ui_ed.cc:361 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:365 msgid "Percentage" -msgstr "Zurücksetzen" +msgstr "Prozent" -#: ardour_ui_ed.cc:362 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:366 msgid "Semitones" -msgstr "Sitzung" +msgstr "Halbtöne" -#: ardour_ui_ed.cc:366 +#: gtk2_ardour/ardour_ui_ed.cc:370 msgid "Send MTC" msgstr "MTC senden" -#: ardour_ui_ed.cc:368 +#: gtk2_ardour/ardour_ui_ed.cc:372 msgid "Send MMC" msgstr "MMC senden" -#: ardour_ui_ed.cc:370 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:374 msgid "Use MMC" -msgstr "MMC senden" +msgstr "Benutze MMC" -#: ardour_ui_ed.cc:372 +#: gtk2_ardour/ardour_ui_ed.cc:376 msgid "Send MIDI feedback" msgstr "" -#: ardour_ui_ed.cc:374 +#: gtk2_ardour/ardour_ui_ed.cc:378 msgid "Use MIDI control" msgstr "" -#: ardour_ui_ed.cc:377 -msgid "Connect new track inputs to hardware" -msgstr "" - -#: ardour_ui_ed.cc:396 -msgid "Connect new track outputs to hardware" -msgstr "" - -#: ardour_ui_ed.cc:398 -msgid "Connect new track outputs to master" -msgstr "" - -#: ardour_ui_ed.cc:400 -msgid "Manually connect new track outputs" -msgstr "" - -#: ardour_ui_ed.cc:405 -msgid "Hardware monitoring" -msgstr "" - -#: ardour_ui_ed.cc:406 -msgid "Software monitoring" -msgstr "" - -#: ardour_ui_ed.cc:407 -msgid "External monitoring" -msgstr "" - -#. Configuration object options (i.e. not session specific) -#: ardour_ui_ed.cc:411 +#: gtk2_ardour/ardour_ui_ed.cc:381 msgid "Stop plugins with transport" -msgstr "" +msgstr "Plugins mit Transport stoppen" -#: ardour_ui_ed.cc:412 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:382 msgid "Verify remove last capture" -msgstr "Synchronisationspunkt entfernen" +msgstr "Verwerfen der letzten Aufnahme bestätigen" -#: ardour_ui_ed.cc:413 +#: gtk2_ardour/ardour_ui_ed.cc:383 msgid "Stop recording on xrun" -msgstr "" +msgstr "Aufnahme bei XRUN stoppen" -#: ardour_ui_ed.cc:414 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:384 msgid "Stop transport at session end" -msgstr "Ans Ende der Sitzung springen" +msgstr "Transport am Ende der Sitzung stoppen" -#: ardour_ui_ed.cc:415 +#: gtk2_ardour/ardour_ui_ed.cc:385 msgid "-12dB gain reduce ffwd/rewind" -msgstr "" +msgstr "Beim Spulen Pegel um -12dB absenken" -#: ardour_ui_ed.cc:416 +#: gtk2_ardour/ardour_ui_ed.cc:386 msgid "Rec-enable stays engaged at stop" -msgstr "" +msgstr "Aufnahmestatus bleibt nach Stop erhalten" -#. session options -#: ardour_ui_ed.cc:420 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:388 msgid "Do not run plugins while recording" -msgstr "Wellenform zeigen" +msgstr "Plugins während der Aufnahme daktivieren" -#: ardour_ui_ed.cc:423 +#: gtk2_ardour/ardour_ui_ed.cc:391 msgid "Latched solo" -msgstr "" +msgstr "Latch Solo" + +#: gtk2_ardour/ardour_ui_ed.cc:399 +#: gtk2_ardour/ardour_ui_ed.cc:407 +#: gtk2_ardour/audio_clock.cc:1800 +#: gtk2_ardour/gain_meter.cc:159 +#: gtk2_ardour/ladspa_pluginui.cc:330 +#: gtk2_ardour/ladspa_pluginui.cc:573 +#: gtk2_ardour/panner_ui.cc:87 +msgid "Off" +msgstr "Aus" -#: ardour_ui_ed.cc:428 -#, fuzzy +#: gtk2_ardour/ardour_ui_ed.cc:400 +#: gtk2_ardour/editor.cc:1334 +#: gtk2_ardour/editor.cc:1351 +msgid "Slowest" +msgstr "Sehr langsam" + +#: gtk2_ardour/ardour_ui_ed.cc:401 +#: gtk2_ardour/editor.cc:1335 +#: gtk2_ardour/editor.cc:1352 +msgid "Slow" +msgstr "Langsam" + +#: gtk2_ardour/ardour_ui_ed.cc:402 +#: gtk2_ardour/ardour_ui_ed.cc:409 +msgid "Medium" +msgstr "Mittel" + +#: gtk2_ardour/ardour_ui_ed.cc:403 +#: gtk2_ardour/editor.cc:1336 +#: gtk2_ardour/editor.cc:1353 +msgid "Fast" +msgstr "Schnell" + +#: gtk2_ardour/ardour_ui_ed.cc:404 +msgid "Faster" +msgstr "Schneller" + +#: gtk2_ardour/ardour_ui_ed.cc:405 +#: gtk2_ardour/editor.cc:1337 +#: gtk2_ardour/editor.cc:1354 +msgid "Fastest" +msgstr "Schnellstmöglich" + +#: gtk2_ardour/ardour_ui_ed.cc:408 +#: gtk2_ardour/editor_actions.cc:58 +msgid "Short" +msgstr "Kurz" + +#: gtk2_ardour/ardour_ui_ed.cc:410 +msgid "Long" +msgstr "Lange" + +#: gtk2_ardour/ardour_ui_ed.cc:428 +msgid "Hardware monitoring" +msgstr "Hardware Monitoring" + +#: gtk2_ardour/ardour_ui_ed.cc:429 +msgid "Software monitoring" +msgstr "Software Monitoring" + +#: gtk2_ardour/ardour_ui_ed.cc:430 +msgid "External monitoring" +msgstr "Externes Monitoring" + +#: gtk2_ardour/ardour_ui_ed.cc:434 msgid "Solo in-place" -msgstr "solo" +msgstr "Solo-In-Place" -#: ardour_ui_ed.cc:430 +#: gtk2_ardour/ardour_ui_ed.cc:436 msgid "Solo via bus" +msgstr "Solo über Bus" + +#: gtk2_ardour/ardour_ui_ed.cc:441 +msgid "Auto-connect inputs to physical inputs" +msgstr "Eingänge automatisch mit Soundkarteneingängen verbinden" + +#: gtk2_ardour/ardour_ui_ed.cc:443 +msgid "Manually connect inputs" +msgstr "Eingänge manuell verbinden" + +#: gtk2_ardour/ardour_ui_ed.cc:448 +msgid "Auto-connect outputs to physical outs" +msgstr "Ausgänge automatisch mit Soundkartenausgängen verbinden" + +#: gtk2_ardour/ardour_ui_ed.cc:450 +msgid "Auto-connect outputs to master bus" +msgstr "Ausgänge automatisch mit Master-Bus verbinden" + +#: gtk2_ardour/ardour_ui_ed.cc:452 +msgid "Manually connect outputs" +msgstr "Ausgänge manuell verbinden" + +#: gtk2_ardour/ardour_ui_ed.cc:547 +#: gtk2_ardour/ladspa_pluginui.cc:168 +msgid "Controls" +msgstr "Steuerelemente" + +#: gtk2_ardour/ardour_ui_ed.cc:551 +msgid "Feedback" msgstr "" -#: ardour_ui_ed.cc:433 -msgid "Automatically create crossfades" +#: gtk2_ardour/ardour_ui_ed.cc:631 +msgid "ardour: clock" +msgstr "Ardour: Uhr" + +#: gtk2_ardour/ardour_ui_options.cc:205 +msgid "programming error: unknown solo model in ARDOUR_UI::set_solo_model: %1" msgstr "" -#: ardour_ui_ed.cc:435 -msgid "Unmute new full crossfades" +#: gtk2_ardour/ardour_ui_options.cc:239 +msgid "programming error: unknown monitor model in ARDOUR_UI::set_monitor_model: %1" msgstr "" -#: ardour_ui_options.cc:406 ardour_ui_options.cc:416 ardour_ui_options.cc:483 -#, fuzzy -msgid "Internal" -msgstr "mittelmäßig" +#: gtk2_ardour/ardour_ui_options.cc:492 +msgid "programming error: unknown file header format passed to ARDOUR_UI::map_file_data_format: %1" +msgstr "" -#: ardour_ui_options.cc:407 ardour_ui_options.cc:486 -msgid "MTC" +#: gtk2_ardour/ardour_ui_options.cc:524 +msgid "programming error: unknown file data format passed to ARDOUR_UI::map_file_data_format: %1" msgstr "" -#: audio_clock.cc:1742 editor.cc:188 -msgid "SMPTE" +#: gtk2_ardour/ardour_ui_options.cc:826 +msgid "ST" msgstr "" -#: audio_clock.cc:1743 editor.cc:187 editor_rulers.cc:360 +#: gtk2_ardour/audio_clock.cc:1796 +#: gtk2_ardour/editor.cc:180 +msgid "Timecode" +msgstr "Timecode" + +#: gtk2_ardour/audio_clock.cc:1797 +#: gtk2_ardour/editor.cc:179 +#: gtk2_ardour/editor_rulers.cc:386 msgid "Bars:Beats" -msgstr "" +msgstr "Takte:Schläge" -#: audio_clock.cc:1744 +#: gtk2_ardour/audio_clock.cc:1798 msgid "Minutes:Seconds" msgstr "Minuten:Sekunden" -#: audio_clock.cc:1745 +#: gtk2_ardour/audio_clock.cc:1799 msgid "Audio Frames" msgstr "" -#. -#. Slowest = 6.6dB/sec falloff at update rate of 40ms -#. Slow = 6.8dB/sec falloff at update rate of 40ms -#. -#: audio_clock.cc:1746 editor_actions.cc:375 editor_actions.cc:383 -#: gain_meter.cc:172 panner_ui.cc:89 plugin_ui.cc:392 plugin_ui.cc:635 -msgid "Off" -msgstr "Aus" - -#: audio_clock.cc:1748 +#: gtk2_ardour/audio_clock.cc:1802 msgid "Mode" msgstr "Modus" -#: audio_time_axis.cc:91 +#: gtk2_ardour/route_time_axis.cc:87 msgid "m" -msgstr "" +msgstr "m" -#: audio_time_axis.cc:91 +#: gtk2_ardour/route_time_axis.cc:87 msgid "s" -msgstr "" +msgstr "s" -#: audio_time_axis.cc:91 +#: gtk2_ardour/route_time_axis.cc:87 msgid "r" msgstr "" -#: audio_time_axis.cc:95 +#: gtk2_ardour/route_time_axis.cc:91 msgid "g" -msgstr "" +msgstr "g" -#. group -#: audio_time_axis.cc:96 +#: gtk2_ardour/route_time_axis.cc:92 msgid "p" -msgstr "" +msgstr "w" -#: audio_time_axis.cc:97 automation_time_axis.cc:32 visual_time_axis.cc:74 +#: gtk2_ardour/route_time_axis.cc:93 +#: gtk2_ardour/automation_time_axis.cc:33 +#: gtk2_ardour/visual_time_axis.cc:74 msgid "h" -msgstr "" +msgstr "h" -#. height -#: audio_time_axis.cc:98 +#: gtk2_ardour/route_time_axis.cc:94 msgid "a" -msgstr "" +msgstr "a" -#: audio_time_axis.cc:99 visual_time_axis.cc:73 +#: gtk2_ardour/route_time_axis.cc:95 +#: gtk2_ardour/visual_time_axis.cc:73 msgid "v" -msgstr "" +msgstr "v" -#: audio_time_axis.cc:168 mixer_strip.cc:86 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:150 +#: gtk2_ardour/mixer_strip.cc:85 msgid "Record" -msgstr "Wiederherstellen" +msgstr "Aufnahme" -#: audio_time_axis.cc:169 editor_actions.cc:37 mixer_strip.cc:86 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:158 +#: gtk2_ardour/editor_actions.cc:38 +#: gtk2_ardour/mixer_strip.cc:85 +#: gtk2_ardour/mixer_strip.cc:433 msgid "Solo" -msgstr "solo" - -#: audio_time_axis.cc:170 editor.cc:1760 editor.cc:1859 mixer_strip.cc:86 -#: panner_ui.cc:427 -#, fuzzy +msgstr "Solo" + +#: gtk2_ardour/route_time_axis.cc:159 +#: gtk2_ardour/editor.cc:1637 +#: gtk2_ardour/editor.cc:1727 +#: gtk2_ardour/mixer_strip.cc:85 +#: gtk2_ardour/mixer_strip.cc:432 +#: gtk2_ardour/panner_ui.cc:417 msgid "Mute" -msgstr "mute" +msgstr "Mute" -#: audio_time_axis.cc:171 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:160 msgid "Edit Group" -msgstr "Mix Gruppen" +msgstr "Bearbeitungsgruppe" -#: audio_time_axis.cc:172 visual_time_axis.cc:92 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:161 +#: gtk2_ardour/visual_time_axis.cc:92 msgid "Display Height" -msgstr "Anzeige" +msgstr "Anzeigehöhe" -#: audio_time_axis.cc:173 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:162 msgid "Playlist" -msgstr "Wiedergabe" +msgstr "Wiedergabeliste" -#: audio_time_axis.cc:174 audio_time_axis.cc:741 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:163 +#: gtk2_ardour/route_time_axis.cc:425 msgid "Automation" -msgstr "Stellen" +msgstr "Automationen" -#: audio_time_axis.cc:175 visual_time_axis.cc:93 +#: gtk2_ardour/route_time_axis.cc:164 +#: gtk2_ardour/visual_time_axis.cc:93 msgid "Visual options" -msgstr "" +msgstr "Visuelle optionen" -#: audio_time_axis.cc:176 visual_time_axis.cc:94 +#: gtk2_ardour/route_time_axis.cc:165 +#: gtk2_ardour/visual_time_axis.cc:94 msgid "Hide this track" -msgstr "" +msgstr "Diese Spur verbergen" -#: audio_time_axis.cc:333 mixer_strip.cc:927 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:276 +#: gtk2_ardour/mixer_strip.cc:917 msgid "No group" msgstr "keine Gruppe" -#: audio_time_axis.cc:702 automation_time_axis.cc:450 -#: imageframe_time_axis.cc:255 marker_time_axis.cc:211 -#, fuzzy -msgid "Height" -msgstr "Rechts" - -#: audio_time_axis.cc:703 color_manager.cc:41 imageframe_time_axis.cc:256 -#: marker_time_axis.cc:212 -#, fuzzy -msgid "Color" -msgstr "solo" - -#: audio_time_axis.cc:707 -msgid "Hide all crossfades" -msgstr "" - -#: audio_time_axis.cc:708 -msgid "Show all crossfades" -msgstr "" - -#: audio_time_axis.cc:712 mixer_strip.cc:1011 -#, fuzzy -msgid "Remote Control ID" -msgstr "Synchronisationspunkt entfernen" - -#: audio_time_axis.cc:718 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:386 msgid "Show all automation" -msgstr "Stellen" +msgstr "Alle Automationen zeigen" -#: audio_time_axis.cc:721 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:389 msgid "Show existing automation" -msgstr "Stellen" +msgstr "Verfügbare Automationen zeigen" -#: audio_time_axis.cc:724 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:392 msgid "Hide all automation" -msgstr "Stellen" - -#: audio_time_axis.cc:729 -#, fuzzy -msgid "Fader" -msgstr "Verbergen" - -#: audio_time_axis.cc:734 -msgid "Pan" -msgstr "" +msgstr "Automationen verbergen" -#: audio_time_axis.cc:739 +#: gtk2_ardour/route_time_axis.cc:395 msgid "Plugins" -msgstr "" - -#: audio_time_axis.cc:747 -#, fuzzy -msgid "Show waveforms" -msgstr "Wellenform zeigen" +msgstr "Plugins" -#: audio_time_axis.cc:755 -msgid "Traditional" -msgstr "" +#: gtk2_ardour/route_time_axis.cc:416 +#: gtk2_ardour/automation_time_axis.cc:425 +#: gtk2_ardour/imageframe_time_axis.cc:255 +#: gtk2_ardour/marker_time_axis.cc:211 +msgid "Height" +msgstr "Höhe" -#: audio_time_axis.cc:758 -msgid "Rectified" -msgstr "" +#: gtk2_ardour/route_time_axis.cc:417 +#: gtk2_ardour/color_manager.cc:41 +#: gtk2_ardour/imageframe_time_axis.cc:256 +#: gtk2_ardour/marker_time_axis.cc:212 +msgid "Color" +msgstr "Farbe" -#: audio_time_axis.cc:761 -#, fuzzy -msgid "Waveform" -msgstr "Wellenform zeigen" +#: gtk2_ardour/route_time_axis.cc:422 +#: gtk2_ardour/mixer_strip.cc:1002 +msgid "Remote Control ID" +msgstr "ID für Fernsteuerung" -#: audio_time_axis.cc:771 +#: gtk2_ardour/route_time_axis.cc:440 msgid "Align with existing material" -msgstr "" +msgstr "An vorhandenem Material ausrichten" -#: audio_time_axis.cc:776 +#: gtk2_ardour/route_time_axis.cc:446 msgid "Align with capture time" -msgstr "" +msgstr "An Aufnahmezeit ausrichten" -#: audio_time_axis.cc:782 +#: gtk2_ardour/route_time_axis.cc:452 msgid "Alignment" -msgstr "" +msgstr "Ausrichtung" + +#: gtk2_ardour/route_time_axis.cc:458 +msgid "Normal mode" +msgstr "Normaler Modus" -#: audio_time_axis.cc:788 editor.cc:527 editor_actions.cc:60 -#: mixer_strip.cc:1000 mixer_ui.cc:111 +#: gtk2_ardour/route_time_axis.cc:461 +msgid "Tape mode" +msgstr "Tape-Modus" + +#: gtk2_ardour/route_time_axis.cc:477 +#: gtk2_ardour/editor.cc:478 +#: gtk2_ardour/editor_actions.cc:61 +#: gtk2_ardour/mixer_strip.cc:991 +#: gtk2_ardour/mixer_ui.cc:109 msgid "Active" msgstr "Aktiv" -#: audio_time_axis.cc:793 editor.cc:1922 editor_actions.cc:320 -#: editor_markers.cc:508 imageframe_time_axis.cc:259 location_ui.cc:57 -#: marker_time_axis.cc:215 mixer_strip.cc:1014 +#: gtk2_ardour/route_time_axis.cc:482 +#: gtk2_ardour/editor.cc:1817 +#: gtk2_ardour/editor_actions.cc:326 +#: gtk2_ardour/editor_markers.cc:511 +#: gtk2_ardour/imageframe_time_axis.cc:259 +#: gtk2_ardour/location_ui.cc:58 +#: gtk2_ardour/marker_time_axis.cc:215 +#: gtk2_ardour/mixer_strip.cc:1005 msgid "Remove" -msgstr "Entfernen" +msgstr "Löschen" -#: audio_time_axis.cc:833 -#, fuzzy -msgid "Name for playlist" -msgstr "Name für Schnappschuß" +#: gtk2_ardour/route_time_axis.cc:508 +#: gtk2_ardour/route_time_axis.cc:563 +#: gtk2_ardour/route_time_axis.cc:826 +#: gtk2_ardour/editor_actions.cc:1034 +msgid "programming error: %1 %2" +msgstr "" -#: audio_time_axis.cc:835 audio_time_axis.cc:1851 editor_markers.cc:827 -#: editor_mouse.cc:4673 imageframe_time_axis.cc:248 marker_time_axis.cc:208 -#: meter_bridge_strip.cc:224 mixer_strip.cc:998 redirect_box.cc:751 -#: redirect_box.cc:1065 route_ui.cc:739 visual_time_axis.cc:326 +#: gtk2_ardour/route_time_axis.cc:850 +msgid "Name for playlist" +msgstr "Name für Wiedergabeliste" + +#: gtk2_ardour/route_time_axis.cc:852 +#: gtk2_ardour/route_time_axis.cc:1285 +#: gtk2_ardour/editor_markers.cc:830 +#: gtk2_ardour/editor_mouse.cc:4732 +#: gtk2_ardour/imageframe_time_axis.cc:248 +#: gtk2_ardour/marker_time_axis.cc:208 +#: gtk2_ardour/mixer_strip.cc:989 +#: gtk2_ardour/redirect_box.cc:752 +#: gtk2_ardour/redirect_box.cc:1075 +#: gtk2_ardour/route_ui.cc:760 +#: gtk2_ardour/visual_time_axis.cc:331 msgid "Rename" msgstr "Umbenennen" -#: audio_time_axis.cc:868 audio_time_axis.cc:908 -#, fuzzy +#: gtk2_ardour/route_time_axis.cc:894 +#: gtk2_ardour/route_time_axis.cc:935 msgid "Name for Playlist" -msgstr "Name für Schnappschuß" +msgstr "Name für Playlist" -#: audio_time_axis.cc:1126 visual_time_axis.cc:383 +#: gtk2_ardour/route_time_axis.cc:1118 +#: gtk2_ardour/visual_time_axis.cc:388 msgid "a track already exists with that name" msgstr "" -#: audio_time_axis.cc:1167 editor.cc:218 -msgid "gain" +#: gtk2_ardour/route_time_axis.cc:1289 +msgid "New Copy" +msgstr "Neue Kopie" + +#: gtk2_ardour/route_time_axis.cc:1291 +msgid "Clear Current" msgstr "" -#: audio_time_axis.cc:1207 -msgid "pan" +#: gtk2_ardour/route_time_axis.cc:1294 +msgid "Select from all ..." msgstr "" -#: audio_time_axis.cc:1410 editor.cc:1483 selection.cc:634 +#: gtk2_ardour/route_time_axis.cc:1494 +#: gtk2_ardour/editor.cc:1359 +#: gtk2_ardour/selection.cc:642 msgid "programming error: " msgstr "" -#: audio_time_axis.cc:1848 -msgid "Current: %1" +#: gtk2_ardour/audio_time_axis.cc:221 +msgid "Fader" +msgstr "Fader" + +#: gtk2_ardour/audio_time_axis.cc:226 +msgid "Pan" msgstr "" -#: audio_time_axis.cc:1855 -#, fuzzy -msgid "New Copy" -msgstr "Kopieren" +#: gtk2_ardour/audio_time_axis.cc:241 +msgid "Hide all crossfades" +msgstr "Alle Crossfades verbergen" -#: audio_time_axis.cc:1857 -msgid "Clear Current" +#: gtk2_ardour/audio_time_axis.cc:242 +msgid "Show all crossfades" +msgstr "Alle Crossfades zeigen" + +#: gtk2_ardour/audio_time_axis.cc:249 +msgid "Show waveforms" +msgstr "Wellenformen zeigen" + +#: gtk2_ardour/audio_time_axis.cc:257 +msgid "Traditional" +msgstr "Traditionell" + +#: gtk2_ardour/audio_time_axis.cc:260 +msgid "Rectified" +msgstr "Gleichgerichtet" + +#: gtk2_ardour/audio_time_axis.cc:263 +msgid "Waveform" +msgstr "Wellenform" + +#: gtk2_ardour/audio_time_axis.cc:323 +msgid "gain" msgstr "" -#: audio_time_axis.cc:1859 editor.cc:2024 editor.cc:2100 -msgid "Select" -msgstr "Auswahl" +#: gtk2_ardour/audio_time_axis.cc:363 +msgid "pan" +msgstr "" -#: automation_line.cc:884 +#: gtk2_ardour/automation_line.cc:801 #, fuzzy msgid "automation event move" msgstr "Stellen" -#: automation_line.cc:886 +#: gtk2_ardour/automation_line.cc:803 #, fuzzy msgid "automation range drag" msgstr "Stellen" -#: automation_line.cc:1015 region_gain_line.cc:62 +#: gtk2_ardour/automation_line.cc:1028 +#: gtk2_ardour/region_gain_line.cc:64 #, fuzzy msgid "remove control point" msgstr "Synchronisationspunkt entfernen" -#: automation_time_axis.cc:33 editor_ops.cc:2885 +#: gtk2_ardour/automation_time_axis.cc:34 +#: gtk2_ardour/editor_ops.cc:2834 msgid "clear" msgstr "leeren" -#: automation_time_axis.cc:75 +#: gtk2_ardour/automation_time_axis.cc:70 msgid "track height" -msgstr "" +msgstr "Anzeigehöhe" -#: automation_time_axis.cc:76 -#, fuzzy +#: gtk2_ardour/automation_time_axis.cc:71 msgid "automation state" -msgstr "Stellen" +msgstr "Automationsmodus" -#: automation_time_axis.cc:77 -#, fuzzy +#: gtk2_ardour/automation_time_axis.cc:72 msgid "clear track" -msgstr "Verbindungen löschen" +msgstr "Verbindungen entfernen" -#: automation_time_axis.cc:78 -#, fuzzy +#: gtk2_ardour/automation_time_axis.cc:73 msgid "hide track" -msgstr "Stille einfügen" +msgstr "Diese Spur verbergen" -#: automation_time_axis.cc:184 automation_time_axis.cc:213 -#: automation_time_axis.cc:461 +#: gtk2_ardour/automation_time_axis.cc:182 +#: gtk2_ardour/automation_time_axis.cc:211 +#: gtk2_ardour/automation_time_axis.cc:436 msgid "Manual" -msgstr "" - -#: automation_time_axis.cc:186 automation_time_axis.cc:224 -#: automation_time_axis.cc:465 editor.cc:2001 editor.cc:2082 gain_meter.cc:174 -#: panner_ui.cc:91 plugin_ui.cc:395 plugin_ui.cc:637 sfdb_ui.cc:56 +msgstr "Manuell" + +#: gtk2_ardour/automation_time_axis.cc:184 +#: gtk2_ardour/automation_time_axis.cc:222 +#: gtk2_ardour/automation_time_axis.cc:440 +#: gtk2_ardour/editor.cc:1894 +#: gtk2_ardour/editor.cc:1975 +#: gtk2_ardour/gain_meter.cc:161 +#: gtk2_ardour/ladspa_pluginui.cc:333 +#: gtk2_ardour/ladspa_pluginui.cc:575 +#: gtk2_ardour/panner_ui.cc:89 +#: gtk2_ardour/sfdb_ui.cc:59 msgid "Play" msgstr "Wiedergabe" -#: automation_time_axis.cc:188 automation_time_axis.cc:235 -#: automation_time_axis.cc:469 gain_meter.cc:176 panner_ui.cc:93 -#: plugin_ui.cc:398 plugin_ui.cc:639 +#: gtk2_ardour/automation_time_axis.cc:186 +#: gtk2_ardour/automation_time_axis.cc:233 +#: gtk2_ardour/automation_time_axis.cc:444 +#: gtk2_ardour/gain_meter.cc:163 +#: gtk2_ardour/ladspa_pluginui.cc:336 +#: gtk2_ardour/ladspa_pluginui.cc:577 +#: gtk2_ardour/panner_ui.cc:91 msgid "Write" -msgstr "" - -#: automation_time_axis.cc:190 automation_time_axis.cc:246 -#: automation_time_axis.cc:473 gain_meter.cc:178 panner_ui.cc:95 -#: plugin_ui.cc:401 plugin_ui.cc:641 +msgstr "Schreiben" + +#: gtk2_ardour/automation_time_axis.cc:188 +#: gtk2_ardour/automation_time_axis.cc:244 +#: gtk2_ardour/automation_time_axis.cc:448 +#: gtk2_ardour/gain_meter.cc:165 +#: gtk2_ardour/ladspa_pluginui.cc:339 +#: gtk2_ardour/ladspa_pluginui.cc:579 +#: gtk2_ardour/panner_ui.cc:93 msgid "Touch" -msgstr "" +msgstr "Berühren" -#: automation_time_axis.cc:257 option_editor.cc:183 option_editor.cc:189 -#: plugin_ui.cc:404 +#: gtk2_ardour/automation_time_axis.cc:255 +#: gtk2_ardour/ladspa_pluginui.cc:342 msgid "???" msgstr "" -#: automation_time_axis.cc:271 -#, fuzzy +#: gtk2_ardour/automation_time_axis.cc:269 msgid "clear automation" -msgstr "Verbindungen löschen" +msgstr "Verbindungen entfernen" -#: automation_time_axis.cc:452 editor_actions.cc:318 +#: gtk2_ardour/automation_time_axis.cc:427 +#: gtk2_ardour/editor_actions.cc:324 msgid "Hide" msgstr "Verbergen" -#: automation_time_axis.cc:454 crossfade_edit.cc:78 redirect_box.cc:1057 +#: gtk2_ardour/automation_time_axis.cc:429 +#: gtk2_ardour/crossfade_edit.cc:79 +#: gtk2_ardour/redirect_box.cc:1067 +#: gtk2_ardour/connection_editor.cc:57 msgid "Clear" msgstr "leeren" -#: automation_time_axis.cc:477 -#, fuzzy +#: gtk2_ardour/automation_time_axis.cc:452 msgid "State" -msgstr "Anfang" +msgstr "Automationssmodus" -#: canvas-imageframe.c:104 +#: gtk2_ardour/canvas-imageframe.c:104 msgid "pixbuf" msgstr "" -#: canvas-imageframe.c:105 +#: gtk2_ardour/canvas-imageframe.c:105 msgid "the pixbuf" msgstr "" -#: canvas-imageframe.c:110 +#: gtk2_ardour/canvas-imageframe.c:110 msgid "x" msgstr "" -#: canvas-imageframe.c:111 canvas-simpleline.c:111 canvas-simplerect.c:107 +#: gtk2_ardour/canvas-imageframe.c:111 +#: gtk2_ardour/canvas-simpleline.c:111 +#: gtk2_ardour/canvas-simplerect.c:107 msgid "x coordinate of upper left corner of rect" msgstr "" -#: canvas-imageframe.c:120 +#: gtk2_ardour/canvas-imageframe.c:120 msgid "y" msgstr "" -#: canvas-imageframe.c:121 canvas-simpleline.c:121 canvas-simplerect.c:117 +#: gtk2_ardour/canvas-imageframe.c:121 +#: gtk2_ardour/canvas-simpleline.c:121 +#: gtk2_ardour/canvas-simplerect.c:117 msgid "y coordinate of upper left corner of rect " msgstr "" -#: canvas-imageframe.c:129 +#: gtk2_ardour/canvas-imageframe.c:129 msgid "width" msgstr "" -#: canvas-imageframe.c:130 +#: gtk2_ardour/canvas-imageframe.c:130 msgid "the width" msgstr "" -#: canvas-imageframe.c:139 +#: gtk2_ardour/canvas-imageframe.c:139 msgid "drawwidth" msgstr "" -#: canvas-imageframe.c:140 +#: gtk2_ardour/canvas-imageframe.c:140 msgid "drawn width" msgstr "" -#: canvas-imageframe.c:148 +#: gtk2_ardour/canvas-imageframe.c:148 #, fuzzy msgid "height" msgstr "Rechts" -#: canvas-imageframe.c:149 +#: gtk2_ardour/canvas-imageframe.c:149 #, fuzzy msgid "the height" msgstr "Rechts" -#: canvas-imageframe.c:157 +#: gtk2_ardour/canvas-imageframe.c:157 msgid "anchor" msgstr "" -#: canvas-imageframe.c:158 +#: gtk2_ardour/canvas-imageframe.c:158 msgid "the anchor" msgstr "" -#: canvas-simpleline.c:110 canvas-simplerect.c:106 +#: gtk2_ardour/canvas-simpleline.c:110 +#: gtk2_ardour/canvas-simplerect.c:106 msgid "x1" msgstr "" -#: canvas-simpleline.c:120 canvas-simplerect.c:116 +#: gtk2_ardour/canvas-simpleline.c:120 +#: gtk2_ardour/canvas-simplerect.c:116 msgid "y1" msgstr "" -#: canvas-simpleline.c:131 canvas-simplerect.c:127 +#: gtk2_ardour/canvas-simpleline.c:131 +#: gtk2_ardour/canvas-simplerect.c:127 msgid "x2" msgstr "" -#: canvas-simpleline.c:132 canvas-simplerect.c:128 +#: gtk2_ardour/canvas-simpleline.c:132 +#: gtk2_ardour/canvas-simplerect.c:128 msgid "x coordinate of lower right corner of rect" msgstr "" -#: canvas-simpleline.c:141 canvas-simplerect.c:137 +#: gtk2_ardour/canvas-simpleline.c:141 +#: gtk2_ardour/canvas-simplerect.c:137 msgid "y2" msgstr "" -#: canvas-simpleline.c:142 canvas-simplerect.c:138 +#: gtk2_ardour/canvas-simpleline.c:142 +#: gtk2_ardour/canvas-simplerect.c:138 msgid "y coordinate of lower right corner of rect " msgstr "" -#: canvas-simpleline.c:150 +#: gtk2_ardour/canvas-simpleline.c:150 msgid "color rgba" msgstr "" -#: canvas-simpleline.c:151 +#: gtk2_ardour/canvas-simpleline.c:151 msgid "color of line" msgstr "" -#: canvas-simplerect.c:148 +#: gtk2_ardour/canvas-simplerect.c:148 msgid "outline pixels" msgstr "" -#: canvas-simplerect.c:149 +#: gtk2_ardour/canvas-simplerect.c:149 msgid "width in pixels of outline" msgstr "" -#: canvas-simplerect.c:159 +#: gtk2_ardour/canvas-simplerect.c:159 msgid "outline what" msgstr "" -#: canvas-simplerect.c:160 +#: gtk2_ardour/canvas-simplerect.c:160 msgid "which boundaries to outline (mask)" msgstr "" -#: canvas-simplerect.c:171 +#: gtk2_ardour/canvas-simplerect.c:171 msgid "fill" msgstr "" -#: canvas-simplerect.c:172 +#: gtk2_ardour/canvas-simplerect.c:172 #, fuzzy msgid "fill rectangle" msgstr "Auswahl zu Schleife machen" -#: canvas-simplerect.c:179 +#: gtk2_ardour/canvas-simplerect.c:179 msgid "draw" msgstr "" -#: canvas-simplerect.c:180 +#: gtk2_ardour/canvas-simplerect.c:180 #, fuzzy msgid "draw rectangle" msgstr "Bereich" -#: canvas-simplerect.c:188 +#: gtk2_ardour/canvas-simplerect.c:188 msgid "outline color rgba" msgstr "" -#: canvas-simplerect.c:189 +#: gtk2_ardour/canvas-simplerect.c:189 msgid "color of outline" msgstr "" -#: canvas-simplerect.c:199 +#: gtk2_ardour/canvas-simplerect.c:199 msgid "fill color rgba" msgstr "" -#: canvas-simplerect.c:200 +#: gtk2_ardour/canvas-simplerect.c:200 msgid "color of fill" msgstr "" -#: color_manager.cc:40 +#: gtk2_ardour/color_manager.cc:40 #, fuzzy msgid "Object" msgstr "Objekt" -#: color_manager.cc:78 +#: gtk2_ardour/color_manager.cc:78 msgid "cannot open color definition file %1: %2" msgstr "" -#: crossfade_edit.cc:75 +#: gtk2_ardour/crossfade_edit.cc:76 #, fuzzy msgid "ardour: x-fade edit" msgstr "Ardour: Editor" -#: crossfade_edit.cc:79 panner_ui.cc:443 +#: gtk2_ardour/crossfade_edit.cc:80 +#: gtk2_ardour/panner_ui.cc:433 #, fuzzy msgid "Reset" msgstr "bestmöglich" -#: crossfade_edit.cc:80 +#: gtk2_ardour/crossfade_edit.cc:81 msgid "Fade" msgstr "" -#: crossfade_edit.cc:81 +#: gtk2_ardour/crossfade_edit.cc:82 msgid "Out (dry)" msgstr "" -#: crossfade_edit.cc:82 +#: gtk2_ardour/crossfade_edit.cc:83 #, fuzzy msgid "Out" msgstr "Ausgänge" -#: crossfade_edit.cc:83 +#: gtk2_ardour/crossfade_edit.cc:84 msgid "In (dry)" msgstr "" -#: crossfade_edit.cc:84 +#: gtk2_ardour/crossfade_edit.cc:85 msgid "In" msgstr "" -#: crossfade_edit.cc:86 +#: gtk2_ardour/crossfade_edit.cc:87 msgid "With Pre-roll" msgstr "" -#: crossfade_edit.cc:87 +#: gtk2_ardour/crossfade_edit.cc:88 msgid "With Post-roll" msgstr "" -#: crossfade_edit.cc:95 +#: gtk2_ardour/crossfade_edit.cc:96 msgid "Fade In" msgstr "" -#: crossfade_edit.cc:96 +#: gtk2_ardour/crossfade_edit.cc:97 msgid "Fade Out" msgstr "" -#: crossfade_edit.cc:172 editor.cc:1835 editor_actions.cc:316 -#: option_editor.cc:130 +#: gtk2_ardour/crossfade_edit.cc:173 +#: gtk2_ardour/editor.cc:1712 +#: gtk2_ardour/editor_actions.cc:322 +#: gtk2_ardour/option_editor.cc:129 msgid "Audition" -msgstr "" - -#: editor.cc:104 editor.cc:3616 -msgid "Slide" -msgstr "" - -#: editor.cc:105 editor.cc:3614 -msgid "Splice" -msgstr "" - -#. note that this menu list starts at zero, not 1, because zero -#. is a valid, if useless, ID. -#. -#. leave some breathing room -#: editor.cc:110 editor.cc:3671 export_dialog.cc:78 export_dialog.cc:92 -#: export_dialog.cc:893 export_dialog.cc:1225 route_ui.cc:437 +msgstr "Vorhören" + +#: gtk2_ardour/editor.cc:102 +#: gtk2_ardour/editor.cc:3469 +#: gtk2_ardour/editor_actions.cc:400 +#: gtk2_ardour/export_dialog.cc:76 +#: gtk2_ardour/export_dialog.cc:90 +#: gtk2_ardour/export_dialog.cc:891 +#: gtk2_ardour/export_dialog.cc:1223 +#: gtk2_ardour/route_ui.cc:459 msgid "None" -msgstr "Nichts" +msgstr "Kein" -#: editor.cc:111 editor.cc:3659 +#: gtk2_ardour/editor.cc:103 +#: gtk2_ardour/editor.cc:3457 msgid "CD Frames" -msgstr "" +msgstr "CD-Frames" -#: editor.cc:112 editor.cc:3661 +#: gtk2_ardour/editor.cc:104 +#: gtk2_ardour/editor.cc:3459 msgid "SMPTE Frames" -msgstr "" +msgstr "SMPTE-Frames" -#: editor.cc:113 editor.cc:3663 +#: gtk2_ardour/editor.cc:105 +#: gtk2_ardour/editor.cc:3461 msgid "SMPTE Seconds" -msgstr "" +msgstr "SMPTE-Sekunden" -#: editor.cc:114 editor.cc:3665 +#: gtk2_ardour/editor.cc:106 +#: gtk2_ardour/editor.cc:3463 msgid "SMPTE Minutes" -msgstr "" +msgstr "SMPTE-Minuten" -#: editor.cc:115 editor.cc:3667 -#, fuzzy +#: gtk2_ardour/editor.cc:107 +#: gtk2_ardour/editor.cc:3465 msgid "Seconds" -msgstr "Minuten:Sekunden" +msgstr "Sekunden" -#: editor.cc:116 editor.cc:3669 -#, fuzzy +#: gtk2_ardour/editor.cc:108 +#: gtk2_ardour/editor.cc:3467 msgid "Minutes" -msgstr "mute" +msgstr "Minuten" -#: editor.cc:117 editor.cc:3641 +#: gtk2_ardour/editor.cc:109 +#: gtk2_ardour/editor.cc:3439 msgid "Beats/32" -msgstr "" +msgstr "Zweiunddreißigstel" -#: editor.cc:118 editor.cc:3639 +#: gtk2_ardour/editor.cc:110 +#: gtk2_ardour/editor.cc:3437 msgid "Beats/16" -msgstr "" +msgstr "Sechzehntel" -#: editor.cc:119 editor.cc:3637 +#: gtk2_ardour/editor.cc:111 +#: gtk2_ardour/editor.cc:3435 msgid "Beats/8" -msgstr "" +msgstr "Achtel" -#: editor.cc:120 editor.cc:3635 +#: gtk2_ardour/editor.cc:112 +#: gtk2_ardour/editor.cc:3433 msgid "Beats/4" -msgstr "" +msgstr "Viertel" -#: editor.cc:121 editor.cc:3633 +#: gtk2_ardour/editor.cc:113 +#: gtk2_ardour/editor.cc:3431 msgid "Beats/3" -msgstr "" +msgstr "Vierteltriolen" -#: editor.cc:122 editor.cc:3643 +#: gtk2_ardour/editor.cc:114 +#: gtk2_ardour/editor.cc:3441 msgid "Beats" -msgstr "" +msgstr "Schläge" -#: editor.cc:123 editor.cc:3645 +#: gtk2_ardour/editor.cc:115 +#: gtk2_ardour/editor.cc:3443 msgid "Bars" -msgstr "" +msgstr "Takte" -#: editor.cc:124 editor.cc:3647 +#: gtk2_ardour/editor.cc:116 +#: gtk2_ardour/editor.cc:3445 msgid "Marks" -msgstr "" +msgstr "Marker" -#: editor.cc:125 editor.cc:144 editor.cc:3649 editor.cc:3715 +#: gtk2_ardour/editor.cc:117 +#: gtk2_ardour/editor.cc:136 +#: gtk2_ardour/editor.cc:3447 +#: gtk2_ardour/editor.cc:3512 msgid "Edit Cursor" -msgstr "" +msgstr "Editierzeiger" -#: editor.cc:126 editor.cc:3651 -#, fuzzy +#: gtk2_ardour/editor.cc:118 +#: gtk2_ardour/editor.cc:3449 msgid "Region starts" -msgstr "Regionen" +msgstr "Regionen-Anfang" -#: editor.cc:127 editor.cc:3653 -#, fuzzy +#: gtk2_ardour/editor.cc:119 +#: gtk2_ardour/editor.cc:3451 msgid "Region ends" -msgstr "Regionen" +msgstr "Regionen-Ende" -#: editor.cc:128 editor.cc:3657 -#, fuzzy +#: gtk2_ardour/editor.cc:120 +#: gtk2_ardour/editor.cc:3455 msgid "Region syncs" -msgstr "Regionen" +msgstr "Regionen-Sync" -#: editor.cc:129 editor.cc:3655 -#, fuzzy +#: gtk2_ardour/editor.cc:121 +#: gtk2_ardour/editor.cc:3453 msgid "Region bounds" -msgstr "Regionen" +msgstr "Regionen-Grenzen" -#: editor.cc:135 editor.cc:3690 -#, fuzzy +#: gtk2_ardour/editor.cc:127 +#: gtk2_ardour/editor.cc:3487 +#: gtk2_ardour/editor_actions.cc:287 msgid "Magnetic" -msgstr "generisch" - -#: editor.cc:140 editor.cc:3707 export_dialog.cc:140 export_dialog.cc:156 -#: export_dialog.cc:1068 export_dialog.cc:1072 +msgstr "Magnetisch" + +#: gtk2_ardour/editor.cc:132 +#: gtk2_ardour/editor.cc:3504 +#: gtk2_ardour/export_dialog.cc:138 +#: gtk2_ardour/export_dialog.cc:154 +#: gtk2_ardour/export_dialog.cc:1066 +#: gtk2_ardour/export_dialog.cc:1070 msgid "Left" msgstr "Links" -#: editor.cc:141 editor.cc:3709 export_dialog.cc:141 export_dialog.cc:157 +#: gtk2_ardour/editor.cc:133 +#: gtk2_ardour/editor.cc:3506 +#: gtk2_ardour/export_dialog.cc:139 +#: gtk2_ardour/export_dialog.cc:155 msgid "Right" msgstr "Rechts" -#: editor.cc:142 editor.cc:3711 +#: gtk2_ardour/editor.cc:134 +#: gtk2_ardour/editor.cc:3508 msgid "Center" msgstr "Mitte" -#: editor.cc:143 editor.cc:3713 +#: gtk2_ardour/editor.cc:135 +#: gtk2_ardour/editor.cc:3510 msgid "Playhead" -msgstr "" +msgstr "Positionszeiger" -#. time display buttons -#: editor.cc:186 +#: gtk2_ardour/editor.cc:178 msgid "Mins:Secs" msgstr "Min:Sek" -#: editor.cc:189 editor_rulers.cc:354 +#: gtk2_ardour/editor.cc:181 +#: gtk2_ardour/editor_rulers.cc:380 msgid "Frames" -msgstr "" +msgstr "Frames" -#: editor.cc:190 editor_rulers.cc:374 +#: gtk2_ardour/editor.cc:182 +#: gtk2_ardour/editor_rulers.cc:400 msgid "Tempo" -msgstr "" +msgstr "Tempo" -#: editor.cc:191 editor_rulers.cc:368 +#: gtk2_ardour/editor.cc:183 +#: gtk2_ardour/editor_rulers.cc:394 msgid "Meter" -msgstr "" +msgstr "Taktart" -#: editor.cc:192 editor_rulers.cc:380 -#, fuzzy +#: gtk2_ardour/editor.cc:184 +#: gtk2_ardour/editor_rulers.cc:406 msgid "Location Markers" -msgstr "Stellen" +msgstr "Positionsmarker" -#: editor.cc:193 editor_rulers.cc:386 +#: gtk2_ardour/editor.cc:185 +#: gtk2_ardour/editor_rulers.cc:412 msgid "Range Markers" -msgstr "" +msgstr "Bereiche" -#: editor.cc:194 editor_rulers.cc:392 +#: gtk2_ardour/editor.cc:186 +#: gtk2_ardour/editor_rulers.cc:418 msgid "Loop/Punch Ranges" -msgstr "" +msgstr "Schleifen/Punch-Bereiche" -#: editor.cc:216 -msgid "range" -msgstr "Bereich" - -#: editor.cc:217 -msgid "object" -msgstr "Objekt" - -#: editor.cc:219 -msgid "zoom" -msgstr "" - -#: editor.cc:220 -msgid "timefx" -msgstr "" - -#: editor.cc:221 -msgid "listen" -msgstr "" - -#: editor.cc:223 +#: gtk2_ardour/editor.cc:204 msgid "mode" msgstr "Modus" -#: editor.cc:224 +#: gtk2_ardour/editor.cc:205 msgid "automation" msgstr "" -#: editor.cc:226 -msgid "Edit Mode" -msgstr "Bearbeitungs Modus" - -#: editor.cc:227 editor_actions.cc:284 -msgid "Snap To" -msgstr "" - -#: editor.cc:228 -#, fuzzy -msgid "Snap Mode" -msgstr "Modus" - -#: editor.cc:229 -#, fuzzy -msgid "Zoom Focus" -msgstr "Verkleinern" - -#. -#. nudge -#: editor.cc:237 editor.cc:1900 editor.cc:2066 editor.cc:2122 -msgid "Nudge" -msgstr "" - -#: editor.cc:470 -msgid "Zoom in" -msgstr "Vergrößern" - -#: editor.cc:471 -msgid "Zoom out" -msgstr "Verkleinern" - -#: editor.cc:474 -#, fuzzy -msgid "Zoom to session" -msgstr "Vergrößern auf Auswahl" - -#: editor.cc:489 -#, fuzzy -msgid "Zoom Span" -msgstr "Vergrößern" - -#: editor.cc:502 editor.cc:528 editor_actions.cc:62 mixer_ui.cc:86 -#: mixer_ui.cc:112 -msgid "Visible" -msgstr "" +#: gtk2_ardour/editor.cc:453 +#: gtk2_ardour/editor.cc:479 +#: gtk2_ardour/editor_actions.cc:63 +#: gtk2_ardour/mixer_ui.cc:84 +#: gtk2_ardour/mixer_ui.cc:110 +#: gtk2_ardour/analysis_window.cc:64 +msgid "Show" +msgstr "Anzeigen" -#: editor.cc:503 editor.cc:526 +#: gtk2_ardour/editor.cc:454 +#: gtk2_ardour/editor.cc:477 #, fuzzy msgid "Name" msgstr "Umbenennen" -#: editor.cc:602 editor.cc:669 -#, fuzzy +#: gtk2_ardour/editor.cc:553 +#: gtk2_ardour/editor.cc:619 msgid "Regions" msgstr "Regionen" -#: editor.cc:642 editor.cc:681 +#: gtk2_ardour/editor.cc:592 +#: gtk2_ardour/editor.cc:631 msgid "Chunks" -msgstr "Stücke" +msgstr "Teile" -#: editor.cc:672 -#, fuzzy +#: gtk2_ardour/editor.cc:622 msgid "Tracks/Busses" -msgstr "MIDI Spur(en) hinzufügen" +msgstr "Spuren/Busse" -#: editor.cc:675 +#: gtk2_ardour/editor.cc:625 msgid "Snapshots" msgstr "Schnapschüsse" -#: editor.cc:678 +#: gtk2_ardour/editor.cc:628 msgid "Edit Groups" -msgstr "" +msgstr "Bearbeitungsgruppen" -#: editor.cc:727 -msgid "Nudge region/selection forwards" -msgstr "" +#: gtk2_ardour/editor.cc:679 +msgid "Nudge Region/Selection Forwards" +msgstr "Region/Auswahl schrittweise nach vorne" -#: editor.cc:728 -msgid "Nudge region/selection backwards" -msgstr "" +#: gtk2_ardour/editor.cc:680 +msgid "Nudge Region/Selection Backwards" +msgstr "Region/Auswahl schrittweise nach hinten" -#: editor.cc:735 editor_mixer.cc:299 +#: gtk2_ardour/editor.cc:687 +#: gtk2_ardour/editor_mixer.cc:299 msgid "ardour: editor" msgstr "Ardour: Editor" -#: editor.cc:736 +#: gtk2_ardour/editor.cc:688 #, fuzzy msgid "ardour_editor" msgstr "Ardour: Editor" -#: editor.cc:1183 +#: gtk2_ardour/editor.cc:1093 msgid "ardour: editor: " msgstr "Ardour: Editor: " -#. force name -#: editor.cc:1268 editor.cc:1277 editor_markers.cc:870 +#: gtk2_ardour/editor.cc:1166 +#: gtk2_ardour/editor.cc:1175 +#: gtk2_ardour/editor_markers.cc:874 msgid "Loop" msgstr "Schleife" -#. force name -#: editor.cc:1282 editor.cc:1291 editor_markers.cc:896 +#: gtk2_ardour/editor.cc:1180 +#: gtk2_ardour/editor.cc:1189 +#: gtk2_ardour/editor_markers.cc:902 msgid "Punch" msgstr "" -#: editor.cc:1439 editor_mouse.cc:1742 +#: gtk2_ardour/editor.cc:1314 +#: gtk2_ardour/editor_mouse.cc:1748 msgid "programming error: fade in canvas item has no regionview data pointer!" msgstr "" -#: editor.cc:1451 editor.cc:1468 redirect_box.cc:1073 -#, fuzzy +#: gtk2_ardour/editor.cc:1326 +#: gtk2_ardour/editor.cc:1343 +#: gtk2_ardour/redirect_box.cc:1083 msgid "Deactivate" -msgstr "Alles deaktivieren" +msgstr "Deaktivieren" -#. activation -#: editor.cc:1453 editor.cc:1470 redirect_box.cc:1071 -#, fuzzy +#: gtk2_ardour/editor.cc:1328 +#: gtk2_ardour/editor.cc:1345 +#: gtk2_ardour/redirect_box.cc:1081 msgid "Activate" -msgstr "Aktiv" +msgstr "Aktivieren" -#: editor.cc:1458 editor.cc:1475 +#: gtk2_ardour/editor.cc:1333 +#: gtk2_ardour/editor.cc:1350 msgid "Linear" msgstr "" -#: editor.cc:1459 editor.cc:1476 editor_actions.cc:376 -#, fuzzy -msgid "Slowest" -msgstr "Alle zeigen" +#: gtk2_ardour/editor.cc:1466 +#: gtk2_ardour/editor.cc:1474 +msgid "Freeze" +msgstr "Einfrieren" -#: editor.cc:1460 editor.cc:1477 editor_actions.cc:377 -#, fuzzy -msgid "Slow" -msgstr "solo" - -#: editor.cc:1461 editor.cc:1478 editor_actions.cc:379 -#, fuzzy -msgid "Fast" -msgstr "Einfügen" - -#: editor.cc:1462 editor.cc:1479 editor_actions.cc:381 -#, fuzzy -msgid "Fastest" -msgstr "schnellstmöglich" - -#: editor.cc:1589 editor.cc:1597 -msgid "Freeze" -msgstr "" - -#: editor.cc:1593 +#: gtk2_ardour/editor.cc:1470 msgid "Unfreeze" -msgstr "" +msgstr "Auftauen" -#: editor.cc:1762 editor.cc:1857 -#, fuzzy +#: gtk2_ardour/editor.cc:1639 msgid "Unmute" -msgstr "mute" - -#. non-operative menu items for menu bar -#. show editors -#: editor.cc:1766 editor.cc:2046 editor.cc:2748 editor_actions.cc:27 -#: editor_markers.cc:507 mixer_strip.cc:495 mixer_strip.cc:563 -#: redirect_box.cc:1079 +msgstr "Unmute" + +#: gtk2_ardour/editor.cc:1643 +#: gtk2_ardour/editor.cc:1939 +#: gtk2_ardour/editor_actions.cc:28 +#: gtk2_ardour/editor_markers.cc:510 +#: gtk2_ardour/mixer_strip.cc:515 +#: gtk2_ardour/mixer_strip.cc:577 +#: gtk2_ardour/redirect_box.cc:1089 msgid "Edit" msgstr "Bearbeiten" -#: editor.cc:1771 +#: gtk2_ardour/editor.cc:1648 msgid "Convert to short" msgstr "" -#: editor.cc:1773 +#: gtk2_ardour/editor.cc:1650 msgid "Convert to full" msgstr "" -#: editor.cc:1784 -#, fuzzy +#: gtk2_ardour/editor.cc:1661 msgid "Crossfade" -msgstr "Ardour: Editor" +msgstr "Crossfade" -#: editor.cc:1827 +#: gtk2_ardour/editor.cc:1704 msgid "Popup region editor" -msgstr "Regionen Editor öffnen" +msgstr "Regioneneditor öffnen" -#: editor.cc:1828 -#, fuzzy +#: gtk2_ardour/editor.cc:1705 msgid "Raise to top layer" msgstr "Region ganz nach oben" -#: editor.cc:1829 -#, fuzzy +#: gtk2_ardour/editor.cc:1706 msgid "Lower to bottom layer" msgstr "Region ganz nach unten" -#: editor.cc:1831 +#: gtk2_ardour/editor.cc:1708 msgid "Define sync point" msgstr "Synchronisationspunkt definieren" -#: editor.cc:1832 +#: gtk2_ardour/editor.cc:1709 msgid "Remove sync point" msgstr "Synchronisationspunkt entfernen" -#: editor.cc:1837 -#, fuzzy +#: gtk2_ardour/editor.cc:1714 msgid "Bounce" -msgstr "Bereich" +msgstr "Bounce" -#: editor.cc:1840 -#, fuzzy +#: gtk2_ardour/editor.cc:1717 msgid "Analyze region" -msgstr "Wiedergabe der Region" +msgstr "Analysiere Region" -#: editor.cc:1852 -#, fuzzy +#: gtk2_ardour/editor.cc:1722 msgid "Lock" -msgstr "OK" +msgstr "Sperren" -#: editor.cc:1853 -#, fuzzy -msgid "Unlock" -msgstr "Rückgängig" +#: gtk2_ardour/editor.cc:1732 +msgid "Opaque" +msgstr "Deckend" -#: editor.cc:1863 -#, fuzzy +#: gtk2_ardour/editor.cc:1738 msgid "Original position" -msgstr "Regionen" +msgstr "Ursprungsposition" -#: editor.cc:1869 -msgid "Toggle envelope visibility" -msgstr "" +#: gtk2_ardour/editor.cc:1750 +msgid "Reset Envelope" +msgstr "Lautstärkekurve zurücksetzen" -#: editor.cc:1870 -msgid "Toggle envelope active" -msgstr "" +#: gtk2_ardour/editor.cc:1752 +msgid "Envelope Visible" +msgstr "Lautstärkekurve sichtbar" -#: editor.cc:1874 -#, fuzzy +#: gtk2_ardour/editor.cc:1759 +msgid "Envelope Active" +msgstr "Lautstärkekurve aktiv" + +#: gtk2_ardour/editor.cc:1769 msgid "DeNormalize" -msgstr "Ardour: Region" +msgstr "Ardour: Region " -#: editor.cc:1876 -#, fuzzy +#: gtk2_ardour/editor.cc:1771 msgid "Normalize" -msgstr "Ardour: Region" +msgstr "Normalisieren" -#: editor.cc:1879 -#, fuzzy +#: gtk2_ardour/editor.cc:1774 msgid "Reverse" -msgstr "Entfernen" +msgstr "Rückwärts" -#. range related stuff -#: editor.cc:1885 -#, fuzzy +#: gtk2_ardour/editor.cc:1780 msgid "Add Range Markers" -msgstr "Ardour: Region umbenennen" +msgstr "Bereichsmarker einfügen" -#: editor.cc:1886 -#, fuzzy -msgid "Set Range" -msgstr "Ausgewählten Bereich wiedergeben" +#: gtk2_ardour/editor.cc:1781 +msgid "Set Range Selection" +msgstr "Bereich auswählen" -#: editor.cc:1895 +#: gtk2_ardour/editor.cc:1790 msgid "Nudge fwd" -msgstr "" +msgstr "Schritt nach vorne" -#: editor.cc:1896 +#: gtk2_ardour/editor.cc:1791 msgid "Nudge bwd" -msgstr "" +msgstr "Schritt nach hinten" -#: editor.cc:1897 +#: gtk2_ardour/editor.cc:1792 msgid "Nudge fwd by capture offset" -msgstr "" +msgstr "Schritt nach vorne um Aufnahme-Offset" -#: editor.cc:1898 +#: gtk2_ardour/editor.cc:1793 msgid "Nudge bwd by capture offset" -msgstr "" +msgstr "Schritt nach hinten um Aufnahme-Offset" + +#: gtk2_ardour/editor.cc:1795 +#: gtk2_ardour/editor.cc:1959 +#: gtk2_ardour/editor.cc:2015 +msgid "Nudge" +msgstr "Verschieben" -#: editor.cc:1907 +#: gtk2_ardour/editor.cc:1802 msgid "Start to edit cursor" -msgstr "" +msgstr "Von Anfang bis Editierzeiger" -#: editor.cc:1908 +#: gtk2_ardour/editor.cc:1803 msgid "Edit cursor to end" -msgstr "" +msgstr "Von Editierzeiger bis Ende" -#: editor.cc:1910 gain_meter.cc:181 gain_meter.cc:813 panner_ui.cc:98 -#: panner_ui.cc:803 +#: gtk2_ardour/editor.cc:1805 +#: gtk2_ardour/gain_meter.cc:168 +#: gtk2_ardour/gain_meter.cc:848 +#: gtk2_ardour/panner_ui.cc:96 +#: gtk2_ardour/panner_ui.cc:793 msgid "Trim" -msgstr "" +msgstr "Abschneiden" -#: editor.cc:1913 +#: gtk2_ardour/editor.cc:1808 msgid "Split" msgstr "Teilen" -#: editor.cc:1916 -#, fuzzy +#: gtk2_ardour/editor.cc:1811 msgid "Make mono regions" -msgstr "Name für Region:" +msgstr "Zu Mono-Regionen umwandeln" -#: editor.cc:1919 +#: gtk2_ardour/editor.cc:1814 msgid "Duplicate" msgstr "Duplizieren" -#: editor.cc:1920 -#, fuzzy +#: gtk2_ardour/editor.cc:1815 msgid "Fill Track" -msgstr "Spur" - -#: editor.cc:1924 -msgid "Destroy" -msgstr "" +msgstr "Spur auffüllen" -#: editor.cc:1954 +#: gtk2_ardour/editor.cc:1847 #, fuzzy msgid "Play range" msgstr "Bereich" -#: editor.cc:1955 +#: gtk2_ardour/editor.cc:1848 #, fuzzy msgid "Loop range" msgstr "Bereich" -#: editor.cc:1959 -#, fuzzy +#: gtk2_ardour/editor.cc:1852 msgid "Analyze range" -msgstr "Bereich" +msgstr "Bereich analysieren" -#: editor.cc:1963 +#: gtk2_ardour/editor.cc:1856 #, fuzzy msgid "Separate range to track" msgstr "Ausgewählten Bereich wiedergeben" -#: editor.cc:1964 +#: gtk2_ardour/editor.cc:1857 #, fuzzy msgid "Separate range to region list" msgstr "Auswahl zu Schleife machen" -#: editor.cc:1967 +#: gtk2_ardour/editor.cc:1860 #, fuzzy msgid "Select all in range" msgstr "Auswahl" -#: editor.cc:1969 editor.cc:2014 -#, fuzzy +#: gtk2_ardour/editor.cc:1862 +#: gtk2_ardour/editor.cc:1907 msgid "Set range to loop range" -msgstr "Ausgewählten Bereich wiedergeben" +msgstr "Ausgewählten Bereich als Schleife" -#: editor.cc:1970 editor.cc:2015 -#, fuzzy +#: gtk2_ardour/editor.cc:1863 +#: gtk2_ardour/editor.cc:1908 msgid "Set range to punch range" -msgstr "Ausgewählten Bereich wiedergeben" +msgstr "Ausgewählten Bereich als Punch-Bereich" -#: editor.cc:1972 -#, fuzzy +#: gtk2_ardour/editor.cc:1865 msgid "Crop region to range" -msgstr "Regionen Editor öffnen" +msgstr "Regionen-Editor öffnen" -#: editor.cc:1973 +#: gtk2_ardour/editor.cc:1866 #, fuzzy msgid "Fill range with region" msgstr "Region erstellen" -#: editor.cc:1974 +#: gtk2_ardour/editor.cc:1867 #, fuzzy msgid "Duplicate range" msgstr "Duplizieren" -#: editor.cc:1975 +#: gtk2_ardour/editor.cc:1868 #, fuzzy msgid "Create chunk from range" msgstr "Auswahl zu Abschnitt machen" -#: editor.cc:1977 +#: gtk2_ardour/editor.cc:1870 #, fuzzy msgid "Bounce range" msgstr "Bereich" -#: editor.cc:1978 +#: gtk2_ardour/editor.cc:1871 #, fuzzy msgid "Export range" msgstr "Name für Region:" -#: editor.cc:1980 +#: gtk2_ardour/editor.cc:1873 #, fuzzy msgid "Range" msgstr "Bereich" -#: editor.cc:1995 editor.cc:2080 -#, fuzzy +#: gtk2_ardour/editor.cc:1888 +#: gtk2_ardour/editor.cc:1973 msgid "Play from edit cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Wiedergabe ab Editierzeiger" -#: editor.cc:1996 editor.cc:2081 +#: gtk2_ardour/editor.cc:1889 +#: gtk2_ardour/editor.cc:1974 msgid "Play from start" msgstr "Wiedergabe ab Anfang" -#: editor.cc:1997 -#, fuzzy +#: gtk2_ardour/editor.cc:1890 msgid "Play region" -msgstr "Wiedergabe der Region" +msgstr "Region wiedergeben" -#: editor.cc:1999 -#, fuzzy +#: gtk2_ardour/editor.cc:1892 msgid "Loop Region" -msgstr "Auswahl zu Schleife machen" +msgstr "Region in Schleife wiedergeben" -#: editor.cc:2009 editor.cc:2090 -#, fuzzy +#: gtk2_ardour/editor.cc:1902 +#: gtk2_ardour/editor.cc:1983 msgid "Select All in track" -msgstr "Auswahl" +msgstr "Alles in Spur auswählen" -#: editor.cc:2010 editor.cc:2091 redirect_box.cc:1067 -#, fuzzy +#: gtk2_ardour/editor.cc:1903 +#: gtk2_ardour/editor.cc:1984 +#: gtk2_ardour/redirect_box.cc:1077 msgid "Select All" -msgstr "Auswahl" +msgstr "Alles Auswählen" -#: editor.cc:2011 editor.cc:2092 -#, fuzzy +#: gtk2_ardour/editor.cc:1904 +#: gtk2_ardour/editor.cc:1985 msgid "Invert selection in track" -msgstr "Stille einfügen" +msgstr "Auswahl in Spur umkehren" -#: editor.cc:2012 editor.cc:2093 -#, fuzzy +#: gtk2_ardour/editor.cc:1905 +#: gtk2_ardour/editor.cc:1986 msgid "Invert selection" -msgstr "Auswahl zu Schleife machen" +msgstr "Auswahl umkehren" -#: editor.cc:2017 editor.cc:2095 -#, fuzzy +#: gtk2_ardour/editor.cc:1910 +#: gtk2_ardour/editor.cc:1988 msgid "Select all after edit cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Alles nach Editierzeiger auswählen" -#: editor.cc:2018 editor.cc:2096 -#, fuzzy +#: gtk2_ardour/editor.cc:1911 +#: gtk2_ardour/editor.cc:1989 msgid "Select all before edit cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Alles vor Editierzeiger auswählen" -#: editor.cc:2019 editor.cc:2097 -#, fuzzy +#: gtk2_ardour/editor.cc:1912 +#: gtk2_ardour/editor.cc:1990 msgid "Select all after playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Alles nach Positionszeiger auswählen" -#: editor.cc:2020 editor.cc:2098 -#, fuzzy +#: gtk2_ardour/editor.cc:1913 +#: gtk2_ardour/editor.cc:1991 msgid "Select all before playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Alles vor Positionszeiger auswählen" -#: editor.cc:2021 -#, fuzzy +#: gtk2_ardour/editor.cc:1914 msgid "Select all between cursors" -msgstr "Wiedergabe ab Cursor" +msgstr "Alles zwischen Zeigern auswählen" -#. standard editing stuff -#: editor.cc:2032 editor.cc:2108 editor.cc:3483 editor_actions.cc:214 -#: redirect_box.cc:1060 +#: gtk2_ardour/editor.cc:1917 +#: gtk2_ardour/editor.cc:1993 +msgid "Select" +msgstr "Auswahl" + +#: gtk2_ardour/editor.cc:1925 +#: gtk2_ardour/editor.cc:2001 +#: gtk2_ardour/editor_actions.cc:215 +#: gtk2_ardour/redirect_box.cc:1070 msgid "Cut" msgstr "Ausschneiden" -#: editor.cc:2033 editor.cc:2109 editor.cc:3485 editor_actions.cc:219 -#: redirect_box.cc:1062 +#: gtk2_ardour/editor.cc:1926 +#: gtk2_ardour/editor.cc:2002 +#: gtk2_ardour/editor_actions.cc:220 +#: gtk2_ardour/redirect_box.cc:1072 msgid "Copy" msgstr "Kopieren" -#: editor.cc:2034 -#, fuzzy +#: gtk2_ardour/editor.cc:1927 msgid "Paste at edit cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Am Editierzeiger einfügen" -#: editor.cc:2035 +#: gtk2_ardour/editor.cc:1928 msgid "Paste at mouse" -msgstr "" +msgstr "An Mausposition einfügen" -#: editor.cc:2039 editor.cc:3490 +#: gtk2_ardour/editor.cc:1932 msgid "Align" -msgstr "" +msgstr "Ausrichten" -#: editor.cc:2040 editor.cc:3492 +#: gtk2_ardour/editor.cc:1933 msgid "Align Relative" -msgstr "" +msgstr "Relativ ausrichten" -#: editor.cc:2044 +#: gtk2_ardour/editor.cc:1937 msgid "Insert chunk" msgstr "Abschnitt einfügen" -#: editor.cc:2051 -#, fuzzy +#: gtk2_ardour/editor.cc:1944 msgid "Insert Selected Region" -msgstr "Auswahl zu Schleife machen" +msgstr "Ausgewählte Region einfügen" -#: editor.cc:2052 +#: gtk2_ardour/editor.cc:1945 msgid "Insert Existing Audio" -msgstr "" +msgstr "Audio importieren..." -#: editor.cc:2061 editor.cc:2117 +#: gtk2_ardour/editor.cc:1954 +#: gtk2_ardour/editor.cc:2010 msgid "Nudge entire track fwd" -msgstr "" +msgstr "Gesamte Spur schrittweise nach vorne" -#: editor.cc:2062 editor.cc:2118 +#: gtk2_ardour/editor.cc:1955 +#: gtk2_ardour/editor.cc:2011 msgid "Nudge track after edit cursor fwd" -msgstr "" +msgstr "Spur nach Editierzeiger schrittweise nach vorne" -#: editor.cc:2063 editor.cc:2119 +#: gtk2_ardour/editor.cc:1956 +#: gtk2_ardour/editor.cc:2012 msgid "Nudge entire track bwd" -msgstr "" +msgstr "Gesamte Spur schrittweise nach hinten" -#: editor.cc:2064 editor.cc:2120 +#: gtk2_ardour/editor.cc:1957 +#: gtk2_ardour/editor.cc:2013 msgid "Nudge track after edit cursor bwd" -msgstr "" +msgstr "Spur nach Editierzeiger schrittweise nach hinten" -#: editor.cc:2110 editor.cc:3487 editor_actions.cc:221 redirect_box.cc:1064 +#: gtk2_ardour/editor.cc:2003 +#: gtk2_ardour/editor_actions.cc:222 +#: gtk2_ardour/redirect_box.cc:1074 msgid "Paste" msgstr "Einfügen" -#: editor.cc:2630 -msgid "select/move objects" -msgstr "" +#: gtk2_ardour/editor.cc:2566 +msgid "Select/Move Objects" +msgstr "Objekte auswählen/verschieben" -#: editor.cc:2631 -#, fuzzy -msgid "select/move ranges" -msgstr "Ausgewählten Bereich wiedergeben" +#: gtk2_ardour/editor.cc:2567 +msgid "Select/Move Ranges" +msgstr "Bereiche auswählen/verschieben" -#: editor.cc:2632 -msgid "draw gain automation" -msgstr "" +#: gtk2_ardour/editor.cc:2568 +msgid "Draw Gain Automation" +msgstr "Lautstärkeautomation zeichnen" -#: editor.cc:2633 -#, fuzzy -msgid "select zoom range" -msgstr "Ausgewählten Bereich wiedergeben" +#: gtk2_ardour/editor.cc:2569 +msgid "Select Zoom Range" +msgstr "Zoombereich auswählen" -#: editor.cc:2634 -msgid "stretch/shrink regions" -msgstr "" +#: gtk2_ardour/editor.cc:2570 +msgid "Stretch/Shrink Regions" +msgstr "Regionen vergrößern/verkleinern (Time-Stretch)" -#: editor.cc:2635 -#, fuzzy -msgid "listen to specific regions" -msgstr "Auswahl zu Schleife machen" +#: gtk2_ardour/editor.cc:2571 +msgid "Listen to Specific Regions" +msgstr "Ausgewählte Regionen vorhören" + +#: gtk2_ardour/editor.cc:2600 +#: gtk2_ardour/editor_actions.cc:143 +msgid "Zoom In" +msgstr "Vergrößern" + +#: gtk2_ardour/editor.cc:2605 +#: gtk2_ardour/editor_actions.cc:141 +msgid "Zoom Out" +msgstr "Verkleinern" + +#: gtk2_ardour/editor.cc:2610 +#: gtk2_ardour/editor_actions.cc:145 +msgid "Zoom to Session" +msgstr "Auf ganze Sitzung zoomen" -#: editor.cc:2746 -msgid "Start:" -msgstr "Anfang:" +#: gtk2_ardour/editor.cc:2617 +msgid "" +"Current Zoom Range\n" +"(Width of visible area)" +msgstr "" -#: editor.cc:2747 -msgid "End:" -msgstr "Ende:" +#: gtk2_ardour/editor.cc:2623 +msgid "Zoom focus" +msgstr "Zoom-Mittelpunkt" + +#: gtk2_ardour/editor.cc:2637 +msgid "Unit to snap cursors and ranges to" +msgstr "" -#: editor.cc:3362 editor.cc:3402 +#: gtk2_ardour/editor.cc:3217 +#: gtk2_ardour/editor.cc:3266 #, fuzzy msgid "set selected regions" msgstr "Auswahl zu Schleife machen" -#: editor.cc:3458 editor_actions.cc:204 +#: gtk2_ardour/editor.cc:3306 +#: gtk2_ardour/editor_actions.cc:205 msgid "Undo" msgstr "Rückgängig" -#: editor.cc:3460 +#: gtk2_ardour/editor.cc:3308 msgid "Undo (%1)" msgstr "Rückgängig (%1)" -#: editor.cc:3470 editor_actions.cc:206 +#: gtk2_ardour/editor.cc:3315 +#: gtk2_ardour/editor_actions.cc:207 msgid "Redo" msgstr "Wiederherstellen" -#: editor.cc:3472 +#: gtk2_ardour/editor.cc:3317 msgid "Redo (%1)" msgstr "Wiederherstellen (%1)" -#: editor.cc:3506 -msgid "... as new track" -msgstr "" - -#: editor.cc:3507 -#, fuzzy -msgid "... as new region" -msgstr "Ardour: Region" - -#: editor.cc:3509 -#, fuzzy -msgid "Import audio (copy)" -msgstr "Audio Importieren" +#: gtk2_ardour/editor.cc:3338 +msgid "Duplicate how many times?" +msgstr "Wie häufig duplizieren?" -#: editor.cc:3512 +#: gtk2_ardour/editor.cc:3416 #, fuzzy -msgid "Remove last capture" -msgstr "Synchronisationspunkt entfernen" +msgid "Splice Edit" +msgstr "Teilen" -#: editor.cc:3536 -msgid "Duplicate how many times?" -msgstr "Wie häufig duplizieren?" +#: gtk2_ardour/editor.cc:3418 +msgid "Slide Edit" +msgstr "" -#: editor.cc:4022 +#: gtk2_ardour/editor.cc:3828 msgid "" "Playlist %1 is currently unused.\n" "If left alone, no audio files used by it will be cleaned.\n" "If deleted, audio files used by it alone by will cleaned." msgstr "" -#: editor.cc:4030 -#, fuzzy +#: gtk2_ardour/editor.cc:3836 msgid "Delete playlist" -msgstr "Name für Schnappschuß" +msgstr "Wiedergabeliste löschen" -#: editor.cc:4031 -#, fuzzy +#: gtk2_ardour/editor.cc:3837 msgid "Keep playlist" -msgstr "Name für Schnappschuß" - -#: editor.cc:4032 editor_audio_import.cc:236 editor_ops.cc:2048 -#: editor_timefx.cc:71 export_dialog.cc:971 io_selector.cc:59 -#: io_selector.cc:793 redirect_box.cc:903 tempo_dialog.cc:20 -#: tempo_dialog.cc:37 tempo_dialog.cc:202 tempo_dialog.cc:220 +msgstr "Wiedergabeliste beibehalten" + +#: gtk2_ardour/editor.cc:3838 +#: gtk2_ardour/editor_audio_import.cc:239 +#: gtk2_ardour/editor_ops.cc:1973 +#: gtk2_ardour/editor_timefx.cc:72 +#: gtk2_ardour/export_dialog.cc:969 +#: gtk2_ardour/io_selector.cc:61 +#: gtk2_ardour/io_selector.cc:750 +#: gtk2_ardour/redirect_box.cc:901 +#: gtk2_ardour/tempo_dialog.cc:20 +#: gtk2_ardour/tempo_dialog.cc:37 +#: gtk2_ardour/tempo_dialog.cc:202 +#: gtk2_ardour/tempo_dialog.cc:220 +#: gtk2_ardour/connection_editor.cc:60 msgid "Cancel" msgstr "Abbrechen" -#: editor.cc:4199 -#, fuzzy +#: gtk2_ardour/editor.cc:4041 msgid "new playlists" -msgstr "Name für Schnappschuß" +msgstr "Neue Wiedergabelisten" -#: editor.cc:4207 -#, fuzzy +#: gtk2_ardour/editor.cc:4049 msgid "copy playlists" -msgstr "Name für Schnappschuß" +msgstr "Wiedergabelisten kopieren" -#: editor.cc:4215 -#, fuzzy +#: gtk2_ardour/editor.cc:4057 msgid "clear playlists" -msgstr "Name für Schnappschuß" +msgstr "" -#: editor_actions.cc:28 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:29 msgid "Select regions" -msgstr "Auswahl zu Schleife machen" +msgstr "Region(en) auswählen" -#: editor_actions.cc:29 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:30 msgid "Select range operations" -msgstr "Auswahl zu Schleife machen" +msgstr "Bereich" -#: editor_actions.cc:30 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:31 msgid "Move edit cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Editierzeiger bewegen" -#: editor_actions.cc:31 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:32 msgid "Region operations" -msgstr "Regionen" +msgstr "Region(en)" -#: editor_actions.cc:32 +#: gtk2_ardour/editor_actions.cc:33 msgid "Tools" msgstr "" -#: editor_actions.cc:33 +#: gtk2_ardour/editor_actions.cc:34 msgid "View" -msgstr "" +msgstr "Ansicht" -#: editor_actions.cc:34 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:35 msgid "ZoomFocus" -msgstr "Verkleinern" +msgstr "Zoom-Mittelpunkt" -#: editor_actions.cc:35 +#: gtk2_ardour/editor_actions.cc:36 msgid "Meter hold" -msgstr "" +msgstr "Pegelanzeige halten" -#: editor_actions.cc:36 +#: gtk2_ardour/editor_actions.cc:37 msgid "Meter falloff" -msgstr "" +msgstr "Abfall der Pegelanzeigen" -#: editor_actions.cc:38 +#: gtk2_ardour/editor_actions.cc:39 #, fuzzy msgid "Crossfades" msgstr "Ardour: Editor" -#: editor_actions.cc:39 +#: gtk2_ardour/editor_actions.cc:40 msgid "Monitoring" -msgstr "" +msgstr "Monitoring" -#: editor_actions.cc:40 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:41 msgid "Autoconnect" -msgstr "Verbindungen" +msgstr "Automatisch verbinden" -#: editor_actions.cc:41 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:42 msgid "Layering" -msgstr "Schicht" +msgstr "Layering" -#: editor_actions.cc:42 -#, fuzzy -msgid "Metering" -msgstr "Schicht" +#: gtk2_ardour/editor_actions.cc:43 +msgid "Timecode fps" +msgstr "" -#: editor_actions.cc:43 -msgid "Fall off rate" +#: gtk2_ardour/editor_actions.cc:44 +msgid "Pullup / Pulldown" msgstr "" -#: editor_actions.cc:44 -msgid "Hold Time" +#: gtk2_ardour/editor_actions.cc:45 +msgid "Subframes" msgstr "" -#: editor_actions.cc:45 +#: gtk2_ardour/editor_actions.cc:46 msgid "Add Existing Audio" -msgstr "" +msgstr "Audio importieren" -#. add named actions for the editor -#: editor_actions.cc:50 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:51 msgid "Show Editor Mixer" -msgstr "Ardour: Mixer" +msgstr "Mixer-Panel zeigen" -#: editor_actions.cc:55 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:56 msgid "Span Entire Overlap" -msgstr "Region eine Ebene nach oben" - -#: editor_actions.cc:57 editor_actions.cc:384 -#, fuzzy -msgid "Short" -msgstr "Anschluß" +msgstr "Gesamte Ãœberlappung" -#: editor_actions.cc:64 +#: gtk2_ardour/editor_actions.cc:65 msgid "Created Automatically" -msgstr "" +msgstr "Automatisch erzeugen" -#: editor_actions.cc:67 +#: gtk2_ardour/editor_actions.cc:68 msgid "Playhead to Next Region Start" -msgstr "" +msgstr "Positionszeiger zum Anfang der nächsten Region" -#: editor_actions.cc:69 +#: gtk2_ardour/editor_actions.cc:70 msgid "Playhead to Next Region End" -msgstr "" +msgstr "Positionszeiger zum Ende der nächsten Region" -#: editor_actions.cc:71 +#: gtk2_ardour/editor_actions.cc:72 msgid "Playhead to Next Region Sync" -msgstr "" +msgstr "Positionszeiger zum Sync der nächsten Region" -#: editor_actions.cc:74 +#: gtk2_ardour/editor_actions.cc:75 msgid "Playhead to Previous Region Start" -msgstr "" +msgstr "Positionszeiger zum Anfang der vorherigen Region" -#: editor_actions.cc:76 +#: gtk2_ardour/editor_actions.cc:77 msgid "Playhead to Previous Region End" -msgstr "" +msgstr "Positionszeiger zum Ende der vorherigen Region" -#: editor_actions.cc:78 +#: gtk2_ardour/editor_actions.cc:79 msgid "Playhead to Previous Region Sync" -msgstr "" +msgstr "Positionszeiger zum Sync der vorherigen Region" -#: editor_actions.cc:81 +#: gtk2_ardour/editor_actions.cc:82 msgid "Edit Cursor to Next Region Start" -msgstr "" +msgstr "Editierzeiger zum Anfang der nächsten Region" -#: editor_actions.cc:83 +#: gtk2_ardour/editor_actions.cc:84 msgid "Edit Cursor to Next Region End" -msgstr "" +msgstr "Editierzeiger zum Ende der nächsten Region" -#: editor_actions.cc:85 +#: gtk2_ardour/editor_actions.cc:86 msgid "Edit Cursor to Next Region Sync" -msgstr "" +msgstr "Editierzeiger zum Sync der nächsten Region" -#: editor_actions.cc:88 +#: gtk2_ardour/editor_actions.cc:89 msgid "Edit Cursor to Previous Region Start" -msgstr "" +msgstr "Editierzeiger zum Anfang der vorherigen Region" -#: editor_actions.cc:90 +#: gtk2_ardour/editor_actions.cc:91 msgid "Edit Cursor to Previous Region End" -msgstr "" +msgstr "Editierzeiger zum Ende der vorherigen Region" -#: editor_actions.cc:92 +#: gtk2_ardour/editor_actions.cc:93 msgid "Edit Cursor to Previous Region Sync" -msgstr "" +msgstr "Editierzeiger zum Sync der vorherigen Region" -#: editor_actions.cc:95 +#: gtk2_ardour/editor_actions.cc:96 msgid "Playhead to Range Start" -msgstr "" +msgstr "Positionszeiger zum Anfang der Auswahl" -#: editor_actions.cc:97 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:98 msgid "Playhead to Range End" -msgstr "Bereich" +msgstr "Positionszeiger zum Ende der Auswahl" -#: editor_actions.cc:100 +#: gtk2_ardour/editor_actions.cc:101 msgid "Edit Cursor to Range Start" -msgstr "" +msgstr "Editierzeiger zum Anfang der Auswahl" -#: editor_actions.cc:102 +#: gtk2_ardour/editor_actions.cc:103 msgid "Edit Cursor to Range End" -msgstr "" +msgstr "Editierzeiger zum Ende der Auswahl" -#: editor_actions.cc:105 editor_ops.cc:1363 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:106 +#: gtk2_ardour/editor_ops.cc:1292 msgid "select all" -msgstr "Auswahl" +msgstr "Alle Regionen auswählen" -#: editor_actions.cc:107 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:108 msgid "Select All After Edit Cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Alle Regionen nach dem Editierzeiger auswählen" -#: editor_actions.cc:109 +#: gtk2_ardour/editor_actions.cc:110 msgid "Select All Before Edit Cursor" -msgstr "" +msgstr "Alle Regionen vor dem Editierzeiger auswählen" -#: editor_actions.cc:112 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:113 msgid "Select All After Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Alle Regionen nach dem Positionszeiger auswählen" -#: editor_actions.cc:114 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:115 msgid "Select All Before Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Alle Regionen vor dem Positionszeiger auswählen" -#: editor_actions.cc:116 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:117 msgid "Select All Between Cursors" -msgstr "Wiedergabe ab Cursor" +msgstr "Alle Regionen zwischen den Zeigern auswählen" -#: editor_actions.cc:119 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:120 msgid "Select All in Punch Range" -msgstr "Ausgewählten Bereich wiedergeben" +msgstr "Alle Regionen im Punch-Bereich auswählen" -#: editor_actions.cc:121 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:122 msgid "Select All in Loop Range" -msgstr "Ausgewählten Bereich wiedergeben" +msgstr "Alle Regionen innerhalb der Schleife auswählen" -#: editor_actions.cc:124 +#: gtk2_ardour/editor_actions.cc:125 msgid "Jump Forward to Mark" -msgstr "" +msgstr "Zum nächsten Marker springen" -#: editor_actions.cc:126 +#: gtk2_ardour/editor_actions.cc:127 msgid "Jump Backward to Mark" -msgstr "" +msgstr "Zum vorherigen Marker springen" -#: editor_actions.cc:128 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:129 msgid "Add Location from Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Marker am Positionszeiger setzen" -#: editor_actions.cc:131 +#: gtk2_ardour/editor_actions.cc:132 msgid "Nudge Forward" -msgstr "" +msgstr "Schritt nach vorne" -#: editor_actions.cc:133 +#: gtk2_ardour/editor_actions.cc:134 msgid "Nudge Next Forward" msgstr "" -#: editor_actions.cc:135 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:136 msgid "Nudge Backward" -msgstr "Stille einfügen" +msgstr "Schritt nach Hinten" -#: editor_actions.cc:137 +#: gtk2_ardour/editor_actions.cc:138 #, fuzzy msgid "Nudge Next Backward" msgstr "Stille einfügen" -#: editor_actions.cc:140 -#, fuzzy -msgid "Zoom Out" -msgstr "Verkleinern" - -#: editor_actions.cc:142 -#, fuzzy -msgid "Zoom In" -msgstr "Vergrößern" - -#: editor_actions.cc:144 -#, fuzzy -msgid "Zoom to Session" -msgstr "Vergrößern auf Auswahl" - -#: editor_actions.cc:147 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:148 msgid "Scroll Tracks Up" -msgstr "Spur" +msgstr "Spuren nach oben scrollen" -#: editor_actions.cc:149 +#: gtk2_ardour/editor_actions.cc:150 msgid "Scroll Tracks Down" -msgstr "" +msgstr "Spuren nach unten scrollen" -#: editor_actions.cc:151 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:152 msgid "Step Tracks Up" -msgstr "Stille einfügen" +msgstr "Spuren langsam nach oben scrollen" -#: editor_actions.cc:153 +#: gtk2_ardour/editor_actions.cc:154 msgid "Step Tracks Down" -msgstr "" +msgstr "Spuren langsam nach unten scrollen" -#: editor_actions.cc:156 +#: gtk2_ardour/editor_actions.cc:157 msgid "Scroll Backward" -msgstr "" +msgstr "Vorwärts scrollen" -#: editor_actions.cc:158 +#: gtk2_ardour/editor_actions.cc:159 msgid "Scroll Forward" -msgstr "" +msgstr "Rückwärts scrollen" -#: editor_actions.cc:160 +#: gtk2_ardour/editor_actions.cc:161 msgid "goto" msgstr "" -#: editor_actions.cc:162 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:163 msgid "Center Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Ansicht am Positionszeiger zentrieren" -#: editor_actions.cc:164 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:165 msgid "Center Edit Cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Editierzeiger zentrieren" -#: editor_actions.cc:166 +#: gtk2_ardour/editor_actions.cc:167 msgid "Playhead Forward" -msgstr "" +msgstr "Positionszeiger vorwärts" -#: editor_actions.cc:168 +#: gtk2_ardour/editor_actions.cc:169 msgid "Playhead Backward" -msgstr "" +msgstr "Positionszeiger rückwärts" -#: editor_actions.cc:170 +#: gtk2_ardour/editor_actions.cc:171 msgid "Playhead to Edit" -msgstr "" +msgstr "Positionszeiger zum Editierzeiger setzen" -#: editor_actions.cc:172 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:173 msgid "Edit to Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Editierzeiger zum Positionszeiger setzen" -#: editor_actions.cc:175 +#: gtk2_ardour/editor_actions.cc:176 #, fuzzy msgid "Align Regions Start" msgstr "Regionen" -#: editor_actions.cc:177 +#: gtk2_ardour/editor_actions.cc:178 #, fuzzy msgid "Align Regions Start Relative" msgstr "nach Anfang der Region in der Datei" -#: editor_actions.cc:179 +#: gtk2_ardour/editor_actions.cc:180 #, fuzzy msgid "Align Regions End" msgstr "Ardour: Region" -#: editor_actions.cc:181 +#: gtk2_ardour/editor_actions.cc:182 msgid "Align Regions End Relative" msgstr "" -#: editor_actions.cc:184 +#: gtk2_ardour/editor_actions.cc:185 #, fuzzy msgid "Align Regions Sync" msgstr "Ardour: Region" -#: editor_actions.cc:186 +#: gtk2_ardour/editor_actions.cc:187 msgid "Align Regions Sync Relative" msgstr "" -#: editor_actions.cc:189 +#: gtk2_ardour/editor_actions.cc:190 msgid "Audition at Mouse" -msgstr "" +msgstr "An Mauszeigerposition vorhören" -#: editor_actions.cc:191 +#: gtk2_ardour/editor_actions.cc:192 msgid "Brush at Mouse" -msgstr "" +msgstr "Pinsel an Mausposition (Brush)" -#: editor_actions.cc:193 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:194 msgid "Set Edit Cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Editierzeiger setzen" -#: editor_actions.cc:195 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:196 msgid "Mute/Unmute Region" -msgstr "Region erstellen" +msgstr "Region Mute/Unmute" -#: editor_actions.cc:197 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:198 msgid "Set Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Positionszeiger setzen" -#: editor_actions.cc:199 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:200 msgid "Split Region" -msgstr "Auswahl zu Schleife machen" +msgstr "Region teilen (Split)" -#: editor_actions.cc:201 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:202 msgid "Set Region Sync Position" -msgstr "nach Zeitstempel der Region" +msgstr "Sync-Position der Region setzen" -#: editor_actions.cc:209 +#: gtk2_ardour/editor_actions.cc:210 #, fuzzy msgid "Export Session" msgstr "Name für Region:" -#: editor_actions.cc:211 +#: gtk2_ardour/editor_actions.cc:212 #, fuzzy msgid "Export Range" msgstr "Ausgewählten Bereich wiedergeben" -#. Note: for now, editor-delete does the exact same thing as editor-cut -#: editor_actions.cc:217 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:218 +#: gtk2_ardour/connection_editor.cc:56 msgid "Delete" -msgstr "entfernen" +msgstr "Löschen" -#: editor_actions.cc:223 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:224 msgid "Duplicate Region" -msgstr "Auswahl zu Schleife machen" +msgstr "Duplizieren" -#: editor_actions.cc:225 +#: gtk2_ardour/editor_actions.cc:226 #, fuzzy msgid "Duplicate Range" msgstr "Duplizieren" -#: editor_actions.cc:227 +#: gtk2_ardour/editor_actions.cc:228 msgid "Insert Region" -msgstr "" +msgstr "Einfügen" -#: editor_actions.cc:229 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:230 msgid "Reverse Region" -msgstr "Name für Region:" +msgstr "Rückwärts" -#: editor_actions.cc:231 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:232 msgid "Normalize Region" -msgstr "Ardour: Region" +msgstr "Normalisieren" -#: editor_actions.cc:233 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:234 msgid "crop" -msgstr "Kopieren" +msgstr "Abschneiden" -#: editor_actions.cc:235 +#: gtk2_ardour/editor_actions.cc:236 #, fuzzy msgid "Insert Chunk" msgstr "Abschnitt einfügen" -#: editor_actions.cc:238 +#: gtk2_ardour/editor_actions.cc:239 #, fuzzy msgid "Split at edit cursor" msgstr "Wiedergabe ab Cursor" -#: editor_actions.cc:241 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:242 msgid "Start Range" -msgstr "Ausgewählten Bereich wiedergeben" +msgstr "Bereich anfangen" -#: editor_actions.cc:243 +#: gtk2_ardour/editor_actions.cc:244 msgid "Finish Range" -msgstr "" +msgstr "Bereich beenden" -#: editor_actions.cc:245 +#: gtk2_ardour/editor_actions.cc:246 msgid "Finish add Range" msgstr "" -#: editor_actions.cc:248 +#: gtk2_ardour/editor_actions.cc:249 msgid "Extend Range to End of Region" -msgstr "" +msgstr "Bereich vergrößern bis zum Ende der Region " -#: editor_actions.cc:250 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:251 msgid "Extend Range to Start of Region" -msgstr "An den Anfang der Sitzung springen" +msgstr "Bereich vergrößern bis zum Anfang der Region " -#: editor_actions.cc:253 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:254 msgid "Follow Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Positionszeiger folgen" -#: editor_actions.cc:261 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:262 msgid "Zoom Focus Left" -msgstr "Verkleinern" +msgstr "Am linken Rand ausrichten" -#: editor_actions.cc:263 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:264 msgid "Zoom Focus Right" -msgstr "Verkleinern" +msgstr "Am rechten Rand ausrichten" -#: editor_actions.cc:265 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:266 msgid "Zoom Focus Center" -msgstr "Verkleinern" +msgstr "Zentriert ausrichten" -#: editor_actions.cc:267 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:268 msgid "Zoom Focus Playhead" -msgstr "Verkleinern" +msgstr "Am Positionszeiger ausrichten" -#: editor_actions.cc:269 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:270 msgid "Zoom Focus Edit" -msgstr "Verkleinern" +msgstr "Am Editierzeiger ausrichten" -#: editor_actions.cc:275 +#: gtk2_ardour/editor_actions.cc:276 msgid "Object Tool" -msgstr "" +msgstr "Objektwerkzeug" -#: editor_actions.cc:276 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:277 msgid "Range Tool" -msgstr "Bereich" +msgstr "Bereich-Werkzeug (Range)" -#: editor_actions.cc:277 +#: gtk2_ardour/editor_actions.cc:278 msgid "Gain Tool" -msgstr "" +msgstr "Lautstärkewerkzeug (Gain)" -#: editor_actions.cc:278 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:279 msgid "Zoom Tool" -msgstr "Verkleinern" +msgstr "Zoom-Werkzeug" -#: editor_actions.cc:279 +#: gtk2_ardour/editor_actions.cc:280 msgid "Timefx Tool" -msgstr "" +msgstr "Zeit-Werkzeug (Time)" -#: editor_actions.cc:286 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:282 +msgid "Snap To" +msgstr "Raster" + +#: gtk2_ardour/editor_actions.cc:283 +msgid "Snap Mode" +msgstr "Einrastmodus" + +#: gtk2_ardour/editor_actions.cc:292 msgid "Snap to frame" -msgstr "Modus" +msgstr "An Frames einrasten" -#: editor_actions.cc:287 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:293 msgid "Snap to cd frame" -msgstr "Modus" +msgstr "An CD-Frames einrasten" -#: editor_actions.cc:288 +#: gtk2_ardour/editor_actions.cc:294 msgid "Snap to SMPTE frame" -msgstr "" +msgstr "An SMPTE-Frames einrasten" -#: editor_actions.cc:289 +#: gtk2_ardour/editor_actions.cc:295 msgid "Snap to SMPTE seconds" -msgstr "" +msgstr "An SMPTE-Sekunden einrasten" -#: editor_actions.cc:290 +#: gtk2_ardour/editor_actions.cc:296 msgid "Snap to SMPTE minutes" -msgstr "" +msgstr "An SMPTE-Minuten einrasten" -#: editor_actions.cc:291 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:297 msgid "Snap to seconds" -msgstr "Minuten:Sekunden" +msgstr "An Sekunden einrasten" -#: editor_actions.cc:292 +#: gtk2_ardour/editor_actions.cc:298 msgid "Snap to minutes" -msgstr "" +msgstr "An Minuten einrasten" -#: editor_actions.cc:293 +#: gtk2_ardour/editor_actions.cc:299 msgid "Snap to thirtyseconds" -msgstr "" +msgstr "An halben Minuten einrasten" -#: editor_actions.cc:294 +#: gtk2_ardour/editor_actions.cc:300 msgid "Snap to asixteenthbeat" -msgstr "" +msgstr "An Sechzehnteln einrasten" -#: editor_actions.cc:295 +#: gtk2_ardour/editor_actions.cc:301 msgid "Snap to eighths" -msgstr "" +msgstr "An Achteln einrasten" -#: editor_actions.cc:296 +#: gtk2_ardour/editor_actions.cc:302 msgid "Snap to quarters" -msgstr "" +msgstr "An Vierteln einrasten" -#: editor_actions.cc:297 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:303 msgid "Snap to thirds" -msgstr "Modus" +msgstr "An Triolen einrasten" -#: editor_actions.cc:298 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:304 msgid "Snap to beat" -msgstr "Modus" +msgstr "An Schlägen einrasten" -#: editor_actions.cc:299 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:305 msgid "Snap to bar" -msgstr "Modus" +msgstr "An Takten einrasten" -#: editor_actions.cc:300 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:306 msgid "Snap to mark" -msgstr "Ardour: Region umbenennen" +msgstr "An Markern einrasten" -#: editor_actions.cc:301 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:307 msgid "Snap to edit cursor" -msgstr "Wiedergabe ab Cursor" +msgstr "Am Editierzeiger einrasten" -#: editor_actions.cc:302 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:308 msgid "Snap to region start" -msgstr "Regionen" +msgstr "Am Anfang der Regionen einrasten" -#: editor_actions.cc:303 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:309 msgid "Snap to region end" -msgstr "Regionen" +msgstr "Am Ende der Regionen einrasten" -#: editor_actions.cc:304 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:310 msgid "Snap to region sync" -msgstr "Regionen" +msgstr "Am Sync der Regionen einrasten" -#: editor_actions.cc:305 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:311 msgid "Snap to region boundary" -msgstr "Regionen" +msgstr "An Grenzen der Regionen einrasten" -#. the region list popup menu -#: editor_actions.cc:314 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:320 msgid "Sort" -msgstr "Anschluß" +msgstr "Sortieren" -#: editor_actions.cc:322 +#: gtk2_ardour/editor_actions.cc:328 msgid "Show all" msgstr "Alle zeigen" -#: editor_actions.cc:323 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:329 msgid "Show automatic regions" -msgstr "Stellen" +msgstr "Automatische Regionen zeigen" -#: editor_actions.cc:325 +#: gtk2_ardour/editor_actions.cc:331 msgid "Ascending" msgstr "aufsteigend" -#: editor_actions.cc:327 +#: gtk2_ardour/editor_actions.cc:333 msgid "Descending" msgstr "absteigend" -#: editor_actions.cc:330 +#: gtk2_ardour/editor_actions.cc:336 msgid "By Region Name" msgstr "nach Name der Region" -#: editor_actions.cc:332 +#: gtk2_ardour/editor_actions.cc:338 msgid "By Region Length" msgstr "nach Länge der Region" -#: editor_actions.cc:334 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:340 msgid "By Region Position" -msgstr "nach Zeitstempel der Region" +msgstr "nach Position der Region" -#: editor_actions.cc:336 +#: gtk2_ardour/editor_actions.cc:342 msgid "By Region Timestamp" msgstr "nach Zeitstempel der Region" -#: editor_actions.cc:338 +#: gtk2_ardour/editor_actions.cc:344 msgid "By Region Start in File" msgstr "nach Anfang der Region in der Datei" -#: editor_actions.cc:340 +#: gtk2_ardour/editor_actions.cc:346 msgid "By Region End in File" msgstr "nach Ende der Region in der Datei" -#: editor_actions.cc:342 +#: gtk2_ardour/editor_actions.cc:348 msgid "By Source File Name" msgstr "nach Namen der Quelldatei" -#: editor_actions.cc:344 +#: gtk2_ardour/editor_actions.cc:350 msgid "By Source File Length" msgstr "nach Länge der Quelldatei" -#: editor_actions.cc:346 +#: gtk2_ardour/editor_actions.cc:352 msgid "By Source File Creation Date" msgstr "nach Erstellungsdatum der Quelldatei" -#: editor_actions.cc:348 +#: gtk2_ardour/editor_actions.cc:354 msgid "By Source Filesystem" msgstr "nach Dateisystem der Quelle" -#. the next two are duplicate items with different names for use in two different contexts -#: editor_actions.cc:354 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:360 msgid "Add External Audio" -msgstr "Ardour: Region" +msgstr "Audio importieren..." -#: editor_actions.cc:356 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:362 msgid "as Region(s)" -msgstr "Ardour: Region" +msgstr "als Region(en)..." -#: editor_actions.cc:358 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:364 msgid "as Tracks" -msgstr "Spuren" +msgstr "als neue Spur(en)..." -#: editor_actions.cc:360 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:366 +msgid "as Tape Tracks" +msgstr "als neue Tape-Spur(en)..." + +#: gtk2_ardour/editor_actions.cc:368 msgid "to Tracks" -msgstr "Spuren" +msgstr "in vorhandene Spuren..." -#: editor_actions.cc:363 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:371 msgid "Show Waveforms" -msgstr "Wellenform zeigen" +msgstr "Wellenformen zeigen" -#: editor_actions.cc:364 -#, fuzzy +#: gtk2_ardour/editor_actions.cc:372 msgid "Show Waveforms While Recording" -msgstr "Wellenform zeigen" +msgstr "Wellenformen beim Aufnehmen zeigen" -#: editor_actions.cc:365 +#: gtk2_ardour/editor_actions.cc:373 msgid "Show Measures" +msgstr "Takte zeigen" + +#: gtk2_ardour/editor_actions.cc:377 +msgid "Later is Higher" +msgstr "Neuste nach oben" + +#: gtk2_ardour/editor_actions.cc:378 +msgid "Most Recently Moved/Added is Higher" +msgstr "Zuletzt bewegte/hinzugefügte nach oben" + +#: gtk2_ardour/editor_actions.cc:379 +msgid "Most Recently Added is Higher" +msgstr "Zuletzt hinzugefügte nach oben" + +#: gtk2_ardour/editor_actions.cc:383 +msgid "23.976" msgstr "" -#: editor_actions.cc:378 editor_actions.cc:385 -msgid "Medium" +#: gtk2_ardour/editor_actions.cc:384 +msgid "24" msgstr "" -#: editor_actions.cc:380 -#, fuzzy -msgid "Faster" -msgstr "Einfügen" +#: gtk2_ardour/editor_actions.cc:385 +msgid "24.976" +msgstr "" -#: editor_actions.cc:386 -msgid "Long" +#: gtk2_ardour/editor_actions.cc:386 +msgid "25" msgstr "" -#: editor_actions.cc:390 -#, fuzzy -msgid "Later is Higher" -msgstr "Region eine Ebene nach unten" +#: gtk2_ardour/editor_actions.cc:387 +msgid "29.97" +msgstr "" -#: editor_actions.cc:391 -#, fuzzy -msgid "Most Recently Moved/Added is Higher" -msgstr "Region eine Ebene nach unten" +#: gtk2_ardour/editor_actions.cc:388 +msgid "29.97 drop" +msgstr "" -#: editor_actions.cc:392 -#, fuzzy -msgid "Most Recently Added is Higher" -msgstr "Region eine Ebene nach unten" +#: gtk2_ardour/editor_actions.cc:389 +msgid "30" +msgstr "" -#: editor_audio_import.cc:72 -#, fuzzy -msgid "You can't import or embed an audiofile until you have a session loaded." +#: gtk2_ardour/editor_actions.cc:390 +msgid "30 drop" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:391 +msgid "59.94" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:392 +msgid "60" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:396 +msgid "+4.1667% + 0.1%" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:397 +msgid "+4.1667%" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:398 +msgid "+4.1667% - 0.1%" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:399 +msgid "+ 0.1%" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:401 +msgid "- 0.1%" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:402 +msgid "-4.1667% + 0.1%" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:403 +msgid "-4.1667%" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:404 +msgid "-4.1667% - 0.1%" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:408 +msgid "80 per frame" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:409 +msgid "100 per frame" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:529 +msgid "programming error: Unexpected SMPTE value (%1, drop = %2) in update_smpte_mode. Menu is probably wrong." +msgstr "" + +#: gtk2_ardour/editor_actions.cc:708 +#: gtk2_ardour/editor_actions.cc:753 +#: gtk2_ardour/editor_actions.cc:764 +#: gtk2_ardour/editor_actions.cc:808 +#: gtk2_ardour/editor_actions.cc:818 +msgid "programming error: %1: %2" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:719 +#: gtk2_ardour/editor_actions.cc:970 +#: gtk2_ardour/editor_actions.cc:983 +#: gtk2_ardour/editor_actions.cc:1047 +#: gtk2_ardour/sfdb_ui.cc:454 +msgid "programming error: %1" msgstr "" -"Sie können keine Audio-Daten importieren, solange keine Sitzung geladen ist." -#: editor_audio_import.cc:77 +#: gtk2_ardour/editor_actions.cc:1002 +msgid "Configuraton is using unhandled subframes per frame value: %1" +msgstr "" + +#: gtk2_ardour/editor_audio_import.cc:75 #, fuzzy +msgid "You can't import or embed an audiofile until you have a session loaded." +msgstr "Sie können keine Audio-Daten importieren, solange keine Sitzung geladen ist." + +#: gtk2_ardour/editor_audio_import.cc:80 msgid "Add existing audio to session" -msgstr "Stellen" +msgstr "Audio importieren" -#: editor_audio_import.cc:142 +#: gtk2_ardour/editor_audio_import.cc:145 #, fuzzy msgid "ardour: importing %1" msgstr "Ardour: Exportieren" -#: editor_audio_import.cc:146 +#: gtk2_ardour/editor_audio_import.cc:149 msgid "Cancel Import" msgstr "Importieren Abbrechen" -#: editor_audio_import.cc:224 +#: gtk2_ardour/editor_audio_import.cc:227 msgid "Editor: cannot open file \"%1\", (%2)" msgstr "" -#: editor_audio_import.cc:232 +#: gtk2_ardour/editor_audio_import.cc:235 #, fuzzy msgid "Cancel entire import" msgstr "Importieren Abbrechen" -#: editor_audio_import.cc:233 +#: gtk2_ardour/editor_audio_import.cc:236 #, fuzzy msgid "Don't embed it" msgstr "Ohne %1" -#: editor_audio_import.cc:234 +#: gtk2_ardour/editor_audio_import.cc:237 msgid "Embed all without questions" msgstr "" -#: editor_audio_import.cc:239 +#: gtk2_ardour/editor_audio_import.cc:242 msgid "Embed it anyway" msgstr "" -#: editor_audio_import.cc:242 +#: gtk2_ardour/editor_audio_import.cc:245 msgid "" "%1\n" "This audiofile's sample rate doesn't match the session sample rate!" msgstr "" -#: editor_audio_import.cc:275 +#: gtk2_ardour/editor_audio_import.cc:282 msgid "could not open %1" msgstr "Konnte \"%s\" nicht öffnen." -#: editor_audio_import.cc:320 +#: gtk2_ardour/editor_audio_import.cc:331 #, fuzzy msgid "insert sndfile" msgstr "Stille einfügen" -#. stuff for the verbose canvas cursor -#: editor_canvas.cc:118 +#: gtk2_ardour/editor_canvas.cc:119 msgid "VerboseCanvasCursor" msgstr "" -#: editor_edit_groups.cc:53 mixer_ui.cc:736 -#, fuzzy +#: gtk2_ardour/editor_edit_groups.cc:53 +#: gtk2_ardour/mixer_ui.cc:754 msgid "Activate All" -msgstr "Aktiv" +msgstr "Alle aktivieren" -#: editor_edit_groups.cc:54 mixer_ui.cc:737 -#, fuzzy +#: gtk2_ardour/editor_edit_groups.cc:54 +#: gtk2_ardour/mixer_ui.cc:755 msgid "Disable All" -msgstr "Trennen" +msgstr "Alle deaktivieren" -#: editor_edit_groups.cc:56 mixer_ui.cc:739 -#, fuzzy +#: gtk2_ardour/editor_edit_groups.cc:56 +#: gtk2_ardour/mixer_ui.cc:757 msgid "Add group" -msgstr "keine Gruppe" +msgstr "Gruppe hinzufügen" -#: editor_edit_groups.cc:229 mixer_ui.cc:970 +#: gtk2_ardour/editor_edit_groups.cc:229 +#: gtk2_ardour/mixer_ui.cc:988 #, fuzzy msgid "unnamed" msgstr "Umbenennen" -#: editor_edit_groups.cc:258 mixer_ui.cc:834 +#: gtk2_ardour/editor_edit_groups.cc:258 +#: gtk2_ardour/mixer_ui.cc:852 msgid "-all-" msgstr "-alle-" -#: editor_export_audio.cc:65 +#: gtk2_ardour/editor_export_audio.cc:67 msgid "" "There is no selection to export.\n" "\n" "Select a selection using the range mouse mode" msgstr "" -#: editor_export_audio.cc:110 +#: gtk2_ardour/editor_export_audio.cc:112 msgid "" "There are no ranges to export.\n" "\n" "Create 1 or more ranges by dragging the mouse in the range bar" msgstr "" -#: editor_imageframe.cc:625 editor_imageframe.cc:655 +#: gtk2_ardour/editor_imageframe.cc:625 +#: gtk2_ardour/editor_imageframe.cc:655 msgid "programming error: no ImageFrameView selected" msgstr "" -#: editor_imageframe.cc:848 editor_imageframe.cc:870 +#: gtk2_ardour/editor_imageframe.cc:848 +#: gtk2_ardour/editor_imageframe.cc:870 msgid "programming error: no MarkerView selected" msgstr "" -#: editor_keyboard.cc:104 +#: gtk2_ardour/editor_keyboard.cc:105 #, fuzzy msgid "mute region" msgstr "Name für Region:" -#: editor_keys.cc:46 +#: gtk2_ardour/editor_keys.cc:46 #, fuzzy msgid "keyboard selection" msgstr "Auswahl zu Abschnitt machen" -#: editor_markers.cc:292 editor_ops.cc:1290 editor_ops.cc:1303 -#: editor_ops.cc:1321 location_ui.cc:774 +#: gtk2_ardour/editor_markers.cc:293 +#: gtk2_ardour/editor_ops.cc:1213 +#: gtk2_ardour/editor_ops.cc:1227 +#: gtk2_ardour/editor_ops.cc:1246 +#: gtk2_ardour/location_ui.cc:776 msgid "add marker" msgstr "" -#: editor_markers.cc:307 editor_markers.cc:380 editor_markers.cc:552 -#: editor_markers.cc:570 editor_markers.cc:589 editor_markers.cc:608 -#: editor_markers.cc:638 editor_markers.cc:666 editor_markers.cc:694 -#: editor_markers.cc:732 editor_markers.cc:759 editor_markers.cc:782 -#: editor_markers.cc:801 editor_mouse.cc:2015 editor_mouse.cc:4275 +#: gtk2_ardour/editor_markers.cc:309 +#: gtk2_ardour/editor_markers.cc:383 +#: gtk2_ardour/editor_markers.cc:555 +#: gtk2_ardour/editor_markers.cc:573 +#: gtk2_ardour/editor_markers.cc:592 +#: gtk2_ardour/editor_markers.cc:611 +#: gtk2_ardour/editor_markers.cc:641 +#: gtk2_ardour/editor_markers.cc:669 +#: gtk2_ardour/editor_markers.cc:697 +#: gtk2_ardour/editor_markers.cc:735 +#: gtk2_ardour/editor_markers.cc:762 +#: gtk2_ardour/editor_markers.cc:785 +#: gtk2_ardour/editor_markers.cc:804 +#: gtk2_ardour/editor_mouse.cc:2031 +#: gtk2_ardour/editor_mouse.cc:4331 msgid "programming error: marker canvas item has no marker object pointer!" msgstr "" -#: editor_markers.cc:331 location_ui.cc:656 +#: gtk2_ardour/editor_markers.cc:333 +#: gtk2_ardour/location_ui.cc:657 msgid "remove marker" -msgstr "" +msgstr "Marker entfernen" -#: editor_markers.cc:458 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:461 msgid "Locate to Mark" -msgstr "Stellen" +msgstr "Positionszeiger zu Marker setzen" -#: editor_markers.cc:459 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:462 msgid "Play from Mark" -msgstr "Wiedergabe ab Anfang" +msgstr "Wiedergabe ab Marker" -#: editor_markers.cc:460 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:463 msgid "Set Mark from Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Marker am Positionszeiger setzen" -#: editor_markers.cc:464 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:467 msgid "Rename Mark" -msgstr "Umbenennen" +msgstr "Marker umbenennen" -#: editor_markers.cc:465 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:468 msgid "Hide Mark" -msgstr "Stille einfügen" +msgstr "Marker verbergen" -#: editor_markers.cc:466 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:469 msgid "Remove Mark" -msgstr "Feld entfernen" +msgstr "Marker entfernen" -#: editor_markers.cc:479 editor_markers.cc:535 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:482 +#: gtk2_ardour/editor_markers.cc:538 msgid "Locate to Range Mark" -msgstr "Stellen" +msgstr "Positionszeiger zu Bereichsmarker" -#: editor_markers.cc:480 editor_markers.cc:536 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:483 +#: gtk2_ardour/editor_markers.cc:539 msgid "Play from Range Mark" -msgstr "Bereich" +msgstr "Wiedergabe ab Bereichsmarker" -#: editor_markers.cc:481 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:484 msgid "Loop Range" -msgstr "Bereich" +msgstr "Bereich in Schleife wiedergeben" -#: editor_markers.cc:482 editor_markers.cc:537 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:485 +#: gtk2_ardour/editor_markers.cc:540 msgid "Set Range Mark from Playhead" -msgstr "Wiedergabe ab Playhead" +msgstr "Bereichsmarker zum Positionszeiger verschieben" -#: editor_markers.cc:483 editor_markers.cc:538 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:486 +#: gtk2_ardour/editor_markers.cc:541 msgid "Set Range from Range Selection" -msgstr "Auswahl wiedergeben" +msgstr "Bereichsmarker zum Auswahlbereich verschieben" -#: editor_markers.cc:487 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:490 msgid "Rename Range" -msgstr "Umbenennen" +msgstr "Bereich umbenennen" -#: editor_markers.cc:488 editor_markers.cc:540 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:491 +#: gtk2_ardour/editor_markers.cc:543 msgid "Hide Range" -msgstr "Bereich" +msgstr "Bereich verbergen" -#: editor_markers.cc:489 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:492 msgid "Remove Range" -msgstr "Feld entfernen" +msgstr "Bereich entfernen" -#: editor_markers.cc:493 editor_markers.cc:542 +#: gtk2_ardour/editor_markers.cc:496 +#: gtk2_ardour/editor_markers.cc:545 msgid "Separate Regions in Range" -msgstr "" +msgstr "Regionen an Bereichsgrenzen teilen" -#: editor_markers.cc:494 editor_markers.cc:543 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:497 +#: gtk2_ardour/editor_markers.cc:546 msgid "Select All in Range" -msgstr "Auswahl" +msgstr "Alles im Bereich auswählen" -#: editor_markers.cc:520 -#, fuzzy +#: gtk2_ardour/editor_markers.cc:523 msgid "Set Loop Range" -msgstr "Ausgewählten Bereich wiedergeben" +msgstr "Schleife erstellen" -#: editor_markers.cc:521 +#: gtk2_ardour/editor_markers.cc:524 msgid "Set Punch Range" -msgstr "" +msgstr "Punch-Bereich erstellen" -#: editor_markers.cc:815 +#: gtk2_ardour/editor_markers.cc:818 #, fuzzy msgid "New Name:" msgstr "Neuer Name: " -#: editor_markers.cc:818 +#: gtk2_ardour/editor_markers.cc:821 #, fuzzy msgid "ardour: rename mark" msgstr "Ardour: Region umbenennen" -#: editor_markers.cc:820 +#: gtk2_ardour/editor_markers.cc:823 #, fuzzy msgid "ardour: rename range" msgstr "Ardour: Region umbenennen" -#: editor_markers.cc:840 +#: gtk2_ardour/editor_markers.cc:843 #, fuzzy msgid "rename marker" msgstr "Feld entfernen" -#: editor_markers.cc:865 +#: gtk2_ardour/editor_markers.cc:869 #, fuzzy msgid "set loop range" msgstr "Ausgewählten Bereich wiedergeben" -#: editor_markers.cc:891 +#: gtk2_ardour/editor_markers.cc:897 #, fuzzy msgid "set punch range" msgstr "Ausgewählten Bereich wiedergeben" -#: editor_mouse.cc:103 +#: gtk2_ardour/editor_mouse.cc:105 msgid "Editor::event_frame() used on unhandled event type %1" msgstr "" -#: editor_mouse.cc:313 +#: gtk2_ardour/editor_mouse.cc:315 #, fuzzy msgid "select on click" msgstr "Auswahl" -#: editor_mouse.cc:1590 +#: gtk2_ardour/editor_mouse.cc:1596 msgid "programming error: start_grab called without drag item" msgstr "" -#: editor_mouse.cc:1814 +#: gtk2_ardour/editor_mouse.cc:1820 msgid "change fade in length" msgstr "" -#: editor_mouse.cc:1832 +#: gtk2_ardour/editor_mouse.cc:1842 msgid "programming error: fade out canvas item has no regionview data pointer!" msgstr "" -#: editor_mouse.cc:1906 +#: gtk2_ardour/editor_mouse.cc:1916 #, fuzzy msgid "change fade out length" msgstr "Ardour: Editor" -#: editor_mouse.cc:1925 +#: gtk2_ardour/editor_mouse.cc:1939 msgid "programming error: cursor canvas item has no cursor data pointer!" msgstr "" -#: editor_mouse.cc:2142 -#, fuzzy +#: gtk2_ardour/editor_mouse.cc:2166 msgid "move marker" -msgstr "Feld entfernen" +msgstr "Marker bewegen" -#: editor_mouse.cc:2165 editor_mouse.cc:2196 editor_tempodisplay.cc:459 -msgid "" -"programming error: meter marker canvas item has no marker object pointer!" +#: gtk2_ardour/editor_mouse.cc:2194 +#: gtk2_ardour/editor_mouse.cc:2225 +#: gtk2_ardour/editor_tempodisplay.cc:492 +msgid "programming error: meter marker canvas item has no marker object pointer!" msgstr "" -#: editor_mouse.cc:2264 +#: gtk2_ardour/editor_mouse.cc:2293 #, fuzzy msgid "copy meter mark" msgstr "Ardour: Region umbenennen" -#: editor_mouse.cc:2274 +#: gtk2_ardour/editor_mouse.cc:2304 msgid "move meter mark" -msgstr "" +msgstr "Taktwechsel bewegen" -#: editor_mouse.cc:2289 editor_mouse.cc:2322 editor_tempodisplay.cc:331 -#: editor_tempodisplay.cc:409 editor_tempodisplay.cc:428 -msgid "" -"programming error: tempo marker canvas item has no marker object pointer!" +#: gtk2_ardour/editor_mouse.cc:2320 +#: gtk2_ardour/editor_mouse.cc:2353 +#: gtk2_ardour/editor_tempodisplay.cc:355 +#: gtk2_ardour/editor_tempodisplay.cc:439 +#: gtk2_ardour/editor_tempodisplay.cc:458 +msgid "programming error: tempo marker canvas item has no marker object pointer!" msgstr "" -#: editor_mouse.cc:2294 editor_mouse.cc:2327 editor_tempodisplay.cc:336 -#: editor_tempodisplay.cc:414 +#: gtk2_ardour/editor_mouse.cc:2325 +#: gtk2_ardour/editor_mouse.cc:2358 +#: gtk2_ardour/editor_tempodisplay.cc:360 +#: gtk2_ardour/editor_tempodisplay.cc:444 msgid "programming error: marker for tempo is not a tempo marker!" msgstr "" -#: editor_mouse.cc:2394 +#: gtk2_ardour/editor_mouse.cc:2425 #, fuzzy msgid "copy tempo mark" msgstr "Ardour: Region umbenennen" -#: editor_mouse.cc:2404 +#: gtk2_ardour/editor_mouse.cc:2436 msgid "move tempo mark" -msgstr "" +msgstr "Tempowechsel bewegen" -#: editor_mouse.cc:2418 editor_mouse.cc:2437 editor_mouse.cc:2450 -msgid "" -"programming error: control point canvas item has no control point object " -"pointer!" +#: gtk2_ardour/editor_mouse.cc:2451 +#: gtk2_ardour/editor_mouse.cc:2470 +#: gtk2_ardour/editor_mouse.cc:2483 +msgid "programming error: control point canvas item has no control point object pointer!" msgstr "" -#: editor_mouse.cc:2555 +#: gtk2_ardour/editor_mouse.cc:2589 msgid "programming error: line canvas item has no line pointer!" msgstr "" -#: editor_mouse.cc:2664 -#, fuzzy +#: gtk2_ardour/editor_mouse.cc:2698 msgid "move region(s)" -msgstr "Name für Region:" +msgstr "Region(en) bewegen" -#: editor_mouse.cc:2727 +#: gtk2_ardour/editor_mouse.cc:2762 #, fuzzy msgid "Drag region brush" msgstr "Ardour: Region" -#. don't copy again -#. this is committed in the grab finished callback. -#: editor_mouse.cc:2751 +#: gtk2_ardour/editor_mouse.cc:2784 msgid "Drag region copy" msgstr "" -#. A selection grab currently creates two undo/redo operations, one for -#. creating the new region and another for moving it. -#. -#: editor_mouse.cc:3609 +#: gtk2_ardour/editor_mouse.cc:3648 #, fuzzy msgid "selection grab" msgstr "Auswahl" -#: editor_mouse.cc:3650 +#: gtk2_ardour/editor_mouse.cc:3690 #, fuzzy msgid "cancel selection" msgstr "Auswahl wiedergeben" -#: editor_mouse.cc:3760 +#: gtk2_ardour/editor_mouse.cc:3800 #, fuzzy msgid "range selection" msgstr "Auswahl wiedergeben" -#: editor_mouse.cc:3776 +#: gtk2_ardour/editor_mouse.cc:3816 #, fuzzy msgid "trim selection start" msgstr "Auswahl zu Abschnitt machen" -#: editor_mouse.cc:3792 +#: gtk2_ardour/editor_mouse.cc:3832 #, fuzzy msgid "trim selection end" msgstr "Auswahl zu Abschnitt machen" -#: editor_mouse.cc:3809 -#, fuzzy +#: gtk2_ardour/editor_mouse.cc:3849 msgid "move selection" -msgstr "Auswahl zu Schleife machen" +msgstr "Auswahl bewegen" -#: editor_mouse.cc:4195 +#: gtk2_ardour/editor_mouse.cc:4240 msgid "Start point trim" msgstr "" -#: editor_mouse.cc:4223 +#: gtk2_ardour/editor_mouse.cc:4272 msgid "End point trim" msgstr "" -#: editor_mouse.cc:4262 +#: gtk2_ardour/editor_mouse.cc:4315 #, fuzzy msgid "trimmed region" msgstr "Ardour: Region" -#: editor_mouse.cc:4400 +#: gtk2_ardour/editor_mouse.cc:4457 #, fuzzy msgid "new range marker" msgstr "Ardour: Region umbenennen" -#: editor_mouse.cc:4642 +#: gtk2_ardour/editor_mouse.cc:4701 #, fuzzy msgid "select regions" msgstr "Auswahl zu Schleife machen" -#: editor_mouse.cc:4671 +#: gtk2_ardour/editor_mouse.cc:4730 msgid "Name for region:" msgstr "Name für Region:" -#: editor_mouse.cc:4735 +#: gtk2_ardour/editor_mouse.cc:4794 #, fuzzy msgid "timestretch" msgstr "Ardour: Mixer" -#: editor_ops.cc:195 +#: gtk2_ardour/editor_ops.cc:115 #, fuzzy msgid "split" msgstr "Teilen" -#: editor_ops.cc:231 -#, fuzzy +#: gtk2_ardour/editor_ops.cc:154 msgid "remove region" -msgstr "Name für Region:" +msgstr "Region(en) löschen" -#: editor_ops.cc:250 +#: gtk2_ardour/editor_ops.cc:174 msgid "" " This is destructive, will possibly delete audio files\n" "It cannot be undone\n" "Do you really want to destroy %1 ?" msgstr "" -#: editor_ops.cc:254 +#: gtk2_ardour/editor_ops.cc:178 #, fuzzy msgid "these regions" msgstr "Name für Region:" -#: editor_ops.cc:254 +#: gtk2_ardour/editor_ops.cc:178 #, fuzzy msgid "this region" msgstr "Name für Region:" -#: editor_ops.cc:256 editor_ops.cc:3318 route_ui.cc:707 -#: visual_time_axis.cc:278 +#: gtk2_ardour/editor_ops.cc:180 +#: gtk2_ardour/editor_ops.cc:3293 +#: gtk2_ardour/route_ui.cc:736 +#: gtk2_ardour/visual_time_axis.cc:283 msgid "No, do nothing." msgstr "Nein, nichts machen." -#: editor_ops.cc:259 +#: gtk2_ardour/editor_ops.cc:183 #, fuzzy msgid "Yes, destroy them." msgstr "Ja, entfernen." -#: editor_ops.cc:261 editor_ops.cc:3319 +#: gtk2_ardour/editor_ops.cc:185 +#: gtk2_ardour/editor_ops.cc:3294 #, fuzzy msgid "Yes, destroy it." msgstr "Ja, entfernen." -#: editor_ops.cc:352 editor_ops.cc:380 +#: gtk2_ardour/editor_ops.cc:271 +#: gtk2_ardour/editor_ops.cc:299 #, fuzzy msgid "extend selection" msgstr "Auswahl zu Abschnitt machen" -#: editor_ops.cc:396 editor_ops.cc:430 editor_ops.cc:474 editor_ops.cc:500 +#: gtk2_ardour/editor_ops.cc:315 +#: gtk2_ardour/editor_ops.cc:350 +#: gtk2_ardour/editor_ops.cc:395 +#: gtk2_ardour/editor_ops.cc:422 msgid "nudge forward" msgstr "" -#: editor_ops.cc:564 +#: gtk2_ardour/editor_ops.cc:487 msgid "build_region_boundary_cache called with snap_type = %1" msgstr "" -#: editor_ops.cc:1420 +#: gtk2_ardour/editor_ops.cc:1350 #, fuzzy msgid "select all within" msgstr "Auswahl" -#: editor_ops.cc:1452 +#: gtk2_ardour/editor_ops.cc:1383 #, fuzzy msgid "set selection from region" msgstr "Ausgewählten Bereich wiedergeben" -#: editor_ops.cc:1485 +#: gtk2_ardour/editor_ops.cc:1416 #, fuzzy msgid "set selection from range" msgstr "Ausgewählten Bereich wiedergeben" -#: editor_ops.cc:1515 +#: gtk2_ardour/editor_ops.cc:1446 #, fuzzy msgid "select all from range" msgstr "Ausgewählten Bereich wiedergeben" -#: editor_ops.cc:1537 +#: gtk2_ardour/editor_ops.cc:1468 #, fuzzy msgid "select all from punch" msgstr "Auswahl" -#: editor_ops.cc:1559 +#: gtk2_ardour/editor_ops.cc:1490 #, fuzzy msgid "select all from loop" msgstr "Auswahl" -#: editor_ops.cc:1573 +#: gtk2_ardour/editor_ops.cc:1504 #, fuzzy msgid "select all after cursor" msgstr "Wiedergabe ab Cursor" -#: editor_ops.cc:1578 +#: gtk2_ardour/editor_ops.cc:1509 #, fuzzy msgid "select all before cursor" msgstr "Wiedergabe ab Cursor" -#: editor_ops.cc:1608 +#: gtk2_ardour/editor_ops.cc:1539 #, fuzzy msgid "select all between cursors" msgstr "Wiedergabe ab Cursor" -#: editor_ops.cc:1739 +#: gtk2_ardour/editor_ops.cc:1670 msgid "clear markers" msgstr "" -#: editor_ops.cc:1751 -#, fuzzy +#: gtk2_ardour/editor_ops.cc:1683 msgid "clear ranges" -msgstr "Verbindungen löschen" +msgstr "Verbindungen entfernen" -#: editor_ops.cc:1770 -#, fuzzy +#: gtk2_ardour/editor_ops.cc:1703 msgid "clear locations" -msgstr "Verbindungen löschen" +msgstr "Verbindungen entfernen" -#: editor_ops.cc:1820 +#: gtk2_ardour/editor_ops.cc:1754 #, fuzzy msgid "insert dragged region" msgstr "Ardour: Region" -#: editor_ops.cc:1856 +#: gtk2_ardour/editor_ops.cc:1797 #, fuzzy msgid "insert region" msgstr "Name für Region:" -#: editor_ops.cc:2047 io_selector.cc:58 io_selector.cc:792 +#: gtk2_ardour/editor_ops.cc:1972 +#: gtk2_ardour/io_selector.cc:60 +#: gtk2_ardour/io_selector.cc:749 +#: gtk2_ardour/connection_editor.cc:86 msgid "OK" msgstr "" -#: editor_ops.cc:2054 +#: gtk2_ardour/editor_ops.cc:1979 msgid "ardour: rename region" msgstr "Ardour: Region umbenennen" -#: editor_ops.cc:2277 editor_ops.cc:2326 +#: gtk2_ardour/editor_ops.cc:2204 +#: gtk2_ardour/editor_ops.cc:2257 #, fuzzy msgid "separate" msgstr "Ausgewählten Bereich wiedergeben" -#: editor_ops.cc:2388 +#: gtk2_ardour/editor_ops.cc:2322 #, fuzzy msgid "trim to selection" msgstr "Auswahl zu Abschnitt machen" -#: editor_ops.cc:2428 +#: gtk2_ardour/editor_ops.cc:2363 msgid "region fill" msgstr "" -#: editor_ops.cc:2487 +#: gtk2_ardour/editor_ops.cc:2427 #, fuzzy msgid "fill selection" msgstr "Auswahl zu Schleife machen" -#: editor_ops.cc:2508 +#: gtk2_ardour/editor_ops.cc:2448 msgid "Programming error. that region doesn't cover that position" msgstr "" -#: editor_ops.cc:2511 +#: gtk2_ardour/editor_ops.cc:2451 #, fuzzy msgid "set region sync position" msgstr "Regionen" -#: editor_ops.cc:2526 +#: gtk2_ardour/editor_ops.cc:2467 msgid "Place the edit cursor at the desired sync point" -msgstr "" -"Positionieren sie den Arbeits-Cursor am gewünschten Synchronisationspunkt" +msgstr "Positionieren sie den Arbeits-Cursor am gewünschten Synchronisationspunkt" -#: editor_ops.cc:2531 +#: gtk2_ardour/editor_ops.cc:2472 #, fuzzy msgid "set sync from edit cursor" msgstr "Wiedergabe ab Cursor" -#: editor_ops.cc:2543 +#: gtk2_ardour/editor_ops.cc:2485 #, fuzzy msgid "remove sync" msgstr "Synchronisationspunkt entfernen" -#: editor_ops.cc:2557 +#: gtk2_ardour/editor_ops.cc:2500 #, fuzzy msgid "naturalize" msgstr "Ardour: Region" -#: editor_ops.cc:2621 +#: gtk2_ardour/editor_ops.cc:2565 msgid "align selection (relative)" msgstr "" -#: editor_ops.cc:2649 +#: gtk2_ardour/editor_ops.cc:2594 #, fuzzy msgid "align selection" msgstr "Auswahl zu Schleife machen" -#: editor_ops.cc:2661 +#: gtk2_ardour/editor_ops.cc:2606 #, fuzzy msgid "align region" msgstr "Ardour: Region" -#: editor_ops.cc:2708 editor_ops.cc:2733 +#: gtk2_ardour/editor_ops.cc:2654 +#: gtk2_ardour/editor_ops.cc:2680 msgid "trim to edit" msgstr "" -#: editor_ops.cc:2784 +#: gtk2_ardour/editor_ops.cc:2732 #, fuzzy msgid "ardour: freeze" msgstr "Ardour: " -#: editor_ops.cc:2789 -#, fuzzy +#: gtk2_ardour/editor_ops.cc:2737 msgid "Cancel Freeze" -msgstr "Abbrechen" +msgstr "Einfrieren abbrechen" -#: editor_ops.cc:2826 +#: gtk2_ardour/editor_ops.cc:2774 #, fuzzy msgid "bounce range" msgstr "Bereich" -#: editor_ops.cc:2879 +#: gtk2_ardour/editor_ops.cc:2828 #, fuzzy msgid "cut" msgstr "Ausschneiden" -#: editor_ops.cc:2882 +#: gtk2_ardour/editor_ops.cc:2831 #, fuzzy msgid "copy" msgstr "Kopieren" -#: editor_ops.cc:2895 +#: gtk2_ardour/editor_ops.cc:2844 #, fuzzy msgid " objects" msgstr "Objekt" -#: editor_ops.cc:2921 +#: gtk2_ardour/editor_ops.cc:2870 #, fuzzy msgid " range" msgstr "Bereich" -#: editor_ops.cc:3078 +#: gtk2_ardour/editor_ops.cc:3050 #, fuzzy msgid "paste" msgstr "Einfügen" -#: editor_ops.cc:3116 +#: gtk2_ardour/editor_ops.cc:3088 #, fuzzy msgid "paste chunk" msgstr "Abschnitt erzeugen:" -#. clear (below) will clear the argument list -#: editor_ops.cc:3157 +#: gtk2_ardour/editor_ops.cc:3129 #, fuzzy msgid "duplicate region" msgstr "Auswahl zu Schleife machen" -#: editor_ops.cc:3202 +#: gtk2_ardour/editor_ops.cc:3174 #, fuzzy msgid "duplicate selection" msgstr "Auswahl zu Schleife machen" -#: editor_ops.cc:3259 +#: gtk2_ardour/editor_ops.cc:3232 #, fuzzy msgid "clear playlist" msgstr "Name für Schnappschuß" -#: editor_ops.cc:3288 +#: gtk2_ardour/editor_ops.cc:3262 #, fuzzy msgid "nudge track" msgstr "Stille einfügen" -#: editor_ops.cc:3315 +#: gtk2_ardour/editor_ops.cc:3290 #, fuzzy msgid "" "Do you really want to destroy the last capture?\n" @@ -4087,715 +4264,756 @@ msgstr "" "Wollen Sie wirklich die Spur \"%1\" löschen?\n" "(Kann nicht rückgängig gemacht werden!)" -#: editor_ops.cc:3343 +#: gtk2_ardour/editor_ops.cc:3318 #, fuzzy msgid "normalize" msgstr "Ardour: Region" -#: editor_ops.cc:3390 +#: gtk2_ardour/editor_ops.cc:3371 #, fuzzy msgid "reverse regions" msgstr "Name für Region:" -#: editor_region_list.cc:98 editor_region_list.cc:103 -#: editor_region_list.cc:106 location_ui.cc:56 +#: gtk2_ardour/editor_ops.cc:3484 +#, fuzzy +msgid "reset region gain" +msgstr "Name für Region:" + +#: gtk2_ardour/editor_region_list.cc:103 +#: gtk2_ardour/editor_region_list.cc:108 +#: gtk2_ardour/editor_region_list.cc:111 +#: gtk2_ardour/location_ui.cc:57 #, fuzzy msgid "Hidden" msgstr "Verbergen" -#. added a new fresh one at the end -#: editor_route_list.cc:102 editor_route_list.cc:103 editor_route_list.cc:247 +#: gtk2_ardour/editor_route_list.cc:100 +#: gtk2_ardour/editor_route_list.cc:101 +#: gtk2_ardour/editor_route_list.cc:250 msgid "editor" msgstr "" -#: editor_route_list.cc:310 mixer_ui.cc:699 +#: gtk2_ardour/editor_route_list.cc:317 +#: gtk2_ardour/mixer_ui.cc:717 msgid "Show All" msgstr "Alles zeigen" -#: editor_route_list.cc:311 mixer_ui.cc:700 +#: gtk2_ardour/editor_route_list.cc:318 +#: gtk2_ardour/mixer_ui.cc:718 msgid "Hide All" -msgstr "Alle verstecken" +msgstr "Alle verbergen" -#: editor_route_list.cc:312 mixer_ui.cc:701 -#, fuzzy +#: gtk2_ardour/editor_route_list.cc:319 +#: gtk2_ardour/mixer_ui.cc:719 msgid "Show All Audio Tracks" -msgstr "Auswahl" +msgstr "Zeige alle Audio-Spuren" -#: editor_route_list.cc:313 mixer_ui.cc:702 -#, fuzzy +#: gtk2_ardour/editor_route_list.cc:320 +#: gtk2_ardour/mixer_ui.cc:720 msgid "Hide All Audio Tracks" -msgstr "Auswahl" +msgstr "Verberge alle Audio-Spuren" -#: editor_route_list.cc:314 mixer_ui.cc:703 +#: gtk2_ardour/editor_route_list.cc:321 +#: gtk2_ardour/mixer_ui.cc:721 msgid "Show All Audio Busses" -msgstr "" +msgstr "Zeige alle Audio-Busse" -#: editor_route_list.cc:315 mixer_ui.cc:704 +#: gtk2_ardour/editor_route_list.cc:322 +#: gtk2_ardour/mixer_ui.cc:722 msgid "Hide All Audio Busses" -msgstr "" +msgstr "Verberge alle Audio-Busse" -#: editor_rulers.cc:312 -#, fuzzy +#: gtk2_ardour/editor_rulers.cc:338 msgid "New location marker" -msgstr "Stellen" +msgstr "Neuer Positionsmarker" -#: editor_rulers.cc:313 -#, fuzzy +#: gtk2_ardour/editor_rulers.cc:339 msgid "Clear all locations" -msgstr "Verbindungen löschen" +msgstr "Alle Positionsmarker entfernen" -#. ruler_items.push_back (MenuElem (_("New Range"))); -#: editor_rulers.cc:318 -#, fuzzy +#: gtk2_ardour/editor_rulers.cc:344 msgid "Clear all ranges" -msgstr "Verbindungen löschen" +msgstr "Alle Bereiche entfernen" -#: editor_rulers.cc:327 +#: gtk2_ardour/editor_rulers.cc:353 msgid "New Tempo" -msgstr "" +msgstr "Tempowechsel einfügen..." -#: editor_rulers.cc:328 -#, fuzzy +#: gtk2_ardour/editor_rulers.cc:354 msgid "Clear tempo" -msgstr "leeren" +msgstr "Tempo zurücksetzen" -#: editor_rulers.cc:333 +#: gtk2_ardour/editor_rulers.cc:359 msgid "New Meter" -msgstr "" +msgstr "Taktwechsel einfügen..." -#: editor_rulers.cc:334 -#, fuzzy +#: gtk2_ardour/editor_rulers.cc:360 msgid "Clear meter" -msgstr "leeren" +msgstr "Taktart zurücksetzen" -#: editor_rulers.cc:342 +#: gtk2_ardour/editor_rulers.cc:368 #, fuzzy msgid "Min:Secs" msgstr "Min:Sek" -#: editor_selection_list.cc:108 +#: gtk2_ardour/editor_selection_list.cc:108 #, fuzzy msgid "Name for Chunk:" msgstr "Name für Abschnitt:" -#: editor_selection_list.cc:111 +#: gtk2_ardour/editor_selection_list.cc:111 #, fuzzy msgid "Create Chunk" msgstr "Abschnitt erzeugen:" -#: editor_selection_list.cc:111 +#: gtk2_ardour/editor_selection_list.cc:111 msgid "Forget it" msgstr "Abbrechen" -#: editor_tempodisplay.cc:253 editor_tempodisplay.cc:293 +#: gtk2_ardour/editor_tempodisplay.cc:272 +#: gtk2_ardour/editor_tempodisplay.cc:315 #, fuzzy msgid "add" msgstr "Hinzufügen" -#: editor_tempodisplay.cc:275 +#: gtk2_ardour/editor_tempodisplay.cc:294 #, fuzzy msgid "add tempo mark" msgstr "Ardour: Region umbenennen" -#: editor_tempodisplay.cc:315 +#: gtk2_ardour/editor_tempodisplay.cc:337 #, fuzzy msgid "add meter mark" msgstr "Ardour: Region umbenennen" -#: editor_tempodisplay.cc:348 editor_tempodisplay.cc:376 +#: gtk2_ardour/editor_tempodisplay.cc:372 +#: gtk2_ardour/editor_tempodisplay.cc:403 #, fuzzy msgid "done" msgstr "keine" -#: editor_tempodisplay.cc:366 editor_tempodisplay.cc:394 +#: gtk2_ardour/editor_tempodisplay.cc:390 +#: gtk2_ardour/editor_tempodisplay.cc:421 msgid "replace tempo mark" msgstr "" -#: editor_tempodisplay.cc:433 editor_tempodisplay.cc:464 +#: gtk2_ardour/editor_tempodisplay.cc:463 +#: gtk2_ardour/editor_tempodisplay.cc:497 msgid "programming error: marker for meter is not a meter marker!" msgstr "" -#: editor_tempodisplay.cc:443 editor_tempodisplay.cc:476 -#, fuzzy +#: gtk2_ardour/editor_tempodisplay.cc:473 +#: gtk2_ardour/editor_tempodisplay.cc:509 msgid "remove tempo mark" -msgstr "Ja, entfernen." +msgstr "Tempowechsel entfernen" -#: editor_timefx.cc:51 +#: gtk2_ardour/editor_timefx.cc:52 msgid "Quick but Ugly" msgstr "" -#: editor_timefx.cc:52 +#: gtk2_ardour/editor_timefx.cc:53 msgid "Skip Anti-aliasing" msgstr "" -#: editor_timefx.cc:56 +#: gtk2_ardour/editor_timefx.cc:57 #, fuzzy msgid "ardour: timestretch" msgstr "Ardour: Mixer" -#: editor_timefx.cc:57 +#: gtk2_ardour/editor_timefx.cc:58 msgid "TimeStretchDialog" msgstr "" -#: editor_timefx.cc:70 +#: gtk2_ardour/editor_timefx.cc:71 msgid "Stretch/Shrink it" msgstr "" -#: editor_timefx.cc:73 editor_timefx.cc:74 +#: gtk2_ardour/editor_timefx.cc:74 +#: gtk2_ardour/editor_timefx.cc:75 msgid "TimeStretchButton" msgstr "" -#: editor_timefx.cc:75 +#: gtk2_ardour/editor_timefx.cc:76 msgid "TimeStretchProgress" msgstr "" -#: editor_timefx.cc:139 +#: gtk2_ardour/editor_timefx.cc:140 msgid "timestretch cannot be started - thread creation error" msgstr "" -#: export_dialog.cc:59 export_dialog.cc:399 export_dialog.cc:1027 -#: export_dialog.cc:1195 +#: gtk2_ardour/export_dialog.cc:57 +#: gtk2_ardour/export_dialog.cc:397 +#: gtk2_ardour/export_dialog.cc:1025 +#: gtk2_ardour/export_dialog.cc:1193 msgid "22.05kHz" msgstr "" -#: export_dialog.cc:60 export_dialog.cc:402 export_dialog.cc:417 -#: export_dialog.cc:1029 export_dialog.cc:1197 +#: gtk2_ardour/export_dialog.cc:58 +#: gtk2_ardour/export_dialog.cc:400 +#: gtk2_ardour/export_dialog.cc:415 +#: gtk2_ardour/export_dialog.cc:1027 +#: gtk2_ardour/export_dialog.cc:1195 msgid "44.1kHz" msgstr "" -#: export_dialog.cc:61 export_dialog.cc:405 export_dialog.cc:1031 -#: export_dialog.cc:1199 +#: gtk2_ardour/export_dialog.cc:59 +#: gtk2_ardour/export_dialog.cc:403 +#: gtk2_ardour/export_dialog.cc:1029 +#: gtk2_ardour/export_dialog.cc:1197 msgid "48kHz" msgstr "" -#: export_dialog.cc:62 export_dialog.cc:408 export_dialog.cc:1033 -#: export_dialog.cc:1201 +#: gtk2_ardour/export_dialog.cc:60 +#: gtk2_ardour/export_dialog.cc:406 +#: gtk2_ardour/export_dialog.cc:1031 +#: gtk2_ardour/export_dialog.cc:1199 msgid "88.2kHz" msgstr "" -#: export_dialog.cc:63 export_dialog.cc:411 export_dialog.cc:1035 -#: export_dialog.cc:1203 +#: gtk2_ardour/export_dialog.cc:61 +#: gtk2_ardour/export_dialog.cc:409 +#: gtk2_ardour/export_dialog.cc:1033 +#: gtk2_ardour/export_dialog.cc:1201 msgid "96kHz" msgstr "" -#: export_dialog.cc:64 export_dialog.cc:414 export_dialog.cc:1037 -#: export_dialog.cc:1205 +#: gtk2_ardour/export_dialog.cc:62 +#: gtk2_ardour/export_dialog.cc:412 +#: gtk2_ardour/export_dialog.cc:1035 +#: gtk2_ardour/export_dialog.cc:1203 msgid "192kHz" msgstr "" -#: export_dialog.cc:69 +#: gtk2_ardour/export_dialog.cc:67 msgid "best" msgstr "bestmöglich" -#: export_dialog.cc:70 export_dialog.cc:1212 +#: gtk2_ardour/export_dialog.cc:68 +#: gtk2_ardour/export_dialog.cc:1210 msgid "fastest" msgstr "schnellstmöglich" -#: export_dialog.cc:71 export_dialog.cc:1214 +#: gtk2_ardour/export_dialog.cc:69 +#: gtk2_ardour/export_dialog.cc:1212 msgid "linear" msgstr "" -#: export_dialog.cc:72 export_dialog.cc:1216 +#: gtk2_ardour/export_dialog.cc:70 +#: gtk2_ardour/export_dialog.cc:1214 msgid "better" msgstr "besser" -#: export_dialog.cc:73 export_dialog.cc:1218 +#: gtk2_ardour/export_dialog.cc:71 +#: gtk2_ardour/export_dialog.cc:1216 msgid "intermediate" msgstr "mittelmäßig" -#: export_dialog.cc:79 export_dialog.cc:1227 +#: gtk2_ardour/export_dialog.cc:77 +#: gtk2_ardour/export_dialog.cc:1225 msgid "Rectangular" msgstr "rechteckig" -#: export_dialog.cc:80 +#: gtk2_ardour/export_dialog.cc:78 msgid "Shaped Noise" msgstr "" -#: export_dialog.cc:81 export_dialog.cc:1229 +#: gtk2_ardour/export_dialog.cc:79 +#: gtk2_ardour/export_dialog.cc:1227 msgid "Triangular" msgstr "dreieckig" -#: export_dialog.cc:86 +#: gtk2_ardour/export_dialog.cc:84 msgid "stereo" msgstr "" -#. default is to use all -#: export_dialog.cc:87 export_dialog.cc:486 export_dialog.cc:1055 -#: export_dialog.cc:1177 +#: gtk2_ardour/export_dialog.cc:85 +#: gtk2_ardour/export_dialog.cc:484 +#: gtk2_ardour/export_dialog.cc:1053 +#: gtk2_ardour/export_dialog.cc:1175 msgid "mono" msgstr "" -#: export_dialog.cc:93 +#: gtk2_ardour/export_dialog.cc:91 msgid "CUE" msgstr "" -#: export_dialog.cc:94 +#: gtk2_ardour/export_dialog.cc:92 msgid "TOC" msgstr "" -#: export_dialog.cc:102 -#, fuzzy +#: gtk2_ardour/export_dialog.cc:100 msgid "Format" -msgstr "Anschluß" +msgstr "Format" -#: export_dialog.cc:103 +#: gtk2_ardour/export_dialog.cc:101 msgid "CD Marker File Type" -msgstr "" +msgstr "CD-Marker" -#: export_dialog.cc:104 -#, fuzzy +#: gtk2_ardour/export_dialog.cc:102 msgid "Channels" -msgstr "Abbrechen" +msgstr "Kanäle" -#: export_dialog.cc:105 -#, fuzzy +#: gtk2_ardour/export_dialog.cc:103 msgid "File Type" -msgstr "nach Dateisystem der Quelle" +msgstr "Dateiformat" -#: export_dialog.cc:106 -#, fuzzy +#: gtk2_ardour/export_dialog.cc:104 msgid "Sample Format" -msgstr "Ausgewählten Bereich wiedergeben" +msgstr "Sampleformat" -#: export_dialog.cc:107 +#: gtk2_ardour/export_dialog.cc:105 msgid "Sample Endianness" -msgstr "" +msgstr "Bytefolge" -#: export_dialog.cc:108 -#, fuzzy +#: gtk2_ardour/export_dialog.cc:106 msgid "Sample Rate" -msgstr "Ausgewählten Bereich wiedergeben" +msgstr "Samplerate" -#: export_dialog.cc:109 +#: gtk2_ardour/export_dialog.cc:107 msgid "Conversion Quality" -msgstr "" +msgstr "Qualität" -#: export_dialog.cc:110 +#: gtk2_ardour/export_dialog.cc:108 msgid "Dither Type" -msgstr "" +msgstr "Dithering" -#: export_dialog.cc:111 +#: gtk2_ardour/export_dialog.cc:109 msgid "Export CD Marker File Only" -msgstr "" +msgstr "Nur CD-Marker exportieren" -#: export_dialog.cc:112 -#, fuzzy +#: gtk2_ardour/export_dialog.cc:110 msgid "Export to File" -msgstr "Export nach CD" +msgstr "Als Audiodatei exportieren" -#: export_dialog.cc:113 option_editor.cc:83 option_editor.cc:84 +#: gtk2_ardour/export_dialog.cc:111 +#: gtk2_ardour/option_editor.cc:82 +#: gtk2_ardour/option_editor.cc:83 msgid "Browse" -msgstr "" +msgstr "Durchsuchen" -#: export_dialog.cc:114 +#: gtk2_ardour/export_dialog.cc:112 msgid "Specific tracks ..." -msgstr "" +msgstr "Alle Spuren..." -#: export_dialog.cc:125 +#: gtk2_ardour/export_dialog.cc:123 msgid "ardour: export" msgstr "Ardour: Exportieren" -#: export_dialog.cc:126 +#: gtk2_ardour/export_dialog.cc:124 #, fuzzy msgid "ardour_export" msgstr "Ardour: Exportieren" -#: export_dialog.cc:139 export_dialog.cc:155 mixer_strip.cc:124 -#: mixer_strip.cc:767 -#, fuzzy +#: gtk2_ardour/export_dialog.cc:137 +#: gtk2_ardour/export_dialog.cc:153 +#: gtk2_ardour/mixer_strip.cc:123 +#: gtk2_ardour/mixer_strip.cc:746 msgid "Output" -msgstr "Ausgänge" +msgstr "Ausgang" -#: export_dialog.cc:633 +#: gtk2_ardour/export_dialog.cc:631 #, fuzzy msgid "Editor: cannot open \"%1\" as export file for CD toc file" -msgstr "" -"Editor: Kann \"%1\" nicht öffnen um CD Track Markierungen zu exportieren." +msgstr "Editor: Kann \"%1\" nicht öffnen um CD Track Markierungen zu exportieren." -#: export_dialog.cc:759 +#: gtk2_ardour/export_dialog.cc:757 #, fuzzy msgid "Editor: cannot open \"%1\" as export file for CD cue file" -msgstr "" -"Editor: Kann \"%1\" nicht öffnen um CD Track Markierungen zu exportieren." +msgstr "Editor: Kann \"%1\" nicht öffnen um CD Track Markierungen zu exportieren." -#: export_dialog.cc:778 +#: gtk2_ardour/export_dialog.cc:776 msgid "WAV" msgstr "" -#: export_dialog.cc:912 +#: gtk2_ardour/export_dialog.cc:910 msgid "Stop Export" msgstr "Export Abbrechen" -#: export_dialog.cc:1131 +#: gtk2_ardour/export_dialog.cc:1129 msgid "Please enter a valid filename." -msgstr "" +msgstr "Bitte geben Sie einen gültigen Dateinamen ein." -#: export_dialog.cc:1141 +#: gtk2_ardour/export_dialog.cc:1139 msgid "Please specify a complete filename for the audio file." -msgstr "" +msgstr "Bitte geben Sie einen kompletten Dateinamen für die Audiodatei ein." -#: export_dialog.cc:1147 +#: gtk2_ardour/export_dialog.cc:1145 msgid "File already exists, do you want to overwrite it?" -msgstr "" +msgstr "Datei existiert bereits, wollen Sie sie überschreiben?" -#: export_dialog.cc:1159 export_range_markers_dialog.cc:153 +#: gtk2_ardour/export_dialog.cc:1157 +#: gtk2_ardour/export_range_markers_dialog.cc:153 msgid "Cannot write file in: " -msgstr "" +msgstr "Konnte Datei nicht in Verzeichnis schreiben:" -#. warning dialog -#: export_range_markers_dialog.cc:135 +#: gtk2_ardour/export_range_markers_dialog.cc:135 msgid "Please enter a valid target directory." -msgstr "" +msgstr "Bitte geben Sie ein gültiges Zielverzeichis an." -#: export_range_markers_dialog.cc:143 +#: gtk2_ardour/export_range_markers_dialog.cc:143 msgid "" "Please select an existing target directory. Files\n" "are not allowed!" msgstr "" +"Bitte wählen Sie ein vorhandenes Zielverzeichnis aus.\n" +"Dateien sind nicht möglich." -#: gain_automation_time_axis.cc:62 +#: gtk2_ardour/gain_automation_time_axis.cc:65 #, fuzzy msgid "add gain automation event" msgstr "Stellen" -#: gain_meter.cc:67 -msgid "cannot find images for fader slider" -msgstr "" - -#: gain_meter.cc:74 -msgid "cannot find images for fader rail" -msgstr "" - -#: gain_meter.cc:130 gain_meter.cc:339 gain_meter.cc:494 gain_meter.cc:539 +#: gtk2_ardour/gain_meter.cc:112 +#: gtk2_ardour/gain_meter.cc:328 +#: gtk2_ardour/gain_meter.cc:504 +#: gtk2_ardour/gain_meter.cc:571 msgid "-inf" msgstr "" -#: gain_meter.cc:140 -#, fuzzy +#: gtk2_ardour/gain_meter.cc:123 msgid "Fader automation mode" -msgstr "Stellen" +msgstr "Fader Automationsmodus" -#: gain_meter.cc:141 +#: gtk2_ardour/gain_meter.cc:124 #, fuzzy msgid "Fader automation type" msgstr "Stellen" -#. XXX it might different in different languages -#: gain_meter.cc:182 gain_meter.cc:817 panner_ui.cc:99 panner_ui.cc:807 +#: gtk2_ardour/gain_meter.cc:169 +#: gtk2_ardour/gain_meter.cc:852 +#: gtk2_ardour/panner_ui.cc:97 +#: gtk2_ardour/panner_ui.cc:797 msgid "Abs" msgstr "" -#: gain_meter.cc:472 +#: gtk2_ardour/gain_meter.cc:482 msgid "-Inf" msgstr "" -#: gain_meter.cc:781 mixer_strip.cc:770 panner_ui.cc:771 +#: gtk2_ardour/gain_meter.cc:816 +#: gtk2_ardour/mixer_strip.cc:749 +#: gtk2_ardour/panner_ui.cc:761 #, fuzzy msgid "O" msgstr "ODER" -#: gain_meter.cc:784 panner_ui.cc:774 +#: gtk2_ardour/gain_meter.cc:819 +#: gtk2_ardour/panner_ui.cc:764 msgid "P" msgstr "" -#: gain_meter.cc:787 panner_ui.cc:777 +#: gtk2_ardour/gain_meter.cc:822 +#: gtk2_ardour/panner_ui.cc:767 msgid "T" msgstr "" -#: gain_meter.cc:790 panner_ui.cc:780 +#: gtk2_ardour/gain_meter.cc:825 +#: gtk2_ardour/panner_ui.cc:770 msgid "W" msgstr "" -#: gtk-custom-ruler.c:126 +#: gtk2_ardour/gtk-custom-ruler.c:126 #, fuzzy msgid "Lower" msgstr "Schicht" -#: gtk-custom-ruler.c:127 +#: gtk2_ardour/gtk-custom-ruler.c:127 #, fuzzy msgid "Lower limit of ruler" msgstr "Region ganz nach unten" -#: gtk-custom-ruler.c:136 +#: gtk2_ardour/gtk-custom-ruler.c:136 msgid "Upper" msgstr "" -#: gtk-custom-ruler.c:137 +#: gtk2_ardour/gtk-custom-ruler.c:137 msgid "Upper limit of ruler" msgstr "" -#: gtk-custom-ruler.c:146 +#: gtk2_ardour/gtk-custom-ruler.c:146 #, fuzzy msgid "Position" msgstr "Stellen" -#: gtk-custom-ruler.c:147 +#: gtk2_ardour/gtk-custom-ruler.c:147 msgid "Position of mark on the ruler" msgstr "" -#: gtk-custom-ruler.c:156 +#: gtk2_ardour/gtk-custom-ruler.c:156 msgid "Max Size" msgstr "" -#: gtk-custom-ruler.c:157 +#: gtk2_ardour/gtk-custom-ruler.c:157 msgid "Maximum size of the ruler" msgstr "" -#: gtk-custom-ruler.c:166 +#: gtk2_ardour/gtk-custom-ruler.c:166 #, fuzzy msgid "Show Position" msgstr "nach Zeitstempel der Region" -#: gtk-custom-ruler.c:167 +#: gtk2_ardour/gtk-custom-ruler.c:167 msgid "Draw current ruler position" msgstr "" -#. end-of-file, other end closed or shutdown? -#: imageframe_socket_handler.cc:127 +#: gtk2_ardour/imageframe_socket_handler.cc:127 msgid "Image Compositor Socket has been shutdown/closed" msgstr "" -#: imageframe_time_axis.cc:286 +#: gtk2_ardour/imageframe_time_axis.cc:286 #, fuzzy msgid "0.5 seconds" msgstr "Minuten:Sekunden" -#: imageframe_time_axis.cc:287 marker_time_axis.cc:242 +#: gtk2_ardour/imageframe_time_axis.cc:287 +#: gtk2_ardour/marker_time_axis.cc:242 #, fuzzy msgid "1 seconds" msgstr "Minuten:Sekunden" -#: imageframe_time_axis.cc:288 marker_time_axis.cc:243 +#: gtk2_ardour/imageframe_time_axis.cc:288 +#: gtk2_ardour/marker_time_axis.cc:243 #, fuzzy msgid "1.5 seconds" msgstr "Minuten:Sekunden" -#: imageframe_time_axis.cc:289 marker_time_axis.cc:244 +#: gtk2_ardour/imageframe_time_axis.cc:289 +#: gtk2_ardour/marker_time_axis.cc:244 #, fuzzy msgid "2 seconds" msgstr "Minuten:Sekunden" -#: imageframe_time_axis.cc:290 marker_time_axis.cc:245 +#: gtk2_ardour/imageframe_time_axis.cc:290 +#: gtk2_ardour/marker_time_axis.cc:245 #, fuzzy msgid "2.5 seconds" msgstr "Minuten:Sekunden" -#: imageframe_time_axis.cc:291 marker_time_axis.cc:246 +#: gtk2_ardour/imageframe_time_axis.cc:291 +#: gtk2_ardour/marker_time_axis.cc:246 #, fuzzy msgid "3 seconds" msgstr "Minuten:Sekunden" -#. duration_items.push_back(SeparatorElem()) ; -#. duration_items.push_back(MenuElem (_("custom"), mem_fun(*this, &ImageFrameTimeAxis::set_marker_duration_custom))) ; -#: imageframe_time_axis.cc:296 marker_time_axis.cc:251 +#: gtk2_ardour/imageframe_time_axis.cc:296 +#: gtk2_ardour/marker_time_axis.cc:251 #, fuzzy msgid "Duration (sec)" msgstr "Ardour: Region" -#: imageframe_time_axis.cc:301 +#: gtk2_ardour/imageframe_time_axis.cc:301 #, fuzzy msgid "Remove Frame" msgstr "Feld entfernen" -#: imageframe_time_axis.cc:304 +#: gtk2_ardour/imageframe_time_axis.cc:304 msgid "Image Frame" msgstr "" -#: imageframe_time_axis.cc:305 marker_time_axis.cc:257 +#: gtk2_ardour/imageframe_time_axis.cc:305 +#: gtk2_ardour/marker_time_axis.cc:257 #, fuzzy msgid "Rename Track" msgstr "Umbenennen" -#: io_selector.cc:60 io_selector.cc:794 +#: gtk2_ardour/io_selector.cc:62 +#: gtk2_ardour/io_selector.cc:751 +#: gtk2_ardour/connection_editor.cc:61 +#: gtk2_ardour/connection_editor.cc:110 #, fuzzy msgid "Rescan" msgstr "Auffrischen" -#: io_selector.cc:68 +#: gtk2_ardour/io_selector.cc:70 msgid "%1 input" msgstr "%1 Eingang" -#: io_selector.cc:70 +#: gtk2_ardour/io_selector.cc:72 msgid "%1 output" msgstr "%1 Ausgang" -#: io_selector.cc:142 route_params_ui.cc:107 +#: gtk2_ardour/io_selector.cc:144 +#: gtk2_ardour/route_params_ui.cc:103 #, fuzzy msgid "Inputs" msgstr "Eingänge" -#: io_selector.cc:142 route_params_ui.cc:108 -#, fuzzy +#: gtk2_ardour/io_selector.cc:144 +#: gtk2_ardour/route_params_ui.cc:104 msgid "Outputs" msgstr "Ausgänge" -#: io_selector.cc:143 -#, fuzzy +#: gtk2_ardour/io_selector.cc:145 msgid "Add Input" -msgstr "Port hinzufügen" +msgstr "Hinzufügen" -#: io_selector.cc:143 -#, fuzzy +#: gtk2_ardour/io_selector.cc:145 msgid "Add Output" -msgstr "%1 Ausgang" +msgstr "Hinzufügen" -#: io_selector.cc:144 -#, fuzzy +#: gtk2_ardour/io_selector.cc:146 msgid "Remove Input" -msgstr "Synchronisationspunkt entfernen" +msgstr "Entfernen" -#: io_selector.cc:144 -#, fuzzy +#: gtk2_ardour/io_selector.cc:146 msgid "Remove Output" -msgstr "Ausgänge" +msgstr "Entfernen" -#: io_selector.cc:145 -#, fuzzy +#: gtk2_ardour/io_selector.cc:147 msgid "Disconnect All" -msgstr "Trennen" +msgstr "Alle trennen" -#: io_selector.cc:159 +#: gtk2_ardour/io_selector.cc:161 msgid "Available connections" msgstr "Verfügbare Verbindungen" -#: io_selector.cc:555 io_selector.cc:574 +#: gtk2_ardour/io_selector.cc:550 +#: gtk2_ardour/io_selector.cc:561 msgid "There are no more JACK ports available." -msgstr "" - -#: io_selector.cc:649 io_selector.cc:676 io_selector.cc:729 -msgid "port" -msgstr "Anschluß" +msgstr "Es sind keine weiteren JACK Ports verfügbar." -#: io_selector.cc:798 +#: gtk2_ardour/io_selector.cc:755 msgid "ardour: " msgstr "Ardour: " -#: keyboard.cc:299 +#: gtk2_ardour/keyboard.cc:299 msgid "KeyboardTarget: keyname \"%1\" is unknown." msgstr "" -#: keyboard.cc:525 -msgid "" -"Your system is completely broken - NumLock uses \"%1\"as its modifier. This " -"is madness - see the man page for xmodmap to find out how to fix this." -msgstr "" +#: gtk2_ardour/keyboard.cc:525 +msgid "Your system is completely broken - NumLock uses \"%1\"as its modifier. This is madness - see the man page for xmodmap to find out how to fix this." +msgstr "Ihr System ist falsch konfiguriert. Die NumLock-Taste nutzt \"%1\" als Modifier. Das wird schwere Probleme bereiten. Auf der man page von xmodmap finden sich Infirmationen, wie dieses Problem behoben werden kann." -#: keyboard.cc:533 -msgid "" -"Your system generates \"%1\" when the NumLock key is pressed. This can cause " -"problems when editing so Ardour will use %2 to mean Meta rather than %1" -msgstr "" +#: gtk2_ardour/keyboard.cc:533 +msgid "Your system generates \"%1\" when the NumLock key is pressed. This can cause problems when editing so Ardour will use %2 to mean Meta rather than %1" +msgstr "Ihr System generiert \"%1\" wenn NumLock gedrückt wird. Dies kann zu Problemen führen. Ardour wird deshalb als Meta-Taste %2 an Stelle von %1 benutzen." -#: keyboard.cc:594 +#: gtk2_ardour/keyboard.cc:594 msgid "You have %1 keys bound to \"mod1\"" msgstr "" -#: keyboard.cc:609 +#: gtk2_ardour/keyboard.cc:609 msgid "You have %1 keys bound to \"mod2\"" msgstr "" -#: keyboard.cc:624 +#: gtk2_ardour/keyboard.cc:624 msgid "You have %1 keys bound to \"mod3\"" msgstr "" -#: keyboard.cc:639 +#: gtk2_ardour/keyboard.cc:639 msgid "You have %1 keys bound to \"mod4\"" msgstr "" -#: keyboard.cc:654 +#: gtk2_ardour/keyboard.cc:654 msgid "You have %1 keys bound to \"mod5\"" msgstr "" -#: location_ui.cc:48 location_ui.cc:51 +#: gtk2_ardour/ladspa_pluginui.cc:77 +msgid "Presets" +msgstr "" + +#: gtk2_ardour/ladspa_pluginui.cc:205 +msgid "Plugin Editor: could not build control element for port %1" +msgstr "" + +#: gtk2_ardour/ladspa_pluginui.cc:296 +#, fuzzy +msgid "Automation control" +msgstr "Stellen" + +#: gtk2_ardour/location_ui.cc:49 +#: gtk2_ardour/location_ui.cc:52 #, fuzzy msgid "Set" msgstr "Auswahl" -#: location_ui.cc:49 location_ui.cc:52 +#: gtk2_ardour/location_ui.cc:50 +#: gtk2_ardour/location_ui.cc:53 msgid "Go" msgstr "" -#: location_ui.cc:55 +#: gtk2_ardour/location_ui.cc:56 msgid "CD" msgstr "CD" -#: location_ui.cc:58 +#: gtk2_ardour/location_ui.cc:59 msgid "SCMS" msgstr "" -#: location_ui.cc:59 +#: gtk2_ardour/location_ui.cc:60 msgid "Pre-Emphasis" msgstr "" -#: location_ui.cc:570 +#: gtk2_ardour/location_ui.cc:571 #, fuzzy msgid "Add New Location" msgstr "Stellen" -#: location_ui.cc:571 +#: gtk2_ardour/location_ui.cc:572 msgid "Add New Range" -msgstr "" +msgstr "Neuen Bereich hinzufügen" -#: location_ui.cc:575 +#: gtk2_ardour/location_ui.cc:576 msgid "ardour: locations" msgstr "" -#: location_ui.cc:576 +#: gtk2_ardour/location_ui.cc:577 #, fuzzy msgid "ardour_locations" msgstr "Ardour: Verbindungen" -#: location_ui.cc:604 +#: gtk2_ardour/location_ui.cc:605 #, fuzzy msgid "Location (CD Index) Markers" msgstr "Stellen" -#: location_ui.cc:624 +#: gtk2_ardour/location_ui.cc:625 msgid "Range (CD Track) Markers" msgstr "" -#: location_ui.cc:790 +#: gtk2_ardour/location_ui.cc:793 #, fuzzy msgid "add range marker" msgstr "Ardour: Region umbenennen" -#: main.cc:72 +#: gtk2_ardour/main.cc:73 msgid "ardour is killing itself for a clean exit\n" msgstr "" -#: main.cc:81 +#: gtk2_ardour/main.cc:82 msgid "stopping user interface\n" -msgstr "" +msgstr "Stoppe Benutzeroberfläche\n" -#. XXX its doubtful that snprintf() is async-safe -#: main.cc:100 +#: gtk2_ardour/main.cc:101 #, c-format msgid "%d(%d): received signal %d\n" msgstr "" -#: main.cc:180 +#: gtk2_ardour/main.cc:181 msgid "cannot become new process group leader (%1)" msgstr "" -#: main.cc:207 +#: gtk2_ardour/main.cc:208 msgid "cannot setup signal handling for %1" msgstr "" -#: main.cc:218 +#: gtk2_ardour/main.cc:219 msgid "cannot set default signal mask (%1)" msgstr "" -#: main.cc:248 +#: gtk2_ardour/main.cc:249 msgid "" "Without a UI style file, ardour will look strange.\n" " Please set ARDOUR2_UI_RC to point to a valid UI style file" msgstr "" +"Ohne UI-Definitionsdatei wird Ardour merkwürdig aussehen.\n" +" Bitte setzen Sie ARDOUR_UI_RC auf eine gültige UI-Definitionsdatei" -#: main.cc:270 +#: gtk2_ardour/main.cc:270 msgid "Ardour could not connect to JACK." -msgstr "" +msgstr "Ardour konnte nicht zu JACK verbinden." -#: main.cc:274 +#: gtk2_ardour/main.cc:274 msgid "" "There are several possible reasons:\n" "\n" @@ -4805,493 +5023,433 @@ msgid "" "\n" "Please consider the possibilities, and perhaps (re)start JACK." msgstr "" - -#: main.cc:304 -msgid "could not load command line session \"%1\"" -msgstr "" - -#. it wasn't new, but we require a new session -#: main.cc:324 -msgid "" +"Dafür kann es verschiedene Gründe geben:\n" "\n" +"1) JACK läuft nicht.\n" +"2) JACK wurde unter einem anderen Benutzer gestartet, möglicherweise als root.\n" +"3) Es gibt bereits einen anderen Client mit der Bezeichnung \"ardour\".\n" "\n" -"A session named \"%1\" already exists.\n" -"To avoid this message, start ardour as \"ardour %1" -msgstr "" +"Betrachten Sie bitte diese Möglichkeiten und starten Sie JACK neu, wenn dies notwendig sein sollte." -#: main.cc:335 +#: gtk2_ardour/main.cc:316 +msgid "could not load command line session \"%1\"" +msgstr "Konnte die per Kommandozeile übergebene Sitzung nicht laden: \"%1\"" + +#: gtk2_ardour/main.cc:324 msgid "" "\n" "\n" "No session named \"%1\" exists.\n" "To create it from the command line, start ardour as \"ardour --new %1" msgstr "" +"\n" +"\n" +"Es existiert keine Sitzung mit dem namen \"%1\".\n" +"Um sie von der Kommandozeile aus zu erstellen, starten Sie Ardour mit \"ardour --new %1" -#: main.cc:399 +#: gtk2_ardour/main.cc:385 msgid "Ardour/GTK " msgstr "" -#: main.cc:401 +#: gtk2_ardour/main.cc:387 msgid "" "\n" " (built using " msgstr "" -#: main.cc:405 -msgid " with libardour " -msgstr "" - -#: main.cc:410 +#: gtk2_ardour/main.cc:390 msgid " and GCC version " msgstr "" -#: main.cc:420 +#: gtk2_ardour/main.cc:400 msgid "Copyright (C) 1999-2006 Paul Davis" msgstr "" -#: main.cc:421 -msgid "" -"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel " -"Baker" +#: gtk2_ardour/main.cc:401 +msgid "Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker" msgstr "" -#: main.cc:423 +#: gtk2_ardour/main.cc:403 msgid "Ardour comes with ABSOLUTELY NO WARRANTY" msgstr "Achtung: Es gibt zu Ardour KEINERLEI Gewährleistung!" -#: main.cc:424 +#: gtk2_ardour/main.cc:404 msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." msgstr "" -#: main.cc:425 +#: gtk2_ardour/main.cc:405 msgid "This is free software, and you are welcome to redistribute it " msgstr "Dies ist freie Software und Sie dürfen sie gerne weiterverbreiten," -#: main.cc:426 +#: gtk2_ardour/main.cc:406 #, fuzzy msgid "under certain conditions; see the source for copying conditions." msgstr "solange Sie sich an die Spielregeln aus der Datei COPYING halten." -#: main.cc:435 +#: gtk2_ardour/main.cc:416 msgid "could not create ARDOUR GUI" msgstr "" -#: main.cc:453 +#: gtk2_ardour/main.cc:433 msgid "Could not connect to JACK server as \"%1\"" -msgstr "" +msgstr "Konnte nicht zu JACK Server als \"%1\" verbinden" -#: main.cc:456 +#: gtk2_ardour/main.cc:443 msgid "could not initialize Ardour." -msgstr "" +msgstr "Konnte Ardour nicht initialisieren." -#: marker.cc:244 +#: gtk2_ardour/marker.cc:244 #, fuzzy msgid "MarkerText" msgstr "Schicht" -#: marker_time_axis.cc:254 -#, fuzzy +#: gtk2_ardour/marker_time_axis.cc:254 msgid "Remove Marker" -msgstr "Feld entfernen" +msgstr "Marker entfernen" -#: marker_time_axis.cc:256 +#: gtk2_ardour/marker_time_axis.cc:256 #, fuzzy msgid "Marker" msgstr "Schicht" -#: meter_bridge.cc:78 -msgid "ardour: meter bridge" -msgstr "" - -#: meter_bridge.cc:79 -msgid "ardour_meter_bridge" -msgstr "" - -#: meter_bridge_strip.cc:80 meter_bridge_strip.cc:94 -#, c-format -msgid "# of %u-sample overs" -msgstr "" - -#: meter_bridge_strip.cc:222 -#, fuzzy -msgid "New Name for Meter:" -msgstr "Name für Mixer-Voreinstellung" - -#: mixer_strip.cc:95 mixer_strip.cc:140 mixer_strip.cc:1227 +#: gtk2_ardour/mixer_strip.cc:94 +#: gtk2_ardour/mixer_strip.cc:139 +#: gtk2_ardour/mixer_strip.cc:1218 msgid "pre" -msgstr "" +msgstr "pre" -#: mixer_strip.cc:96 mixer_strip.cc:822 +#: gtk2_ardour/mixer_strip.cc:95 +#: gtk2_ardour/mixer_strip.cc:796 msgid "Comments" -msgstr "" +msgstr "Kommentare" -#: mixer_strip.cc:119 +#: gtk2_ardour/mixer_strip.cc:118 #, fuzzy msgid "Input" msgstr "Eingänge" -#: mixer_strip.cc:136 mixer_strip.cc:1223 -#, fuzzy +#: gtk2_ardour/mixer_strip.cc:135 +#: gtk2_ardour/mixer_strip.cc:1214 msgid "input" -msgstr "%1 Eingang" +msgstr "input" -#: mixer_strip.cc:144 mixer_strip.cc:1231 -#, fuzzy +#: gtk2_ardour/mixer_strip.cc:143 +#: gtk2_ardour/mixer_strip.cc:1222 msgid "post" -msgstr "Anschluß" +msgstr "post" -#. TRANSLATORS: this string should be longest of the strings -#. used to describe meter points. In english, its "input". -#. -#: mixer_strip.cc:152 +#: gtk2_ardour/mixer_strip.cc:150 msgid "tupni" msgstr "" -#: mixer_strip.cc:207 +#: gtk2_ardour/mixer_strip.cc:204 msgid "Varispeed" msgstr "" -#: mixer_strip.cc:233 mixer_strip.cc:836 +#: gtk2_ardour/mixer_strip.cc:230 +#: gtk2_ardour/mixer_strip.cc:812 msgid "Click to Add/Edit Comments" -msgstr "" +msgstr "Kommentare hinzufügen/ändern" -#: mixer_strip.cc:374 +#: gtk2_ardour/mixer_strip.cc:386 msgid "unknown strip width \"%1\" in XML GUI information" msgstr "" -#: mixer_strip.cc:417 -#, fuzzy +#: gtk2_ardour/mixer_strip.cc:430 msgid "record" -msgstr "Wiederherstellen" - -#: mixer_strip.cc:418 region_editor.cc:47 -msgid "mute" -msgstr "mute" - -#: mixer_strip.cc:419 -msgid "solo" -msgstr "solo" +msgstr "Aufnahme" -#: mixer_strip.cc:422 +#: gtk2_ardour/mixer_strip.cc:437 msgid "comments" -msgstr "" +msgstr "Kommentare" -#: mixer_strip.cc:424 +#: gtk2_ardour/mixer_strip.cc:440 msgid "*comments*" msgstr "" -#: mixer_strip.cc:438 +#: gtk2_ardour/mixer_strip.cc:455 #, fuzzy msgid "Rec" msgstr "Auffrischen" -#: mixer_strip.cc:439 +#: gtk2_ardour/mixer_strip.cc:457 msgid "M" -msgstr "" +msgstr "M" -#: mixer_strip.cc:440 +#: gtk2_ardour/mixer_strip.cc:458 msgid "S" -msgstr "" +msgstr "S" -#: mixer_strip.cc:443 mixer_strip.cc:830 +#: gtk2_ardour/mixer_strip.cc:462 +#: gtk2_ardour/mixer_strip.cc:806 #, fuzzy msgid "Cmt" msgstr "Ausschneiden" -#: mixer_strip.cc:445 mixer_strip.cc:828 +#: gtk2_ardour/mixer_strip.cc:465 +#: gtk2_ardour/mixer_strip.cc:803 msgid "*Cmt*" msgstr "" -#: mixer_strip.cc:483 mixer_strip.cc:549 redirect_box.cc:1006 +#: gtk2_ardour/mixer_strip.cc:503 +#: gtk2_ardour/mixer_strip.cc:569 +#: gtk2_ardour/redirect_box.cc:1012 msgid "Not connected to JACK - no I/O changes are possible" -msgstr "" - -#: mixer_strip.cc:560 -msgid "Track" -msgstr "Spur" +msgstr "Nicht mit Jack verbunden - es sind keine Änderungen an Ein-/Ausgängen möglich" -#: mixer_strip.cc:588 mixer_strip.cc:604 +#: gtk2_ardour/mixer_strip.cc:603 +#: gtk2_ardour/mixer_strip.cc:619 msgid "could not register new ports required for that connection" -msgstr "" +msgstr "Konnte die Ports, die diese Verbindung benötigt nicht registrieren" -#: mixer_strip.cc:747 +#: gtk2_ardour/mixer_strip.cc:726 #, fuzzy msgid " Input" msgstr "Eingänge" -#: mixer_strip.cc:750 +#: gtk2_ardour/mixer_strip.cc:729 msgid "I" msgstr "" -#: mixer_strip.cc:820 +#: gtk2_ardour/mixer_strip.cc:793 msgid "*Comments*" msgstr "" -#: mixer_strip.cc:859 +#: gtk2_ardour/mixer_strip.cc:848 #, fuzzy msgid ": comment editor" msgstr "Der Editor konnte nicht initialisiert werden." -#: mixer_strip.cc:953 +#: gtk2_ardour/mixer_strip.cc:943 msgid "Grp" -msgstr "" +msgstr "Grp" -#: mixer_strip.cc:956 +#: gtk2_ardour/mixer_strip.cc:946 msgid "~G" msgstr "" -#: mixer_strip.cc:1004 -#, fuzzy +#: gtk2_ardour/mixer_strip.cc:995 msgid "Invert Polarity" -msgstr "Polarität" +msgstr "Polarität umkehren" -#: mixer_ui.cc:85 +#: gtk2_ardour/mixer_ui.cc:83 msgid "Strips" -msgstr "Streifen" +msgstr "Spur" -#: mixer_ui.cc:110 -#, fuzzy +#: gtk2_ardour/mixer_ui.cc:108 msgid "Group" -msgstr "Mix Gruppen" +msgstr "Gruppe" -#: mixer_ui.cc:211 mixer_ui.cc:370 +#: gtk2_ardour/mixer_ui.cc:209 +#: gtk2_ardour/mixer_ui.cc:389 msgid "ardour: mixer" msgstr "Ardour: Mixer" -#: mixer_ui.cc:212 +#: gtk2_ardour/mixer_ui.cc:210 #, fuzzy msgid "ardour_mixer" msgstr "Ardour: Mixer" -#: mixer_ui.cc:346 +#: gtk2_ardour/mixer_ui.cc:361 msgid "ardour: mixer: " msgstr "Ardour: Mixer: " -#: mixer_ui.cc:573 +#: gtk2_ardour/mixer_ui.cc:592 msgid "signal" msgstr "Signal" -#: mixer_ui.cc:723 +#: gtk2_ardour/mixer_ui.cc:741 msgid "track display list item for renamed strip not found!" msgstr "" -#: new_session_dialog.cc:39 +#: gtk2_ardour/new_session_dialog.cc:41 #, fuzzy -msgid "New Session Name :" -msgstr "Name der Sitzung" +msgid "Name :" +msgstr "Umbenennen" -#: new_session_dialog.cc:41 -msgid "Create Session Directory In :" -msgstr "" +#: gtk2_ardour/new_session_dialog.cc:45 +#: gtk2_ardour/new_session_dialog.cc:46 +#: gtk2_ardour/new_session_dialog.cc:47 +#: gtk2_ardour/new_session_dialog.cc:48 +#: gtk2_ardour/sfdb_ui.cc:172 +msgid "channels" +msgstr "Kanäle" -#: new_session_dialog.cc:43 -#, fuzzy -msgid "Use Session Template :" -msgstr "Name der Sitzung" +#: gtk2_ardour/new_session_dialog.cc:66 +msgid "Busses" +msgstr "Busse" -#: new_session_dialog.cc:45 -#, fuzzy -msgid "Channel Count" -msgstr "Importieren Abbrechen" +#: gtk2_ardour/new_session_dialog.cc:67 +msgid "Inputs" +msgstr "Eingänge" + +#: gtk2_ardour/new_session_dialog.cc:68 +msgid "Outputs" +msgstr "Ausgänge" + +#: gtk2_ardour/new_session_dialog.cc:70 +msgid "Create Folder In :" +msgstr "Verzeichnis erstellen in:" -#: new_session_dialog.cc:46 +#: gtk2_ardour/new_session_dialog.cc:72 +msgid "Template :" +msgstr "Vorlage :" + +#: gtk2_ardour/new_session_dialog.cc:74 msgid "Create Monitor Bus" -msgstr "" +msgstr "Monitor Bus erstellen" -#: new_session_dialog.cc:53 +#: gtk2_ardour/new_session_dialog.cc:81 msgid "Create Master Bus" -msgstr "" +msgstr "Master Bus erstellen" -#: new_session_dialog.cc:55 -#, fuzzy -msgid "Automatically Connect Inputs" -msgstr "Verfügbare Verbindungen" +#: gtk2_ardour/new_session_dialog.cc:83 +msgid "Automatically Connect to Physical Inputs" +msgstr "Eingänge automatisch mit Soundkarteneingängen verbinden" -#: new_session_dialog.cc:56 new_session_dialog.cc:67 -#, fuzzy -msgid "Port Limit" -msgstr "Abbrechen" - -#: new_session_dialog.cc:64 -#, fuzzy -msgid "Track/Bus Inputs" -msgstr "Ausgänge" +#: gtk2_ardour/new_session_dialog.cc:84 +#: gtk2_ardour/new_session_dialog.cc:97 +msgid "Use only" +msgstr "Benutze nur" -#: new_session_dialog.cc:66 -#, fuzzy +#: gtk2_ardour/new_session_dialog.cc:96 msgid "Automatically Connect Outputs" -msgstr "Verfügbare Verbindungen" +msgstr "Ausgänge automatisch verbinden" -#: new_session_dialog.cc:75 -msgid "Connect to Master Bus" -msgstr "" +#: gtk2_ardour/new_session_dialog.cc:105 +msgid "... to Master Bus" +msgstr "... mit Master Bus" -#: new_session_dialog.cc:76 -msgid "Connect to Physical Outputs" -msgstr "" +#: gtk2_ardour/new_session_dialog.cc:106 +msgid "... to Physical Outputs" +msgstr "... mit Soundkartenausgängen" -#: new_session_dialog.cc:80 -#, fuzzy -msgid "Track/Bus Outputs" -msgstr "Ausgänge" - -#: new_session_dialog.cc:83 -#, fuzzy +#: gtk2_ardour/new_session_dialog.cc:112 msgid "Advanced Options" -msgstr "Geschwindigkeitseditor" +msgstr "Erweiterte Einstellungen" -#: new_session_dialog.cc:91 -#, fuzzy -msgid "Open Recent Session" -msgstr "Sitzung" +#: gtk2_ardour/new_session_dialog.cc:120 +msgid "Recent:" +msgstr "Zuletzt verwendet:" -#: new_session_dialog.cc:127 -#, fuzzy -msgid "Open Session File :" -msgstr "Sitzung" +#: gtk2_ardour/new_session_dialog.cc:157 +msgid "Browse:" +msgstr "Durchsuchen:" -#: new_session_dialog.cc:274 -#, fuzzy +#: gtk2_ardour/new_session_dialog.cc:335 msgid "New Session" -msgstr "Sitzung" +msgstr "Neue Sitzung" -#: new_session_dialog.cc:276 -#, fuzzy +#: gtk2_ardour/new_session_dialog.cc:337 msgid "Open Session" -msgstr "Sitzung" +msgstr "Sitzung öffnen" -#: new_session_dialog.cc:281 -#, fuzzy +#: gtk2_ardour/new_session_dialog.cc:342 msgid "ardour: session control" msgstr "Ardour: Neue Sitzung" -#: new_session_dialog.cc:310 -#, fuzzy +#: gtk2_ardour/new_session_dialog.cc:371 msgid "select template" -msgstr "Voreinstellung" +msgstr "Vorlage auswählen" -#: new_session_dialog.cc:316 +#: gtk2_ardour/new_session_dialog.cc:377 #, fuzzy msgid "select session file" msgstr "Auswahl zu Schleife machen" -#: new_session_dialog.cc:325 +#: gtk2_ardour/new_session_dialog.cc:386 #, fuzzy msgid "select directory" msgstr "Auswahl zu Schleife machen" -#: option_editor.cc:76 +#: gtk2_ardour/option_editor.cc:75 msgid "SMPTE offset is negative" -msgstr "" +msgstr "Negatives SMPTE-Offset" -#: option_editor.cc:102 +#: gtk2_ardour/option_editor.cc:101 #, fuzzy msgid "ardour: options editor" msgstr "Ardour: Einstellungen" -#: option_editor.cc:103 +#: gtk2_ardour/option_editor.cc:102 #, fuzzy msgid "ardour_option_editor" msgstr "Ardour: Einstellungen" -#: option_editor.cc:127 +#: gtk2_ardour/option_editor.cc:126 msgid "Paths/Files" -msgstr "Pfade- und Dateinamen" +msgstr "Pfade" -#: option_editor.cc:128 +#: gtk2_ardour/option_editor.cc:127 msgid "Kbd/Mouse" -msgstr "" +msgstr "Tastatur/Maus" -#: option_editor.cc:131 +#: gtk2_ardour/option_editor.cc:130 msgid "Layers & Fades" -msgstr "" +msgstr "Layer & Fades" -#: option_editor.cc:135 +#: gtk2_ardour/option_editor.cc:134 msgid "MIDI" -msgstr "" - -#: option_editor.cc:177 -msgid "24 FPS" -msgstr "" +msgstr "MIDI" -#: option_editor.cc:179 -msgid "25 FPS" -msgstr "" - -#: option_editor.cc:181 -msgid "30 FPS" -msgstr "" - -#: option_editor.cc:187 -msgid "30 FPS drop" -msgstr "" - -#: option_editor.cc:244 +#: gtk2_ardour/option_editor.cc:222 msgid "session RAID path" -msgstr "" +msgstr "Sitzungsverzeichnis (RAID)" -#: option_editor.cc:249 -#, fuzzy +#: gtk2_ardour/option_editor.cc:227 msgid "Soundfile Search Paths" -msgstr "Ardour: Audio Bibliothek" - -#: option_editor.cc:254 -#, fuzzy -msgid "Paths" -msgstr "Pfade- und Dateinamen" +msgstr "Suchpfade für Audiodateien" -#: option_editor.cc:268 option_editor.cc:274 option_editor.cc:723 -#: option_editor.cc:750 -#, fuzzy +#: gtk2_ardour/option_editor.cc:252 +#: gtk2_ardour/option_editor.cc:258 +#: gtk2_ardour/option_editor.cc:670 +#: gtk2_ardour/option_editor.cc:697 msgid "internal" -msgstr "mittelmäßig" +msgstr "intern" -#: option_editor.cc:287 +#: gtk2_ardour/option_editor.cc:271 msgid "Short crossfade length (msecs)" -msgstr "" +msgstr "Länge für kurze Crossfades (ms)" -#: option_editor.cc:299 +#: gtk2_ardour/option_editor.cc:283 msgid "Destructive crossfade length (msecs)" -msgstr "" - -#: option_editor.cc:367 -msgid "SMPTE Frames/second" -msgstr "" +msgstr "Länge für destruktive Crossfades (ms)" -#: option_editor.cc:368 +#: gtk2_ardour/option_editor.cc:343 msgid "SMPTE Offset" -msgstr "" +msgstr "SMPTE Offset" -#: option_editor.cc:462 option_editor.cc:469 option_editor.cc:472 -#: option_editor.cc:618 +#: gtk2_ardour/option_editor.cc:410 +#: gtk2_ardour/option_editor.cc:417 +#: gtk2_ardour/option_editor.cc:420 +#: gtk2_ardour/option_editor.cc:565 #, fuzzy msgid "online" msgstr "Verbindungen" -#. remember, we have to handle the i18n case where the relative -#. lengths of the strings in language N is different than in english. -#. -#: option_editor.cc:469 option_editor.cc:470 option_editor.cc:615 +#: gtk2_ardour/option_editor.cc:417 +#: gtk2_ardour/option_editor.cc:418 +#: gtk2_ardour/option_editor.cc:562 msgid "offline" msgstr "" -#: option_editor.cc:670 +#: gtk2_ardour/option_editor.cc:617 msgid "Choose Click" msgstr "" -#: option_editor.cc:689 +#: gtk2_ardour/option_editor.cc:636 msgid "Choose Click Emphasis" msgstr "" -#: option_editor.cc:803 +#: gtk2_ardour/option_editor.cc:750 msgid "Click audio file" -msgstr "" +msgstr "Audiodatei für Click" -#: option_editor.cc:809 +#: gtk2_ardour/option_editor.cc:756 msgid "Click emphasis audiofile" -msgstr "" +msgstr "Audiodatei für betonten Click " -#: option_editor.cc:846 +#: gtk2_ardour/option_editor.cc:793 msgid "" "The auditioner is a dedicated mixer strip used\n" "for listening to specific regions outside the context\n" @@ -5299,265 +5457,239 @@ msgid "" "other mixer strip." msgstr "" -#: option_editor.cc:919 -#, fuzzy +#: gtk2_ardour/option_editor.cc:866 msgid "Edit using" -msgstr "Mix Gruppen" +msgstr "Bearbeiten mit" -#: option_editor.cc:926 option_editor.cc:953 +#: gtk2_ardour/option_editor.cc:873 +#: gtk2_ardour/option_editor.cc:900 msgid "+ button" -msgstr "" +msgstr "und Maustaste" -#: option_editor.cc:946 -#, fuzzy +#: gtk2_ardour/option_editor.cc:893 msgid "Delete using" -msgstr "Messungen" +msgstr "Entfernen mit" -#: option_editor.cc:973 +#: gtk2_ardour/option_editor.cc:920 msgid "Ignore snap using" -msgstr "" +msgstr "Einrasten übergehen mit" -#: opts.cc:46 +#: gtk2_ardour/opts.cc:46 msgid "Usage: " msgstr "Aufruf:" -#: opts.cc:47 +#: gtk2_ardour/opts.cc:47 msgid " -v, --version Show version information\n" msgstr " -v, --version Versionsinformation ausgeben\n" -#: opts.cc:48 +#: gtk2_ardour/opts.cc:48 msgid " -h, --help Print this message\n" msgstr " -h, --help Diese Hinweise\n" -#: opts.cc:49 -msgid "" -" -b, --bindings Print all possible keyboard binding " -"names\n" -msgstr "" -" -b, --bindings Alle möglichen Tastenzuweisungsnamen " -"ausgeben\n" +#: gtk2_ardour/opts.cc:49 +msgid " -b, --bindings Print all possible keyboard binding names\n" +msgstr " -b, --bindings Alle möglichen Tastenzuweisungsnamen ausgeben\n" -#: opts.cc:50 +#: gtk2_ardour/opts.cc:50 #, fuzzy msgid " -n, --show-splash Show splash screen\n" msgstr " -h, --help Diese Hinweise\n" -#: opts.cc:51 +#: gtk2_ardour/opts.cc:51 #, fuzzy -msgid "" -" -c, --name name Use a specific jack client name, default " -"is ardour\n" +msgid " -c, --name name Use a specific jack client name, default is ardour\n" msgstr " -U, --ui-rcfile=FILENAME Dateiname für UI Einstellungen\n" -#: opts.cc:52 +#: gtk2_ardour/opts.cc:52 #, fuzzy -msgid "" -" -N, --new session-name Create a new session from the command " -"line\n" +msgid " -N, --new session-name Create a new session from the command line\n" msgstr " [session-name] Name der zu ladenden Sitzung\n" -#: opts.cc:53 -msgid "" -" -o, --use-hw-optimizations Try to use h/w specific optimizations\n" +#: gtk2_ardour/opts.cc:53 +msgid " -o, --use-hw-optimizations Try to use h/w specific optimizations\n" msgstr "" -#: opts.cc:55 +#: gtk2_ardour/opts.cc:55 #, fuzzy msgid " -V, --novst Do not use VST support\n" msgstr " -h, --help Diese Hinweise\n" -#: opts.cc:57 +#: gtk2_ardour/opts.cc:57 msgid " [session-name] Name of session to load\n" msgstr " [session-name] Name der zu ladenden Sitzung\n" -#: opts.cc:58 +#: gtk2_ardour/opts.cc:58 msgid " -C, --curvetest filename Curve algorithm debugger\n" msgstr "" -#: opts.cc:59 +#: gtk2_ardour/opts.cc:59 #, fuzzy msgid " -g, --gtktheme Allow GTK to load a theme\n" msgstr " -h, --help Diese Hinweise\n" -#: pan_automation_time_axis.cc:60 -msgid "You can't graphically edit panning of more than stream" +#: gtk2_ardour/pan_automation_time_axis.cc:70 +msgid "You need to select which line to edit" msgstr "" -#: pan_automation_time_axis.cc:80 +#: gtk2_ardour/pan_automation_time_axis.cc:91 #, fuzzy msgid "add pan automation event" msgstr "Stellen" -#: panner2d.cc:589 panner_ui.cc:435 plugin_ui.cc:834 +#: gtk2_ardour/panner2d.cc:589 +#: gtk2_ardour/panner_ui.cc:425 +#: gtk2_ardour/plugin_ui.cc:151 msgid "Bypass" -msgstr "" +msgstr "Bypass" -#: panner_ui.cc:58 panner_ui.cc:225 +#: gtk2_ardour/panner_ui.cc:56 +#: gtk2_ardour/panner_ui.cc:223 #, fuzzy msgid "link" msgstr "leer" -#: panner_ui.cc:69 -#, fuzzy +#: gtk2_ardour/panner_ui.cc:67 msgid "Pan automation mode" -msgstr "Stellen" +msgstr "Pan-Automationsmodus" -#: panner_ui.cc:70 +#: gtk2_ardour/panner_ui.cc:68 #, fuzzy msgid "Pan automation type" msgstr "Stellen" -#: panner_ui.cc:81 +#: gtk2_ardour/panner_ui.cc:79 msgid "panning link control" -msgstr "" +msgstr "Pan-Regler gruppieren" -#: panner_ui.cc:83 +#: gtk2_ardour/panner_ui.cc:81 msgid "panning link direction" -msgstr "" +msgstr "Richtung der Gruppierung" -#: panner_ui.cc:235 +#: gtk2_ardour/panner_ui.cc:233 msgid "L" -msgstr "" - -#: panner_ui.cc:335 -#, c-format -msgid "panner for channel %lu" -msgstr "" +msgstr "L" -#: panner_ui.cc:337 +#: gtk2_ardour/panner_ui.cc:328 #, c-format -msgid "panner for channel %u" -msgstr "" +msgid "panner for channel %zu" +msgstr "Pan-Regler für Kanal %zu" -#: panner_ui.cc:445 +#: gtk2_ardour/panner_ui.cc:435 #, fuzzy msgid "Reset all" msgstr "bestmöglich" -#: playlist_selector.cc:52 +#: gtk2_ardour/playlist_selector.cc:52 #, fuzzy msgid "ardour: playlists" msgstr "Ardour: Plugins" -#: playlist_selector.cc:59 +#: gtk2_ardour/playlist_selector.cc:59 msgid "Playlists grouped by track" msgstr "" -#: playlist_selector.cc:98 +#: gtk2_ardour/playlist_selector.cc:98 #, fuzzy msgid "ardour: playlist for " msgstr "Ardour: Editor: " -#: playlist_selector.cc:114 +#: gtk2_ardour/playlist_selector.cc:114 #, fuzzy msgid "Other tracks" msgstr "Stille einfügen" -#: playlist_selector.cc:130 +#: gtk2_ardour/playlist_selector.cc:130 msgid "unassigned" msgstr "" -#: plugin_selector.cc:43 +#: gtk2_ardour/plugin_selector.cc:43 msgid "ardour: plugins" msgstr "Ardour: Plugins" -#: plugin_selector.cc:56 -#, fuzzy +#: gtk2_ardour/plugin_selector.cc:56 msgid "Available LADSPA Plugins" msgstr "Verfügbare LADSPA Plugins" -#: plugin_selector.cc:57 +#: gtk2_ardour/plugin_selector.cc:57 msgid "Type" msgstr "Typ" -#: plugin_selector.cc:58 plugin_selector.cc:81 +#: gtk2_ardour/plugin_selector.cc:58 +#: gtk2_ardour/plugin_selector.cc:81 +#: gtk2_ardour/plugin_selector.cc:99 msgid "# Inputs" msgstr "Eingänge" -#: plugin_selector.cc:59 plugin_selector.cc:82 +#: gtk2_ardour/plugin_selector.cc:59 +#: gtk2_ardour/plugin_selector.cc:82 +#: gtk2_ardour/plugin_selector.cc:100 msgid "# Outputs" msgstr "Ausgänge" -#: plugin_selector.cc:68 +#: gtk2_ardour/plugin_selector.cc:68 msgid "Plugins to be Connected to Insert" -msgstr "" +msgstr "Plugins, die als Insert verbunden werden" -#: plugin_selector.cc:80 -#, fuzzy +#: gtk2_ardour/plugin_selector.cc:80 +#: gtk2_ardour/plugin_selector.cc:98 msgid "Available plugins" -msgstr "Verfügbare LADSPA Plugins" +msgstr "Verfügbare VST-Plugins" -#: plugin_selector.cc:98 +#: gtk2_ardour/plugin_selector.cc:117 msgid "Add a plugin to the effect list" msgstr "Plugin zur Effektliste hinzufügen" -#: plugin_selector.cc:102 +#: gtk2_ardour/plugin_selector.cc:121 msgid "Remove a plugin from the effect list" msgstr "Plugin aus der Effektliste entfernen" -#: plugin_selector.cc:104 +#: gtk2_ardour/plugin_selector.cc:123 msgid "Update available plugins" msgstr "Verfügbare Plugins auffrischen" -#: plugin_selector.cc:126 +#: gtk2_ardour/plugin_selector.cc:146 msgid "LADSPA" -msgstr "" +msgstr "LADSPA" -#: plugin_selector.cc:129 +#: gtk2_ardour/plugin_selector.cc:150 msgid "VST" -msgstr "" +msgstr "VST" -#: plugin_ui.cc:84 -msgid "" -"unknown type of editor-supplying plugin (note: no VST support in this " -"version of ardour)" +#: gtk2_ardour/plugin_selector.cc:155 +msgid "AudioUnit" msgstr "" -#: plugin_ui.cc:139 -msgid "Presets" +#: gtk2_ardour/plugin_ui.cc:85 +msgid "unknown type of editor-supplying plugin (note: no VST support in this version of ardour)" msgstr "" -#: plugin_ui.cc:230 -#, fuzzy -msgid "Controls" -msgstr "Verbindungen" - -#: plugin_ui.cc:267 -msgid "Plugin Editor: could not build control element for port %1" -msgstr "" - -#: plugin_ui.cc:358 -#, fuzzy -msgid "Automation control" -msgstr "Stellen" - -#: plugin_ui.cc:854 +#: gtk2_ardour/plugin_ui.cc:171 msgid "Plugin preset %1 not found" -msgstr "" +msgstr "Plugin Preset %1 nicht gefunden" -#: plugin_ui.cc:864 +#: gtk2_ardour/plugin_ui.cc:181 #, fuzzy msgid "Name of New Preset:" msgstr "Name für neue Verbindung:" -#: redirect_automation_line.cc:54 +#: gtk2_ardour/redirect_automation_line.cc:54 msgid "redirect automation created for non-plugin" msgstr "" -#: redirect_automation_time_axis.cc:94 +#: gtk2_ardour/redirect_automation_time_axis.cc:96 #, fuzzy msgid "add automation event to " msgstr "Stellen" -#: redirect_box.cc:223 +#: gtk2_ardour/redirect_box.cc:226 msgid "New send" msgstr "" -#: redirect_box.cc:224 +#: gtk2_ardour/redirect_box.cc:227 msgid "Show send controls" msgstr "" -#: redirect_box.cc:383 +#: gtk2_ardour/redirect_box.cc:386 msgid "" "You attempted to add a plugin (%1).\n" "The plugin has %2 inputs\n" @@ -5568,7 +5700,7 @@ msgid "" "part of the signal." msgstr "" -#: redirect_box.cc:395 +#: gtk2_ardour/redirect_box.cc:398 msgid "" "You attempted to add a plugin (%1).\n" "The plugin has %2 inputs\n" @@ -5580,7 +5712,7 @@ msgid "" "support this type of configuration." msgstr "" -#: redirect_box.cc:408 +#: gtk2_ardour/redirect_box.cc:411 msgid "" "You attempted to add a plugin (%1).\n" "\n" @@ -5593,34 +5725,35 @@ msgid "" "Ardour does not understand what to do in such situations.\n" msgstr "" -#: redirect_box.cc:495 +#: gtk2_ardour/redirect_box.cc:499 msgid "Pre-fader inserts, sends & plugins:" msgstr "" -#: redirect_box.cc:498 +#: gtk2_ardour/redirect_box.cc:502 msgid "Post-fader inserts, sends & plugins:" -msgstr "" +msgstr "Post-Fader Inserts, Sends & Plugins:" -#: redirect_box.cc:644 +#: gtk2_ardour/redirect_box.cc:650 msgid "" "You cannot reorder this set of redirects\n" "in that way because the inputs and\n" "outputs do not work correctly." msgstr "" -#: redirect_box.cc:749 +#: gtk2_ardour/redirect_box.cc:750 #, fuzzy msgid "rename redirect" msgstr "Ardour: Region umbenennen" -#: redirect_box.cc:826 redirect_box.cc:874 +#: gtk2_ardour/redirect_box.cc:824 +#: gtk2_ardour/redirect_box.cc:872 msgid "" "Copying the set of redirects on the clipboard failed,\n" "probably because the I/O configuration of the plugins\n" "could not match the configuration of this track." msgstr "" -#: redirect_box.cc:896 +#: gtk2_ardour/redirect_box.cc:894 #, fuzzy msgid "" "Do you really want to remove all redirects from this track?\n" @@ -5629,7 +5762,7 @@ msgstr "" "Wollen Sie wirklich die Spur \"%1\" löschen?\n" "(Kann nicht rückgängig gemacht werden!)" -#: redirect_box.cc:899 +#: gtk2_ardour/redirect_box.cc:897 #, fuzzy msgid "" "Do you really want to remove all redirects from this bus?\n" @@ -5638,261 +5771,194 @@ msgstr "" "Wollen Sie wirklich die Spur \"%1\" löschen?\n" "(Kann nicht rückgängig gemacht werden!)" -#: redirect_box.cc:904 -#, fuzzy +#: gtk2_ardour/redirect_box.cc:902 msgid "Yes, remove them all" -msgstr "Ja, entfernen." +msgstr "Ja, alle löschen" -#: redirect_box.cc:940 +#: gtk2_ardour/redirect_box.cc:938 #, fuzzy msgid "ardour: %1" msgstr "Ardour: " -#: redirect_box.cc:982 -#, fuzzy -msgid "ardour: %1: %2 (by %3)" -msgstr "Ardour: " - -#. new stuff -#: redirect_box.cc:1054 +#: gtk2_ardour/redirect_box.cc:1060 msgid "New Plugin ..." -msgstr "" +msgstr "Plugin einfügen..." -#: redirect_box.cc:1055 -#, fuzzy +#: gtk2_ardour/redirect_box.cc:1062 msgid "New Insert" -msgstr "Neuer Eingang" +msgstr "Insert einfügen" -#: redirect_box.cc:1056 +#: gtk2_ardour/redirect_box.cc:1064 msgid "New Send ..." -msgstr "" +msgstr "Send einfügen..." -#: redirect_box.cc:1068 -#, fuzzy +#: gtk2_ardour/redirect_box.cc:1078 msgid "Deselect All" -msgstr "Auswahl" +msgstr "Nichts auswählen" -#: redirect_box.cc:1075 -#, fuzzy +#: gtk2_ardour/redirect_box.cc:1085 msgid "Activate all" -msgstr "Aktiv" +msgstr "Alle aktivieren" -#: redirect_box.cc:1076 -#, fuzzy +#: gtk2_ardour/redirect_box.cc:1086 msgid "Deactivate all" -msgstr "Alles deaktivieren" - -#: region_editor.cc:45 -msgid "NAME:" -msgstr "" - -#: region_editor.cc:46 -msgid "lock" -msgstr "" - -#: region_editor.cc:48 -msgid "opaque" -msgstr "" - -#: region_editor.cc:49 region_editor.cc:192 region_editor.cc:226 -msgid "active" -msgstr "" - -#: region_editor.cc:50 -msgid "visible" -msgstr "" - -#: region_editor.cc:53 -msgid "Layer" -msgstr "Schicht" - -#: region_editor.cc:54 -msgid "play" -msgstr "" +msgstr "Alle deaktivieren" -#: region_editor.cc:61 -msgid "ENVELOPE" -msgstr "" - -#: region_editor.cc:107 +#: gtk2_ardour/redirect_box.cc:1263 #, fuzzy -msgid "mute this region" -msgstr "Name für Region:" - -#: region_editor.cc:108 -msgid "regions underneath this one cannot be heard" -msgstr "" - -#: region_editor.cc:109 -msgid "prevent any changes to this region" -msgstr "" - -#: region_editor.cc:110 -msgid "use the gain envelope during playback" -msgstr "" - -#: region_editor.cc:111 -msgid "show the gain envelope" -msgstr "" +msgid "ardour: %1: %2 (by %3)" +msgstr "Ardour: " -#: region_editor.cc:112 -msgid "use fade in curve during playback" -msgstr "" +#: gtk2_ardour/audio_region_editor.cc:47 +msgid "NAME:" +msgstr "NAME:" -#: region_editor.cc:113 -msgid "use fade out curve during playback" +#: gtk2_ardour/audio_region_editor.cc:48 +msgid "play" msgstr "" -#: region_editor.cc:114 +#: gtk2_ardour/audio_region_editor.cc:67 msgid "audition this region" msgstr "" -#: region_editor.cc:147 +#: gtk2_ardour/audio_region_editor.cc:82 msgid "START:" -msgstr "" +msgstr "BEGINN:" -#: region_editor.cc:149 +#: gtk2_ardour/audio_region_editor.cc:84 msgid "END:" -msgstr "" +msgstr "ENDE:" -#: region_editor.cc:151 +#: gtk2_ardour/audio_region_editor.cc:86 msgid "LENGTH:" -msgstr "" - -#: region_editor.cc:191 -msgid "FADE IN" -msgstr "" +msgstr "LÄNGE:" -#: region_editor.cc:193 region_editor.cc:227 -msgid "msecs" -msgstr "" - -#: region_editor.cc:225 -msgid "FADE OUT" -msgstr "" - -#: region_editor.cc:265 +#: gtk2_ardour/audio_region_editor.cc:122 msgid "ardour: region " msgstr "Ardour: Region" -#: region_editor.cc:402 -msgid "fade in edit" -msgstr "" +#: gtk2_ardour/audio_region_editor.cc:202 +#, fuzzy +msgid "change region start position" +msgstr "Regionen" + +#: gtk2_ardour/audio_region_editor.cc:219 +#, fuzzy +msgid "change region end position" +msgstr "Regionen" -#: region_editor.cc:414 +#: gtk2_ardour/audio_region_editor.cc:240 #, fuzzy -msgid "fade out edit" +msgid "change region length" msgstr "Ardour: Editor" -#: regionview.cc:1146 +#: gtk2_ardour/audio_region_view.cc:937 #, fuzzy msgid "add gain control point" msgstr "Synchronisationspunkt entfernen" -#: route_params_ui.cc:89 +#: gtk2_ardour/route_params_ui.cc:85 msgid "Tracks/Buses" msgstr "" -#: route_params_ui.cc:109 +#: gtk2_ardour/route_params_ui.cc:105 msgid "Pre-fader Redirects" msgstr "" -#: route_params_ui.cc:110 +#: gtk2_ardour/route_params_ui.cc:106 msgid "Post-fader Redirects" msgstr "" -#: route_params_ui.cc:144 +#: gtk2_ardour/route_params_ui.cc:140 #, fuzzy msgid "ardour: track/bus inspector" msgstr "Ardour: Editor" -#: route_params_ui.cc:145 +#: gtk2_ardour/route_params_ui.cc:141 #, fuzzy msgid "ardour_route_parameters" msgstr "Ardour: Route" -#: route_params_ui.cc:202 +#: gtk2_ardour/route_params_ui.cc:202 msgid "route display list item for renamed route not found!" msgstr "" -#: route_params_ui.cc:453 +#: gtk2_ardour/route_params_ui.cc:449 msgid "NO TRACK" msgstr "" -#: route_params_ui.cc:695 +#: gtk2_ardour/route_params_ui.cc:672 #, fuzzy msgid "ardour: track/bus inspector: " msgstr "Ardour: Editor" -#: route_params_ui.cc:699 +#: gtk2_ardour/route_params_ui.cc:676 msgid "No Route Selected" msgstr "Keine Route ausgewählt" -#: route_params_ui.cc:700 +#: gtk2_ardour/route_params_ui.cc:677 #, fuzzy msgid "ardour: track/bus/inspector: no route selected" msgstr "Ardour: Route: keine Route ausgewählt" -#. ctrl-shift-click applies change to all routes -#: route_ui.cc:134 +#: gtk2_ardour/route_ui.cc:144 #, fuzzy msgid "mute change" msgstr "Bereich" -#. ctrl-shift-click applies change to all routes -#. ctrl-alt-click: exclusively solo this track, not a toggle */ -#: route_ui.cc:209 route_ui.cc:219 +#: gtk2_ardour/route_ui.cc:222 +#: gtk2_ardour/route_ui.cc:233 #, fuzzy msgid "solo change" msgstr "Bereich" -#: route_ui.cc:282 +#: gtk2_ardour/route_ui.cc:291 +msgid "Not connected to JACK - cannot engage record" +msgstr "" + +#: gtk2_ardour/route_ui.cc:303 msgid "rec-enable change" msgstr "" -#: route_ui.cc:479 +#: gtk2_ardour/route_ui.cc:501 #, fuzzy msgid "Solo-safe" msgstr "solo" -#: route_ui.cc:487 route_ui.cc:530 -msgid "MIDI Bind" -msgstr "" - -#: route_ui.cc:501 +#: gtk2_ardour/route_ui.cc:523 msgid "Pre Fader" msgstr "" -#: route_ui.cc:508 +#: gtk2_ardour/route_ui.cc:530 msgid "Post Fader" msgstr "" -#: route_ui.cc:515 +#: gtk2_ardour/route_ui.cc:537 msgid "Control Outs" msgstr "" -#: route_ui.cc:522 +#: gtk2_ardour/route_ui.cc:544 msgid "Main Outs" msgstr "" -#: route_ui.cc:559 +#: gtk2_ardour/route_ui.cc:581 msgid "mix group solo change" msgstr "" -#: route_ui.cc:593 +#: gtk2_ardour/route_ui.cc:620 msgid "mix group mute change" msgstr "" -#: route_ui.cc:609 +#: gtk2_ardour/route_ui.cc:637 msgid "mix group rec-enable change" msgstr "" -#: route_ui.cc:626 visual_time_axis.cc:237 +#: gtk2_ardour/route_ui.cc:655 +#: gtk2_ardour/visual_time_axis.cc:242 msgid "ardour: color selection" msgstr "Ardour: Farbe auswählen" -#: route_ui.cc:702 -#, fuzzy +#: gtk2_ardour/route_ui.cc:731 msgid "" "Do you really want to remove track \"%1\" ?\n" "\n" @@ -5900,221 +5966,269 @@ msgid "" "(cannot be undone)" msgstr "" "Wollen Sie wirklich die Spur \"%1\" löschen?\n" -"(Kann nicht rückgängig gemacht werden!)" +"\n" +"Sie werden auch die Wiedergabeliste, die diese Spur benutzt verlieren.(Dies kann nicht rückgängig gemacht werden!)" -#: route_ui.cc:704 +#: gtk2_ardour/route_ui.cc:733 msgid "" "Do you really want to remove bus \"%1\" ?\n" "(cannot be undone)" msgstr "" +"Wollen Sie den Bus \"%1\" wirklich löschen?\n" +"(Dies kann nicht rückgängig gemacht werden!)" -#: route_ui.cc:708 visual_time_axis.cc:279 +#: gtk2_ardour/route_ui.cc:737 +#: gtk2_ardour/visual_time_axis.cc:284 msgid "Yes, remove it." msgstr "Ja, entfernen." -#: route_ui.cc:737 +#: gtk2_ardour/route_ui.cc:758 #, fuzzy msgid "New Name: " msgstr "Neuer Name: " -#: sfdb_ui.cc:58 +#: gtk2_ardour/sfdb_ui.cc:61 msgid "Add Field..." msgstr "Feld hinzufügen..." -#: sfdb_ui.cc:59 +#: gtk2_ardour/sfdb_ui.cc:62 msgid "Remove Field" msgstr "Feld entfernen" -#: sfdb_ui.cc:62 +#: gtk2_ardour/sfdb_ui.cc:65 msgid "Soundfile Info" msgstr "" -#: sfdb_ui.cc:80 +#: gtk2_ardour/sfdb_ui.cc:84 msgid "Field" msgstr "Feld" -#: sfdb_ui.cc:81 +#: gtk2_ardour/sfdb_ui.cc:85 msgid "Value" msgstr "Wert" -#: sfdb_ui.cc:161 +#: gtk2_ardour/sfdb_ui.cc:139 +msgid "Length: %1" +msgstr "" + +#: gtk2_ardour/sfdb_ui.cc:145 #, fuzzy -msgid "channels" -msgstr "Abbrechen" +msgid "Channels: %1" +msgstr "Kanäle" + +#: gtk2_ardour/sfdb_ui.cc:148 +#, fuzzy +msgid "Samplerate: %1" +msgstr "Ausgewählten Bereich wiedergeben" -#: sfdb_ui.cc:161 +#: gtk2_ardour/sfdb_ui.cc:151 +#, fuzzy +msgid "Timecode: %1" +msgstr "Timecode" + +#: gtk2_ardour/sfdb_ui.cc:172 #, fuzzy msgid "samplerate" msgstr "Ausgewählten Bereich wiedergeben" -#: sfdb_ui.cc:162 +#: gtk2_ardour/sfdb_ui.cc:173 #, fuzzy msgid "resolution" msgstr "Auswahl wiedergeben" -#: sfdb_ui.cc:162 +#: gtk2_ardour/sfdb_ui.cc:173 #, fuzzy msgid "format" msgstr "Anschluß" -#: sfdb_ui.cc:183 +#: gtk2_ardour/sfdb_ui.cc:194 msgid "Could not read file: %1 (%2)." msgstr "" -#: sfdb_ui.cc:199 +#: gtk2_ardour/sfdb_ui.cc:212 msgid "Could not access soundfile: " msgstr "" -#: sfdb_ui.cc:236 +#: gtk2_ardour/sfdb_ui.cc:260 #, fuzzy msgid "Name for Field" msgstr "Name für Region:" -#: sfdb_ui.cc:335 +#: gtk2_ardour/sfdb_ui.cc:327 +msgid "Add to Region list" +msgstr "Zur Liste der Regionen hinzufügen" + +#: gtk2_ardour/sfdb_ui.cc:328 +msgid "Add to selected Track(s)" +msgstr "Zu ausgewählten Spuren hinzufügen" + +#: gtk2_ardour/sfdb_ui.cc:329 +msgid "Add as new Track(s)" +msgstr "Als neue Spur(en) hinzufügen" + +#: gtk2_ardour/sfdb_ui.cc:330 +msgid "Add as new Tape Track(s)" +msgstr "Als neue Tape-Spuren hinzufügen" + +#: gtk2_ardour/sfdb_ui.cc:372 msgid "Split Channels" -msgstr "" +msgstr "Kanäle aufteilen" -#: sfdb_ui.cc:342 +#: gtk2_ardour/sfdb_ui.cc:379 msgid "Create a region for each channel" -msgstr "" +msgstr "Erstellt aus jedem Kanal eine eigene Region" -#: sfdb_ui.cc:344 +#: gtk2_ardour/sfdb_ui.cc:381 msgid "Embed" -msgstr "" +msgstr "Einbetten" -#: sfdb_ui.cc:346 +#: gtk2_ardour/sfdb_ui.cc:383 msgid "Link to an external file" -msgstr "" +msgstr "Bettet eine externe Datei ein, ohne sie zu ins Verzeichnis der Sitzung zu importieren" -#: sfdb_ui.cc:348 +#: gtk2_ardour/sfdb_ui.cc:387 msgid "Import" msgstr "Importieren" -#: sfdb_ui.cc:350 +#: gtk2_ardour/sfdb_ui.cc:389 msgid "Copy a file to the session folder" -msgstr "" +msgstr "Kopiert eine Datei in das Verzeichnis der Sitzung" -#: sfdb_ui.cc:414 -msgid "programming error: %1" -msgstr "" - -#: tempo_dialog.cc:18 tempo_dialog.cc:35 +#: gtk2_ardour/tempo_dialog.cc:18 +#: gtk2_ardour/tempo_dialog.cc:35 msgid "Beats per minute" msgstr "" -#: tempo_dialog.cc:21 tempo_dialog.cc:38 tempo_dialog.cc:203 -#: tempo_dialog.cc:221 +#: gtk2_ardour/tempo_dialog.cc:21 +#: gtk2_ardour/tempo_dialog.cc:38 +#: gtk2_ardour/tempo_dialog.cc:203 +#: gtk2_ardour/tempo_dialog.cc:221 msgid "Bar" msgstr "" -#: tempo_dialog.cc:22 tempo_dialog.cc:39 tempo_dialog.cc:204 -#: tempo_dialog.cc:222 +#: gtk2_ardour/tempo_dialog.cc:22 +#: gtk2_ardour/tempo_dialog.cc:39 +#: gtk2_ardour/tempo_dialog.cc:204 +#: gtk2_ardour/tempo_dialog.cc:222 msgid "Beat" msgstr "" -#: tempo_dialog.cc:24 tempo_dialog.cc:41 tempo_dialog.cc:205 -#: tempo_dialog.cc:223 +#: gtk2_ardour/tempo_dialog.cc:24 +#: gtk2_ardour/tempo_dialog.cc:41 +#: gtk2_ardour/tempo_dialog.cc:205 +#: gtk2_ardour/tempo_dialog.cc:223 #, fuzzy msgid "Location" msgstr "Stellen" -#: tempo_dialog.cc:199 tempo_dialog.cc:217 +#: gtk2_ardour/tempo_dialog.cc:199 +#: gtk2_ardour/tempo_dialog.cc:217 msgid "Meter denominator" msgstr "" -#: tempo_dialog.cc:200 tempo_dialog.cc:218 +#: gtk2_ardour/tempo_dialog.cc:200 +#: gtk2_ardour/tempo_dialog.cc:218 msgid "Beats per bar" msgstr "" -#: tempo_dialog.cc:236 tempo_dialog.cc:247 +#: gtk2_ardour/tempo_dialog.cc:236 +#: gtk2_ardour/tempo_dialog.cc:247 msgid "whole (1)" msgstr "" -#: tempo_dialog.cc:237 tempo_dialog.cc:249 +#: gtk2_ardour/tempo_dialog.cc:237 +#: gtk2_ardour/tempo_dialog.cc:249 msgid "second (2)" msgstr "" -#: tempo_dialog.cc:238 tempo_dialog.cc:251 +#: gtk2_ardour/tempo_dialog.cc:238 +#: gtk2_ardour/tempo_dialog.cc:251 msgid "third (3)" msgstr "" -#: tempo_dialog.cc:239 tempo_dialog.cc:253 tempo_dialog.cc:261 +#: gtk2_ardour/tempo_dialog.cc:239 +#: gtk2_ardour/tempo_dialog.cc:253 +#: gtk2_ardour/tempo_dialog.cc:261 msgid "quarter (4)" msgstr "" -#: tempo_dialog.cc:240 tempo_dialog.cc:255 +#: gtk2_ardour/tempo_dialog.cc:240 +#: gtk2_ardour/tempo_dialog.cc:255 msgid "eighth (8)" msgstr "" -#: tempo_dialog.cc:241 tempo_dialog.cc:257 +#: gtk2_ardour/tempo_dialog.cc:241 +#: gtk2_ardour/tempo_dialog.cc:257 msgid "sixteenth (16)" msgstr "" -#: tempo_dialog.cc:242 tempo_dialog.cc:259 +#: gtk2_ardour/tempo_dialog.cc:242 +#: gtk2_ardour/tempo_dialog.cc:259 msgid "thirty-second (32)" msgstr "" -#: tempo_dialog.cc:420 +#: gtk2_ardour/tempo_dialog.cc:420 msgid "garbaged note type entry (%1)" msgstr "" -#: tempo_dialog.cc:430 +#: gtk2_ardour/tempo_dialog.cc:430 msgid "incomprehensible note type entry (%1)" msgstr "" -#: time_axis_view.cc:112 +#: gtk2_ardour/time_axis_view.cc:112 msgid "gTortnam" msgstr "" -#: time_axis_view.cc:549 +#: gtk2_ardour/time_axis_view.cc:583 msgid "Largest" -msgstr "" +msgstr "Am größten" -#: time_axis_view.cc:550 -#, fuzzy +#: gtk2_ardour/time_axis_view.cc:584 msgid "Large" -msgstr "Schicht" +msgstr "Groß" -#: time_axis_view.cc:551 -#, fuzzy +#: gtk2_ardour/time_axis_view.cc:585 msgid "Larger" -msgstr "Schicht" +msgstr "Größer" -#: time_axis_view.cc:553 +#: gtk2_ardour/time_axis_view.cc:587 msgid "Smaller" -msgstr "" +msgstr "Kleiner" -#: time_axis_view.cc:554 -#, fuzzy +#: gtk2_ardour/time_axis_view.cc:588 msgid "Small" -msgstr "Alle zeigen" +msgstr "Klein" -#: time_axis_view.cc:870 +#: gtk2_ardour/time_axis_view.cc:902 msgid "unknown track height name \"%1\" in XML GUI information" msgstr "" -#. first constructed item sets up font info -#: time_axis_view_item.cc:79 +#: gtk2_ardour/time_axis_view_item.cc:79 msgid "TimeAxisViewItemName" msgstr "" -#: time_axis_view_item.cc:298 +#: gtk2_ardour/time_axis_view_item.cc:302 msgid "new duration %1 frames is out of bounds for %2" msgstr "" -#: time_selection.cc:41 +#: gtk2_ardour/time_selection.cc:41 msgid "programming error: request for non-existent audio range (%1)!" msgstr "" -#: utils.cc:107 utils.cc:150 +#: gtk2_ardour/utils.cc:106 +#: gtk2_ardour/utils.cc:149 msgid "bad XPM header %1" msgstr "" -#: utils.cc:332 +#: gtk2_ardour/utils.cc:331 msgid "missing RGBA style for \"%1\"" msgstr "" -#: visual_time_axis.cc:276 +#: gtk2_ardour/utils.cc:513 +msgid "cannot find icon image for %1" +msgstr "" + +#: gtk2_ardour/visual_time_axis.cc:281 msgid "" "Do you really want to remove track \"%1\" ?\n" "(cannot be undone)" @@ -6122,368 +6236,107 @@ msgstr "" "Wollen Sie wirklich die Spur \"%1\" löschen?\n" "(Kann nicht rückgängig gemacht werden!)" -#: visual_time_axis.cc:325 +#: gtk2_ardour/visual_time_axis.cc:330 msgid "new name: " msgstr "Neuer Name: " -#: visual_time_axis.cc:336 +#: gtk2_ardour/visual_time_axis.cc:341 msgid "A track already exists with that name" msgstr "" -#, fuzzy -#~ msgid "set selected trackview" -#~ msgstr "Stille einfügen" - -#, fuzzy -#~ msgid "set selected control point" -#~ msgstr "Synchronisationspunkt entfernen" - -#, fuzzy -#~ msgid "set selected regionview" -#~ msgstr "Auswahl zu Schleife machen" - -#, fuzzy -#~ msgid "Start a new session\n" -#~ msgstr "Bitte mittels des \"Sitzung\"-Menüs\n" - -#~ msgid "via Session menu" -#~ msgstr "eine Sitzung laden oder eine neue erstellen!" - -#, fuzzy -#~ msgid "Advanced" -#~ 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) = 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 ZoomChanged; sigc::signal Resized; sigc::signal Realized; + sigc::signal UpdateAllTransportClocks; Glib::RefPtr 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 +#include #include @@ -136,11 +137,12 @@ RedirectBox::RedirectBox (Placement pcmnt, Session& sess, boost::shared_ptrredirects_changed.connect (mem_fun(*this, &RedirectBox::redisplay_redirects)); + _route->GoingAway.connect (mem_fun (*this, &RedirectBox::route_going_away)); redirect_eventbox.signal_enter_notify_event().connect (bind (sigc::ptr_fun (RedirectBox::enter_box), this)); redirect_display.signal_button_press_event().connect (mem_fun(*this, &RedirectBox::redirect_button_press_event), false); - redirect_display.signal_button_release_event().connect (mem_fun(*this, &RedirectBox::redirect_button_press_event)); + redirect_display.signal_button_release_event().connect (mem_fun(*this, &RedirectBox::redirect_button_release_event)); /* start off as a passthru strip. we'll correct this, if necessary, in update_diskstream_display(). @@ -155,6 +157,13 @@ RedirectBox::~RedirectBox () { } +void +RedirectBox::route_going_away () +{ + /* don't keep updating display as redirects are deleted */ + no_redirect_redisplay = true; +} + void RedirectBox::object_drop (string type, uint32_t cnt, const boost::shared_ptr* 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; + 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))); + 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) boost::shared_ptr 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))); uint32_t err_streams; @@ -440,7 +471,7 @@ void RedirectBox::choose_insert () { boost::shared_ptr 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))); _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(send), ios)); + + boost::shared_ptr r = boost::static_pointer_cast(send); + + ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), boost::weak_ptr(r), ios)); } void -RedirectBox::send_io_finished (IOSelector::Result r, boost::shared_ptr redirect, IOSelectorWindow* ios) +RedirectBox::send_io_finished (IOSelector::Result r, boost::weak_ptr weak_redirect, IOSelectorWindow* ios) { + boost::shared_ptr 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) 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_name_connections.push_back (redirect->name_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_name), boost::weak_ptr(redirect)))); } string -RedirectBox::redirect_name (boost::shared_ptr redirect) +RedirectBox::redirect_name (boost::weak_ptr weak_redirect) { + boost::shared_ptr redirect (weak_redirect.lock()); + + if (!redirect) { + return string(); + } + boost::shared_ptr 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) +RedirectBox::show_redirect_name (void* src, boost::weak_ptr 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 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 weak_redirect) +{ + ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_active), weak_redirect)); + + boost::shared_ptr 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 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 >::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) +RedirectBox::idle_delete_redirect (boost::weak_ptr weak_redirect) { + boost::shared_ptr 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) } return; - } void @@ -784,9 +854,12 @@ RedirectBox::cut_redirect (boost::shared_ptr redirect) static_cast(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 >& redir { vector pathlist = redirect_display.get_selection()->get_selected_rows(); - for (vector::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) - redirects.push_back ((*(model->get_iter(*iter)))[columns.redirect]); + for (vector::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) 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 (plugin_insert))); } else { @@ -1240,11 +1314,13 @@ RedirectBox::rb_edit () } void -RedirectBox::route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::shared_ptr pi) +RedirectBox::route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::weak_ptr 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 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, IOSelectorWindow*); + void send_io_finished (IOSelector::Result, boost::weak_ptr, IOSelectorWindow*); void choose_insert (); void choose_plugin (); void insert_plugin_chosen (boost::shared_ptr); @@ -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); void row_deleted (const Gtk::TreeModel::Path& path); - void show_redirect_name (void*, boost::shared_ptr); - - /* these are handlers for Redirect signals, so they take Redirect* - directly, rather than shared_ptr - */ - - void show_redirect_active (ARDOUR::Redirect*, void *); - - string redirect_name (boost::shared_ptr); + void show_redirect_active_r (ARDOUR::Redirect*, void *, boost::weak_ptr); + void show_redirect_active (boost::weak_ptr); + void show_redirect_name (void* src, boost::weak_ptr); + string redirect_name (boost::weak_ptr); void remove_redirect_gui (boost::shared_ptr); @@ -195,7 +193,7 @@ class RedirectBox : public Gtk::HBox void hide_redirect_editor (boost::shared_ptr); void rename_redirect (boost::shared_ptr); - gint idle_delete_redirect (boost::shared_ptr); + gint idle_delete_redirect (boost::weak_ptr); void wierd_plugin_dialog (ARDOUR::Plugin& p, uint32_t streams, boost::shared_ptr 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 pi); + void route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::weak_ptr pi); std::string generate_redirect_title (boost::shared_ptr 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(*(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 newplaylist) { - Playlist *pl = playlist(); + boost::shared_ptr pl = playlist(); assert(pl); modified_connection.disconnect (); @@ -321,7 +319,7 @@ RouteTimeAxisView::playlist_changed () label_view (); if (is_track()) { - set_playlist (dynamic_cast(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 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 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 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 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 RouteTimeAxisView::playlist () const { boost::shared_ptr ds; @@ -1092,7 +1112,7 @@ RouteTimeAxisView::playlist () const if ((ds = get_diskstream()) != 0) { return ds->playlist(); } else { - return 0; + return boost::shared_ptr (); } } @@ -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 RouteTimeAxisView::find_next_region (nframes_t pos, RegionPoint point, int32_t dir) { boost::shared_ptr stream; - Playlist *playlist; + boost::shared_ptr 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 what_we_got; boost::shared_ptr ds = get_diskstream(); - Playlist* playlist; + boost::shared_ptr 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, &before, &playlist->get_state())); + _session.add_command( new MementoCommand(*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, &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 = 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, &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 playlists; + vector > playlists; boost::shared_ptr ds = get_diskstream(); RadioMenuItem::Group playlist_group; _session.get_playlists (playlists); - for (vector::iterator i = playlists.begin(); i != playlists.end(); ++i) { + for (vector >::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 (*i)))); if (ds->playlist()->id() == (*i)->id()) { static_cast(&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(*i)))); + static_cast(&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 wpl) { - AudioPlaylist* apl = dynamic_cast (pl); - assert (is_track()); + boost::shared_ptr pl (wpl.lock()); + + if (!pl) { + return; + } + + boost::shared_ptr apl = boost::dynamic_pointer_cast (pl); + if (apl) { get_diskstream()->use_playlist (apl); } @@ -1533,7 +1564,9 @@ RouteTimeAxisView::add_redirect_automation_curve (boost::shared_ptr 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 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); 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); ArdourCanvas::SimpleRect* timestretch_rect; @@ -241,6 +241,8 @@ protected: vector 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 r) } void -Selection::toggle (Playlist* pl) +Selection::toggle (boost::shared_ptr 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 r) } void -Selection::add (Playlist* pl) +Selection::add (boost::shared_ptr pl) { if (find (playlists.begin(), playlists.end(), pl) == playlists.end()) { - pl->ref (); + pl->use (); playlists.push_back(pl); PlaylistsChanged (); } } void -Selection::add (const list& pllist) +Selection::add (const list >& pllist) { bool changed = false; - for (list::const_iterator i = pllist.begin(); i != pllist.end(); ++i) { + for (list >::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& track_list) } void -Selection::remove (Playlist* track) +Selection::remove (boost::shared_ptr track) { - list::iterator i; + list >::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& pllist) +Selection::remove (const list >& pllist) { bool changed = false; - for (list::const_iterator i = pllist.begin(); i != pllist.end(); ++i) { + for (list >::const_iterator i = pllist.begin(); i != pllist.end(); ++i) { - list::iterator x; + list >::iterator x; if ((x = find (playlists.begin(), playlists.end(), (*i))) != playlists.end()) { playlists.erase (x); @@ -520,14 +520,14 @@ Selection::set (const list& track_list) } void -Selection::set (Playlist* playlist) +Selection::set (boost::shared_ptr playlist) { clear_playlists (); add (playlist); } void -Selection::set (const list& pllist) +Selection::set (const list >& 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&); long set (TimeAxisView*, nframes_t, nframes_t); void set (ARDOUR::AutomationList*); - void set (ARDOUR::Playlist*); - void set (const list&); + void set (boost::shared_ptr); + void set (const list >&); void set (boost::shared_ptr); void set (AutomationSelectable*); @@ -112,8 +112,8 @@ class Selection : public sigc::trackable void toggle (std::vector&); long toggle (nframes_t, nframes_t); void toggle (ARDOUR::AutomationList*); - void toggle (ARDOUR::Playlist*); - void toggle (const list&); + void toggle (boost::shared_ptr); + void toggle (const list >&); void toggle (boost::shared_ptr); void add (TimeAxisView*); @@ -122,8 +122,8 @@ class Selection : public sigc::trackable void add (std::vector&); long add (nframes_t, nframes_t); void add (ARDOUR::AutomationList*); - void add (ARDOUR::Playlist*); - void add (const list&); + void add (boost::shared_ptr); + void add (const list >&); void add (boost::shared_ptr); 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&); + void remove (boost::shared_ptr); + void remove (const list >&); void remove (boost::shared_ptr); 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 #include +#include #include #include #include +#include #include @@ -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(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 tags = Library->get_tags (filename); + + stringstream tag_string; + for (vector::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 field_list; - Library->get_fields(field_list); - - vector::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 (RegionFactory::create (srclist, 0, srclist[0]->length(), rname, 0, Region::DefaultFlags, false)); - res = region_cache.insert (newpair); the_region = res.first; } @@ -252,56 +238,21 @@ SoundFileBox::stop_btn_clicked () } void -SoundFileBox::add_field_clicked () -{ - ArdourPrompter prompter (true); - string name; - - prompter.set_prompt (_("Name for Field")); - prompter.add_button (Gtk::Stock::ADD, Gtk::RESPONSE_ACCEPT); - prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); - - switch (prompter.run ()) { - case Gtk::RESPONSE_ACCEPT: - prompter.get_result (name); - if (name.length()) { - Library->add_field (name); - Library->save_changes (); - } - break; - - default: - break; - } -} - -void -SoundFileBox::remove_field_clicked () +SoundFileBox::apply_btn_clicked () { - field_view.get_selection()->selected_foreach_iter(mem_fun(*this, &SoundFileBox::delete_row)); + string tag_string = tags_entry.get_text (); - Library->save_changes (); -} + vector tags; -void -SoundFileBox::field_edited (const Glib::ustring& str1, const Glib::ustring& str2) -{ - Gtk::TreeModel::Children rows(fields->children()); - Gtk::TreeModel::Row row(rows[atoi(str1.c_str())]); - - Library->set_field (path, row[label_columns.field], str2); + if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) { + warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg; + return; + } + Library->set_tags (path, tags); Library->save_changes (); } -void -SoundFileBox::delete_row (const Gtk::TreeModel::iterator& iter) -{ - Gtk::TreeModel::Row row = *iter; - - Library->remove_field(row[label_columns.field]); -} - void SoundFileBox::audition_status_changed (bool active) { @@ -312,16 +263,6 @@ SoundFileBox::audition_status_changed (bool active) } } -void -SoundFileBox::field_selected () -{ - if (field_view.get_selection()->count_selected_rows()) { - remove_field_btn.set_sensitive(true); - } else { - remove_field_btn.set_sensitive(false); - } -} - // this needs to be kept in sync with the ImportMode enum defined in editing.h and editing_syms.h. static const char *import_mode_strings[] = { N_("Add to Region list"), @@ -333,14 +274,41 @@ static const char *import_mode_strings[] = { SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s) : ArdourDialog (title, false), - chooser (Gtk::FILE_CHOOSER_ACTION_OPEN) + chooser (Gtk::FILE_CHOOSER_ACTION_OPEN), + found_list (Gtk::ListStore::create(found_list_columns)), + found_list_view (found_list), + found_search_btn (_("Search")) { - get_vbox()->pack_start(chooser); - chooser.set_preview_widget(preview); - chooser.set_select_multiple (true); + set_default_size (700, 500); + Gtk::HBox* hbox = manage(new Gtk::HBox); + hbox->pack_start(notebook); + hbox->pack_start(preview, Gtk::PACK_SHRINK); + get_vbox()->pack_start(*hbox); + + hbox = manage(new Gtk::HBox); + hbox->pack_start (found_entry); + hbox->pack_start (found_search_btn); + + Gtk::VBox* vbox = manage(new Gtk::VBox); + vbox->pack_start (*hbox, Gtk::PACK_SHRINK); + vbox->pack_start (found_list_view); + found_list_view.append_column(_("Paths"), found_list_columns.pathname); + + notebook.append_page (chooser, _("Files")); + notebook.append_page (*vbox, _("Tags")); + + found_list_view.get_selection()->set_mode (Gtk::SELECTION_MULTIPLE); + filter.add_custom (Gtk::FILE_FILTER_FILENAME, mem_fun(*this, &SoundFileBrowser::on_custom)); + chooser.set_filter (filter); + chooser.set_select_multiple (true); chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview)); + found_list_view.get_selection()->signal_changed().connect(mem_fun(*this, &SoundFileBrowser::found_list_view_selected)); + + found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked)); + show_all (); + set_session (s); } @@ -350,10 +318,54 @@ SoundFileBrowser::set_session (Session* s) preview.set_session(s); } +bool +SoundFileBrowser::on_custom (const Gtk::FileFilter::Info& filter_info) +{ + return AudioFileSource::safe_file_extension(filter_info.filename); +} + void SoundFileBrowser::update_preview () { - chooser.set_preview_widget_active(preview.setup_labels(chooser.get_filename())); + preview.setup_labels(chooser.get_filename()); +} + +void +SoundFileBrowser::found_list_view_selected () +{ + string file; + + Gtk::TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows (); + + if (!rows.empty()) { + Gtk::TreeIter iter = found_list->get_iter(*rows.begin()); + file = (*iter)[found_list_columns.pathname]; + chooser.set_filename (file); + } + preview.setup_labels (file); +} + +void +SoundFileBrowser::found_search_clicked () +{ + string tag_string = found_entry.get_text (); + + vector tags; + + if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) { + warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg; + return; + } + + vector results; + Library->search_members_and (results, tags); + + found_list->clear(); + for (vector::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 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 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 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 #include #include +#include #include #include #include -#include #include #include -#include -#include #include #include @@ -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 field; - Gtk::TreeModelColumn 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 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 pathname; + + FoundTagColumns() { add(pathname); } + }; + + FoundTagColumns found_list_columns; + Glib::RefPtr 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 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 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 mode_strings; + Gtk::CheckButton split_check; + Gtk::ComboBoxText mode_combo; + + void mode_changed (); + + static std::vector 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::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::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 #include +#include + #include #include @@ -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 playlist() const { return boost::shared_ptr (); } 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 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(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(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& 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 get_icon (const char*); static std::map > xpm_map; const char* const *get_xpm_data (std::string path); std::string longest (std::vector&); +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 WaveView::property_region_start() const { return Glib::PropertyProxy_ReadOnly (this, "region_start"); } +Glib::PropertyProxy WaveView::property_logscaled() +{ + return Glib::PropertyProxy (this, "logscaled"); +} +Glib::PropertyProxy_ReadOnly WaveView::property_logscaled() const +{ + return Glib::PropertyProxy_ReadOnly (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 property_rectified() const; Glib::PropertyProxy property_region_start(); Glib::PropertyProxy_ReadOnly property_region_start() const; + Glib::PropertyProxy property_logscaled(); + Glib::PropertyProxy_ReadOnly 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 +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(_playlist); } + boost::shared_ptr audio_playlist () { return boost::dynamic_pointer_cast(_playlist); } - int use_playlist (Playlist *); + int use_playlist (boost::shared_ptr); 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 fades_source; - boost::shared_ptr write_source; - - Port *source; - Sample *current_capture_buffer; - Sample *current_playback_buffer; + ChannelInfo (); + ~ChannelInfo (); - RingBufferNPT *playback_buf; - RingBufferNPT *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::rw_vector playback_vector; - RingBufferNPT::rw_vector capture_vector; - - RingBufferNPT * 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 fades_source; + boost::shared_ptr write_source; + + Port *source; + Sample *current_capture_buffer; + Sample *current_playback_buffer; + + RingBufferNPT *playback_buf; + RingBufferNPT *capture_buf; + + Sample* scrub_buffer; + Sample* scrub_forward_buffer; + Sample* scrub_reverse_buffer; + + RingBufferNPT::rw_vector playback_vector; + RingBufferNPT::rw_vector capture_vector; + + RingBufferNPT * 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 #include -#include - -#include - 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 paths); - vector get_paths (); - void scan_paths (); - - void add_member (string member); - void remove_member (string uri); + void set_tags (string member, vector tags); + vector get_tags (string member); - void search_members_and (vector& results, - const map& fields); - void search_members_or (vector& results, - const map& fields); - - void add_field (string field); - void get_fields (vector& 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& results, const vector tags); void save_changes(); - - sigc::signal fields_changed; private: - vector 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& 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, string name, bool hidden = false); + AudioPlaylist (boost::shared_ptr, 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, bool norefresh); void remove_dependents (boost::shared_ptr 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 > pending_peak_sources; static Glib::Mutex* pending_peak_sources_lock; - static void queue_for_peaks (boost::shared_ptr); + static void queue_for_peaks (boost::shared_ptr, 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, boost::shared_ptr); /* 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 #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 () { return _playlist; } - virtual int use_playlist (Playlist *); + virtual int use_playlist (boost::shared_ptr); 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); 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; 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 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 _peak_power; std::vector _visible_peak_power; + std::vector _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(_playlist); } + boost::shared_ptr midi_playlist () { return boost::dynamic_pointer_cast(_playlist); } - int use_playlist (Playlist *); + int use_playlist (boost::shared_ptr); 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 other, string name, bool hidden = false); + MidiPlaylist (boost::shared_ptr 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); void remove_dependents (boost::shared_ptr 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 #include +#include #include @@ -35,12 +36,12 @@ class Playlist; struct NamedSelection : public Stateful { - NamedSelection (std::string, std::list&); + NamedSelection (std::string, std::list >&); NamedSelection (Session&, const XMLNode&); virtual ~NamedSelection (); std::string name; - std::list playlists; + std::list > 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 #include #include +#include #include @@ -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 { public: typedef list > 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, string name, bool hidden = false); + Playlist (boost::shared_ptr, 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, nframes_t position, float times); void nudge_after (nframes_t start, nframes_t distance, bool forwards); - Playlist* cut (list&, bool result_is_hidden = true); - Playlist* copy (list&, bool result_is_hidden = true); - int paste (Playlist&, nframes_t position, float times); + boost::shared_ptr cut (list&, bool result_is_hidden = true); + boost::shared_ptr copy (list&, bool result_is_hidden = true); + int paste (boost::shared_ptr, 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 InUse; - sigc::signal Modified; - sigc::signal NameChanged; - sigc::signal LengthChanged; - sigc::signal LayeringChanged; - sigc::signal StatePushed; - - static sigc::signal PlaylistCreated; + sigc::signal InUse; + sigc::signal Modified; + sigc::signal NameChanged; + sigc::signal LengthChanged; + sigc::signal 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_by_id (PBD::ID); - void add_region_internal (boost::shared_ptr, nframes_t position, bool delay_sort = false); - - int remove_region_internal (boost::shared_ptr, bool delay_sort = false); + void add_region_internal (boost::shared_ptr, nframes_t position); + + int remove_region_internal (boost::shared_ptr); 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& 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 cut_copy (boost::shared_ptr (Playlist::*pmf)(nframes_t, nframes_t, bool), + list& ranges, bool result_is_hidden); + boost::shared_ptr cut (nframes_t start, nframes_t cnt, bool result_is_hidden); + boost::shared_ptr copy (nframes_t start, nframes_t cnt, bool result_is_hidden); int move_region_to_layer (layer_t, boost::shared_ptr 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 + +class XMLNode; + +namespace ARDOUR { + +class Session; + +class PlaylistFactory { + + public: + static sigc::signal > PlaylistCreated; + + static boost::shared_ptr create (Session&, const XMLNode&, bool hidden = false); + static boost::shared_ptr create (DataType type, Session&, string name, bool hidden = false); + static boost::shared_ptr create (boost::shared_ptr, string name, bool hidden = false); + static boost::shared_ptr create (boost::shared_ptr, 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 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 playlist() const { return _playlist.lock(); } + virtual void set_playlist (boost::weak_ptr); void source_deleted (boost::shared_ptr); @@ -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 _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 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 #include +#include #include @@ -117,9 +118,9 @@ using std::set; class Session : public PBD::StatefulDestructible { private: - typedef std::pair,bool> RouteBooleanState; + typedef std::pair,bool> RouteBooleanState; typedef vector GlobalRouteBooleanState; - typedef std::pair,MeterPoint> RouteMeterState; + typedef std::pair,MeterPoint> RouteMeterState; typedef vector 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 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 paths; /* result */ std::vector > new_regions; @@ -602,7 +594,6 @@ class Session : public PBD::StatefulDestructible void add_source (boost::shared_ptr); void remove_source (boost::weak_ptr); - int cleanup_audio_file_source (boost::shared_ptr); struct cleanup_report { vector paths; @@ -622,8 +613,7 @@ class Session : public PBD::StatefulDestructible this playlist. */ - sigc::signal AskAboutPlaylistDeletion; - + sigc::signal > 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 AskAboutPendingState; - sigc::signal > SourceAdded; - sigc::signal > SourceRemoved; - boost::shared_ptr create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive); boost::shared_ptr 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 PlaylistAdded; - sigc::signal PlaylistRemoved; + boost::shared_ptr playlist_by_name (string name); + void add_playlist (boost::shared_ptr); + sigc::signal > PlaylistAdded; + sigc::signal > PlaylistRemoved; uint32_t n_playlists() const; - template void foreach_playlist (T *obj, void (T::*func)(Playlist *)); - void get_playlists (std::vector&); + template void foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr)); + void get_playlists (std::vector >&); /* 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 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 PlaylistList; + typedef set > 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); + void track_playlist (bool, boost::weak_ptr); - Playlist *playlist_factory (string name); - Playlist *XMLPlaylistFactory (const XMLNode&); + boost::shared_ptr playlist_factory (string name); + boost::shared_ptr XMLPlaylistFactory (const XMLNode&); - void playlist_length_changed (Playlist *); + void playlist_length_changed (); void diskstream_playlist_changed (boost::shared_ptr); /* NAMED SELECTIONS */ @@ -1522,9 +1528,12 @@ class Session : public PBD::StatefulDestructible list _port_inserts; list _plugin_inserts; list _sends; + boost::dynamic_bitset send_bitset; + boost::dynamic_bitset 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 void -Session::foreach_playlist (T *obj, void (T::*func)(Playlist *)) +Session::foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr)) { 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); + void remove_playlist (boost::weak_ptr); uint32_t used() const; @@ -83,7 +83,7 @@ class Source : public PBD::StatefulDestructible time_t _timestamp; jack_nframes_t _length; - std::set _playlists; + std::set > _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; vector 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 #include #include +#include #include #include @@ -46,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -95,34 +97,6 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node) } } -void -AudioDiskstream::init_channel (ChannelInfo &chan) -{ - chan.playback_wrap_buffer = 0; - chan.capture_wrap_buffer = 0; - chan.speed_buffer = 0; - chan.peak_power = 0.0f; - chan.source = 0; - chan.current_capture_buffer = 0; - chan.current_playback_buffer = 0; - chan.curr_capture_cnt = 0; - - chan.playback_buf = new RingBufferNPT (_session.diskstream_buffer_size()); - chan.capture_buf = new RingBufferNPT (_session.diskstream_buffer_size()); - chan.capture_transition_buf = new RingBufferNPT (128); - - - /* touch the ringbuffer buffers, which will cause - them to be mapped into locked physical RAM if - we're running with mlockall(). this doesn't do - much if we're not. - */ - memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize()); - memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize()); - memset (chan.capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * chan.capture_transition_buf->bufsize()); -} - - void AudioDiskstream::init (Diskstream::Flag f) { @@ -140,40 +114,21 @@ AudioDiskstream::init (Diskstream::Flag f) assert(_n_channels == ChanCount(DataType::AUDIO, 1)); } -void -AudioDiskstream::destroy_channel (ChannelInfo &chan) -{ - if (chan.write_source) { - chan.write_source.reset (); - } - - if (chan.speed_buffer) { - delete [] chan.speed_buffer; - } - - if (chan.playback_wrap_buffer) { - delete [] chan.playback_wrap_buffer; - } - if (chan.capture_wrap_buffer) { - delete [] chan.capture_wrap_buffer; - } - - delete chan.playback_buf; - delete chan.capture_buf; - delete chan.capture_transition_buf; - - chan.playback_buf = 0; - chan.capture_buf = 0; -} - AudioDiskstream::~AudioDiskstream () { - Glib::Mutex::Lock lm (state_lock); + notify_callbacks (); - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) - destroy_channel((*chan)); - - channels.clear(); + { + /* don't be holding this lock as we exit the destructor, glib will wince + visibly since the mutex gets destroyed before we release it. + */ + + Glib::Mutex::Lock lm (state_lock); + for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { + (*chan).release (); + } + channels.clear(); + } } void @@ -288,15 +243,13 @@ AudioDiskstream::get_input_sources () int AudioDiskstream::find_and_use_playlist (const string& name) { - Playlist* pl; - AudioPlaylist* playlist; + boost::shared_ptr playlist; - if ((pl = _session.playlist_by_name (name)) == 0) { - playlist = new AudioPlaylist(_session, name); - pl = playlist; + if ((playlist = boost::dynamic_pointer_cast (_session.playlist_by_name (name))) == 0) { + playlist = boost::dynamic_pointer_cast (PlaylistFactory::create (_session, name)); } - if ((playlist = dynamic_cast (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) { - assert(dynamic_cast(playlist)); + assert(boost::dynamic_pointer_cast(playlist)); Diskstream::use_playlist(playlist); @@ -318,7 +271,7 @@ int AudioDiskstream::use_new_playlist () { string newname; - AudioPlaylist* playlist; + boost::shared_ptr 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 (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 playlist; newname = Playlist::bump_name (_playlist->name(), _session); - if ((playlist = new AudioPlaylist (*audio_playlist(), newname)) != 0) { + if ((playlist = boost::dynamic_pointer_cast(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 (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 (RegionFactory::create (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()))); + region = boost::dynamic_pointer_cast (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 (bufsize); + capture_buf = new RingBufferNPT (bufsize); + capture_transition_buf = new RingBufferNPT (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 // Needed so that libraptor (included in lrdf) won't complain -#include -#include #include -#include -#include -#include -#include +#include #include #include -#include -#include #include #include @@ -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,80 +44,103 @@ AudioLibrary::AudioLibrary () touch_file(get_user_ardour_path() + "sfdb"); lrdf_read_file(src.c_str()); - - lrdf_statement pattern; - - pattern.subject = SOUNDFILE; - pattern.predicate = RDF_TYPE; - pattern.object = RDFS_CLASS; - pattern.object_type = lrdf_uri; - - lrdf_statement* matches = lrdf_matches(&pattern); - - // if empty DB, create basic schema - if (matches == 0) { - initialize_db (); - save_changes(); - } - - lrdf_free_statements(matches); } AudioLibrary::~AudioLibrary () { } -void -AudioLibrary::initialize_db () -{ - // define ardour:Soundfile - lrdf_add_triple(src.c_str(), SOUNDFILE, RDF_TYPE, RDFS_CLASS, lrdf_uri); - - // add intergral fields - add_field(_("channels")); - add_field(_("samplerate")); - add_field(_("resolution")); - add_field(_("format")); -} - void AudioLibrary::save_changes () { if (lrdf_export_by_source(src.c_str(), src.substr(5).c_str())) { - warning << string_compose(_("Could not open %1. Audio Library not saved"), src) << endmsg; + PBD::warning << string_compose(_("Could not open %1. Audio Library not saved"), src) << endmsg; } } -void -AudioLibrary::add_member (string member) +string +AudioLibrary::path2uri (string path) { - string file_uri(string_compose("file:%1", member)); + xmlURI temp; + memset(&temp, 0, sizeof(temp)); + + xmlChar *cal = xmlCanonicPath((xmlChar*) path.c_str()); + temp.path = (char *) cal; + xmlChar *ret = xmlSaveUri(&temp); + xmlFree(cal); + + stringstream uri; + uri << "file:" << (const char*) ret; + + xmlFree (ret); + + return uri.str(); +} - lrdf_add_triple(src.c_str(), file_uri.c_str(), RDF_TYPE, - SOUNDFILE, lrdf_uri); +string +AudioLibrary::uri2path (string uri) +{ + string path = xmlURIUnescapeString(uri.c_str(), 0, 0); + return path.substr(5); } void -AudioLibrary::remove_member (string uri) +AudioLibrary::set_tags (string member, vector 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::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 +AudioLibrary::get_tags (string member) { - lrdf_remove_uri_matches (uri.c_str()); + vector 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& members, - const map& fields) +AudioLibrary::search_members_and (vector& members, const vector tags) { lrdf_statement **head; lrdf_statement* pattern = 0; lrdf_statement* old = 0; head = &pattern; - map::const_iterator i; - for (i = fields.begin(); i != fields.end(); ++i){ + vector::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& 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& members, - const map& fields) -{ - map::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& 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& vec) -{ - sort(vec.begin(), vec.end()); - unique(vec.begin(), vec.end()); -} - -void -AudioLibrary::set_paths (vector paths) -{ - sfdb_paths = paths; - - scan_paths (); -} - -vector -AudioLibrary::get_paths () -{ - return sfdb_paths; -} - -void -AudioLibrary::scan_paths () -{ - if (sfdb_paths.size() < 1) { - return; - } - - vector 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::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 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 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 ar = boost::dynamic_pointer_cast(*in_o); // We look only for crossfades which begin with the current region, so we don't get doubles - for (list::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) { + for (list::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_ptrar2 = boost::dynamic_pointer_cast(*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 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 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) x = xtmp; } - region->set_playlist (0); + region->set_playlist (boost::shared_ptr()); } 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 + #include #include #include +#include +#include + #include #include #include @@ -32,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -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::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 pl = _session.playlist_by_name (prop->value()); if (pl) { - _freeze_record.playlist = dynamic_cast (pl); + _freeze_record.playlist = boost::dynamic_pointer_cast (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(diskstream->playlist()); + boost::shared_ptr apl = boost::dynamic_pointer_cast(diskstream->playlist()); assert(apl); if (apl->read (buffers.get_audio(nframes).data(nframes), @@ -777,12 +768,12 @@ AudioTrack::freeze (InterThreadInfo& itt) { vector > srcs; string new_playlist_name; - Playlist* new_playlist; + boost::shared_ptr new_playlist; string dir; string region_name; boost::shared_ptr diskstream = audio_diskstream(); - if ((_freeze_record.playlist = dynamic_cast(diskstream->playlist())) == 0) { + if ((_freeze_record.playlist = boost::dynamic_pointer_cast(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(new_playlist)); + diskstream->use_playlist (boost::dynamic_pointer_cast(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(arg)->Xrun (); /* EMIT SIGNAL */ + AudioEngine* ae = static_cast (arg); + if (ae->jack()) { + ae->Xrun (); /* EMIT SIGNAL */ + } return 0; } int AudioEngine::_graph_order_callback (void *arg) { - static_cast(arg)->GraphReordered (); /* EMIT SIGNAL */ + AudioEngine* ae = static_cast (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 (arg); + AudioEngine* ae = static_cast (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 #include #include +#include #include #include #include #include #include +#include #include @@ -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 #include #include +#include #include #include @@ -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 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 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 #include +#include #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 source) +AudioSource::queue_for_peaks (boost::shared_ptr 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 #include +#include #include #include #include @@ -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(_diskstream->playlist()); + boost::shared_ptr apl = boost::dynamic_pointer_cast(_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 #include #include -#include +#include #include "i18n.h" @@ -37,6 +37,11 @@ using namespace PBD; sigc::signal AutomationList::AutomationListCreated; +static bool sort_events_by_time (ControlEvent* a, ControlEvent* b) +{ + return a->when < b->when; +} + #if 0 static void dumpit (const AutomationList& al, string prefix = "") { @@ -50,7 +55,7 @@ static void dumpit (const AutomationList& al, string prefix = "") AutomationList::AutomationList (double defval) { - _frozen = false; + _frozen = 0; changed_when_thawed = false; _state = Off; _style = Absolute; @@ -63,13 +68,14 @@ AutomationList::AutomationList (double defval) rt_insertion_point = events.end(); lookup_cache.left = -1; lookup_cache.range.first = events.end(); + sort_pending = false; AutomationListCreated(this); } AutomationList::AutomationList (const AutomationList& other) { - _frozen = false; + _frozen = 0; changed_when_thawed = false; _style = other._style; min_yval = other.min_yval; @@ -82,6 +88,7 @@ AutomationList::AutomationList (const AutomationList& other) rt_insertion_point = events.end(); lookup_cache.left = -1; lookup_cache.range.first = events.end(); + sort_pending = false; for (const_iterator i = other.events.begin(); i != other.events.end(); ++i) { /* we have to use other point_factory() because @@ -96,7 +103,7 @@ AutomationList::AutomationList (const AutomationList& other) AutomationList::AutomationList (const AutomationList& other, double start, double end) { - _frozen = false; + _frozen = 0; changed_when_thawed = false; _style = other._style; min_yval = other.min_yval; @@ -109,6 +116,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl rt_insertion_point = events.end(); lookup_cache.left = -1; lookup_cache.range.first = events.end(); + sort_pending = false; /* now grab the relevant points, and shift them back if necessary */ @@ -129,7 +137,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl AutomationList::AutomationList (const XMLNode& node) { - _frozen = false; + _frozen = 0; changed_when_thawed = false; _touching = false; min_yval = FLT_MIN; @@ -141,6 +149,7 @@ AutomationList::AutomationList (const XMLNode& node) rt_insertion_point = events.end(); lookup_cache.left = -1; lookup_cache.range.first = events.end(); + sort_pending = false; set_state (node); @@ -402,7 +411,7 @@ AutomationList::add (double when, double value) } if (insert) { - + events.insert (insertion_point, point_factory (when, value)); reposition_for_rt_add (0); @@ -512,15 +521,43 @@ AutomationList::move_range (iterator start, iterator end, double xdelta, double while (start != end) { (*start)->when += xdelta; (*start)->value += ydelta; + if (isnan ((*start)->value)) { + abort (); + } ++start; } + if (!_frozen) { + events.sort (sort_events_by_time); + } else { + sort_pending = true; + } + mark_dirty (); } maybe_signal_changed (); } +void +AutomationList::slide (iterator before, double distance) +{ + { + Glib::Mutex::Lock lm (lock); + + if (before == events.end()) { + return; + } + + while (before != events.end()) { + (*before)->when += distance; + ++before; + } + } + + maybe_signal_changed (); +} + void AutomationList::modify (iterator iter, double when, double val) { @@ -531,11 +568,23 @@ AutomationList::modify (iterator iter, double when, double val) { Glib::Mutex::Lock lm (lock); + (*iter)->when = when; (*iter)->value = val; + + if (isnan (val)) { + abort (); + } + + if (!_frozen) { + events.sort (sort_events_by_time); + } else { + sort_pending = true; + } + mark_dirty (); } - + maybe_signal_changed (); } @@ -576,13 +625,31 @@ AutomationList::control_points_adjacent (double xval) void AutomationList::freeze () { - _frozen = true; + _frozen++; } void AutomationList::thaw () { - _frozen = false; + if (_frozen == 0) { + PBD::stacktrace (cerr); + fatal << string_compose (_("programming error: %1"), X_("AutomationList::thaw() called while not frozen")) << endmsg; + /*NOTREACHED*/ + } + + if (--_frozen > 0) { + return; + } + + { + Glib::Mutex::Lock lm (lock); + + if (sort_pending) { + events.sort (sort_events_by_time); + sort_pending = false; + } + } + if (changed_when_thawed) { StateChanged(); /* EMIT SIGNAL */ } @@ -1240,6 +1307,7 @@ AutomationList::deserialize_events (const XMLNode& node) } thaw (); + return 0; } @@ -1271,6 +1339,7 @@ AutomationList::set_state (const XMLNode& node) jack_nframes_t x; double y; + freeze (); clear (); for (i = elist.begin(); i != elist.end(); ++i) { @@ -1287,9 +1356,11 @@ AutomationList::set_state (const XMLNode& node) } y = atof (prop->value().c_str()); - add (x, y); + fast_simple_add (x, y); } + thaw (); + return 0; } @@ -1345,7 +1416,7 @@ AutomationList::set_state (const XMLNode& node) deserialize_events (*(*niter)); } } - + return 0; } 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 #include -#include #include #include #include @@ -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 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) { { 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))); } - 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 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 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace PBD; +using namespace ARDOUR; + +void +setup_enum_writer () +{ + EnumWriter* enum_writer = new EnumWriter(); + vector i; + vector 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 (o, var); } std::istream& operator>>(std::istream& o, ShuttleBehaviour& var) { return int_to_type (o, var); } std::istream& operator>>(std::istream& o, ShuttleUnits& var) { return int_to_type (o, var); } +std::istream& operator>>(std::istream& o, SmpteFormat& var) { return int_to_type (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 r (boost::dynamic_pointer_cast (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 r (boost::dynamic_pointer_cast + (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 (RegionFactory::create (boost::static_pointer_cast (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 #include +#include #include #include @@ -35,6 +36,8 @@ #include "i18n.h" +#define SUFFIX_MAX 32 + using namespace std; using namespace ARDOUR; using namespace sigc; @@ -217,12 +220,12 @@ Location::set_flag_internal (bool yn, Flags flag) { if (yn) { if (!(_flags & flag)) { - _flags |= flag; + _flags = Flags (_flags | flag); return true; } } else { if (_flags & flag) { - _flags &= ~flag; + _flags = Flags (_flags & ~flag); return true; } } @@ -273,8 +276,7 @@ Location::get_state (void) node->add_property ("start", buf); snprintf (buf, sizeof (buf), "%u", end()); node->add_property ("end", buf); - snprintf (buf, sizeof (buf), "%" PRIu32, (uint32_t) _flags); - node->add_property ("flags", buf); + node->add_property ("flags", enum_2_string (_flags)); return *node; } @@ -327,14 +329,12 @@ Location::set_state (const XMLNode& node) _end = atoi (prop->value().c_str()); - _flags = 0; - if ((prop = node.property ("flags")) == 0) { error << _("XML node for Location has no flags information") << endmsg; return -1; } - _flags = Flags (atoi (prop->value().c_str())); + _flags = Flags (string_2_enum (prop->value(), _flags)); for (cd_iter = cd_list.begin(); cd_iter != cd_list.end(); ++cd_iter) { @@ -403,6 +403,40 @@ Locations::set_current (Location *loc, bool want_lock) return ret; } +int +Locations::next_available_name(string& result,string base) +{ + LocationList::iterator i; + Location* location; + string temp; + string::size_type l; + int suffix; + char buf[32]; + bool available[SUFFIX_MAX+1]; + + result = base; + for (int k=1; kname(); + 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) { 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 @@ -56,6 +56,14 @@ PeakMeter::reset () } } +void +PeakMeter::reset_max () +{ + for (size_t i = 0; i < _max_peak_power.size(); ++i) { + _max_peak_power[i] = -INFINITY; + } +} + void PeakMeter::setup (const ChanCount& in) { @@ -68,11 +76,13 @@ PeakMeter::setup (const ChanCount& in) while (_peak_power.size() < limit) { _peak_power.push_back (0); - _visible_peak_power.push_back (0); + _visible_peak_power.push_back (minus_infinity()); + _max_peak_power.push_back (minus_infinity()); } assert(_peak_power.size() == limit); assert(_visible_peak_power.size() == limit); + assert(_max_peak_power.size() == limit); } /** To be driven by the Meter signal from IO. @@ -102,6 +112,10 @@ PeakMeter::meter () new_peak = minus_infinity(); } + /* update max peak */ + + _max_peak_power[n] = std::max (new_peak, _max_peak_power[n]); + if (Config->get_meter_falloff() == 0.0f || new_peak > _visible_peak_power[n]) { _visible_peak_power[n] = new_peak; } else { 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 @@ -36,6 +34,7 @@ #include #include #include +#include #include #include @@ -47,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -220,16 +220,14 @@ MidiDiskstream::get_input_sources () int MidiDiskstream::find_and_use_playlist (const string& name) { - Playlist* pl; - MidiPlaylist* playlist; + boost::shared_ptr playlist; - if ((pl = _session.playlist_by_name (name)) == 0) { - playlist = new MidiPlaylist(_session, name); - pl = playlist; + if ((playlist = boost::dynamic_pointer_cast (_session.playlist_by_name (name))) == 0) { + playlist = boost::dynamic_pointer_cast (PlaylistFactory::create (_session, name)); } - if ((playlist = dynamic_cast (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(playlist)); +MidiDiskstream::use_playlist (boost::shared_ptr playlist) +{ + assert(boost::dynamic_pointer_cast(playlist)); - return Diskstream::use_playlist(playlist); + Diskstream::use_playlist(playlist); + + return 0; } int MidiDiskstream::use_new_playlist () -{ +{ string newname; - MidiPlaylist* playlist; + boost::shared_ptr 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 (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 playlist; newname = Playlist::bump_name (_playlist->name(), _session); - if ((playlist = new MidiPlaylist (*midi_playlist(), newname)) != 0) { + if ((playlist = boost::dynamic_pointer_cast(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 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 (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 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 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 pl = _session.playlist_by_name (prop->value()); if (pl) { - _freeze_record.playlist = dynamic_cast (pl); + _freeze_record.playlist = boost::dynamic_pointer_cast (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 NamedSelection::NamedSelectionCreated; -NamedSelection::NamedSelection (string n, list& l) +typedef std::list > PlaylistList; + +NamedSelection::NamedSelection (string n, PlaylistList& l) : name (n) { playlists = l; - for (list::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; 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::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::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 #include #include +#include #include #include @@ -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 #include #include +#include #include "i18n.h" @@ -43,14 +44,12 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -sigc::signal Playlist::PlaylistCreated; - struct ShowMeTheList { - ShowMeTheList (Playlist *pl, const string& n) : playlist (pl), name (n) {} + ShowMeTheList (boost::shared_ptr pl, const string& n) : playlist (pl), name (n) {} ~ShowMeTheList () { cerr << ">>>>" << name << endl; playlist->dump(); cerr << "<<<<" << name << endl << endl; }; - Playlist *playlist; + boost::shared_ptr 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 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 >::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 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 (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; boost::shared_ptr 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 >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) { - (*i)->set_playlist (0); + (*i)->set_playlist (boost::shared_ptr()); } } @@ -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, 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, nframes_t position, floa for (int i = 0; i < itimes; ++i) { boost::shared_ptr 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, nframes_t position, floa string name; _session.region_name (name, region->name(), false); boost::shared_ptr 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 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, nframes_t position, bool delay_sort) +Playlist::add_region_internal (boost::shared_ptr region, nframes_t position) { RegionSortByPosition cmp; nframes_t old_length = 0; @@ -511,7 +517,11 @@ Playlist::add_region_internal (boost::shared_ptr region, nframes_t posit old_length = _get_maximum_extent(); } - region->set_playlist (this); + if (!in_set_state) { + boost::shared_ptr foo (shared_from_this()); + region->set_playlist (boost::weak_ptr(foo)); + } + region->set_position (position, this); timestamp_layer_op (region); @@ -564,7 +574,7 @@ Playlist::remove_region (boost::shared_ptr region) } int -Playlist::remove_region_internal (boost::shared_ptrregion, bool delay_sort) +Playlist::remove_region_internal (boost::shared_ptrregion) { 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& ranges, bool result_is_hidden) +boost::shared_ptr +Playlist::cut_copy (boost::shared_ptr (Playlist::*pmf)(nframes_t, nframes_t,bool), list& ranges, bool result_is_hidden) { - Playlist* ret; - Playlist* pl; + boost::shared_ptr ret; + boost::shared_ptr pl; nframes_t start; if (ranges.empty()) { - return 0; + return boost::shared_ptr(); } start = ranges.front().start; - for (list::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::cut (list& ranges, bool result_is_hidden) { - Playlist* (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::cut; + boost::shared_ptr (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::cut; return cut_copy (pmf, ranges, result_is_hidden); } -Playlist* +boost::shared_ptr Playlist::copy (list& ranges, bool result_is_hidden) { - Playlist* (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::copy; + boost::shared_ptr (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::copy; return cut_copy (pmf, ranges, result_is_hidden); } -Playlist * +boost::shared_ptr Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden) { - Playlist *the_copy; + boost::shared_ptr 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(); } 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::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 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 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, nframes_t position, float while (itimes--) { boost::shared_ptr 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, nframes_t position, float string name; _session.region_name (name, region->name(), false); boost::shared_ptr 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, 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, 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 } 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 } 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 #include +#include +#include #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 > PlaylistFactory::PlaylistCreated; + +boost::shared_ptr +PlaylistFactory::create (Session& s, const XMLNode& node, bool hidden) +{ + const XMLProperty* type = node.property("type"); + + boost::shared_ptr pl; + + if ( !type || type->value() == "audio" ) + pl = boost::shared_ptr (new AudioPlaylist (s, node, hidden)); + else if ( type->value() == "midi" ) + pl = boost::shared_ptr (new MidiPlaylist (s, node, hidden)); + + pl->set_region_ownership (); + + if (pl && !hidden) { + PlaylistCreated (pl); + } + return pl; +} + +boost::shared_ptr +PlaylistFactory::create (DataType type, Session& s, string name, bool hidden) +{ + boost::shared_ptr pl; + + if (type == DataType::AUDIO) + pl = boost::shared_ptr (new AudioPlaylist (s, name, hidden)); + else if (type == DataType::MIDI) + pl = boost::shared_ptr (new MidiPlaylist (s, name, hidden)); + + if (pl && !hidden) { + PlaylistCreated (pl); + } + + return pl; +} + +boost::shared_ptr +PlaylistFactory::create (boost::shared_ptr old, string name, bool hidden) { - const AudioPlaylist* apl; - - if ((apl = dynamic_cast (&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 pl; + boost::shared_ptr apl; + boost::shared_ptr mpl; + + if ((apl = boost::dynamic_pointer_cast (old)) != 0) { + pl = boost::shared_ptr (new AudioPlaylist (apl, name, hidden)); + pl->set_region_ownership (); + } else if ((mpl = boost::dynamic_pointer_cast (old)) != 0) { + pl = boost::shared_ptr (new MidiPlaylist (mpl, name, hidden)); + pl->set_region_ownership (); } + + if (pl && !hidden) { + PlaylistCreated (pl); + } + + return pl; +} + +boost::shared_ptr +PlaylistFactory::create (boost::shared_ptr old, nframes_t start, nframes_t cnt, string name, bool hidden) +{ + boost::shared_ptr pl; + boost::shared_ptr apl; + boost::shared_ptr mpl; + + if ((apl = boost::dynamic_pointer_cast (old)) != 0) { + pl = boost::shared_ptr (new AudioPlaylist (apl, start, cnt, name, hidden)); + pl->set_region_ownership (); + } else if ((mpl = boost::dynamic_pointer_cast (old)) != 0) { + pl = boost::shared_ptr (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 (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 #include +#include #include #include @@ -58,6 +59,7 @@ Redirect::Redirect (Session& s, const string& name, Placement p, Redirect::~Redirect () { + notify_callbacks (); } boost::shared_ptr @@ -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 @@ -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 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 > unique_srcs; @@ -125,7 +123,6 @@ Region::Region (boost::shared_ptr 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 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 > unique_srcs; for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) { @@ -250,7 +243,6 @@ Region::Region (boost::shared_ptr 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 src, const XMLNode& node) Region::~Region () { - if (_playlist) { + boost::shared_ptr 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 wpl) { - if (pl == _playlist) { + boost::shared_ptr old_playlist = (_playlist.lock()); + boost::shared_ptr 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 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 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 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 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 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 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 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 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::get_parent() const { - if (_playlist) { + boost::shared_ptr pl (playlist()); + + if (pl) { boost::shared_ptr r; boost::shared_ptr grrr2 = boost::dynamic_pointer_cast (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 (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 #include +#include #include #include @@ -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, 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 #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -290,12 +291,13 @@ Session::Session (AudioEngine &eng, if (new_session) { if (create (new_session, mix_template, compute_initial_length())) { cerr << "create failed\n"; + destroy (); throw failed_constructor (); } } if (second_stage_init (new_session)) { - cerr << "2nd state failed\n"; + destroy (); throw failed_constructor (); } @@ -359,6 +361,7 @@ Session::Session (AudioEngine &eng, if (new_session) { if (create (new_session, 0, initial_length)) { + destroy (); throw failed_constructor (); } } @@ -386,6 +389,7 @@ Session::Session (AudioEngine &eng, Config->set_output_auto_connect (output_ac); if (second_stage_init (new_session)) { + destroy (); throw failed_constructor (); } @@ -401,6 +405,12 @@ Session::Session (AudioEngine &eng, } Session::~Session () +{ + destroy (); +} + +void +Session::destroy () { /* if we got to here, leaving pending capture state around is a mistake. @@ -469,10 +479,24 @@ Session::~Session () tmp = i; ++tmp; - delete *i; + (*i)->drop_references (); + + i = tmp; + } + + for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) { + PlaylistList::iterator tmp; + + tmp = i; + ++tmp; + + (*i)->drop_references (); i = tmp; } + + playlists.clear (); + unused_playlists.clear (); #ifdef TRACK_DESTRUCTION cerr << "delete regions\n"; @@ -619,8 +643,6 @@ Session::when_engine_running () /* we don't want to run execute this again */ - first_time_running.disconnect (); - set_block_size (_engine.frames_per_cycle()); set_frame_rate (_engine.frame_rate()); @@ -685,23 +707,6 @@ Session::when_engine_running () // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO? } - if (auditioner == 0) { - - /* we delay creating the auditioner till now because - it makes its own connections to ports named - in the ARDOUR_RC config file. the engine has - to be running for this to work. - */ - - try { - auditioner.reset (new Auditioner (*this)); - } - - catch (failed_constructor& err) { - warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg; - } - } - /* Create a set of Connection objects that map to the physical outputs currently available */ @@ -841,6 +846,7 @@ Session::when_engine_running () } } + _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty)); /* hook us up to the engine */ @@ -867,6 +873,22 @@ Session::hookup_io () _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting); + if (auditioner == 0) { + + /* we delay creating the auditioner till now because + it makes its own connections to ports. + the engine has to be running for this to work. + */ + + try { + auditioner.reset (new Auditioner (*this)); + } + + catch (failed_constructor& err) { + warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg; + } + } + /* Tell all IO objects to create their ports */ IO::enable_ports (); @@ -918,7 +940,7 @@ Session::hookup_io () } void -Session::playlist_length_changed (Playlist* pl) +Session::playlist_length_changed () { /* we can't just increase end_location->end() if pl->get_maximum_extent() if larger. if the playlist used to be the longest playlist, @@ -932,10 +954,10 @@ Session::playlist_length_changed (Playlist* pl) void Session::diskstream_playlist_changed (boost::shared_ptr dstream) { - Playlist *playlist; + boost::shared_ptr 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 dsl = diskstreams.reader(); for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) { - Playlist* pl = (*i)->playlist(); + boost::shared_ptr pl = (*i)->playlist(); if ((me = pl->get_maximum_extent()) > max) { max = me; } @@ -2697,14 +2719,10 @@ Session::add_source (boost::shared_ptr 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))); + set_dirty(); } - - source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr (source))); - set_dirty(); - - SourceAdded (source); /* EMIT SIGNAL */ } void @@ -2737,8 +2755,6 @@ Session::remove_source (boost::weak_ptr src) save_state (_current_snapshot_name); } - - SourceRemoved(source); /* EMIT SIGNAL */ } boost::shared_ptr @@ -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 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(); } void -Session::add_playlist (Playlist* playlist) +Session::add_playlist (boost::shared_ptr 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->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr(playlist))); } } @@ -3216,7 +3235,7 @@ Session::add_playlist (Playlist* playlist) } void -Session::get_playlists (vector& s) +Session::get_playlists (vector >& s) { { Glib::Mutex::Lock lm (playlist_lock); @@ -3230,15 +3249,25 @@ Session::get_playlists (vector& s) } void -Session::track_playlist (Playlist* pl, bool inuse) +Session::track_playlist (bool inuse, boost::weak_ptr wpl) { + boost::shared_ptr 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 weak_playlist) { if (_state_of_the_state & Deletion) { return; } + boost::shared_ptr 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 (redirect)) != 0) { if ((port_insert = dynamic_cast (insert)) != 0) { - _port_inserts.remove (port_insert); + list::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 (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 (redirect)) != 0) { - _sends.remove (send); + list::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::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::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 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 >& srcs, InterThreadInfo& itt) { + int ret = -1; + boost::shared_ptr playlist; boost::shared_ptr 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 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 #include #include -using namespace PBD; -#include "i18n.h" +#include +#include +#include +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(*_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(*pl, before, after); + if (boost::shared_ptr pl = playlist_by_name(child->property("name")->value())) { + return new MementoCommand(*(pl.get()), before, after); + } } else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name()) { return new MementoCommand(*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; + 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); + + 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 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 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 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 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; + 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); + + 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 #else -#include #include +#include #endif #include @@ -57,6 +57,8 @@ #include #include #include +#include +#include #include #include @@ -93,6 +95,7 @@ #include #include #include +#include #include @@ -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; nlist = node.children(); @@ -1812,7 +1863,7 @@ Session::load_unused_playlists (const XMLNode& node) { XMLNodeList nlist; XMLNodeConstIterator niter; - Playlist *playlist; + boost::shared_ptr 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)); } return 0; } -Playlist * +boost::shared_ptr 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(); + } } 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 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 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& result, bool exclude_th return 0; } +struct RegionCounter { + typedef std::map > AudioSourceList; + AudioSourceList::iterator iter; + boost::shared_ptr region; + uint32_t count; + + RegionCounter() : count (0) {} +}; + int Session::cleanup_sources (Session::cleanup_report& rep) { vector > dead_sources; - vector playlists_tbd; + vector > playlists_tbd; PathScanner scanner; string sound_path; vector::iterator i; @@ -2549,73 +2605,36 @@ Session::cleanup_sources (Session::cleanup_report& rep) /* now delete any that were marked for deletion */ - for (vector::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 >::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 >::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 reg = r->second; - - for (uint32_t n = 0; n < reg->n_channels(); ++n) { - if (reg->source (n) == (*i)) { - /* this region is dead */ - remove_region (reg); - } - } - - r = tmp; - } - } - /* build a list of all the possible sound directories for the session */ for (i = session_dirs.begin(); i != session_dirs.end(); ) { @@ -2624,7 +2643,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) ++nexti; sound_path += (*i).path; - sound_path += sound_dir_name; + sound_path += sound_dir (false); if (nexti != session_dirs.end()) { sound_path += ':'; @@ -2632,7 +2651,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) i = nexti; } - + /* now do the same thing for the files that ended up in the sounds dir(s) but are not referenced as sources in any snapshot. */ @@ -2672,7 +2691,6 @@ Session::cleanup_sources (Session::cleanup_report& rep) used = true; break; } - } if (!used) { @@ -2697,11 +2715,31 @@ Session::cleanup_sources (Session::cleanup_report& rep) on whichever filesystem it was already on. */ - newpath = Glib::path_get_dirname (*x); - newpath = Glib::path_get_dirname (newpath); + if (_path.find ("/sounds/")) { + + /* old school, go up 1 level */ + + newpath = Glib::path_get_dirname (*x); // "sounds" + newpath = Glib::path_get_dirname (newpath); // "session-name" + + } else { + + /* new school, go up 4 levels */ + + newpath = Glib::path_get_dirname (*x); // "audiofiles" + newpath = Glib::path_get_dirname (newpath); // "session-name" + newpath = Glib::path_get_dirname (newpath); // "interchange" + newpath = Glib::path_get_dirname (newpath); // "session-dir" + } newpath += '/'; newpath += dead_sound_dir_name; + + if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg; + return -1; + } + newpath += '/'; newpath += Glib::path_get_basename ((*x)); @@ -2741,7 +2779,6 @@ Session::cleanup_sources (Session::cleanup_report& rep) << endmsg; goto out; } - /* see if there an easy to find peakfile for this file, and remove it. */ @@ -2759,7 +2796,6 @@ Session::cleanup_sources (Session::cleanup_report& rep) goto out; } } - } ret = 0; @@ -2865,6 +2901,12 @@ Session::set_clean () } } +void +Session::set_deletion_in_progress () +{ + _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion); +} + void Session::add_controllable (Controllable* c) { @@ -2916,8 +2958,8 @@ Session::save_history (string snapshot_name) XMLTree tree; string xml_path; string bak_path; - - tree.set_root (&_history.get_state()); + + tree.set_root (&_history.get_state (Config->get_saved_history_depth())); if (snapshot_name.empty()) { snapshot_name = _current_snapshot_name; @@ -2934,8 +2976,6 @@ Session::save_history (string snapshot_name) return -1; } - cerr << "actually writing history\n"; - if (!tree.write (xml_path)) { error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg; @@ -2965,18 +3005,22 @@ Session::restore_history (string snapshot_name) XMLTree tree; string xmlpath; + if (snapshot_name.empty()) { + snapshot_name = _current_snapshot_name; + } + /* read xml */ xmlpath = _path + snapshot_name + ".history"; cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg; if (access (xmlpath.c_str(), F_OK)) { - error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg; - return 1; + info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg; + return 1; } if (!tree.read (xmlpath)) { - error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg; - return -1; + error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg; + return -1; } /* replace history */ @@ -3005,10 +3049,19 @@ Session::restore_history (string snapshot_name) if (n->name() == "MementoCommand" || n->name() == "MementoUndoCommand" || n->name() == "MementoRedoCommand") { + if ((c = memento_command_factory(n))) { ut->add_command(c); } + + } else if (n->name() == X_("GlobalRouteStateCommand")) { + + if ((c = global_state_command_factory (*n))) { + ut->add_command (c); + } + } else { + error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg; } } @@ -3039,7 +3092,6 @@ Session::config_changed (const char* parameter_name) for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { if ((*i)->record_enabled ()) { - //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (!Config->get_auto_input()); } } @@ -3099,7 +3151,7 @@ Session::config_changed (const char* parameter_name) setup_raid_path (Config->get_raid_path()); - } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) { + } else if (PARAM_IS ("smpte-format")) { sync_time_vars (); 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 - + // 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 r = routes.reader (); boost::shared_ptr 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 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 pl) { _playlists.insert (pl); + pl->GoingAway.connect (bind (mem_fun (*this, &Source::remove_playlist), boost::weak_ptr (pl))); } void -Source::remove_playlist (Playlist* pl) +Source::remove_playlist (boost::weak_ptr wpl) { - std::set::iterator x; + boost::shared_ptr pl (wpl.lock()); + + if (!pl) { + return; + } + + std::set >::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 ret (new DestructiveFileSource (s, node)); + try { + boost::shared_ptr ret (new CoreAudioSource (s, node)); if (setup_peakfile (ret)) { return boost::shared_ptr(); } SourceCreated (ret); return ret; + } - } else { - - try { - boost::shared_ptr ret (new CoreAudioSource (s, node)); + catch (failed_constructor& err) { + boost::shared_ptr ret (new SndFileSource (s, node)); if (setup_peakfile (ret)) { return boost::shared_ptr(); } SourceCreated (ret); return ret; - - } catch (failed_constructor& err) { - - try { - boost::shared_ptr ret (new CoreAudioSource (node)); - SourceCreated (ret); - return ret; - } - - - catch (failed_constructor& err) { - - boost::shared_ptr ret (new SndFileSource (s, node)); - if (setup_peakfile (ret)) { - return boost::shared_ptr(); - } - SourceCreated (ret); - return ret; - } } } else if (type == DataType::MIDI) { - + boost::shared_ptr 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 ret (new DestructiveFileSource (s, node)); - if (setup_peakfile (ret)) { - return boost::shared_ptr(); - } - SourceCreated (ret); - return ret; + boost::shared_ptr ret (new SndFileSource (s, node)); - } else { - - boost::shared_ptr ret (new SndFileSource (s, node)); - if (setup_peakfile (ret)) { - return boost::shared_ptr(); - } - SourceCreated (ret); - return ret; + if (setup_peakfile (ret)) { + return boost::shared_ptr(); } + + SourceCreated (ret); + return ret; } else if (type == DataType::MIDI) { boost::shared_ptr ret (new SMFSource (s, node)); + SourceCreated (ret); return ret; } - + return boost::shared_ptr (); } @@ -164,39 +134,53 @@ boost::shared_ptr SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFileSource::Flag flags, bool announce) { if (type == DataType::AUDIO) { - if (flags & Destructive) { - boost::shared_ptr ret (new DestructiveFileSource (s, idstr, flags)); - if (setup_peakfile (ret)) { - return boost::shared_ptr(); - } - if (announce) { - SourceCreated (ret); - } - return ret; - + + if (!(flags & Destructive)) { + try { boost::shared_ptr ret (new CoreAudioSource (s, idstr, flags)); + if (setup_peakfile (ret)) { + return boost::shared_ptr(); + } if (announce) { SourceCreated (ret); } return ret; - - } catch (failed_constructor& err) { + } + + catch (failed_constructor& err) { boost::shared_ptr ret (new SndFileSource (s, idstr, flags)); + if (setup_peakfile (ret)) { + return boost::shared_ptr(); + } if (announce) { SourceCreated (ret); } return ret; } + } else { + + boost::shared_ptr ret (new SndFileSource (s, idstr, flags)); + if (setup_peakfile (ret)) { + return boost::shared_ptr(); + } + if (announce) { + SourceCreated (ret); + } + return ret; + } + } else if (type == DataType::MIDI) { boost::shared_ptr ret (new SMFSource (s, node)); - SourceCreated (ret); + if (announce) { + SourceCreated (ret); + } return ret; } - + return boost::shared_ptr(); } @@ -206,27 +190,32 @@ boost::shared_ptr SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFileSource::Flag flags, bool announce) { if (type == DataType::AUDIO) { - + boost::shared_ptr ret (new SndFileSource (s, idstr, flags)); + if (setup_peakfile (ret)) { return boost::shared_ptr(); } + if (announce) { SourceCreated (ret); } + return ret; } else if (type == DataType::MIDI) { - boost::shared_ptr ret (new SMFSource (s, idstr, SMFSource::Flag(0))); // FIXME: flags? + // FIXME: flags? + boost::shared_ptr ret (new SMFSource (s, idstr, SMFSource::Flag(0))); + if (announce) { SourceCreated (ret); } - return ret; + return ret; } - - return boost::shared_ptr (); + + return boost::shared_ptr(); } #endif // HAVE_COREAUDIO @@ -235,39 +224,33 @@ boost::shared_ptr 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 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(); - } - if (announce) { - SourceCreated (ret); - } - } else { - boost::shared_ptr 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(); - } - if (announce) { - SourceCreated (ret); - } - return ret; + boost::shared_ptr 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(); + } + if (announce) { + SourceCreated (ret); } + return ret; } else if (type == DataType::MIDI) { boost::shared_ptr ret (new SMFSource (s, path)); - SourceCreated (ret); + + if (announce) { + SourceCreated (ret); + } return ret; - + } return boost::shared_ptr (); 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 #include #include +#include #include #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 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 + +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 +#include +#include #include namespace ARDOUR { @@ -35,10 +36,6 @@ class BarController : public Gtk::Frame BarController (Gtk::Adjustment& adj, PBD::Controllable&, sigc::slot); 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 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 + +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 + +#include +#include +#include + +namespace Gtkmm2ext { + +class PixFader : public Gtk::DrawingArea { + public: + PixFader (Glib::RefPtr 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 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 #include -#include +#include #include namespace Gtkmm2ext { @@ -35,11 +35,10 @@ namespace PBD { namespace Gtkmm2ext { -class SliderController : public Gtkmm2ext::PixScroller +class SliderController : public Gtkmm2ext::PixFader { public: - SliderController (Glib::RefPtr slider, - Glib::RefPtr rail, + SliderController (Glib::RefPtr 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 slider, - Glib::RefPtr rail, + VSliderController (Glib::RefPtr 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 slider, - Glib::RefPtr rail, + HSliderController (Glib::RefPtr 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 +#include + +using namespace Gtkmm2ext; +using namespace Gtk; +using namespace Gdk; +using namespace std; + +PixFader::PixFader (Glib::RefPtr 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 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 #include -#include +#include #include #include "i18n.h" @@ -28,13 +28,12 @@ using namespace Gtkmm2ext; using namespace PBD; -SliderController::SliderController (Glib::RefPtr slide, - Glib::RefPtr rail, +SliderController::SliderController (Glib::RefPtr 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 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 slide, - Glib::RefPtr rail, +VSliderController::VSliderController (Glib::RefPtr 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 slide, } } -HSliderController::HSliderController (Glib::RefPtr slide, - Glib::RefPtr rail, +HSliderController::HSliderController (Glib::RefPtr 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 -#include #include +#include +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 +#include + +#include +#include +#include + +#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 + +#include +#include + +#include +#include +#include + +using namespace std; +using namespace PBD; + +#include "i18n.h" + +EnumWriter* EnumWriter::_instance = 0; +map 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 v, vector s) +{ + pair newpair; + pair 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 v, vector s) +{ + pair newpair; + pair 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::iterator i; + vector::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::iterator i; + vector::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::iterator i; + vector::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::iterator i; + vector::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::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 +#include 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 + +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 +#include +#include +#include + + +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, std::vector); + void register_bits (std::string type, std::vector, std::vector); + + 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 values; + std::vector names; + bool bitwise; + + EnumRegistration() {} + EnumRegistration (std::vector& v, std::vector& s, bool b) + : values (v), names (s), bitwise (b) {} + }; + + typedef std::map 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 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 #include +#include + 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 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 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 +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::iterator it; - for (it = UndoList.begin(); it != UndoList.end(); it++) { - node->add_child_nocopy((*it)->get_state()); + if (depth == 0) { + /* everything */ + + for (list::iterator it = UndoList.begin(); it != UndoList.end(); ++it) { + node->add_child_nocopy((*it)->get_state()); + } + + } else { + + /* just the last "depth" transactions */ + + list in_order; + + for (list::reverse_iterator it = UndoList.rbegin(); it != UndoList.rend() && depth; ++it, depth--) { + in_order.push_front (*it); + } + + for (list::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 +#include 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 #include #include @@ -33,6 +58,7 @@ #include #include #include +#include #include #include @@ -51,6 +77,12 @@ BaseUI::RequestType LEDChange = BaseUI::new_request_type (); BaseUI::RequestType Print = BaseUI::new_request_type (); BaseUI::RequestType SetCurrentTrack = BaseUI::new_request_type (); +/* Base Tranzport cmd strings */ + +static const uint8_t cmd_light_on[] = { 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 }; +static const uint8_t cmd_light_off[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; +static const uint8_t cmd_write_screen[] = { 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 }; + static inline double gain_to_slider_position (ARDOUR::gain_t g) { @@ -74,8 +106,7 @@ TranzportControlProtocol::TranzportControlProtocol (Session& s) /* tranzport controls one track at a time */ set_route_table_size (1); - - timeout = 60000; + timeout = 6000; // what is this for? buttonmask = 0; _datawheel = 0; _device_status = STATUS_OFFLINE; @@ -84,51 +115,212 @@ TranzportControlProtocol::TranzportControlProtocol (Session& s) last_where = max_frames; wheel_mode = WheelTimeline; wheel_shift_mode = WheelShiftGain; + wheel_increment = WheelIncrScreen; + bling_mode = BlingOff; timerclear (&last_wheel_motion); last_wheel_dir = 1; last_track_gain = FLT_MAX; display_mode = DisplayNormal; gain_fraction = 0.0; + invalidate(); + screen_init(); + lights_init(); + print(0,0,"!!Welcome to Ardour!!"); + print(1,0,"!Peace through Music!"); +} - memset (current_screen, 0, sizeof (current_screen)); - memset (pending_screen, 0, sizeof (pending_screen)); +void TranzportControlProtocol::light_validate (LightID light) +{ + lights_invalid[light] = 0; +} + +void TranzportControlProtocol::light_invalidate (LightID light) +{ + lights_invalid[light] = 1; +} - for (uint32_t i = 0; i < sizeof(lights)/sizeof(lights[0]); ++i) { - lights[i] = false; +void TranzportControlProtocol::lights_validate () +{ + memset (lights_invalid, 0, sizeof (lights_invalid)); +} + +void TranzportControlProtocol::lights_invalidate () +{ + memset (lights_invalid, 1, sizeof (lights_invalid)); +} + +void TranzportControlProtocol::lights_init() +{ + for (uint32_t i = 0; i < sizeof(lights_current)/sizeof(lights_current[0]); i++) { + lights_invalid[i] = lights_current[i] = + lights_pending[i] = lights_flash[i] = false; + } +} + + + +int +TranzportControlProtocol::lights_flush () +{ + if ( _device_status == STATUS_OFFLINE) { return (0); } + + // Figure out iterators one day soon + // for (LightID i = i.start(), i = i.end(); i++) { + // if (lights_pending[i] != lights_current[i] || lights_invalid[i]) { + // if (light_set(i, lights_pending[i])) { + // return i-1; + // } + // } + //} + if ((lights_pending[LightRecord] != lights_current[LightRecord]) || lights_invalid[LightRecord]) { + if (light_set(LightRecord,lights_pending[LightRecord])) { + return 1; + } + } + if ((lights_pending[LightTrackrec] != lights_current[LightTrackrec]) || lights_invalid[LightTrackrec]) { + if (light_set(LightTrackrec,lights_pending[LightTrackrec])) { + return 1; + } + } + + if ((lights_pending[LightTrackmute] != lights_current[LightTrackmute]) || lights_invalid[LightTrackmute]) { + if (light_set(LightTrackmute,lights_pending[LightTrackmute])) { + return 1; + } } - for (uint32_t i = 0; i < sizeof(pending_lights)/sizeof(pending_lights[0]); ++i) { - pending_lights[i] = false; + if ((lights_pending[LightTracksolo] != lights_current[LightTracksolo]) || lights_invalid[LightTracksolo]) { + if (light_set(LightTracksolo,lights_pending[LightTracksolo])) { + return 1; + } + } + if ((lights_pending[LightAnysolo] != lights_current[LightAnysolo]) || lights_invalid[LightAnysolo]) { + if (light_set(LightAnysolo,lights_pending[LightAnysolo])) { + return 1; + } + } + if ((lights_pending[LightLoop] != lights_current[LightLoop]) || lights_invalid[LightLoop]) { + if (light_set(LightLoop,lights_pending[LightLoop])) { + return 1; + } } + if ((lights_pending[LightPunch] != lights_current[LightPunch]) || lights_invalid[LightPunch]) { + if (light_set(LightPunch,lights_pending[LightPunch])) { + return 1; + } + } + + return 0; } -TranzportControlProtocol::~TranzportControlProtocol () +// Screen specific commands + +void +TranzportControlProtocol::screen_clear () { - set_active (false); + const char *blank = " "; + print(0,0,blank); + print(1,0,blank); } -bool -TranzportControlProtocol::probe () +void TranzportControlProtocol::screen_invalidate () { - struct usb_bus *bus; - struct usb_device *dev; + for(int row = 0; row < 2; row++) { + for(int col = 0; col < 20; col++) { + screen_invalid[row][col] = true; + screen_current[row][col] = 0x7f; + screen_pending[row][col] = ' '; + // screen_flash[row][col] = ' '; + } + } + // memset (&screen_invalid, 1, sizeof(screen_invalid)); + // memset (&screen_current, 0x7F, sizeof (screen_current)); // fill cache with a character we otherwise never use +} - usb_init(); - usb_find_busses(); - usb_find_devices(); +void TranzportControlProtocol::screen_validate () +{ +} - for (bus = usb_busses; bus; bus = bus->next) { +void TranzportControlProtocol::screen_init () +{ + screen_invalidate(); +} - for(dev = bus->devices; dev; dev = dev->next) { - if (dev->descriptor.idVendor == VENDORID && dev->descriptor.idProduct == PRODUCTID) { - return true; +int +TranzportControlProtocol::screen_flush () +{ + int cell = 0, row, col_base, col, pending = 0; + if ( _device_status == STATUS_OFFLINE) { return (-1); } + + for (row = 0; row < 2 && pending == 0; row++) { + for (col_base = 0, col = 0; col < 20 && pending == 0; ) { + if ((screen_pending[row][col] != screen_current[row][col]) + || screen_invalid[row][col]) { + + /* something in this cell is different, so dump the cell to the device. */ + + uint8_t cmd[8]; + cmd[0] = 0x00; + cmd[1] = 0x01; + cmd[2] = cell; + cmd[3] = screen_pending[row][col_base]; + cmd[4] = screen_pending[row][col_base+1]; + cmd[5] = screen_pending[row][col_base+2]; + cmd[6] = screen_pending[row][col_base+3]; + cmd[7] = 0x00; + + if(write(cmd) != 0) { + /* try to update this cell on the next go-round */ +#if DEBUG_TRANZPORT > 4 + printf("usb screen update failed for some reason... why? \ncmd and data were %02x %02x %02x %02x %02x %02x %02x %02x\n", + cmd[0],cmd[1],cmd[2], cmd[3], cmd[4], cmd[5],cmd[6],cmd[7]); +#endif + pending += 1; + // Shouldn't need to do this + // screen_invalid[row][col_base] = screen_invalid[row][col_base+1] = + // screen_invalid[row][col_base+2] = screen_invalid[row][col_base+3] = true; + + } else { + /* successful write: copy to current cached display */ + screen_invalid[row][col_base] = screen_invalid[row][col_base+1] = + screen_invalid[row][col_base+2] = screen_invalid[row][col_base+3] = false; + memcpy (&screen_current[row][col_base], &screen_pending[row][col_base], 4); + } + + /* skip the rest of the 4 character cell since we wrote+copied it already */ + + col_base += 4; + col = col_base; + cell++; + + } else { + + col++; + + if (col && col % 4 == 0) { + cell++; + col_base += 4; + } } } } + return pending; +} - return false; + +// Tranzport specific + +void TranzportControlProtocol::invalidate() +{ + lcd_damage(); lights_invalidate(); screen_invalidate(); // one of these days lcds can be fine but screens not +} + +TranzportControlProtocol::~TranzportControlProtocol () +{ + set_active (false); } + int TranzportControlProtocol::set_active (bool yn) { @@ -139,7 +331,7 @@ TranzportControlProtocol::set_active (bool yn) if (open ()) { return -1; } - + if (pthread_create_and_store (X_("tranzport monitor"), &thread, 0, _monitor_work, this) == 0) { _active = true; } else { @@ -148,11 +340,12 @@ TranzportControlProtocol::set_active (bool yn) } else { cerr << "Begin tranzport shutdown\n"; + screen_clear (); + lcd_damage(); + lights_off (); + for(int x = 0; x < 10 && flush(); x++) { usleep(1000); } pthread_cancel_one (thread); - cerr << "Thread dead\n"; - // lcd_clear (); - // lights_off (); - // cerr << "dev reset\n"; + cerr << "Tranzport Thread dead\n"; close (); _active = false; cerr << "End tranzport shutdown\n"; @@ -167,8 +360,8 @@ TranzportControlProtocol::show_track_gain () { if (route_table[0]) { gain_t g = route_get_gain (0); - if (g != last_track_gain) { - char buf[16]; + if ((g != last_track_gain) || lcd_isdamaged(0,9,8)) { + char buf[16]; snprintf (buf, sizeof (buf), "%6.1fdB", coefficient_to_dB (route_get_effective_gain (0))); print (0, 9, buf); last_track_gain = g; @@ -191,20 +384,66 @@ void TranzportControlProtocol::next_display_mode () { switch (display_mode) { - case DisplayNormal: - display_mode = DisplayBigMeter; - break; - case DisplayBigMeter: - display_mode = DisplayNormal; - break; + case DisplayNormal: + enter_big_meter_mode(); + break; + + case DisplayBigMeter: + enter_normal_display_mode(); + break; + + case DisplayRecording: + enter_normal_display_mode(); + break; + + case DisplayRecordingMeter: + enter_big_meter_mode(); + break; + + case DisplayConfig: + case DisplayBling: + case DisplayBlingMeter: + enter_normal_display_mode(); + break; } } +// FIXME, these 3 aren't done yet + +void +TranzportControlProtocol::enter_recording_mode () +{ + lcd_damage(); // excessive + screen_clear (); + lights_off (); + display_mode = DisplayRecording; +} + +void +TranzportControlProtocol::enter_bling_mode () +{ + lcd_damage(); + screen_clear (); + lights_off (); + display_mode = DisplayBling; +} + +void +TranzportControlProtocol::enter_config_mode () +{ + lcd_damage(); + screen_clear (); + lights_off (); + display_mode = DisplayConfig; +} + + void TranzportControlProtocol::enter_big_meter_mode () { - lcd_clear (); + screen_clear (); + lcd_damage(); lights_off (); last_meter_fill = 0; display_mode = DisplayBigMeter; @@ -213,16 +452,11 @@ TranzportControlProtocol::enter_big_meter_mode () void TranzportControlProtocol::enter_normal_display_mode () { - last_where += 1; /* force time redisplay */ - last_track_gain = FLT_MAX; /* force gain redisplay */ - - lcd_clear (); + screen_clear (); + lcd_damage(); lights_off (); - show_current_track (); - show_wheel_mode (); - show_wheel_mode (); - show_transport_time (); display_mode = DisplayNormal; + // normal_update(); } @@ -230,10 +464,11 @@ float log_meter (float db) { float def = 0.0f; /* Meter deflection %age */ - - if (db < -70.0f) { - def = 0.0f; - } else if (db < -60.0f) { + + if (db < -70.0f) return 0.0f; + if (db > 6.0f) return 1.0f; + + if (db < -60.0f) { def = (db + 70.0f) * 0.25f; } else if (db < -50.0f) { def = (db + 60.0f) * 0.5f + 2.5f; @@ -245,32 +480,36 @@ log_meter (float db) def = (db + 30.0f) * 2.0f + 30.0f; } else if (db < 6.0f) { def = (db + 20.0f) * 2.5f + 50.0f; - } else { - def = 115.0f; } - + /* 115 is the deflection %age that would be when db=6.0. this is an arbitrary endpoint for our scaling. - */ - + */ + return def/115.0f; } void TranzportControlProtocol::show_meter () { + // you only seem to get a route_table[0] on moving forward - bug elsewhere if (route_table[0] == 0) { + // Principle of least surprise + print (0, 0, "No audio to meter!!!"); + print (1, 0, "Select another track"); return; } float level = route_get_peak_input_power (0, 0); float fraction = log_meter (level); + /* Someday add a peak bar*/ + /* we draw using a choice of a sort of double colon-like character ("::") or a single, left-aligned ":". the screen is 20 chars wide, so we can display 40 different levels. compute the level, then figure out how many "::" to fill. if the answer is odd, make the last one a ":" - */ + */ uint32_t fill = (uint32_t) floor (fraction * 40); char buf[21]; @@ -285,7 +524,7 @@ TranzportControlProtocol::show_meter () bool add_single_level = (fill % 2 != 0); fill /= 2; - + if (fraction > 0.98) { light_on (LightAnysolo); } @@ -310,25 +549,64 @@ TranzportControlProtocol::show_meter () } /* print() requires this */ - + buf[21] = '\0'; print (0, 0, buf); print (1, 0, buf); } +void +TranzportControlProtocol::show_bbt (nframes_t where) +{ + if ((where != last_where) || lcd_isdamaged(1,9,8)) { + char buf[16]; + BBT_Time bbt; + session->tempo_map().bbt_time (where, bbt); + sprintf (buf, "%03" PRIu32 "|%02" PRIu32 "|%04" PRIu32, bbt.bars,bbt.beats,bbt.ticks); + last_bars = bbt.bars; + last_beats = bbt.beats; + last_ticks = bbt.ticks; + last_where = where; + + if(last_ticks < 1960) { print (1, 9, buf); } // save a write so we can do leds + + // if displaymode is recordmode show beats but not yet + lights_pending[LightRecord] = false; + lights_pending[LightAnysolo] = false; + switch(last_beats) { + case 1: if(last_ticks < 500 || last_ticks > 1960) lights_pending[LightRecord] = true; break; + default: if(last_ticks < 250) lights_pending[LightAnysolo] = true; + } + + // update lights for tempo one day + // if (bbt_upper_info_label) { + // TempoMap::Metric m (session->tempo_map().metric_at (when)); + // sprintf (buf, "%-5.2f", m.tempo().beats_per_minute()); + // bbt_lower_info_label->set_text (buf); + // sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor()); + // bbt_upper_info_label->set_text (buf); + } + } + + void TranzportControlProtocol::show_transport_time () { nframes_t where = session->transport_frame(); - - if (where != last_where) { + show_bbt(where); +} + +void +TranzportControlProtocol::show_smpte (nframes_t where) +{ + if ((where != last_where) || lcd_isdamaged(1,9,10)) { char buf[5]; SMPTE::Time smpte; session->smpte_time (where, smpte); - + if (smpte.negative) { sprintf (buf, "-%02" PRIu32 ":", smpte.hours); } else { @@ -343,7 +621,7 @@ TranzportControlProtocol::show_transport_time () print (1, 15, buf); sprintf (buf, "%02" PRIu32, smpte.frames); - print (1, 18, buf); + print_noretry (1, 18, buf); last_where = where; } @@ -355,6 +633,33 @@ TranzportControlProtocol::_monitor_work (void* arg) return static_cast(arg)->monitor_work (); } +// I note that these usb specific open, close, probe, read routines are basically +// pure boilerplate and could easily be abstracted elsewhere + +#if !HAVE_TRANZPORT_KERNEL_DRIVER + +bool +TranzportControlProtocol::probe () +{ + struct usb_bus *bus; + struct usb_device *dev; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_busses; bus; bus = bus->next) { + + for(dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.idVendor == VENDORID && dev->descriptor.idProduct == PRODUCTID) { + return true; + } + } + } + + return false; +} + int TranzportControlProtocol::open () { @@ -424,393 +729,469 @@ TranzportControlProtocol::close () return ret; } + +int TranzportControlProtocol::read(uint8_t *buf, uint32_t timeout_override) +{ + int val; + // Get smarter about handling usb errors soon. Like disconnect + // pthread_testcancel(); + val = usb_interrupt_read (udev, READ_ENDPOINT, (char *) buf, 8, 10); + // pthread_testcancel(); + return val; +} + int -TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override) +TranzportControlProtocol::write_noretry (uint8_t* cmd, uint32_t timeout_override) { int val; - + if(inflight > MAX_TRANZPORT_INFLIGHT) { return (-1); } val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout); - if (val < 0) + if (val < 0) { +#if DEBUG_TRANZPORT + printf("usb_interrupt_write failed: %d\n", val); +#endif return val; - if (val != 8) + } + + if (val != 8) { +#if DEBUG_TRANZPORT + printf("usb_interrupt_write failed: %d\n", val); +#endif return -1; + } + ++inflight; + return 0; } -void -TranzportControlProtocol::lcd_clear () +int +TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override) { - /* special case this for speed and atomicity */ - - uint8_t cmd[8]; +#if MAX_RETRY > 1 + int val; + int retry = 0; + if(inflight > MAX_TRANZPORT_INFLIGHT) { return (-1); } - cmd[0] = 0x00; - cmd[1] = 0x01; - cmd[3] = ' '; - cmd[4] = ' '; - cmd[5] = ' '; - cmd[6] = ' '; - cmd[7] = 0x00; - - for (uint8_t i = 0; i < 10; ++i) { - cmd[2] = i; - usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, 1000); + while((val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout))!=8 && retry++ < MAX_RETRY) { + printf("usb_interrupt_write failed, retrying: %d\n", val); } - - memset (current_screen, ' ', sizeof (current_screen)); - memset (pending_screen, ' ', sizeof (pending_screen)); -} -void -TranzportControlProtocol::lights_off () + if (retry == MAX_RETRY) { + printf("Too many retries on a tranzport write, aborting\n"); + } + + if (val < 0) { + printf("usb_interrupt_write failed: %d\n", val); + return val; + } + if (val != 8) { + printf("usb_interrupt_write failed: %d\n", val); + return -1; + } + ++inflight; + return 0; +#else + return (write_noretry(cmd,timeout_override)); +#endif + +} + +#else +#error Kernel API not defined yet for Tranzport +// Something like open(/dev/surface/tranzport/event) for reading and raw for writing) +#endif + +// We have a state "Unknown" - STOP USING SPACES FOR IT - switching to arrow character +// We have another state - no_retry. Misleading, as we still retry on the next pass +// I think it's pointless to keep no_retry and instead we should throttle writes +// We have an "displayed" screen +// We always draw into the pending screen, which could be any of several screens +// We have an active screen +// Print arg - we have +// setactive +// so someday I think we need a screen object. + +/* +screen_flash.clear(); +screen_flash.print(0,0,"Undone:"); // Someday pull the undo stack from somewhere +screen_flash.print(1,0,"Nextup:"); + +if(flash_messages && lcd.getactive() != screen_flash) lcd.setactive(screen_flash,2000); + +screen::setactive(screen_name,duration); // duration in ms +screen::getactive(); +*/ + + +int +TranzportControlProtocol::flush () { - uint8_t cmd[8]; + int pending = 0; + if(!(pending = lights_flush())) { + pending = screen_flush(); + } + return pending; +} - cmd[0] = 0x00; - cmd[1] = 0x00; - cmd[3] = 0x00; - cmd[4] = 0x00; - cmd[5] = 0x00; - cmd[6] = 0x00; - cmd[7] = 0x00; +// doing these functions made me realize that screen_invalid should be lcd_isdamaged FIXME soon - cmd[2] = LightRecord; - if (write (cmd, 1000) == 0) { - lights[LightRecord] = false; - } - cmd[2] = LightTrackrec; - if (write (cmd, 1000) == 0) { - lights[LightTrackrec] = false; - } - cmd[2] = LightTrackmute; - if (write (cmd, 1000) == 0) { - lights[LightTrackmute] = false; - } - cmd[2] = LightTracksolo; - if (write (cmd, 1000) == 0) { - lights[LightTracksolo] = false; - } - cmd[2] = LightAnysolo; - if (write (cmd, 1000) == 0) { - lights[LightAnysolo] = false; +bool TranzportControlProtocol::lcd_damage() +{ + screen_invalidate(); + return true; +} + +bool TranzportControlProtocol::lcd_damage (int row, int col, int length) +{ + bool result = false; + int endcol = col+length-1; + if((endcol > 19)) { endcol = 19; } + if((row >= 0 && row < 2) && (col >=0 && col < 20)) { + for(int c = col; c < endcol; c++) { + screen_invalid[row][c] = true; + } + result = true; } - cmd[2] = LightLoop; - if (write (cmd, 1000) == 0) { - lights[LightLoop] = false; + return result; +} + +// Gotta switch to bitfields, this is collossally dumb +// Still working on the layering, arguably screen_invalid should be lcd_invalid + +bool TranzportControlProtocol::lcd_isdamaged () +{ + for(int r = 0; r < 2; r++) { + for(int c = 0; c < 20; c++) { + if(screen_invalid[r][c]) { +#if DEBUG_TRANZPORT > 5 + printf("row: %d,col: %d is damaged, should redraw it\n", r,c); +#endif + return true; + } + } } - cmd[2] = LightPunch; - if (write (cmd, 1000) == 0) { - lights[LightPunch] = false; + return false; +} + +bool TranzportControlProtocol::lcd_isdamaged (int row, int col, int length) +{ + bool result = 0; + int endcol = col+length; + if((endcol > 19)) { endcol = 19; } + if((row >= 0 && row < 2) && (col >=0 && col < 20)) { + for(int c = col; c < endcol; c++) { + if(screen_invalid[row][c]) { +#if DEBUG_TRANZPORT > 5 + printf("row: %d,col: %d is damaged, should redraw it\n", row,c); +#endif + return true; + } + } } + return result; } +// lcd_clear would be a separate function for a smart display +// here it does nothing, but for the sake of completeness it should +// probably write the lcd, and while I'm on the topic it should probably +// take a row, col, length argument.... + +void +TranzportControlProtocol::lcd_clear () +{ + +} + +// These lcd commands are not universally used yet and may drop out of the api + int -TranzportControlProtocol::light_on (LightID light) +TranzportControlProtocol::lcd_flush () { - uint8_t cmd[8]; + return 0; +} - if (!lights[light]) { +int +TranzportControlProtocol::lcd_write(uint8_t* cmd, uint32_t timeout_override) +{ + return write(cmd,timeout_override); +} - cmd[0] = 0x00; - cmd[1] = 0x00; - cmd[2] = light; - cmd[3] = 0x01; - cmd[4] = 0x00; - cmd[5] = 0x00; - cmd[6] = 0x00; - cmd[7] = 0x00; +void +TranzportControlProtocol::lcd_fill (uint8_t fill_char) +{ +} - if (write (cmd, 1000) == 0) { - lights[light] = true; - return 0; - } else { - return -1; - } +void +TranzportControlProtocol::lcd_print (int row, int col, const char* text) +{ + print(row,col,text); +} - } else { - return 0; - } +void TranzportControlProtocol::lcd_print_noretry (int row, int col, const char* text) +{ + print(row,col,text); } -int -TranzportControlProtocol::light_off (LightID light) +// Lights are buffered + +void +TranzportControlProtocol::lights_on () { - uint8_t cmd[8]; + lights_pending[LightRecord] = lights_pending[LightTrackrec] = + lights_pending[LightTrackmute] = lights_pending[LightTracksolo] = + lights_pending[LightAnysolo] = lights_pending[LightLoop] = + lights_pending[LightPunch] = true; +} - if (lights[light]) { +void +TranzportControlProtocol::lights_off () +{ + lights_pending[LightRecord] = lights_pending[LightTrackrec] = + lights_pending[LightTrackmute] = lights_pending[LightTracksolo] = + lights_pending[LightAnysolo] = lights_pending[LightLoop] = + lights_pending[LightPunch] = false; +} - cmd[0] = 0x00; - cmd[1] = 0x00; - cmd[2] = light; - cmd[3] = 0x00; - cmd[4] = 0x00; - cmd[5] = 0x00; - cmd[6] = 0x00; - cmd[7] = 0x00; +int +TranzportControlProtocol::light_on (LightID light) +{ + lights_pending[light] = true; + return 0; +} - if (write (cmd, 1000) == 0) { - lights[light] = false; - return 0; - } else { - return -1; - } +int +TranzportControlProtocol::light_off (LightID light) +{ + lights_pending[light] = false; + return 0; +} - } else { +int +TranzportControlProtocol::light_set (LightID light, bool offon) +{ + uint8_t cmd[8]; + cmd[0] = 0x00; cmd[1] = 0x00; cmd[2] = light; cmd[3] = offon; + cmd[4] = 0x00; cmd[5] = 0x00; cmd[6] = 0x00; cmd[7] = 0x00; + + if (write (cmd) == 0) { + lights_current[light] = offon; + lights_invalid[light] = false; return 0; + } else { + return -1; } } -void* -TranzportControlProtocol::monitor_work () +int TranzportControlProtocol::rtpriority_set(int priority) { struct sched_param rtparam; int err; - uint8_t buf[8]; - int val; - bool first_time = true; + // preallocate and memlock some stack with memlock? + char *a = (char*) alloca(4096*2); a[0] = 'a'; a[4096] = 'b'; + memset (&rtparam, 0, sizeof (rtparam)); + rtparam.sched_priority = priority; /* XXX should be relative to audio (JACK) thread */ + // Note - try SCHED_RR with a low limit + // - we don't care if we can't write everything this ms + // and it will help if we lose the device + if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) { + PBD::info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror (errno)) << endmsg; + return 1; + } + return 0; +} - PBD::ThreadCreated (pthread_self(), X_("Tranzport")); +// Running with realtime privs is bad when you have problems +int TranzportControlProtocol::rtpriority_unset(int priority) +{ + struct sched_param rtparam; + int err; memset (&rtparam, 0, sizeof (rtparam)); - rtparam.sched_priority = 3; /* XXX should be relative to audio (JACK) thread */ - + rtparam.sched_priority = priority; if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) { - // do we care? not particularly. - PBD::info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror (errno)) << endmsg; + PBD::info << string_compose (_("%1: can't stop realtime scheduling (%2)"), name(), strerror (errno)) << endmsg; + return 1; } + PBD::info << string_compose (_("%1: realtime scheduling stopped (%2)"), name(), strerror (errno)) << endmsg; + return 0; +} + +// Slowly breaking this into where I can make usb processing it's own thread. + +void* +TranzportControlProtocol::monitor_work () +{ + uint8_t buf[8]; + int val = 0, pending = 0; + bool first_time = true; + uint8_t offline = 0; + + PBD::ThreadCreated (pthread_self(), X_("Tranzport")); pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); - next_track (); + rtpriority_set(); + inflight=0; + flush(); while (true) { /* bInterval for this beastie is 10ms */ - /* anything to read ? */ - if (_device_status == STATUS_OFFLINE) { - light_off (LightRecord); - first_time = true; - } - - pthread_testcancel(); - val = usb_interrupt_read (udev, READ_ENDPOINT, (char*) buf, 8, 10); - pthread_testcancel(); - - if (val == 8) { - process (buf); - } - - if (_device_status != STATUS_OFFLINE) { - if (first_time) { - lcd_clear (); - lights_off (); - first_time = false; - } - /* update whatever needs updating */ - update_state (); - } - } - - return (void*) 0; -} - -int -TranzportControlProtocol::update_state () -{ - int row; - int col_base; - int col; - int cell; - - /* do the text updates */ + first_time = true; + if(offline++ == 1) { + cerr << "Transport has gone offline\n"; + } + } else { + offline = 0; // hate writing this + } - switch (display_mode) { - case DisplayBigMeter: - show_meter (); - break; + val = read(buf); - case DisplayNormal: - normal_update (); - break; - } + if (val == 8) { + process (buf); + } - /* next: flush LCD */ +#if DEBUG_TRANZPORT > 2 + if(inflight > 1) printf("Inflight: %d\n", inflight); +#endif - cell = 0; - - for (row = 0; row < 2; ++row) { - - for (col_base = 0, col = 0; col < 20; ) { - - if (pending_screen[row][col] != current_screen[row][col]) { - - /* something in this cell is different, so dump the cell - to the device. - */ - - uint8_t cmd[8]; - - cmd[0] = 0x00; - cmd[1] = 0x01; - cmd[2] = cell; - cmd[3] = pending_screen[row][col_base]; - cmd[4] = pending_screen[row][col_base+1]; - cmd[5] = pending_screen[row][col_base+2]; - cmd[6] = pending_screen[row][col_base+3]; - cmd[7] = 0x00; - if (usb_interrupt_write (udev, WRITE_ENDPOINT, (char *) cmd, 8, 1000) == 8) { - /* successful write: copy to current */ - memcpy (¤t_screen[row][col_base], &pending_screen[row][col_base], 4); - } + if (_device_status != STATUS_OFFLINE) { + if (first_time) { + invalidate(); + lcd_clear (); + lights_off (); + first_time = false; + offline = 0; + pending = 3; // Give some time for the device to recover + } + /* update whatever needs updating */ + update_state (); - /* skip the rest of the 4 character cell since we wrote+copied it already */ - - col_base += 4; - col = col_base; - cell++; + /* still struggling with a good means of exerting flow control */ + // pending = flush(); + if(pending == 0) { + pending = flush(); } else { - - col++; - - if (col && col % 4 == 0) { - cell++; - col_base += 4; + if(inflight > 0) { + pending = --inflight; // we just did a whole bunch of writes so wait + } else { + pending = 0; } } - } + // pending = 0; + } } - /* now update LED's */ + return (void*) 0; +} - /* per track */ +int TranzportControlProtocol::lights_show_recording() +{ + // FIXME, flash recording light when recording and transport is moving + return lights_show_normal(); +} - if (route_table[0]) { - boost::shared_ptr at = boost::dynamic_pointer_cast (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 at = boost::dynamic_pointer_cast (route_table[0]); + lights_pending[LightTrackrec] = at && at->record_enabled(); + lights_pending[LightTrackmute] = route_get_muted(0); + lights_pending[LightTracksolo] = route_get_soloed(0); } else { - pending_lights[LightLoop] = false; + lights_pending[LightTrackrec] = false; + lights_pending[LightTracksolo] = false; + lights_pending[LightTrackmute] = false; } - if (Config->get_punch_in() || Config->get_punch_out()) { - pending_lights[LightPunch] = true; - } else { - pending_lights[LightPunch] = false; - } + /* Global settings */ - if (session->get_record_enabled()) { - pending_lights[LightRecord] = true; - } else { - pending_lights[LightRecord] = false; - } + lights_pending[LightLoop] = session->get_play_loop(); + lights_pending[LightPunch] = Config->get_punch_in() || Config->get_punch_out(); + lights_pending[LightRecord] = session->get_record_enabled(); + lights_pending[LightAnysolo] = session->soloing(); - if (session->soloing ()) { - pending_lights[LightAnysolo] = true; - } else { - pending_lights[LightAnysolo] = false; - } + return 0; +} - /* flush changed light change */ +int TranzportControlProtocol::lights_show_tempo() +{ + // someday soon fiddle with the lights based on the tempo + return lights_show_normal(); +} - if (pending_lights[LightRecord] != lights[LightRecord]) { - if (pending_lights[LightRecord]) { - light_on (LightRecord); - } else { - light_off (LightRecord); - } - } +int +TranzportControlProtocol::update_state () +{ + /* do the text and light updates */ - if (pending_lights[LightTracksolo] != lights[LightTracksolo]) { - if (pending_lights[LightTracksolo]) { - light_on (LightTracksolo); - } else { - light_off (LightTracksolo); - } - } + switch (display_mode) { + case DisplayBigMeter: + lights_show_tempo(); + show_meter (); + break; - if (pending_lights[LightTrackrec] != lights[LightTrackrec]) { - if (pending_lights[LightTrackrec]) { - light_on (LightTrackrec); - } else { - light_off (LightTrackrec); - } - } + case DisplayNormal: + lights_show_normal(); + normal_update (); + break; - if (pending_lights[LightTrackmute] != lights[LightTrackmute]) { - if (pending_lights[LightTrackmute]) { - light_on (LightTrackmute); - } else { - light_off (LightTrackmute); - } - } + case DisplayConfig: + break; - if (pending_lights[LightTracksolo] != lights[LightTracksolo]) { - if (pending_lights[LightTracksolo]) { - light_on (LightTracksolo); - } else { - light_off (LightTracksolo); - } - } + case DisplayRecording: + lights_show_recording(); + normal_update(); + break; - if (pending_lights[LightAnysolo] != lights[LightAnysolo]) { - if (pending_lights[LightAnysolo]) { - light_on (LightAnysolo); - } else { - light_off (LightAnysolo); - } - } + case DisplayRecordingMeter: + lights_show_recording(); + show_meter(); + break; - if (pending_lights[LightLoop] != lights[LightLoop]) { - if (pending_lights[LightLoop]) { - light_on (LightLoop); - } else { - light_off (LightLoop); - } - } + case DisplayBling: + lights_show_bling(); + normal_update(); + break; - if (pending_lights[LightPunch] != lights[LightPunch]) { - if (pending_lights[LightPunch]) { - light_on (LightPunch); - } else { - light_off (LightPunch); - } + case DisplayBlingMeter: + lights_show_bling(); + show_meter(); + break; } - return 0; + } +#define TRANZPORT_BUTTON_HANDLER(callback, button_arg) if (button_changes & button_arg) { \ + if (buttonmask & button_arg) { \ + callback##_press (buttonmask&ButtonShift); } else { callback##_release (buttonmask&ButtonShift); } } + int TranzportControlProtocol::process (uint8_t* buf) { @@ -820,6 +1201,7 @@ TranzportControlProtocol::process (uint8_t* buf) uint32_t button_changes; _device_status = buf[1]; + this_button_mask = 0; this_button_mask |= buf[2] << 24; this_button_mask |= buf[3] << 16; @@ -834,157 +1216,50 @@ TranzportControlProtocol::process (uint8_t* buf) datawheel (); } - if (button_changes & ButtonBattery) { - if (buttonmask & ButtonBattery) { - button_event_battery_press (buttonmask&ButtonShift); - } else { - button_event_battery_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonBacklight) { - if (buttonmask & ButtonBacklight) { - button_event_backlight_press (buttonmask&ButtonShift); - } else { - button_event_backlight_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonTrackLeft) { - if (buttonmask & ButtonTrackLeft) { - button_event_trackleft_press (buttonmask&ButtonShift); - } else { - button_event_trackleft_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonTrackRight) { - if (buttonmask & ButtonTrackRight) { - button_event_trackright_press (buttonmask&ButtonShift); - } else { - button_event_trackright_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonTrackRec) { - if (buttonmask & ButtonTrackRec) { - button_event_trackrec_press (buttonmask&ButtonShift); - } else { - button_event_trackrec_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonTrackMute) { - if (buttonmask & ButtonTrackMute) { - button_event_trackmute_press (buttonmask&ButtonShift); - } else { - button_event_trackmute_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonTrackSolo) { - if (buttonmask & ButtonTrackSolo) { - button_event_tracksolo_press (buttonmask&ButtonShift); - } else { - button_event_tracksolo_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonUndo) { - if (buttonmask & ButtonUndo) { - button_event_undo_press (buttonmask&ButtonShift); - } else { - button_event_undo_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonIn) { - if (buttonmask & ButtonIn) { - button_event_in_press (buttonmask&ButtonShift); - } else { - button_event_in_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonOut) { - if (buttonmask & ButtonOut) { - button_event_out_press (buttonmask&ButtonShift); - } else { - button_event_out_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonPunch) { - if (buttonmask & ButtonPunch) { - button_event_punch_press (buttonmask&ButtonShift); - } else { - button_event_punch_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonLoop) { - if (buttonmask & ButtonLoop) { - button_event_loop_press (buttonmask&ButtonShift); - } else { - button_event_loop_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonPrev) { - if (buttonmask & ButtonPrev) { - button_event_prev_press (buttonmask&ButtonShift); - } else { - button_event_prev_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonAdd) { - if (buttonmask & ButtonAdd) { - button_event_add_press (buttonmask&ButtonShift); - } else { - button_event_add_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonNext) { - if (buttonmask & ButtonNext) { - button_event_next_press (buttonmask&ButtonShift); - } else { - button_event_next_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonRewind) { - if (buttonmask & ButtonRewind) { - button_event_rewind_press (buttonmask&ButtonShift); - } else { - button_event_rewind_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonFastForward) { - if (buttonmask & ButtonFastForward) { - button_event_fastforward_press (buttonmask&ButtonShift); - } else { - button_event_fastforward_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonStop) { - if (buttonmask & ButtonStop) { - button_event_stop_press (buttonmask&ButtonShift); - } else { - button_event_stop_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonPlay) { - if (buttonmask & ButtonPlay) { - button_event_play_press (buttonmask&ButtonShift); - } else { - button_event_play_release (buttonmask&ButtonShift); - } - } - if (button_changes & ButtonRecord) { - if (buttonmask & ButtonRecord) { - button_event_record_press (buttonmask&ButtonShift); - } else { - button_event_record_release (buttonmask&ButtonShift); - } - } - + // SHIFT + STOP + PLAY for bling mode? + // if (button_changes & ButtonPlay & ButtonStop) { + // bling_mode_toggle(); + // } or something like that + + TRANZPORT_BUTTON_HANDLER(button_event_battery,ButtonBattery); + TRANZPORT_BUTTON_HANDLER(button_event_backlight,ButtonBacklight); + TRANZPORT_BUTTON_HANDLER(button_event_trackleft,ButtonTrackLeft); + TRANZPORT_BUTTON_HANDLER(button_event_trackright,ButtonTrackRight); + TRANZPORT_BUTTON_HANDLER(button_event_trackrec,ButtonTrackRec); + TRANZPORT_BUTTON_HANDLER(button_event_trackmute,ButtonTrackMute); + TRANZPORT_BUTTON_HANDLER(button_event_tracksolo,ButtonTrackSolo); + TRANZPORT_BUTTON_HANDLER(button_event_undo,ButtonUndo); + TRANZPORT_BUTTON_HANDLER(button_event_in,ButtonIn); + TRANZPORT_BUTTON_HANDLER(button_event_out,ButtonOut); + TRANZPORT_BUTTON_HANDLER(button_event_punch,ButtonPunch); + TRANZPORT_BUTTON_HANDLER(button_event_loop,ButtonLoop); + TRANZPORT_BUTTON_HANDLER(button_event_prev,ButtonPrev); + TRANZPORT_BUTTON_HANDLER(button_event_add,ButtonAdd); + TRANZPORT_BUTTON_HANDLER(button_event_next,ButtonNext); + TRANZPORT_BUTTON_HANDLER(button_event_rewind,ButtonRewind); + TRANZPORT_BUTTON_HANDLER(button_event_fastforward,ButtonFastForward); + TRANZPORT_BUTTON_HANDLER(button_event_stop,ButtonStop); + TRANZPORT_BUTTON_HANDLER(button_event_play,ButtonPlay); + TRANZPORT_BUTTON_HANDLER(button_event_record,ButtonRecord); return 0; } void TranzportControlProtocol::show_current_track () { + char pad[11]; + char *v; + int len; if (route_table[0] == 0) { - print (0, 0, "--------"); + print (0, 0, "----------"); + last_track_gain = FLT_MAX; } else { - print (0, 0, route_get_name (0).substr (0, 8).c_str()); + strcpy(pad," "); + v = (char *)route_get_name (0).substr (0, 10).c_str(); + if((len = strlen(v)) > 0) { + strncpy(pad,(char *)v,len); + } + print (0, 0, pad); } } @@ -1001,11 +1276,24 @@ TranzportControlProtocol::button_event_battery_release (bool shifted) void TranzportControlProtocol::button_event_backlight_press (bool shifted) { +#if DEBUG_TRANZPORT + printf("backlight pressed\n"); +#endif } void TranzportControlProtocol::button_event_backlight_release (bool shifted) { +#if DEBUG_TRANZPORT + printf("backlight released\n\n"); +#endif + if (shifted) { + lcd_damage(); + lcd_clear(); + last_where += 1; /* force time redisplay */ + last_track_gain = FLT_MAX; + normal_update(); // redraw_screen(); + } } void @@ -1048,7 +1336,11 @@ TranzportControlProtocol::button_event_trackrec_release (bool shifted) void TranzportControlProtocol::button_event_trackmute_press (bool shifted) { - route_set_muted (0, !route_get_muted (0)); + if (shifted) { + // Mute ALL? Something useful when a phone call comes in. Mute master? + } else { + route_set_muted (0, !route_get_muted (0)); + } } void @@ -1059,6 +1351,9 @@ TranzportControlProtocol::button_event_trackmute_release (bool shifted) void TranzportControlProtocol::button_event_tracksolo_press (bool shifted) { +#if DEBUG_TRANZPORT + printf("solo pressed\n"); +#endif if (display_mode == DisplayBigMeter) { light_off (LightAnysolo); return; @@ -1074,15 +1369,18 @@ TranzportControlProtocol::button_event_tracksolo_press (bool shifted) void TranzportControlProtocol::button_event_tracksolo_release (bool shifted) { +#if DEBUG_TRANZPORT + printf("solo released\n"); +#endif } void TranzportControlProtocol::button_event_undo_press (bool shifted) { if (shifted) { - redo (); + redo (); // someday flash the screen with what was redone } else { - undo (); + undo (); // someday flash the screen with what was undone } } @@ -1235,7 +1533,11 @@ TranzportControlProtocol::button_event_stop_release (bool shifted) void TranzportControlProtocol::button_event_play_press (bool shifted) { - transport_play (); + if (shifted) { + set_transport_speed (1.0f); + } else { + transport_play (); + } } void @@ -1258,11 +1560,17 @@ TranzportControlProtocol::button_event_record_release (bool shifted) { } +void button_event_mute (bool pressed, bool shifted) +{ + //static int was_pressed = 0; + // if(pressed) { } +} + void TranzportControlProtocol::datawheel () { if ((buttonmask & ButtonTrackRight) || (buttonmask & ButtonTrackLeft)) { - + /* track scrolling */ if (_datawheel < WheelDirectionThreshold) { @@ -1274,7 +1582,7 @@ TranzportControlProtocol::datawheel () timerclear (&last_wheel_motion); } else if ((buttonmask & ButtonPrev) || (buttonmask & ButtonNext)) { - + if (_datawheel < WheelDirectionThreshold) { next_marker (); } else { @@ -1289,23 +1597,27 @@ TranzportControlProtocol::datawheel () if (route_table[0]) { switch (wheel_shift_mode) { - case WheelShiftGain: - if (_datawheel < WheelDirectionThreshold) { - step_gain_up (); - } else { - step_gain_down (); - } - break; - case WheelShiftPan: - if (_datawheel < WheelDirectionThreshold) { - step_pan_right (); - } else { - step_pan_left (); - } - break; + case WheelShiftGain: + if (_datawheel < WheelDirectionThreshold) { + step_gain_up (); + } else { + step_gain_down (); + } + break; + case WheelShiftPan: + if (_datawheel < WheelDirectionThreshold) { + step_pan_right (); + } else { + step_pan_left (); + } + break; + + case WheelShiftMarker: + break; + + case WheelShiftMaster: + break; - case WheelShiftMaster: - break; } } @@ -1314,17 +1626,17 @@ TranzportControlProtocol::datawheel () } else { switch (wheel_mode) { - case WheelTimeline: - scroll (); - break; - - case WheelScrub: - scrub (); - break; + case WheelTimeline: + scroll (); + break; - case WheelShuttle: - shuttle (); - break; + case WheelScrub: + scrub (); + break; + + case WheelShuttle: + shuttle (); + break; } } } @@ -1332,10 +1644,15 @@ TranzportControlProtocol::datawheel () void TranzportControlProtocol::scroll () { + float m = 1.0; if (_datawheel < WheelDirectionThreshold) { - ScrollTimeline (0.2); + m = 1.0; } else { - ScrollTimeline (-0.2); + m = -1.0; + } + switch(wheel_increment) { + case WheelIncrScreen: ScrollTimeline (0.2*m); break; + default: break; // other modes unimplemented as yet } } @@ -1346,41 +1663,47 @@ TranzportControlProtocol::scrub () struct timeval now; struct timeval delta; int dir; - + gettimeofday (&now, 0); - + if (_datawheel < WheelDirectionThreshold) { dir = 1; } else { dir = -1; } - + if (dir != last_wheel_dir) { /* changed direction, start over */ speed = 0.1f; } else { if (timerisset (&last_wheel_motion)) { - + timersub (&now, &last_wheel_motion, &delta); - + /* 10 clicks per second => speed == 1.0 */ - + speed = 100000.0f / (delta.tv_sec * 1000000 + delta.tv_usec); - + } else { - + /* start at half-speed and see where we go from there */ - + speed = 0.5f; } } - + last_wheel_motion = now; last_wheel_dir = dir; - + set_transport_speed (speed * dir); } +void +TranzportControlProtocol::config () +{ + // FIXME +} + void TranzportControlProtocol::shuttle () { @@ -1453,6 +1776,10 @@ TranzportControlProtocol::next_wheel_shift_mode () break; case WheelShiftMaster: wheel_shift_mode = WheelShiftGain; + break; + case WheelShiftMarker: // Not done yet, disabled + wheel_shift_mode = WheelShiftGain; + break; } show_wheel_mode (); @@ -1495,36 +1822,48 @@ TranzportControlProtocol::show_wheel_mode () string text; switch (wheel_mode) { - case WheelTimeline: - text = "Time"; - break; - case WheelScrub: - text = "Scrb"; - break; - case WheelShuttle: - text = "Shtl"; - break; + case WheelTimeline: + text = "Time"; + break; + case WheelScrub: + text = "Scrb"; + break; + case WheelShuttle: + text = "Shtl"; + break; } switch (wheel_shift_mode) { - case WheelShiftGain: - text += ":Gain"; - break; + case WheelShiftGain: + text += ":Gain"; + break; - case WheelShiftPan: - text += ":Pan"; - break; + case WheelShiftPan: + text += ":Pan "; + break; - case WheelShiftMaster: - text += ":Mstr"; - break; + case WheelShiftMaster: + text += ":Mstr"; + break; + + case WheelShiftMarker: + text += ":Mrkr"; + break; } - + print (1, 0, text.c_str()); } +// Was going to keep state around saying to retry or not +// haven't got to it yet, still not sure it's a good idea + +void +TranzportControlProtocol::print (int row, int col, const char *text) { + print_noretry(row,col,text); +} + void -TranzportControlProtocol::print (int row, int col, const char *text) +TranzportControlProtocol::print_noretry (int row, int col, const char *text) { int cell; uint32_t left = strlen (text); @@ -1564,7 +1903,7 @@ TranzportControlProtocol::print (int row, int col, const char *text) /* copy current cell contents into tmp */ - memcpy (tmp, &pending_screen[row][base_col], 4); + memcpy (tmp, &screen_pending[row][base_col], 4); /* overwrite with new text */ @@ -1574,7 +1913,7 @@ TranzportControlProtocol::print (int row, int col, const char *text) /* copy it back to pending */ - memcpy (&pending_screen[row][base_col], tmp, 4); + memcpy (&screen_pending[row][base_col], tmp, 4); text += tocopy; left -= tocopy; @@ -1595,3 +1934,17 @@ TranzportControlProtocol::set_state (const XMLNode& node) { return 0; } + +int +TranzportControlProtocol::save (char *name) +{ + // Presently unimplemented + return 0; +} + +int +TranzportControlProtocol::load (char *name) +{ + // Presently unimplemented + return 0; +} 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 Binary files a/tools/osx_packaging/Ardour2.icns and b/tools/osx_packaging/Ardour2.icns differ diff --git a/tools/osx_packaging/COPYING b/tools/osx_packaging/COPYING new file mode 100644 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. + + + Copyright (C) + + 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. + + , 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', -- cgit v1.2.3