diff options
168 files changed, 11726 insertions, 5243 deletions
diff --git a/SConstruct b/SConstruct index 2944040f50..a1a3dbbf80 100644 --- a/SConstruct +++ b/SConstruct @@ -16,7 +16,7 @@ import SCons.Node.FS SConsignFile() EnsureSConsVersion(0, 96) -ardour_version = '3.0' +ardour_version = '2.1' subst_dict = { } @@ -28,26 +28,26 @@ opts = Options('scache.conf') opts.AddOptions( ('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''), BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0), - BoolOption('CMT', 'Compile with support for CMT Additions', 1), BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0), BoolOption('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0), - BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 1), + BoolOption('NATIVE_OSX_KEYS', 'Build key bindings file that matches OS X conventions', 0), + BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0), PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'), EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'none' ), ignorecase=2), BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0), BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0), BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0), BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1), - BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0), 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', 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('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1), BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 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('GPROFILE', 'Compile with support for gprofile (Developers only)', 0), + BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1) ) #---------------------------------------------------------------------- @@ -65,6 +65,7 @@ class LibraryInfo(Environment): self.Append (LIBPATH = other.get ('LIBPATH', [])) self.Append (CPPPATH = other.get('CPPPATH', [])) self.Append (LINKFLAGS = other.get('LINKFLAGS', [])) + self.Append (CCFLAGS = other.get('CCFLAGS', [])) self.Replace(LIBPATH = list(Set(self.get('LIBPATH', [])))) self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[])))) #doing LINKFLAGS breaks -framework @@ -402,6 +403,29 @@ else: os.remove('.personal_use_only') +#################### +# push environment +#################### + +def pushEnvironment(context): + if os.environ.has_key('PATH'): + context.Append(PATH = os.environ['PATH']) + + if os.environ.has_key('PKG_CONFIG_PATH'): + context.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH']) + + if os.environ.has_key('CC'): + context['CC'] = os.environ['CC'] + + if os.environ.has_key('CXX'): + context['CXX'] = os.environ['CXX'] + + if os.environ.has_key('DISTCC_HOSTS'): + context['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS'] + context['ENV']['HOME'] = os.environ['HOME'] + +pushEnvironment (env) + ####################### # Dependency Checking # ####################### @@ -415,7 +439,7 @@ deps = \ 'samplerate' : '0.1.0', 'raptor' : '1.4.2', 'lrdf' : '0.4.0', - 'jack' : '0.105.0', + 'jack' : '0.101.1', 'libgnomecanvas-2.0' : '2.0' } @@ -424,16 +448,22 @@ def DependenciesRequiredMessage(): 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 + 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 + context.Message( 'Checking for %s... ' % name ) + ret = context.TryAction('pkg-config --atleast-version=%s %s' %(version,name) )[0] + context.Result( ret ) + return ret + +def CheckPKGExists(context, name): + context.Message ('Checking for %s...' % name) + ret = context.TryAction('pkg-config --exists %s' % name)[0] + context.Result (ret) + return ret conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig, 'CheckPKGVersion' : CheckPKGVersion }) @@ -473,27 +503,30 @@ libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor') libraries['samplerate'] = LibraryInfo() libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate') -libraries['rubberband'] = LibraryInfo() -# -# chris cannam's rubberband has not yet been released -# -if os.path.exists ('libs/rubberband'): - libraries['rubberband'] = LibraryInfo (LIBS='rubberband', - LIBPATH='#libs/rubberband/lib', - CPPPATH='#libs/rubberband/src', - CXXFLAGS='-DUSE_RUBBERBAND') +conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } ) + +if conf.CheckPKGExists ('fftw3f'): + libraries['fftw3f'] = LibraryInfo() + libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f') + +if conf.CheckPKGExists ('fftw3'): + libraries['fftw3'] = LibraryInfo() + libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3') + +env = conf.Finish () 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(); + # + conf = Configure(libraries['fftw3']) + + if conf.CheckHeader ('fftw3.h') == False: + print ('FFT Analysis cannot be compiled without the FFTW3 headers, which do not seem to be installed') + sys.exit (1) + conf.Finish() + libraries['jack'] = LibraryInfo() libraries['jack'].ParseConfig('pkg-config --cflags --libs jack') @@ -515,12 +548,6 @@ libraries['gtk2'].ParseConfig ('pkg-config --cflags --libs gtk+-2.0') libraries['pango'] = LibraryInfo() libraries['pango'].ParseConfig ('pkg-config --cflags --libs pango') -libraries['cairo'] = LibraryInfo() -libraries['cairo'].ParseConfig ('pkg-config --cflags --libs cairo') - -libraries['gtk2-unix-print'] = LibraryInfo() -libraries['gtk2-unix-print'].ParseConfig ('pkg-config --cflags --libs gtk+-unix-print-2.0') - libraries['libgnomecanvas2'] = LibraryInfo() libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomecanvas-2.0') @@ -541,7 +568,7 @@ libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext # SCons should really do this for us -conf = Configure (env) +conf = env.Configure () have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version')) if have_cxx[0] != 1: @@ -559,9 +586,9 @@ env = conf.Finish() opt_flags = [] if env['GPROFILE'] == 1: - debug_flags = [ '-O0', '-g', '-pg' ] + debug_flags = [ '-g', '-pg' ] else: - debug_flags = [ '-O0', '-g' ] + debug_flags = [ '-g' ] # guess at the platform, used to define compiler flags @@ -728,23 +755,45 @@ if env['LIBLO']: def prep_libcheck(topenv, libinfo): if topenv['DIST_TARGET'] == 'panther' or topenv['DIST_TARGET'] == 'tiger': - # - # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default. - # All libraries needed should be built against this location - if topenv['GTKOSX']: - libinfo.Append(CCFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib") - libinfo.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib") - + # + # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default. + # All libraries needed should be built against this location + if topenv['GTKOSX']: + libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib") + libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib") + libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib") + libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib") + prep_libcheck(env, env) # -# glibc backtrace API, needed everywhere if we want to do shared_ptr<T> debugging +# check for VAMP and rubberband (currently optional) # -conf = Configure (env) -if conf.CheckCHeader('execinfo.h'): - conf.env.Append(CXXFLAGS="-DHAVE_EXECINFO") -env = conf.Finish () +libraries['vamp'] = LibraryInfo() + +env['RUBBERBAND'] = False + +#conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } ) +# +#if conf.CheckPKGExists('vamp-sdk'): +# have_vamp = True +# libraries['vamp'].ParseConfig('pkg-config --cflags --libs vamp-sdk') +#else: +# have_vamp = False +# +#libraries['vamp'] = conf.Finish () +# +#if have_vamp: +# if os.path.exists ('libs/rubberband/src'): +# conf = Configure (libraries['vamp']) +# if conf.CheckHeader ('fftw3.h'): +# env['RUBBERBAND'] = True +# libraries['rubberband'] = LibraryInfo (LIBS='rubberband', +# LIBPATH='#libs/rubberband', +# CPPPATH='#libs/rubberband', +# CCFLAGS='-DUSE_RUBBERBAND') +# libraries['vamp'] = conf.Finish () # # Check for libusb @@ -771,7 +820,7 @@ libraries['usb'] = conf.Finish () libraries['flac'] = LibraryInfo () prep_libcheck(env, libraries['flac']) -libraries['flac'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib") +libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib") # # june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions @@ -780,12 +829,14 @@ libraries['flac'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local # conf = Configure (libraries['flac']) -if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_set_read_callback', language='CXX'): +if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_init', language='CXX'): conf.env.Append(CCFLAGS='-DHAVE_FLAC') use_flac = True else: use_flac = False + libraries['flac'] = conf.Finish () + # or if that fails... #libraries['flac'] = LibraryInfo (LIBS='FLAC') @@ -793,7 +844,7 @@ libraries['flac'] = conf.Finish () libraries['boost'] = LibraryInfo () prep_libcheck(env, libraries['boost']) -libraries['boost'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib") +libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib") conf = Configure (libraries['boost']) if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False: print "Boost header files do not appear to be installed." @@ -834,17 +885,16 @@ else: libraries['dmalloc'] = conf.Finish () # -# Audio/MIDI library (needed for MIDI, since audio is all handled via JACK. Note, however, that -# we still need ALSA & CoreAudio to discover audio devices for the engine -# dialog, regardless of what MIDI subsystem is being used) +# Audio/MIDI library (needed for MIDI, since audio is all handled via JACK) # conf = Configure(env) + +# ALSA, for engine dialog +libraries['asound'] = LibraryInfo () if conf.CheckCHeader('alsa/asoundlib.h'): - libraries['sysaudio'] = LibraryInfo (LIBS='asound') -elif conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/CoreAudio.h'): - libraries['sysaudio'] = LibraryInfo (LINKFLAGS= '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load') + libraries['asound'] = LibraryInfo (LIBS='asound') if conf.CheckCHeader('jack/midiport.h'): libraries['sysmidi'] = LibraryInfo (LIBS='jack') @@ -863,14 +913,13 @@ elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/Co if env['GTKOSX']: # We need Carbon as well as the rest libraries['sysmidi'] = LibraryInfo ( - LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' ) + LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -framework Carbon -bind_at_load' ) else: libraries['sysmidi'] = LibraryInfo ( LINKFLAGS = ' -framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework CoreServices -framework AudioUnit -framework AudioToolbox -bind_at_load' ) env['SYSMIDI'] = 'CoreMIDI' subst_dict['%MIDITAG%'] = "ardour" subst_dict['%MIDITYPE%'] = "coremidi" - print "Using CoreMIDI" else: print "It appears you don't have the required MIDI libraries installed. For Linux this means you are missing the development package for ALSA libraries." sys.exit (1) @@ -883,8 +932,7 @@ if env['SYSLIBS']: { 'sigc++-2.0' : '2.0', 'gtkmm-2.4' : '2.8', - 'libgnomecanvasmm-2.6' : '2.12.0', - 'libSoundTouch' : '1.2.1' + 'libgnomecanvasmm-2.6' : '2.12.0' } conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig, @@ -912,8 +960,6 @@ if env['SYSLIBS']: libraries['atkmm'].ParseConfig ('pkg-config --cflags --libs atkmm-1.6') libraries['pangomm'] = LibraryInfo() libraries['pangomm'].ParseConfig ('pkg-config --cflags --libs pangomm-1.4') - libraries['cairomm'] = LibraryInfo() - libraries['cairomm'].ParseConfig ('pkg-config --cflags --libs cairomm-1.0') libraries['libgnomecanvasmm'] = LibraryInfo() libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6') @@ -930,17 +976,16 @@ if env['SYSLIBS']: # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas') libraries['soundtouch'] = LibraryInfo() - libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch') + #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0') # Comment the previous line and uncomment this for Debian: - #libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch') + libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch') libraries['appleutility'] = LibraryInfo(LIBS='libappleutility', LIBPATH='#libs/appleutility', CPPPATH='#libs/appleutility') coredirs = [ - 'templates', - 'manual' + 'templates' ] subdirs = [ @@ -972,10 +1017,7 @@ else: CPPPATH='#libs/sigc++2') libraries['glibmm2'] = LibraryInfo(LIBS='glibmm2', LIBPATH='#libs/glibmm2', - CPPPATH=['#libs/glibmm2/glib', '#libs/glibmm2']) - libraries['cairomm'] = LibraryInfo(LIBS='cairomm', - LIBPATH="#libs/cairomm", - CPPPATH='#libs/cairomm') + CPPPATH='#libs/glibmm2') libraries['pangomm'] = LibraryInfo(LIBS='pangomm', LIBPATH='#libs/gtkmm2/pango', CPPPATH='#libs/gtkmm2/pango') @@ -1006,9 +1048,7 @@ else: CPPPATH='#libs/appleutility') coredirs = [ - 'libs/soundtouch', - 'templates', - 'manual' + 'templates' ] subdirs = [ @@ -1034,7 +1074,6 @@ else: 'libs/gtkmm2/atk', 'libs/gtkmm2/gdk', 'libs/gtkmm2/gtk', - 'libs/cairomm', 'libs/libgnomecanvasmm', # 'libs/flowcanvas', 'libs/gtkmm2ext', @@ -1075,25 +1114,17 @@ else: env['POWERMATE'] = 0 env['TRANZPORT'] = 0 +# +# timestretch libraries +# + +timefx_subdirs = ['libs/soundtouch'] +#if env['RUBBERBAND']: +# timefx_subdirs += ['libs/rubberband'] + opts.Save('scache.conf', env) Help(opts.GenerateHelpText(env)) -if os.environ.has_key('PATH'): - env.Append(PATH = os.environ['PATH']) - -if os.environ.has_key('PKG_CONFIG_PATH'): - env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH']) - -if os.environ.has_key('CC'): - env['CC'] = os.environ['CC'] - -if os.environ.has_key('CXX'): - env['CXX'] = os.environ['CXX'] - -if os.environ.has_key('DISTCC_HOSTS'): - env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS'] - env['ENV']['HOME'] = os.environ['HOME'] - final_prefix = '$PREFIX' if env['DESTDIR'] : @@ -1112,14 +1143,6 @@ else: config_prefix = '$DESTDIR' + final_config_prefix -# For colorgcc -if os.environ.has_key('PATH'): - env['PATH'] = os.environ['PATH'] -if os.environ.has_key('TERM'): - env['TERM'] = os.environ['TERM'] -if os.environ.has_key('HOME'): - env['HOME'] = os.environ['HOME'] - # # everybody needs this # @@ -1174,8 +1197,8 @@ if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Versions/A/ subst_dict['%JACK_INPUT%'] = "coreaudio:Built-in Audio:in" subst_dict['%JACK_OUTPUT%'] = "coreaudio:Built-in Audio:out" else: - subst_dict['%JACK_INPUT%'] = "system:playback_" - subst_dict['%JACK_OUTPUT%'] = "system:capture_" + subst_dict['%JACK_INPUT%'] = "alsa_pcm:playback_" + subst_dict['%JACK_OUTPUT%'] = "alsa_pcm:capture_" # posix_memalign available if not conf.CheckFunc('posix_memalign'): @@ -1256,7 +1279,7 @@ env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE'])))) for subdir in coredirs: SConscript (subdir + '/SConscript') -for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]: +for sublistdir in [ subdirs, timefx_subdirs, gtk_subdirs, surface_subdirs ]: for subdir in sublistdir: SConscript (subdir + '/SConscript') diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 388a416143..f3b8788fad 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -49,12 +49,10 @@ gtkardour.Merge ([ libraries['gtk2'], libraries['xml'], libraries['xslt'], - libraries['soundtouch'], - libraries['rubberband'], libraries['samplerate'], libraries['jack'], - libraries['sysaudio'], - libraries['cairomm'] + libraries['cairomm'], + libraries['asound'] ]) gtkmmtests.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED") @@ -78,17 +76,22 @@ if gtkardour['FFT_ANALYSIS']: gtkardour.Merge ([libraries['fftw3f']]) gtkardour.Append(CCFLAGS='-DFFT_ANALYSIS') +if gtkardour['RUBBERBAND']: + gtkardour.Merge ([ libraries['rubberband'], libraries['vamp'], libraries['fftw3f'], libraries['fftw3'] ]) +else: + gtkardour.Merge ([ libraries['soundtouch'] ]) + skipped_files=Split(""" connection_editor.cc """) audiounit_files=Split(""" -au_pluginui.cc +au_pluginui.mm """) gtkosx_files=Split(""" sync-menu.c -cocoacarbon.c +cocoacarbon.mm """) x11_files=Split(""" @@ -165,6 +168,7 @@ export_session_dialog.cc export_region_dialog.cc export_range_markers_dialog.cc gain_meter.cc +generic_pluginui.cc ghostregion.cc gtk-custom-hruler.c gtk-custom-ruler.c @@ -172,7 +176,6 @@ io_selector.cc port_matrix.cc keyboard.cc keyeditor.cc -ladspa_pluginui.cc latency_gui.cc level_meter.cc location_ui.cc @@ -183,6 +186,7 @@ mixer_ui.cc new_session_dialog.cc option_editor.cc opts.cc + panner.cc panner2d.cc panner_ui.cc @@ -230,6 +234,10 @@ icon_files = glob.glob ('icons/*.png') intl_files = gtkardour_files + glob.glob('*.h') +evtest_files=Split(""" +evtest.cc +""") + mtest_files=Split(""" mtest.cc """) @@ -274,21 +282,23 @@ marker_view.cc visual_time_axis.cc """) -if env['CMT']: - extra_sources += cmt_files - gtkardour.Append (CCFLAGS="-DWITH_CMT") +#if env['CMT']: +# extra_sources += cmt_files +# gtkardour.Append (CCFLAGS="-DWITH_CMT") if gtkardour['GTKOSX']: - extra_sources += gtkosx_files - gtkardour.Append (CCFLAGS="-DTOP_MENUBAR -DGTKOSX") + extra_sources += gtkosx_files + gtkardour.Append (CCFLAGS="-DTOP_MENUBAR -DGTKOSX") + gtkardour.Append (LINKFLAGS=" -framework AppKit -framework CoreAudioKit") + + if gtkardour['AUDIOUNITS']: + extra_sources += audiounit_files + gtkardour.Append(CCFLAGS='-DHAVE_AUDIOUNITS') + gtkardour.Merge([libraries['appleutility']]) + else: extra_sources += x11_files -if gtkardour['AUDIOUNITS']: - extra_sources += audiounit_files - gtkardour.Append(CCFLAGS='-DHAVE_AUDIOUNITS') - gtkardour.Append(LINKFLAGS='-framework Carbon') - gtkardour.Merge([libraries['appleutility']]) if env['FFT_ANALYSIS']: extra_sources += fft_analysis_files @@ -307,6 +317,7 @@ executable = 'ardour-' + ardour_version ardour = gtkardour.Program(target = executable, source = gtkardour_files + extra_sources) ardourlib = gtkardour.SharedLibrary(target = 'ardourgtk', source = gtkardour_files + extra_sources) +evest = gtkmmtests.Program(target = 'evtest', source = evtest_files) mtest = gtkardour.Program(target = 'mtest', source = mtest_files) itest = gtkardour.Program(target = 'itest', source = itest_files) rcu = gtkardour.Program(target = 'rcu', source = rcu_files) @@ -396,7 +407,30 @@ my_subst_dict = { } # null substitution just to avoid ardour.bindings being in svn # -ardourbindings = env.SubstInFile ('ardour.bindings', 'ardour.bindings.in', SUBST_DICT = my_subst_dict); +keybindings_dict = { } + +if gtkardour['GTKOSX'] and gtkardour['NATIVE_OSX_KEYS']: + # + # Command(Mod1), Alt(Mod5), Ctrl, Shift + # + keybindings_dict['%PRIMARY%'] = 'Mod5' + keybindings_dict['%SECONDARY%'] = 'Alt' + keybindings_dict['%TERTIARY%'] = 'Shift' + keybindings_dict['%LEVEL4%'] = 'Ctrl' + keybindings_dict['%WINDOW%'] = 'Mod5' +else: + # + # Ctrl, Alt, Shift, Mod3(Meta) + # + keybindings_dict['%PRIMARY%'] = 'Ctrl' + keybindings_dict['%SECONDARY%'] = 'Alt' + keybindings_dict['%TERTIARY%'] = 'Shift' + keybindings_dict['%LEVEL4%'] = 'Mod2' + keybindings_dict['%WINDOW%'] = 'Ctrl' + +ardourbindings = env.SubstInFile ('ardour.bindings', 'ardour.bindings.in', SUBST_DICT = keybindings_dict); +ardoursaeDEbindings = env.SubstInFile ('ardour-sae-de.bindings', 'ardour-sae-de.bindings.in', SUBST_DICT = keybindings_dict); +ardoursaeANSIbindings = env.SubstInFile ('ardour-sae-ansi.bindings', 'ardour-sae-ansi.bindings.in', SUBST_DICT = keybindings_dict); my_subst_dict['%INSTALL_PREFIX%'] = final_prefix my_subst_dict['%LIBDIR%'] = env['LIBDIR'] @@ -409,6 +443,8 @@ ardourdev = env.SubstInFile ('ardev_common.sh','ardev_common.sh.in', SUBST_DICT env.AddPostAction (ardourdev, Chmod ('$TARGET', 0755)) Default(ardourbindings) +Default(ardoursaeDEbindings) +Default(ardoursaeANSIbindings) Default(ardourdev) Default(ardoursh) Default(ardour_dark_theme) @@ -441,7 +477,8 @@ env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), ardour_ env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.menus')) env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour-sae.menus')) env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour.bindings')) -env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour2_ui_default.conf')) +env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour-sae-ansi.bindings')) +env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour-sae-de.bindings')) # 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)) @@ -457,9 +494,11 @@ env.Alias ('tarball', env.Distribute (env['DISTTREE'], 'ardev_common.sh.in', 'ardev', 'ardbg', 'ardour2_ui_dark.rc.in', 'ardour2_ui_light.rc.in', 'splash.png', - 'ardour.menus', - 'ardour-sae.menus', - 'ardour.bindings.in', 'ardour2_ui_default.conf', + 'ardour.menus', 'ardour-sae.menus', + 'ardour.bindings.in', + 'ardour-sae-ansi.bindings.in', + 'ardour-sae-de.bindings.in', + 'ardour2_ui_default.conf', 'editor_xpms' ] + gtkardour_files + diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc index 023520c17e..1484c01454 100644 --- a/gtk2_ardour/actions.cc +++ b/gtk2_ardour/actions.cc @@ -19,6 +19,7 @@ #include <vector> #include <string> +#include <list> #include <gtk/gtkaccelmap.h> #include <gtk/gtkuimanager.h> @@ -150,6 +151,14 @@ ActionManager::lookup_entry (const ustring accel_path, Gtk::AccelKey& key) return known; } +struct SortActionsByLabel { + bool operator() (Glib::RefPtr<Gtk::Action> a, Glib::RefPtr<Gtk::Action> b) { + ustring astr = a->get_accel_path(); + ustring bstr = b->get_accel_path(); + return astr < bstr; + } +}; + void ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, vector<string>& keys, vector<AccelKey>& bindings) { @@ -162,18 +171,29 @@ ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, ve GList* acts; for (node = list; node; node = g_list_next (node)) { - + GtkActionGroup* group = (GtkActionGroup*) node->data; + + /* first pass: collect them all */ + + typedef std::list<Glib::RefPtr<Gtk::Action> > action_list; + action_list the_acts; for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) { - GtkAction* action = (GtkAction*) acts->data; + the_acts.push_back (Glib::wrap (action, true)); + } + + /* now sort by label */ + + SortActionsByLabel cmp; + the_acts.sort (cmp); - Glib::RefPtr<Action> act = Glib::wrap (action, true); + for (action_list::iterator a = the_acts.begin(); a != the_acts.end(); ++a) { + + string accel_path = (*a)->get_accel_path (); + ustring label = (*a)->property_label(); - string accel_path = act->get_accel_path (); - ustring label = act->property_label(); - names.push_back (label); paths.push_back (accel_path); diff --git a/gtk2_ardour/add_route_dialog.cc b/gtk2_ardour/add_route_dialog.cc index 45fe7456f3..dbf95037e8 100644 --- a/gtk2_ardour/add_route_dialog.cc +++ b/gtk2_ardour/add_route_dialog.cc @@ -25,6 +25,7 @@ #include <pbd/error.h> #include <pbd/convert.h> #include <gtkmm2ext/utils.h> +#include <ardour/profile.h> #include "utils.h" #include "add_route_dialog.h" @@ -67,10 +68,27 @@ AddRouteDialog::AddRouteDialog () { if (channel_combo_strings.empty()) { channel_combo_strings = I18N (channel_setup_names); + + if (ARDOUR::Profile->get_sae()) { + /* remove all but the first two (Mono & Stereo) */ + + while (track_mode_strings.size() > 2) { + track_mode_strings.pop_back(); + } + } + } if (track_mode_strings.empty()) { track_mode_strings = I18N (track_mode_names); + + if (ARDOUR::Profile->get_sae()) { + /* remove all but the first track mode (Normal) */ + + while (track_mode_strings.size() > 1) { + track_mode_strings.pop_back(); + } + } } set_name ("AddRouteDialog"); @@ -121,7 +139,9 @@ AddRouteDialog::AddRouteDialog () ccframe.set_shadow_type (SHADOW_IN); dvbox->pack_start (channel_combo, true, false, 5); - dvbox->pack_start (track_mode_combo, true, false, 5); + if (!ARDOUR::Profile->get_sae()) { + dvbox->pack_start (track_mode_combo, true, false, 5); + } dhbox->pack_start (*dvbox, true, false, 5); ccframe.add (*dhbox); @@ -198,6 +218,10 @@ AddRouteDialog::count () ARDOUR::TrackMode AddRouteDialog::mode () { + if (ARDOUR::Profile->get_sae()) { + return ARDOUR::Normal; + } + Glib::ustring str = track_mode_combo.get_active_text(); if (str == _("Normal")) { return ARDOUR::Normal; diff --git a/gtk2_ardour/ardev_common.sh.in b/gtk2_ardour/ardev_common.sh.in index e8746e9fed..8165b22bc4 100644 --- a/gtk2_ardour/ardev_common.sh.in +++ b/gtk2_ardour/ardev_common.sh.in @@ -7,10 +7,10 @@ export GTK_PATH=libs/clearlooks export ARDOUR_SURFACES_PATH=libs/surfaces/frontier:libs/surfaces/generic_midi:libs/surfaces/mackie:libs/surfaces/tranzport -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:libs/cairomm:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH=libs/surfaces/control_protocol:libs/ardour:libs/midi++2:libs/pbd:libs/rubberband: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 +export DYLD_FALLBACK_LIBRARY_PATH=$LD_LIBRARY_PATH # For the internal clearlooks engine export GTK_PATH=$PWD/libs/clearlooks:~/.ardour2 diff --git a/gtk2_ardour/ardour-sae-ansi.bindings.in b/gtk2_ardour/ardour-sae-ansi.bindings.in new file mode 100644 index 0000000000..523878bd3f --- /dev/null +++ b/gtk2_ardour/ardour-sae-ansi.bindings.in @@ -0,0 +1,346 @@ +; ardour GtkAccelMap rc-file -*- scheme -*- +; this file is an automated accelerator map dump +; +; (gtk_accel_path "<Actions>/RegionList/RegionListSort" "") +(gtk_accel_path "<Actions>/Common/Quit" "<%PRIMARY%>q") +(gtk_accel_path "<Actions>/Common/Save" "<%PRIMARY%>s") +; (gtk_accel_path "<Actions>/Editor/Pullup" "") +; (gtk_accel_path "<Actions>/Editor/zoom-to-session" "") +; (gtk_accel_path "<Actions>/JACK/JACKReconnect" "") +; (gtk_accel_path "<Actions>/Editor/Autoconnect" "") +; (gtk_accel_path "<Actions>/Editor/Edit" "") +(gtk_accel_path "<Actions>/Editor/cycle-edit-point" "grave") +(gtk_accel_path "<Actions>/Editor/cycle-edit-point-with-marker" "<%SECONDARY%>grave") +(gtk_accel_path "<Actions>/Editor/toggle-edit-mode" "1") +(gtk_accel_path "<Actions>/Editor/cycle-snap-mode" "2") +(gtk_accel_path "<Actions>/Editor/cycle-snap-choice" "3") +; (gtk_accel_path "<Actions>/redirectmenu/copy" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffFaster" "") +(gtk_accel_path "<Actions>/Transport/ToggleRollForgetCapture" "<%PRIMARY%>space") +(gtk_accel_path "<Actions>/Transport/record-roll" "<%TERTIARY%>space") +(gtk_accel_path "<Actions>/Transport/Record" "<%TERTIARY%>r") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionLength" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffSlowest" "") +; (gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-sync" "") +; (gtk_accel_path "<Actions>/redirectmenu/deactivate_all" "") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionPosition" "") +; (gtk_accel_path "<Actions>/Editor/ZoomFocus" "") +(gtk_accel_path "<Actions>/Editor/addExistingAudioFiles" "<%SECONDARY%>i") +; (gtk_accel_path "<Actions>/options/MeterFalloffSlow" "") +; (gtk_accel_path "<Actions>/RegionList/rlHide" "") +; (gtk_accel_path "<Actions>/Main/Metering" "") +(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-boundary" "rightarrow") +(gtk_accel_path "<Actions>/Editor/selected-marker-to-next-region-boundary" "<%PRIMARY%><%TERTIARY%>rightarrow") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-playhead" "") +; (gtk_accel_path "<Actions>/Editor/center-edit-cursor" "") +; (gtk_accel_path "<Actions>/Editor/Monitoring" "") +; (gtk_accel_path "<Actions>/redirectmenu/deactivate" "") +; (gtk_accel_path "<Actions>/options/LatchedRecordEnable" "") +; (gtk_accel_path "<Actions>/Transport/TogglePunchIn" "") +; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsPercentage" "") +; (gtk_accel_path "<Actions>/Main/Close" "") +; (gtk_accel_path "<Actions>/Main/New" "") +(gtk_accel_path "<Actions>/Editor/nudge-next-backward" "<%PRIMARY%>KP_Subtract") +; (gtk_accel_path "<Actions>/Editor/EditSelectRangeOptions" "") +; (gtk_accel_path "<Actions>/Transport/ToggleTimeMaster" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-thirds" "") +(gtk_accel_path "<Actions>/Editor/align-regions-start-relative" "<%TERTIARY%>a") +; (gtk_accel_path "<Actions>/Main/Export" "") +(gtk_accel_path "<Actions>/Editor/jump-forward-to-mark" "<%PRIMARY%>KP_Right") +; (gtk_accel_path "<Actions>/Editor/Smpte30" "") +; (gtk_accel_path "<Actions>/Editor/playhead-to-range-start" "") +; (gtk_accel_path "<Actions>/Editor/Subframes" "") +; (gtk_accel_path "<Actions>/Editor/Smpte2997drop" "") +(gtk_accel_path "<Actions>/Main/AddTrackBus" "<%PRIMARY%><%SECONDARY%>n") +(gtk_accel_path "<Actions>/Editor/align-regions-end" "<%LEVEL4%>a") +; (gtk_accel_path "<Actions>/JACK/JACKDisconnect" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffFast" "") +; (gtk_accel_path "<Actions>/options/FileDataFormatFloat" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-region-end" "") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-sync" "semicolon") +; (gtk_accel_path "<Actions>/options/StopRecordingOnXrun" "") +; (gtk_accel_path "<Actions>/RegionList/SortDescending" "") +; (gtk_accel_path "<Actions>/options/DoNotRunPluginsWhileRecording" "") +; (gtk_accel_path "<Actions>/Editor/PullupNone" "") +(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-range" "r") +(gtk_accel_path "<Actions>/Editor/jump-backward-to-mark" "<%PRIMARY%>KP_Left") +; (gtk_accel_path "<Actions>/Main/AudioFileFormatData" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffFastest" "") +(gtk_accel_path "<Actions>/Editor/play-selected-regions" "w") +(gtk_accel_path "<Actions>/Editor/play-edit-range" "<%SECONDARY%>w") +(gtk_accel_path "<Actions>/Transport/Forward" "<%PRIMARY%>rightarrow") +; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-seconds" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-frame" "") +; (gtk_accel_path "<Actions>/Main/ExportSelection" "") +; (gtk_accel_path "<Actions>/options/StopPluginsWithTransport" "") +(gtk_accel_path "<Actions>/Editor/editor-paste" "<%PRIMARY%>v") +(gtk_accel_path "<Actions>/Editor/scroll-tracks-down" "Page_Down") +(gtk_accel_path "<Actions>/Editor/select-next-route" "downarrow") +(gtk_accel_path "<Actions>/Editor/select-prev-route" "uparrow") +; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-minutes" "") +; (gtk_accel_path "<Actions>/Main/FlushWastebasket" "") +(gtk_accel_path "<Actions>/Editor/normalize-region" "n") +(gtk_accel_path "<Actions>/Editor/nudge-forward" "h") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionEndinFile" "") +; (gtk_accel_path "<Actions>/Editor/ToggleMeasureVisibility" "") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-center" "") +(gtk_accel_path "<Actions>/Editor/nudge-backward" "g") +; (gtk_accel_path "<Actions>/options/LatchedSolo" "") +; (gtk_accel_path "<Actions>/options/MeterHoldOff" "") +; (gtk_accel_path "<Actions>/options/OutputAutoConnectMaster" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency64" "") +(gtk_accel_path "<Actions>/Editor/undo" "<%PRIMARY%>z") +(gtk_accel_path "<Actions>/Editor/insert-region" "i") +; (gtk_accel_path "<Actions>/Editor/center-playhead" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-region-start" "") +; (gtk_accel_path "<Actions>/Editor/View" "") +; (gtk_accel_path "<Actions>/Editor/Layering" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency4096" "") +(gtk_accel_path "<Actions>/Editor/scroll-tracks-up" "Page_Up") +(gtk_accel_path "<Actions>/Editor/set-edit-point" "g") +; (gtk_accel_path "<Actions>/Editor/Smpte30drop" "") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-edit" "") +(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-boundary" "leftarrow") +(gtk_accel_path "<Actions>/Editor/selected-marker-to-previous-region-boundary" "<%PRIMARY%><%TERTIARY%>leftarrow") +; (gtk_accel_path "<Actions>/Editor/EditCursorMovementOptions" "") +; (gtk_accel_path "<Actions>/redirectmenu/activate_all" "") +; (gtk_accel_path "<Actions>/redirectmenu/paste" "") +; (gtk_accel_path "<Actions>/Editor/Smpte25" "") +; (gtk_accel_path "<Actions>/options/RegionEquivalentsOverlap" "") +; (gtk_accel_path "<Actions>/Main/MeteringFallOffRate" "") +; (gtk_accel_path "<Actions>/options/UseHardwareMonitoring" "") +; (gtk_accel_path "<Actions>/Editor/Smpte24" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-mark" "") +; (gtk_accel_path "<Actions>/Editor/CrossfadesShort" "") +; (gtk_accel_path "<Actions>/Editor/Smpte5994" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency8192" "") +; (gtk_accel_path "<Actions>/Editor/toggle-xfades-visible" "") +(gtk_accel_path "<Actions>/Editor/extend-range-to-end-of-region" "rightanglebracket") +(gtk_accel_path "<Actions>/Editor/start-range" "F1") +; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsSemitones" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency128" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-beat" "") +; (gtk_accel_path "<Actions>/Editor/RegionEditOps" "") +; (gtk_accel_path "<Actions>/Editor/snap-magnetic" "") +; (gtk_accel_path "<Actions>/Editor/playhead-to-range-end" "") +(gtk_accel_path "<Actions>/Editor/scroll-playhead-forward" "<%TERTIARY%>rightarrow") +(gtk_accel_path "<Actions>/Editor/align-regions-sync-relative" "<%SECONDARY%>less") +(gtk_accel_path "<Actions>/Editor/align-regions-sync" "less") +; (gtk_accel_path "<Actions>/Editor/EditSelectRegionOptions" "") +(gtk_accel_path "<Actions>/Editor/crop" "c") +; (gtk_accel_path "<Actions>/redirectmenu/newsend" "") +; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurfaceSubMenu" "") +; (gtk_accel_path "<Actions>/Editor/MeterFalloff" "") +; (gtk_accel_path "<Actions>/RegionList/rlRemove" "") +(gtk_accel_path "<Actions>/Transport/GotoStart" "Home") +(gtk_accel_path "<Actions>/Editor/select-all-before-edit-cursor" "<%TERTIARY%>Home") +(gtk_accel_path "<Actions>/Editor/scroll-playhead-backward" "<%TERTIARY%>leftarrow") +(gtk_accel_path "<Actions>/Editor/split-region" "z") +; (gtk_accel_path "<Actions>/Transport/ToggleAutoInput" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-thirtyseconds" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-minutes" "") +; (gtk_accel_path "<Actions>/Main/Windows" "") +; (gtk_accel_path "<Actions>/Main/CleanupUnused" "") +; (gtk_accel_path "<Actions>/redirectmenu/deselectall" "") +; (gtk_accel_path "<Actions>/options/SoloViaBus" "") +; (gtk_accel_path "<Actions>/RegionList/rlAudition" "") +(gtk_accel_path "<Actions>/Editor/set-region-sync-position" "u") +; (gtk_accel_path "<Actions>/Editor/PullupPlus4Plus1" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-region-boundary" "") +; (gtk_accel_path "<Actions>/JACK/JACK" "") +(gtk_accel_path "<Actions>/Editor/editor-cut" "<%PRIMARY%>x") +(gtk_accel_path "<Actions>/Editor/editor-separate" "F4") +; (gtk_accel_path "<Actions>/RegionList/SortAscending" "") +; (gtk_accel_path "<Actions>/Main/Help" "") +; (gtk_accel_path "<Actions>/options/UseExternalMonitoring" "") +; (gtk_accel_path "<Actions>/Editor/Smpte23976" "") +(gtk_accel_path "<Actions>/Common/goto-editor" "<%WINDOW%>e") +(gtk_accel_path "<Actions>/Editor/select-all" "F14") +(gtk_accel_path "<Actions>/Editor/invert-selection" "F15") +(gtk_accel_path "<Actions>/Editor/nudge-next-forward" "<%PRIMARY%>KP_Add") +; (gtk_accel_path "<Actions>/options/ShowSoloMutes" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-eighths" "") +(gtk_accel_path "<Actions>/Editor/select-all-after-playhead" "<%TERTIARY%><%PRIMARY%>p") +(gtk_accel_path "<Actions>/Common/ToggleMaximalEditor" "F11") +; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileLength" "") +; (gtk_accel_path "<Actions>/Editor/Timecode" "") +; (gtk_accel_path "<Actions>/Transport/PlaySelection" "") +; (gtk_accel_path "<Actions>/Editor/PullupMinus4Minus1" "") +(gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<%TERTIARY%><%PRIMARY%>e") +; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileName" "") +(gtk_accel_path "<Actions>/Editor/finish-range" "F2") +(gtk_accel_path "<Actions>/Editor/select-range-between-cursors" "F16") +(gtk_accel_path "<Actions>/Transport/Loop" "l") +; (gtk_accel_path "<Actions>/Editor/CrossfadesFull" "") +(gtk_accel_path "<Actions>/Editor/finish-add-range" "<%TERTIARY%><%PRIMARY%>KP_Up") +; (gtk_accel_path "<Actions>/options/SendMTC" "") +; (gtk_accel_path "<Actions>/Transport/TogglePunchOut" "") +(gtk_accel_path "<Actions>/Editor/select-all-in-loop-range" "<%PRIMARY%>l") +(gtk_accel_path "<Actions>/Editor/show-editor-mixer" "<%TERTIARY%>e") +; (gtk_accel_path "<Actions>/options/SoloInPlace" "") +; (gtk_accel_path "<Actions>/Main/Options" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffMedium" "") +(gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "f") +; (gtk_accel_path "<Actions>/Main/SaveTemplate" "") +(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<%PRIMARY%>uparrow") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionStartinFile" "") +; (gtk_accel_path "<Actions>/options/GainReduceFastTransport" "") +; (gtk_accel_path "<Actions>/Common/ToggleInspector" "") +; (gtk_accel_path "<Actions>/Transport/ToggleAutoPlay" "") +; (gtk_accel_path "<Actions>/Editor/playhead-to-next-region-sync" "") +(gtk_accel_path "<Actions>/Editor/edit-to-playhead" "<%SECONDARY%>Return") +; (gtk_accel_path "<Actions>/Editor/LayerMoveAddHigher" "") +; (gtk_accel_path "<Actions>/Editor/Smpte60" "") +; (gtk_accel_path "<Actions>/Main/Open" "") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-left" "") +; (gtk_accel_path "<Actions>/Main/TransportOptions" "") +; (gtk_accel_path "<Actions>/Main/ControlSurfaces" "") +; (gtk_accel_path "<Actions>/options/FileHeaderFormatBWF" "") +; (gtk_accel_path "<Actions>/Transport/ToggleAutoReturn" "") +; (gtk_accel_path "<Actions>/Editor/Smpte2997" "") +; (gtk_accel_path "<Actions>/Editor/ToggleWaveformVisibility" "") +(gtk_accel_path "<Actions>/Editor/redo" "<%PRIMARY%>r") +; (gtk_accel_path "<Actions>/Main/ExportSession" "") +; (gtk_accel_path "<Actions>/options/InputAutoConnectPhysical" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-edit-cursor" "") +(gtk_accel_path "<Actions>/Editor/temporal-zoom-in" "t") +; (gtk_accel_path "<Actions>/JACK/Latency" "") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-end" "<%TERTIARY%>F2") +; (gtk_accel_path "<Actions>/redirectmenu/rename" "") +; (gtk_accel_path "<Actions>/RegionList/rlShowAuto" "") +(gtk_accel_path "<Actions>/Editor/select-all-before-playhead" "<%PRIMARY%>p") +; (gtk_accel_path "<Actions>/Main/Session" "") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "<%TERTIARY%>F1") +; (gtk_accel_path "<Actions>/Main/AudioFileFormat" "") +; (gtk_accel_path "<Actions>/Transport/Transport" "") +(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionName" "") +; (gtk_accel_path "<Actions>/Main/KeyMouse Actions" "") +(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-gain" "g") +; (gtk_accel_path "<Actions>/Snap/snap-to-frame" "") +; (gtk_accel_path "<Actions>/Editor/SnapTo" "") +(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<%PRIMARY%>downarrow") +; (gtk_accel_path "<Actions>/Editor/Crossfades" "") +; (gtk_accel_path "<Actions>/Editor/PullupPlus4" "") +; (gtk_accel_path "<Actions>/Main/MeteringHoldTime" "") +; (gtk_accel_path "<Actions>/Editor/PullupPlus1" "") +; (gtk_accel_path "<Actions>/Editor/Smpte24976" "") +; (gtk_accel_path "<Actions>/options/FileDataFormat24bit" "") +; (gtk_accel_path "<Actions>/Editor/SnapMode" "") +(gtk_accel_path "<Actions>/Common/ToggleOptionsEditor" "<%WINDOW%>o") +; (gtk_accel_path "<Actions>/Editor/PullupMinus4" "") +(gtk_accel_path "<Actions>/Common/goto-mixer" "<%WINDOW%>m") +; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileCreationDate" "") +; (gtk_accel_path "<Actions>/redirectmenu/activate" "") +(gtk_accel_path "<Actions>/Editor/extend-range-to-start-of-region" "leftanglebracket") +; (gtk_accel_path "<Actions>/Editor/PullupMinus1" "") +; (gtk_accel_path "<Actions>/Editor/snap-normal" "") +(gtk_accel_path "<Actions>/Common/ToggleBigClock" "<%WINDOW%>b") +(gtk_accel_path "<Actions>/Common/ToggleKeyEditor" "<%WINDOW%>k") +; (gtk_accel_path "<Actions>/Snap/snap-to-asixteenthbeat" "") +(gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<%PRIMARY%>d") +; (gtk_accel_path "<Actions>/redirectmenu/edit" "") +(gtk_accel_path "<Actions>/Editor/duplicate-region" "d") +(gtk_accel_path "<Actions>/Editor/multi-duplicate-region" "<%SECONDARY%>d") +; (gtk_accel_path "<Actions>/JACK/JACKLatency2048" "") +; (gtk_accel_path "<Actions>/Editor/ToggleWaveformsWhileRecording" "") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-right" "") +(gtk_accel_path "<Actions>/Editor/remove-last-capture" "<%PRIMARY%>Delete") +; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE" "") +(gtk_accel_path "<Actions>/Transport/GotoZero" "KP_0") +(gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<%TERTIARY%>End") +; (gtk_accel_path "<Actions>/redirectmenu/cut" "") +; (gtk_accel_path "<Actions>/redirectmenu/newinsert" "") +; (gtk_accel_path "<Actions>/options/UseMMC" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffOff" "") +;(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-object" "o") +; (gtk_accel_path "<Actions>/Editor/PullupMinus4Plus1" "") +; (gtk_accel_path "<Actions>/Editor/MeterHold" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-cd-frame" "") +; (gtk_accel_path "<Actions>/options/StopTransportAtEndOfSession" "") +; (gtk_accel_path "<Actions>/Main/Cleanup" "") +; (gtk_accel_path "<Actions>/Main/Snapshot" "") +; (gtk_accel_path "<Actions>/Transport/ToggleVideoSync" "") +(gtk_accel_path "<Actions>/Transport/ToggleRoll" "space") +; (gtk_accel_path "<Actions>/RegionList/SortBySourceFilesystem" "") +(gtk_accel_path "<Actions>/Common/ToggleColorManager" "<%WINDOW%>c") +; (gtk_accel_path "<Actions>/Common/About" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency32" "") +(gtk_accel_path "<Actions>/Editor/playhead-to-edit" "Return") +; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE64" "") +(gtk_accel_path "<Actions>/Editor/brush-at-mouse" "F3") +; (gtk_accel_path "<Actions>/RegionList/rlShowAll" "") +(gtk_accel_path "<Actions>/Transport/Rewind" "<%PRIMARY%>leftarrow") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionTimestamp" "") +; (gtk_accel_path "<Actions>/options/VerifyRemoveLastCapture" "") +; (gtk_accel_path "<Actions>/options/OutputAutoConnectPhysical" "") +; (gtk_accel_path "<Actions>/options/SendMMC" "") +; (gtk_accel_path "<Actions>/Editor/toggle-auto-xfades" "") +; (gtk_accel_path "<Actions>/Main/AudioFileFormatHeader" "") +; (gtk_accel_path "<Actions>/options/MeterHoldShort" "") +; (gtk_accel_path "<Actions>/options/MeterHoldMedium" "") +(gtk_accel_path "<Actions>/Editor/select-all-before-edit-cursor" "<%PRIMARY%>e") +; (gtk_accel_path "<Actions>/Editor/Subframes80" "") +; (gtk_accel_path "<Actions>/options/FileHeaderFormatCAF" "") +(gtk_accel_path "<Actions>/Common/ToggleLocations" "<%WINDOW%>l") +; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurface" "") +(gtk_accel_path "<Actions>/Editor/editor-delete" "BackSpace") +; (gtk_accel_path "<Actions>/JACK/JACKLatency256" "") +(gtk_accel_path "<Actions>/Editor/select-all-between-cursors" "F16") +; (gtk_accel_path "<Actions>/Editor/LayerAddHigher" "") +; (gtk_accel_path "<Actions>/Editor/Solo" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency1024" "") +; (gtk_accel_path "<Actions>/Main/ExportRangeMarkers" "") +(gtk_accel_path "<Actions>/Editor/set-playhead" "p") +; (gtk_accel_path "<Actions>/Editor/toggle-xfades-active" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-bar" "") +; (gtk_accel_path "<Actions>/Editor/LayerLaterHigher" "") +; (gtk_accel_path "<Actions>/redirectmenu/selectall" "") +(gtk_accel_path "<Actions>/Editor/editor-copy" "<%PRIMARY%>c") +; (gtk_accel_path "<Actions>/Snap/snap-to-quarters" "") +(gtk_accel_path "<Actions>/Editor/temporal-zoom-out" "r") +; (gtk_accel_path "<Actions>/options/UseSoftwareMonitoring" "") +; (gtk_accel_path "<Actions>/Editor/Subframes100" "") +(gtk_accel_path "<Actions>/Editor/mute-unmute-region" "<%SECONDARY%>m") +(gtk_accel_path "<Actions>/Editor/add-location-from-playhead" "m") +; (gtk_accel_path "<Actions>/options/OutputAutoConnectManual" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-region-sync" "") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-sync" "apostrophe") +; (gtk_accel_path "<Actions>/redirectmenu/clear" "") +; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurfaceFeedback" "") +; (gtk_accel_path "<Actions>/Editor/PullupPlus4Minus1" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency512" "") +; (gtk_accel_path "<Actions>/Main/Recent" "") +; (gtk_accel_path "<Actions>/redirectmenu/newplugin" "") +; (gtk_accel_path "<Actions>/options/InputAutoConnectManual" "") +; (gtk_accel_path "<Actions>/options/MeterHoldLong" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-seconds" "") +(gtk_accel_path "<Actions>/Editor/set-fade-in-length" "q") +(gtk_accel_path "<Actions>/Editor/toggle-fade-in-active" "<%SECONDARY%>q") +(gtk_accel_path "<Actions>/Editor/set-fade-out-length" "e") +(gtk_accel_path "<Actions>/Editor/toggle-fade-out-active" "<%SECONDARY%>e") +(gtk_accel_path "<Actions>/Editor/trim-from-start" "<%TERTIARY%>braceleft") +(gtk_accel_path "<Actions>/Editor/trim-to-end" "<%TERTIARY%>braceright") +(gtk_accel_path "<Actions>/Editor/trim-front" "a") +(gtk_accel_path "<Actions>/Editor/trim-back" "s") +(gtk_accel_path "<Actions>/Editor/goto-mark-1" "KP_1") +(gtk_accel_path "<Actions>/Editor/goto-mark-2" "KP_2") +(gtk_accel_path "<Actions>/Editor/goto-mark-3" "KP_3") +(gtk_accel_path "<Actions>/Editor/goto-mark-4" "KP_4") +(gtk_accel_path "<Actions>/Editor/goto-mark-5" "KP_5") +(gtk_accel_path "<Actions>/Editor/goto-mark-6" "KP_6") +(gtk_accel_path "<Actions>/Editor/goto-mark-7" "KP_7") +(gtk_accel_path "<Actions>/Editor/goto-mark-8" "KP_8") +(gtk_accel_path "<Actions>/Editor/goto-mark-9" "KP_9") +(gtk_accel_path "<Actions>/Transport/ToggleClick" "5") +(gtk_accel_path "<Actions>/Transport/ToggleAutoReturn" "4") +(gtk_accel_path "<Actions>/Transport/focus-on-clock" "KP_Divide") +(gtk_accel_path "<Actions>/Editor/set-loop-from-edit-range" "bracketright") +(gtk_accel_path "<Actions>/Editor/set-punch-from-edit-range" "bracketleft") +(gtk_accel_path "<Actions>/Editor/set-loop-from-region" "<%PRIMARY%><%SECONDARY%>bracketright") +(gtk_accel_path "<Actions>/Editor/loop-region" "<%PRIMARY%>bracketright") +(gtk_accel_path "<Actions>/Editor/toggle-zoom" "o") +(gtk_accel_path "<Actions>/Editor/zoom-to-region" "y") +(gtk_accel_path "<Actions>/Editor/pitch-shift-region" "F5") +(gtk_accel_path "<Actions>/Editor/play-from-edit-point-and-return" "<%LEVEL4%>space") + diff --git a/gtk2_ardour/ardour-sae-de.bindings.in b/gtk2_ardour/ardour-sae-de.bindings.in new file mode 100644 index 0000000000..7feaed247b --- /dev/null +++ b/gtk2_ardour/ardour-sae-de.bindings.in @@ -0,0 +1,346 @@ +; ardour GtkAccelMap rc-file -*- scheme -*- +; this file is an automated accelerator map dump +; +; (gtk_accel_path "<Actions>/RegionList/RegionListSort" "") +(gtk_accel_path "<Actions>/Common/Quit" "<%PRIMARY%>q") +(gtk_accel_path "<Actions>/Common/Save" "<%PRIMARY%>s") +; (gtk_accel_path "<Actions>/Editor/Pullup" "") +(gtk_accel_path "<Actions>/Editor/zoom-to-session" "<%SECONDARY%>z") +; (gtk_accel_path "<Actions>/JACK/JACKReconnect" "") +; (gtk_accel_path "<Actions>/Editor/Autoconnect" "") +; (gtk_accel_path "<Actions>/Editor/Edit" "") +(gtk_accel_path "<Actions>/Editor/cycle-edit-point" "asciicircum") +(gtk_accel_path "<Actions>/Editor/cycle-edit-point-with-marker" "<%SECONDARY%>asciicircum") +(gtk_accel_path "<Actions>/Editor/toggle-edit-mode" "1") +(gtk_accel_path "<Actions>/Editor/cycle-snap-mode" "2") +(gtk_accel_path "<Actions>/Editor/cycle-snap-choice" "3") +; (gtk_accel_path "<Actions>/redirectmenu/copy" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffFaster" "") +(gtk_accel_path "<Actions>/Transport/ToggleRollForgetCapture" "<%PRIMARY%>space") +(gtk_accel_path "<Actions>/Transport/record-roll" "<%TERTIARY%>space") +(gtk_accel_path "<Actions>/Transport/Record" "<%TERTIARY%>r") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionLength" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffSlowest" "") +; (gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-sync" "") +; (gtk_accel_path "<Actions>/redirectmenu/deactivate_all" "") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionPosition" "") +; (gtk_accel_path "<Actions>/Editor/ZoomFocus" "") +(gtk_accel_path "<Actions>/Editor/addExistingAudioFiles" "<%PRIMARY%>i") +; (gtk_accel_path "<Actions>/options/MeterFalloffSlow" "") +; (gtk_accel_path "<Actions>/RegionList/rlHide" "") +; (gtk_accel_path "<Actions>/Main/Metering" "") +(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-boundary" "rightarrow") +(gtk_accel_path "<Actions>/Editor/selected-marker-to-next-region-boundary" "<%PRIMARY%><%TERTIARY%>rightarrow") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-playhead" "") +; (gtk_accel_path "<Actions>/Editor/center-edit-cursor" "") +; (gtk_accel_path "<Actions>/Editor/Monitoring" "") +; (gtk_accel_path "<Actions>/redirectmenu/deactivate" "") +; (gtk_accel_path "<Actions>/options/LatchedRecordEnable" "") +; (gtk_accel_path "<Actions>/Transport/TogglePunchIn" "") +; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsPercentage" "") +(gtk_accel_path "<Actions>/Main/Close" "<%PRIMARY%>w") +(gtk_accel_path "<Actions>/Main/New" "<%PRIMARY%>n") +(gtk_accel_path "<Actions>/Editor/nudge-next-backward" "<%PRIMARY%>KP_Subtract") +; (gtk_accel_path "<Actions>/Editor/EditSelectRangeOptions" "") +; (gtk_accel_path "<Actions>/Transport/ToggleTimeMaster" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-thirds" "") +(gtk_accel_path "<Actions>/Editor/align-regions-start-relative" "<%LEVEL4%>less") +(gtk_accel_path "<Actions>/Editor/align-regions-start" "<%LEVEL4%><%SECONDARY%>less") +; (gtk_accel_path "<Actions>/Main/Export" "<%PRIMARY%>e") +(gtk_accel_path "<Actions>/Editor/jump-forward-to-mark" "<%PRIMARY%>KP_6") +; (gtk_accel_path "<Actions>/Editor/Smpte30" "") +; (gtk_accel_path "<Actions>/Editor/playhead-to-range-start" "") +; (gtk_accel_path "<Actions>/Editor/Subframes" "") +; (gtk_accel_path "<Actions>/Editor/Smpte2997drop" "") +(gtk_accel_path "<Actions>/Main/AddTrackBus" "<%PRIMARY%><%TERTIARY%>n") +(gtk_accel_path "<Actions>/Editor/align-regions-end" "<%PRIMARY%><%SECONDARY%>less") +(gtk_accel_path "<Actions>/Editor/align-regions-end-relative" "<%PRIMARY%>less") +; (gtk_accel_path "<Actions>/JACK/JACKDisconnect" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffFast" "") +; (gtk_accel_path "<Actions>/options/FileDataFormatFloat" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-region-end" "") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-sync" "semicolon") +; (gtk_accel_path "<Actions>/options/StopRecordingOnXrun" "") +; (gtk_accel_path "<Actions>/RegionList/SortDescending" "") +; (gtk_accel_path "<Actions>/options/DoNotRunPluginsWhileRecording" "") +; (gtk_accel_path "<Actions>/Editor/PullupNone" "") +(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-range" "r") +(gtk_accel_path "<Actions>/Editor/jump-backward-to-mark" "<%PRIMARY%>KP_4") +; (gtk_accel_path "<Actions>/Main/AudioFileFormatData" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffFastest" "") +(gtk_accel_path "<Actions>/Editor/audition-at-mouse" "w") +(gtk_accel_path "<Actions>/Transport/Forward" "<%PRIMARY%>rightarrow") +; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-seconds" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-frame" "") +; (gtk_accel_path "<Actions>/Main/ExportSelection" "") +; (gtk_accel_path "<Actions>/options/StopPluginsWithTransport" "") +(gtk_accel_path "<Actions>/Editor/editor-paste" "<%PRIMARY%>v") +(gtk_accel_path "<Actions>/Editor/scroll-tracks-down" "Page_Down") +(gtk_accel_path "<Actions>/Editor/select-next-route" "downarrow") +(gtk_accel_path "<Actions>/Editor/select-prev-route" "uparrow") +; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-minutes" "") +; (gtk_accel_path "<Actions>/Main/FlushWastebasket" "") +(gtk_accel_path "<Actions>/Editor/normalize-region" "n") +(gtk_accel_path "<Actions>/Editor/nudge-forward" "h") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionEndinFile" "") +; (gtk_accel_path "<Actions>/Editor/ToggleMeasureVisibility" "") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-center" "") +(gtk_accel_path "<Actions>/Editor/nudge-backward" "g") +; (gtk_accel_path "<Actions>/options/LatchedSolo" "") +; (gtk_accel_path "<Actions>/options/MeterHoldOff" "") +; (gtk_accel_path "<Actions>/options/OutputAutoConnectMaster" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency64" "") +(gtk_accel_path "<Actions>/Editor/undo" "<%PRIMARY%>z") +(gtk_accel_path "<Actions>/Editor/insert-region" "i") +; (gtk_accel_path "<Actions>/Editor/center-playhead" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-region-start" "") +; (gtk_accel_path "<Actions>/Editor/View" "") +; (gtk_accel_path "<Actions>/Editor/Layering" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency4096" "") +(gtk_accel_path "<Actions>/Editor/scroll-tracks-up" "Page_Up") +(gtk_accel_path "<Actions>/Editor/set-edit-point" "g") +; (gtk_accel_path "<Actions>/Editor/Smpte30drop" "") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-edit" "") +(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-boundary" "leftarrow") +(gtk_accel_path "<Actions>/Editor/selected-marker-to-previous-region-boundary" "<%PRIMARY%><%TERTIARY%>leftarrow") +; (gtk_accel_path "<Actions>/Editor/EditCursorMovementOptions" "") +; (gtk_accel_path "<Actions>/redirectmenu/activate_all" "") +; (gtk_accel_path "<Actions>/redirectmenu/paste" "") +; (gtk_accel_path "<Actions>/Editor/Smpte25" "") +; (gtk_accel_path "<Actions>/options/RegionEquivalentsOverlap" "") +; (gtk_accel_path "<Actions>/Main/MeteringFallOffRate" "") +; (gtk_accel_path "<Actions>/options/UseHardwareMonitoring" "") +; (gtk_accel_path "<Actions>/Editor/Smpte24" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-mark" "") +; (gtk_accel_path "<Actions>/Editor/CrossfadesShort" "") +; (gtk_accel_path "<Actions>/Editor/Smpte5994" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency8192" "") +; (gtk_accel_path "<Actions>/Editor/toggle-xfades-visible" "") +(gtk_accel_path "<Actions>/Editor/extend-range-to-end-of-region" "rightanglebracket") +(gtk_accel_path "<Actions>/Editor/start-range" "F1") +; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsSemitones" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency128" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-beat" "") +; (gtk_accel_path "<Actions>/Editor/RegionEditOps" "") +; (gtk_accel_path "<Actions>/Editor/snap-magnetic" "") +; (gtk_accel_path "<Actions>/Editor/playhead-to-range-end" "") +(gtk_accel_path "<Actions>/Editor/scroll-playhead-forward" "<%TERTIARY%>rightarrow") +(gtk_accel_path "<Actions>/Editor/align-regions-sync-relative" "less") +(gtk_accel_path "<Actions>/Editor/align-regions-sync" "<%SECONDARY%>less") +; (gtk_accel_path "<Actions>/Editor/EditSelectRegionOptions" "") +(gtk_accel_path "<Actions>/Editor/crop" "c") +; (gtk_accel_path "<Actions>/redirectmenu/newsend" "") +; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurfaceSubMenu" "") +; (gtk_accel_path "<Actions>/Editor/MeterFalloff" "") +; (gtk_accel_path "<Actions>/RegionList/rlRemove" "") +(gtk_accel_path "<Actions>/Transport/GotoStart" "Home") +(gtk_accel_path "<Actions>/Editor/select-all-before-edit-cursor" "<%TERTIARY%>Home") +(gtk_accel_path "<Actions>/Editor/scroll-playhead-backward" "<%TERTIARY%>leftarrow") +(gtk_accel_path "<Actions>/Editor/split-region" "y") +; (gtk_accel_path "<Actions>/Transport/ToggleAutoInput" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-thirtyseconds" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-minutes" "") +; (gtk_accel_path "<Actions>/Main/Windows" "") +; (gtk_accel_path "<Actions>/Main/CleanupUnused" "") +; (gtk_accel_path "<Actions>/redirectmenu/deselectall" "<%PRIMARY%><%TERTIARY%>a") +; (gtk_accel_path "<Actions>/options/SoloViaBus" "") +; (gtk_accel_path "<Actions>/RegionList/rlAudition" "") +(gtk_accel_path "<Actions>/Editor/set-region-sync-position" "u") +; (gtk_accel_path "<Actions>/Editor/PullupPlus4Plus1" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-region-boundary" "") +; (gtk_accel_path "<Actions>/JACK/JACK" "") +(gtk_accel_path "<Actions>/Editor/editor-cut" "<%PRIMARY%>x") +(gtk_accel_path "<Actions>/Editor/editor-separate" "x") +; (gtk_accel_path "<Actions>/RegionList/SortAscending" "") +; (gtk_accel_path "<Actions>/Main/Help" "") +; (gtk_accel_path "<Actions>/options/UseExternalMonitoring" "") +; (gtk_accel_path "<Actions>/Editor/Smpte23976" "") +(gtk_accel_path "<Actions>/Common/goto-editor" "<%PRIMARY%>e") +(gtk_accel_path "<Actions>/Editor/select-all" "<%PRIMARY%>a") +(gtk_accel_path "<Actions>/Editor/invert-selection" "<%TERTIARY%>i") +(gtk_accel_path "<Actions>/Editor/nudge-next-forward" "<%PRIMARY%>KP_Add") +; (gtk_accel_path "<Actions>/options/ShowSoloMutes" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-eighths" "") +(gtk_accel_path "<Actions>/Editor/select-all-after-playhead" "<%TERTIARY%><%PRIMARY%>End") +(gtk_accel_path "<Actions>/Common/ToggleMaximalEditor" "F11") +; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileLength" "") +; (gtk_accel_path "<Actions>/Editor/Timecode" "") +; (gtk_accel_path "<Actions>/Transport/PlaySelection" "") +; (gtk_accel_path "<Actions>/Editor/PullupMinus4Minus1" "") +(gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<%TERTIARY%><%PRIMARY%>e") +; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileName" "") +(gtk_accel_path "<Actions>/Editor/finish-range" "F2") +(gtk_accel_path "<Actions>/Editor/select-range-between-cursors" "F16") +(gtk_accel_path "<Actions>/Transport/Loop" "l") +; (gtk_accel_path "<Actions>/Editor/CrossfadesFull" "") +(gtk_accel_path "<Actions>/Editor/finish-add-range" "<%TERTIARY%><%PRIMARY%>KP_Up") +; (gtk_accel_path "<Actions>/options/SendMTC" "") +; (gtk_accel_path "<Actions>/Transport/TogglePunchOut" "") +(gtk_accel_path "<Actions>/Editor/select-all-in-loop-range" "<%TERTIARY%>l") +(gtk_accel_path "<Actions>/Editor/show-editor-mixer" "<%TERTIARY%>e") +; (gtk_accel_path "<Actions>/options/SoloInPlace" "") +; (gtk_accel_path "<Actions>/Main/Options" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffMedium" "") +(gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "f") +; (gtk_accel_path "<Actions>/Main/SaveTemplate" "") +(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<%PRIMARY%>uparrow") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionStartinFile" "") +; (gtk_accel_path "<Actions>/options/GainReduceFastTransport" "") +; (gtk_accel_path "<Actions>/Common/ToggleInspector" "") +; (gtk_accel_path "<Actions>/Transport/ToggleAutoPlay" "") +; (gtk_accel_path "<Actions>/Editor/playhead-to-next-region-sync" "") +(gtk_accel_path "<Actions>/Editor/edit-to-playhead" "<%SECONDARY%>Return") +; (gtk_accel_path "<Actions>/Editor/LayerMoveAddHigher" "") +; (gtk_accel_path "<Actions>/Editor/Smpte60" "") +(gtk_accel_path "<Actions>/Main/Open" "<%PRIMARY%>o") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-left" "") +; (gtk_accel_path "<Actions>/Main/TransportOptions" "") +; (gtk_accel_path "<Actions>/Main/ControlSurfaces" "") +; (gtk_accel_path "<Actions>/options/FileHeaderFormatBWF" "") +; (gtk_accel_path "<Actions>/Transport/ToggleAutoReturn" "") +; (gtk_accel_path "<Actions>/Editor/Smpte2997" "") +; (gtk_accel_path "<Actions>/Editor/ToggleWaveformVisibility" "") +(gtk_accel_path "<Actions>/Editor/redo" "<%PRIMARY%>r") +(gtk_accel_path "<Actions>/Main/ExportSession" "<%PRIMARY%>e") +; (gtk_accel_path "<Actions>/options/InputAutoConnectPhysical" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-edit-cursor" "") +(gtk_accel_path "<Actions>/Editor/temporal-zoom-in" "t") +; (gtk_accel_path "<Actions>/JACK/Latency" "") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-end" "<%TERTIARY%>F2") +; (gtk_accel_path "<Actions>/redirectmenu/rename" "") +; (gtk_accel_path "<Actions>/RegionList/rlShowAuto" "") +(gtk_accel_path "<Actions>/Editor/select-all-before-playhead" "<%TERTIARY%>Home") +; (gtk_accel_path "<Actions>/Main/Session" "") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "<%TERTIARY%>F1") +; (gtk_accel_path "<Actions>/Main/AudioFileFormat" "") +; (gtk_accel_path "<Actions>/Transport/Transport" "") +; (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionName" "") +; (gtk_accel_path "<Actions>/Main/KeyMouse Actions" "") +(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-gain" "g") +; (gtk_accel_path "<Actions>/Snap/snap-to-frame" "") +; (gtk_accel_path "<Actions>/Editor/SnapTo" "") +(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<%PRIMARY%>downarrow") +; (gtk_accel_path "<Actions>/Editor/Crossfades" "") +; (gtk_accel_path "<Actions>/Editor/PullupPlus4" "") +; (gtk_accel_path "<Actions>/Main/MeteringHoldTime" "") +; (gtk_accel_path "<Actions>/Editor/PullupPlus1" "") +; (gtk_accel_path "<Actions>/Editor/Smpte24976" "") +; (gtk_accel_path "<Actions>/options/FileDataFormat24bit" "") +; (gtk_accel_path "<Actions>/Editor/SnapMode" "") +(gtk_accel_path "<Actions>/Common/ToggleOptionsEditor" "<%PRIMARY%>o") +; (gtk_accel_path "<Actions>/Editor/PullupMinus4" "") +(gtk_accel_path "<Actions>/Common/goto-mixer" "<%PRIMARY%>m") +; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileCreationDate" "") +; (gtk_accel_path "<Actions>/redirectmenu/activate" "") +(gtk_accel_path "<Actions>/Editor/extend-range-to-start-of-region" "leftanglebracket") +; (gtk_accel_path "<Actions>/Editor/PullupMinus1" "") +; (gtk_accel_path "<Actions>/Editor/snap-normal" "") +(gtk_accel_path "<Actions>/Common/ToggleBigClock" "<%PRIMARY%>b") +(gtk_accel_path "<Actions>/Common/ToggleKeyEditor" "<%PRIMARY%>k") +; (gtk_accel_path "<Actions>/Snap/snap-to-asixteenthbeat" "") +(gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<%TERTIARY%>p") +; (gtk_accel_path "<Actions>/redirectmenu/edit" "") +(gtk_accel_path "<Actions>/Editor/duplicate-region" "d") +(gtk_accel_path "<Actions>/Editor/multi-duplicate-region" "<%SECONDARY%>d") +; (gtk_accel_path "<Actions>/JACK/JACKLatency2048" "") +; (gtk_accel_path "<Actions>/Editor/ToggleWaveformsWhileRecording" "") +; (gtk_accel_path "<Actions>/Zoom/zoom-focus-right" "") +(gtk_accel_path "<Actions>/Editor/remove-last-capture" "<%PRIMARY%>Delete") +; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE" "") +(gtk_accel_path "<Actions>/Transport/GotoZero" "KP_Insert") +(gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<%TERTIARY%>End") +; (gtk_accel_path "<Actions>/redirectmenu/cut" "") +; (gtk_accel_path "<Actions>/redirectmenu/newinsert" "") +; (gtk_accel_path "<Actions>/options/UseMMC" "") +; (gtk_accel_path "<Actions>/options/MeterFalloffOff" "") +;(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-object" "o") +; (gtk_accel_path "<Actions>/Editor/PullupMinus4Plus1" "") +; (gtk_accel_path "<Actions>/Editor/MeterHold" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-cd-frame" "") +; (gtk_accel_path "<Actions>/options/StopTransportAtEndOfSession" "") +; (gtk_accel_path "<Actions>/Main/Cleanup" "") +(gtk_accel_path "<Actions>/Main/Snapshot" "<%PRIMARY%><%TERTIARY%>s") +; (gtk_accel_path "<Actions>/Transport/ToggleVideoSync" "") +(gtk_accel_path "<Actions>/Transport/ToggleRoll" "space") +; (gtk_accel_path "<Actions>/RegionList/SortBySourceFilesystem" "") +(gtk_accel_path "<Actions>/Common/ToggleColorManager" "<%PRIMARY%>c") +; (gtk_accel_path "<Actions>/Common/About" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency32" "") +(gtk_accel_path "<Actions>/Editor/playhead-to-edit" "Return") +; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE64" "") +(gtk_accel_path "<Actions>/Editor/brush-at-mouse" "F3") +; (gtk_accel_path "<Actions>/RegionList/rlShowAll" "") +(gtk_accel_path "<Actions>/Transport/Rewind" "<%PRIMARY%>leftarrow") +; (gtk_accel_path "<Actions>/RegionList/SortByRegionTimestamp" "") +; (gtk_accel_path "<Actions>/options/VerifyRemoveLastCapture" "") +; (gtk_accel_path "<Actions>/options/OutputAutoConnectPhysical" "") +; (gtk_accel_path "<Actions>/options/SendMMC" "") +; (gtk_accel_path "<Actions>/Editor/toggle-auto-xfades" "") +; (gtk_accel_path "<Actions>/Main/AudioFileFormatHeader" "") +; (gtk_accel_path "<Actions>/options/MeterHoldShort" "") +; (gtk_accel_path "<Actions>/options/MeterHoldMedium" "") +(gtk_accel_path "<Actions>/Editor/select-all-before-edit-cursor" "<%PRIMARY%>e") +; (gtk_accel_path "<Actions>/Editor/Subframes80" "") +; (gtk_accel_path "<Actions>/options/FileHeaderFormatCAF" "") +(gtk_accel_path "<Actions>/Common/ToggleLocations" "<%PRIMARY%>l") +; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurface" "") +(gtk_accel_path "<Actions>/Editor/editor-delete" "BackSpace") +; (gtk_accel_path "<Actions>/JACK/JACKLatency256" "") +(gtk_accel_path "<Actions>/Editor/select-all-between-cursors" "F16") +; (gtk_accel_path "<Actions>/Editor/LayerAddHigher" "") +; (gtk_accel_path "<Actions>/Editor/Solo" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency1024" "") +; (gtk_accel_path "<Actions>/Main/ExportRangeMarkers" "") +(gtk_accel_path "<Actions>/Editor/set-playhead" "p") +; (gtk_accel_path "<Actions>/Editor/toggle-xfades-active" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-bar" "") +; (gtk_accel_path "<Actions>/Editor/LayerLaterHigher" "") +; (gtk_accel_path "<Actions>/redirectmenu/selectall" "") +(gtk_accel_path "<Actions>/Editor/editor-copy" "<%PRIMARY%>c") +; (gtk_accel_path "<Actions>/Snap/snap-to-quarters" "") +(gtk_accel_path "<Actions>/Editor/temporal-zoom-out" "r") +; (gtk_accel_path "<Actions>/options/UseSoftwareMonitoring" "") +; (gtk_accel_path "<Actions>/Editor/Subframes100" "") +(gtk_accel_path "<Actions>/Editor/mute-unmute-region" "<%SECONDARY%>m") +(gtk_accel_path "<Actions>/Editor/add-location-from-playhead" "m") +; (gtk_accel_path "<Actions>/options/OutputAutoConnectManual" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-region-sync" "") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-sync" "apostrophe") +; (gtk_accel_path "<Actions>/redirectmenu/clear" "") +; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurfaceFeedback" "") +; (gtk_accel_path "<Actions>/Editor/PullupPlus4Minus1" "") +; (gtk_accel_path "<Actions>/JACK/JACKLatency512" "") +(gtk_accel_path "<Actions>/Main/Recent" "<%PRIMARY%><%TERTIARY%>o") +; (gtk_accel_path "<Actions>/redirectmenu/newplugin" "") +; (gtk_accel_path "<Actions>/options/InputAutoConnectManual" "") +; (gtk_accel_path "<Actions>/options/MeterHoldLong" "") +; (gtk_accel_path "<Actions>/Snap/snap-to-seconds" "") +(gtk_accel_path "<Actions>/Editor/set-fade-in-length" "q") +(gtk_accel_path "<Actions>/Editor/toggle-fade-in-active" "<%SECONDARY%>q") +(gtk_accel_path "<Actions>/Editor/set-fade-out-length" "e") +(gtk_accel_path "<Actions>/Editor/toggle-fade-out-active" "<%SECONDARY%>e") +(gtk_accel_path "<Actions>/Editor/trim-from-start" "<%TERTIARY%>braceleft") +(gtk_accel_path "<Actions>/Editor/trim-to-end" "<%TERTIARY%>braceright") +(gtk_accel_path "<Actions>/Editor/trim-front" "a") +(gtk_accel_path "<Actions>/Editor/trim-back" "s") +(gtk_accel_path "<Actions>/Editor/goto-mark-1" "KP_1") +(gtk_accel_path "<Actions>/Editor/goto-mark-2" "KP_2") +(gtk_accel_path "<Actions>/Editor/goto-mark-3" "KP_3") +(gtk_accel_path "<Actions>/Editor/goto-mark-4" "KP_4") +(gtk_accel_path "<Actions>/Editor/goto-mark-5" "KP_5") +(gtk_accel_path "<Actions>/Editor/goto-mark-6" "KP_6") +(gtk_accel_path "<Actions>/Editor/goto-mark-7" "KP_7") +(gtk_accel_path "<Actions>/Editor/goto-mark-8" "KP_8") +(gtk_accel_path "<Actions>/Editor/goto-mark-9" "KP_9") +(gtk_accel_path "<Actions>/Transport/ToggleClick" "5") +(gtk_accel_path "<Actions>/Transport/ToggleAutoReturn" "4") +(gtk_accel_path "<Actions>/Transport/focus-on-clock" "KP_Divide") +(gtk_accel_path "<Actions>/Editor/set-loop-from-edit-range" "bracketright") +(gtk_accel_path "<Actions>/Editor/set-punch-from-edit-range" "bracketleft") +(gtk_accel_path "<Actions>/Editor/set-loop-from-region" "<%PRIMARY%><%SECONDARY%>bracketright") +(gtk_accel_path "<Actions>/Editor/loop-region" "<%PRIMARY%>bracketright") +(gtk_accel_path "<Actions>/Editor/toggle-zoom" "<%TERTIARY%>z") +(gtk_accel_path "<Actions>/Editor/zoom-to-region" "z") + + diff --git a/gtk2_ardour/ardour-sae.menus b/gtk2_ardour/ardour-sae.menus index e132329dbc..a1818a9965 100644 --- a/gtk2_ardour/ardour-sae.menus +++ b/gtk2_ardour/ardour-sae.menus @@ -6,30 +6,36 @@ <menuitem action='Open'/> <menuitem action='Recent'/> <menuitem action='Close'/> + <menuitem action='Quit'/> <separator/> <menuitem action='Save'/> <menuitem action='Snapshot'/> <menuitem action='SaveTemplate'/> <separator/> <menuitem action='AddTrackBus'/> + + <menu name='Files' action='Files'> + <menuitem action='addExistingAudioFiles'/> + <separator/> + <menuitem action='ExportSession'/> + </menu> + <separator/> <menu name='Cleanup' action='Cleanup'> <menuitem action='CleanupUnused'/> <menuitem action='FlushWastebasket'/> </menu> + <menuitem action='ToggleOptionsEditor'/> + <menuitem action='About'/> </menu> - <menu name='Files' action='Files'> - <menuitem action='addExistingAudioFiles'/> - <separator/> - <menuitem action='ExportSession'/> - <menuitem action='ExportSelection'/> - <menuitem action='ExportRangeMarkers'/> - </menu> <menu name='Transport' action='Transport'> <menuitem action='ToggleRoll'/> + <menuitem action='play-from-edit-point-and-return'/> + <menuitem action='play-edit-range'/> + <menuitem action='record-roll'/> <menuitem action='ToggleRollForgetCapture'/> <menuitem action='Loop'/> - <menuitem action='PlaySelection'/> + <menuitem action='loop-region'/> <menuitem action='set-playhead'/> <menuitem action='Forward'/> <menuitem action='Rewind'/> @@ -46,28 +52,38 @@ <menuitem action='jump-backward-to-mark'/> <menuitem action='add-location-from-playhead'/> <separator/> - <menuitem action='playhead-to-next-region-start'/> - <menuitem action='playhead-to-next-region-end'/> - <menuitem action='playhead-to-previous-region-start'/> - <menuitem action='playhead-to-previous-region-end'/> + <menuitem action='playhead-to-next-region-boundary'/> + <menuitem action='playhead-to-previous-region-boundary'/> <menuitem action='playhead-to-next-region-sync'/> <menuitem action='playhead-to-previous-region-sync'/> <menuitem action='center-playhead'/> + <separator/> <menuitem action='playhead-to-edit'/> - <separator/> - <menuitem action='playhead-to-range-start'/> - <menuitem action='playhead-to-range-end'/> - <menu action='TransportOptions'> - <menuitem action='ToggleTimeMaster'/> - <menuitem action='TogglePunchIn'/> - <menuitem action='TogglePunchOut'/> - <menuitem action='ToggleAutoInput'/> - <menuitem action='ToggleAutoPlay'/> - <menuitem action='ToggleAutoReturn'/> - <menuitem action='ToggleClick'/> - <menuitem action='toggle-follow-playhead'/> - <menuitem action='ToggleVideoSync'/> - </menu> + <menuitem action='focus-on-clock'/> + <separator/> + <menuitem action='ToggleTimeMaster'/> + <menuitem action='TogglePunchIn'/> + <menuitem action='TogglePunchOut'/> + <menuitem action='ToggleAutoInput'/> + <menuitem action='ToggleAutoPlay'/> + <menuitem action='ToggleAutoReturn'/> + <menuitem action='ToggleClick'/> + <menuitem action='toggle-follow-playhead'/> + <separator/> + <menuitem action='set-loop-from-edit-range'/> + <menuitem action='set-loop-from-region'/> + <menuitem action='set-punch-from-edit-range'/> + <menu action='LocateToMarker'> + <menuitem action='goto-mark-1'/> + <menuitem action='goto-mark-2'/> + <menuitem action='goto-mark-3'/> + <menuitem action='goto-mark-4'/> + <menuitem action='goto-mark-5'/> + <menuitem action='goto-mark-6'/> + <menuitem action='goto-mark-7'/> + <menuitem action='goto-mark-8'/> + <menuitem action='goto-mark-9'/> + </menu> </menu> <menu name='Edit' action='Edit'> <menuitem action='undo'/> @@ -77,22 +93,33 @@ <menuitem action='editor-copy'/> <menuitem action='editor-paste'/> <menuitem action='set-edit-point'/> + <menuitem action='editor-separate'/> + <separator/> <menuitem action='remove-last-capture'/> <separator/> + <menuitem action='select-all'/> + <menuitem action='deselect-all'/> + <menuitem action='invert-selection'/> + <menuitem action='select-all-after-edit-cursor'/> + <menuitem action='select-all-before-edit-cursor'/> + <menuitem action='select-all-between-cursors'/> + <menuitem action='select-all-within-cursors'/> + <menuitem action='select-all-in-punch-range'/> + <menuitem action='select-all-in-loop-range'/> + <separator/> + <menuitem action='select-next-route'/> + <menuitem action='select-prev-route'/> + <separator/> <menu action='EditCursorMovementOptions'> - <menuitem action='edit-cursor-to-next-region-start'/> - <menuitem action='edit-cursor-to-next-region-end'/> - <menuitem action='edit-cursor-to-previous-region-start'/> - <menuitem action='edit-cursor-to-previous-region-end'/> + <menuitem action='selected-marker-to-next-region-boundary'/> + <menuitem action='selected-marker-to-previous-region-boundary'/> <menuitem action='edit-cursor-to-next-region-sync'/> <menuitem action='edit-cursor-to-previous-region-sync'/> <menuitem action='center-edit-cursor'/> <menuitem action='edit-to-playhead'/> - <menuitem action='edit-cursor-to-range-start'/> - <menuitem action='edit-cursor-to-range-end'/> </menu> <menu name='KeyMouse Actions' action='KeyMouse Actions'> - <menuitem action='audition-at-mouse'/> + <menuitem action='play-selected-regions'/> <menuitem action='brush-at-mouse'/> <menuitem action='mute-unmute-region'/> <separator/> @@ -101,28 +128,12 @@ <menuitem action='set-mouse-mode-gain'/> <menuitem action='set-mouse-mode-zoom'/> <menuitem action='set-mouse-mode-timefx'/> + <separator/> + <menuitem action='cycle-edit-point'/> + <menuitem action='cycle-edit-point-with-marker'/> + <menuitem action='toggle-edit-mode'/> </menu> - <separator/> - <menuitem action='ToggleOptionsEditor'/> </menu> - <menu name='Select' action='Select'> - <menuitem action='select-range-between-cursors'/> - <menuitem action='extend-range-to-start-of-region'/> - <menuitem action='extend-range-to-end-of-region'/> - <menuitem action='start-range'/> - <menuitem action='finish-range'/> - <menuitem action='finish-add-range'/> - <separator/> - <menuitem action='select-all'/> - <menuitem action='select-all-after-edit-cursor'/> - <menuitem action='select-all-before-edit-cursor'/> - <menuitem action='select-all-after-playhead'/> - <menuitem action='select-all-before-playhead'/> - <menuitem action='select-all-between-cursors'/> - <menuitem action='select-all-within-cursors'/> - <menuitem action='select-all-in-punch-range'/> - <menuitem action='select-all-in-loop-range'/> - </menu> <menu name='Regions' action='Regions'> <menuitem action='crop'/> <menuitem action='duplicate-region'/> @@ -130,9 +141,7 @@ <menuitem action='normalize-region'/> <separator/> <menuitem action="nudge-forward"/> - <menuitem action="nudge-next-forward"/> <menuitem action="nudge-backward"/> - <menuitem action="nudge-next-backward"/> <menuitem action='split-region'/> <menuitem action='set-region-sync-position'/> <separator/> @@ -144,28 +153,33 @@ <menuitem action='align-regions-sync-relative'/> <separator/> <menuitem action='set-fade-in-length'/> + <menuitem action='toggle-fade-in-active'/> <menuitem action='set-fade-out-length'/> + <menuitem action='toggle-fade-out-active'/> <separator/> - <menuitem action='trim-from-start'/> - <menuitem action='trim-to-end'/> + <menuitem action='trim-front'/> + <menuitem action='trim-back'/> <menuitem action='trim-region-to-loop'/> <menuitem action='trim-region-to-punch'/> + <separator/> + <menuitem action='pitch-shift-region'/> </menu> <menu name='View' action = 'View'> + <menuitem action='ToggleMaximalEditor'/> + <separator/> <menu name='ZoomFocus' action='ZoomFocus'> - <menuitem action='zoom-focus-left'/> - <menuitem action='zoom-focus-right'/> - <menuitem action='zoom-focus-center'/> <menuitem action='zoom-focus-playhead'/> <menuitem action='zoom-focus-edit'/> <menuitem action='zoom-focus-mouse'/> </menu> <menu name='SnapMode' action='SnapMode'> + <menuitem action='snap-off'/> <menuitem action='snap-normal'/> <menuitem action='snap-magnetic'/> + <separator/> + <menuitem action='cycle-snap-mode'/> </menu> <menu name='SnapTo' action='SnapTo'> - <menuitem action='snap-to-frame'/> <menuitem action='snap-to-cd-frame'/> <menuitem action='snap-to-smpte-frame'/> <menuitem action='snap-to-smpte-seconds'/> @@ -180,17 +194,18 @@ <menuitem action='snap-to-beat'/> <menuitem action='snap-to-bar'/> <menuitem action='snap-to-mark'/> - <menuitem action='snap-to-edit-cursor'/> <menuitem action='snap-to-region-start'/> <menuitem action='snap-to-region-end'/> <menuitem action='snap-to-region-sync'/> <menuitem action='snap-to-region-boundary'/> + <menuitem action='cycle-snap-choice'/> </menu> <separator/> - <menuitem action='temporal-zoom-in'/> <menuitem action='temporal-zoom-out'/> <menuitem action='zoom-to-session'/> + <menuitem action='zoom-to-region'/> + <menuitem action='toggle-zoom'/> <menuitem action='scroll-tracks-down'/> <menuitem action='scroll-tracks-up'/> <menuitem action='scroll-tracks-down'/> @@ -205,77 +220,24 @@ <separator/> <menuitem action='show-editor-mixer'/> <menuitem action='SyncEditorAndMixerTrackOrder'/> + <menuitem action='ToggleMeasureVisibility'/> <menuitem action='ToggleLogoVisibility'/> - </menu> - <menu name='JACK' action='JACK'> - <menuitem action='JACKDisconnect'/> - <menuitem action='JACKReconnect'/> - <menu name='Latency' action='Latency'> - <menuitem action='JACKLatency32'/> - <menuitem action='JACKLatency64'/> - <menuitem action='JACKLatency128'/> - <menuitem action='JACKLatency256'/> - <menuitem action='JACKLatency512'/> - <menuitem action='JACKLatency1024'/> - <menuitem action='JACKLatency2048'/> - <menuitem action='JACKLatency4096'/> - <menuitem action='JACKLatency8192'/> - </menu> - </menu> - <menu name='Windows' action = 'Windows'> - <menuitem action='ToggleMaximalEditor'/> <separator/> <menuitem action='goto-editor'/> <menuitem action='goto-mixer'/> - <menuitem action='ToggleInspector'/> <menuitem action='ToggleLocations'/> + <menuitem action='ToggleKeyEditor'/> <menuitem action='ToggleThemeManager'/> <menuitem action='ToggleBigClock'/> - <separator/> </menu> <menu name='Options' action='Options'> - <menu action='AudioFileFormat'> - <menu action='AudioFileFormatData'> - <menuitem action='FileDataFormatFloat'/> - <menuitem action='FileDataFormat24bit'/> - <menuitem action='FileDataFormat16bit'/> - </menu> - <menu action='AudioFileFormatHeader'> - <menuitem action='FileHeaderFormatBWF'/> - <menuitem action='FileHeaderFormatWAVE'/> - <menuitem action='FileHeaderFormatWAVE64'/> - <menuitem action='FileHeaderFormatCAF'/> - </menu> - </menu> <menu action='Monitoring'> - <menuitem action='UseHardwareMonitoring'/> <menuitem action='UseSoftwareMonitoring'/> <menuitem action='UseExternalMonitoring'/> </menu> - <menu action='Metering'> - <menu action='MeteringFallOffRate'> - <menuitem action='MeterFalloffOff'/> - <menuitem action='MeterFalloffSlowest'/> - <menuitem action='MeterFalloffSlow'/> - <menuitem action='MeterFalloffMedium'/> - <menuitem action='MeterFalloffFast'/> - <menuitem action='MeterFalloffFaster'/> - <menuitem action='MeterFalloffFastest'/> - </menu> - <menu action='MeteringHoldTime'> - <menuitem action='MeterHoldOff'/> - <menuitem action='MeterHoldShort'/> - <menuitem action='MeterHoldMedium'/> - <menuitem action='MeterHoldLong'/> - </menu> - </menu> - <menu action='Solo'> - <menuitem action='LatchedSolo'/> - </menu> + <menuitem action='LatchedSolo'/> + <menuitem action='link-region-and-track-selection'/> </menu> - <menu name='Help' action='Help'> - <menuitem action='About'/> - </menu> </menubar> <popup name='redirectmenu'> diff --git a/gtk2_ardour/ardour.bindings.in b/gtk2_ardour/ardour.bindings.in index 2e9b4af1e9..fb26ff1b56 100644 --- a/gtk2_ardour/ardour.bindings.in +++ b/gtk2_ardour/ardour.bindings.in @@ -2,29 +2,31 @@ ; this file is an automated accelerator map dump ; ; (gtk_accel_path "<Actions>/RegionList/RegionListSort" "") -(gtk_accel_path "<Actions>/Common/Quit" "<Control>q") -(gtk_accel_path "<Actions>/Common/Save" "<Control>s") +(gtk_accel_path "<Actions>/Common/Quit" "<%PRIMARY%>q") +(gtk_accel_path "<Actions>/Common/Save" "<%PRIMARY%>s") ; (gtk_accel_path "<Actions>/Editor/Pullup" "") ; (gtk_accel_path "<Actions>/Editor/zoom-to-session" "") ; (gtk_accel_path "<Actions>/JACK/JACKReconnect" "") ; (gtk_accel_path "<Actions>/Editor/Autoconnect" "") ; (gtk_accel_path "<Actions>/Editor/Edit" "") -(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-end" "<Control>comma") +(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-boundary" "comma") +(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-sync" "<%PRIMARY%>comma") ; (gtk_accel_path "<Actions>/processormenu/copy" "") ; (gtk_accel_path "<Actions>/options/MeterFalloffFaster" "") -(gtk_accel_path "<Actions>/Transport/ToggleRollForgetCapture" "<Control>space") -(gtk_accel_path "<Actions>/Transport/Record" "<Shift>r") +(gtk_accel_path "<Actions>/Transport/ToggleRollForgetCapture" "<%PRIMARY%>space") +(gtk_accel_path "<Actions>/Transport/Record" "<%TERTIARY%>r") ; (gtk_accel_path "<Actions>/RegionList/SortByRegionLength" "") ; (gtk_accel_path "<Actions>/options/MeterFalloffSlowest" "") ; (gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-sync" "") ; (gtk_accel_path "<Actions>/processormenu/deactivate_all" "") ; (gtk_accel_path "<Actions>/RegionList/SortByRegionPosition" "") ; (gtk_accel_path "<Actions>/Editor/ZoomFocus" "") +(gtk_accel_path "<Actions>/Editor/addExistingAudioFiles" "<%SECONDARY%>i") ; (gtk_accel_path "<Actions>/options/MeterFalloffSlow" "") (gtk_accel_path "<Actions>/options/ABAllPlugins" "<Control><Alt>p") ; (gtk_accel_path "<Actions>/RegionList/rlHide" "") ; (gtk_accel_path "<Actions>/Main/Metering" "") -(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-end" "<Control>period") +(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-sync" "<%PRIMARY%>period") ; (gtk_accel_path "<Actions>/Zoom/zoom-focus-playhead" "") ; (gtk_accel_path "<Actions>/Editor/center-edit-cursor" "") ; (gtk_accel_path "<Actions>/Editor/Monitoring" "") @@ -35,19 +37,19 @@ (gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-start" "bracketleft") ; (gtk_accel_path "<Actions>/Main/Close" "") ; (gtk_accel_path "<Actions>/Main/New" "") -(gtk_accel_path "<Actions>/Editor/nudge-next-backward" "<Control>KP_Subtract") +(gtk_accel_path "<Actions>/Editor/nudge-next-backward" "<%PRIMARY%>KP_Subtract") ; (gtk_accel_path "<Actions>/Editor/EditSelectRangeOptions" "") ; (gtk_accel_path "<Actions>/Transport/ToggleTimeMaster" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-thirds" "") -(gtk_accel_path "<Actions>/Editor/align-regions-start-relative" "<Shift>a") +(gtk_accel_path "<Actions>/Editor/align-regions-start-relative" "<%TERTIARY%>a") ; (gtk_accel_path "<Actions>/Main/Export" "") -(gtk_accel_path "<Actions>/Editor/jump-forward-to-mark" "<Control>KP_Right") +(gtk_accel_path "<Actions>/Editor/jump-forward-to-mark" "<%PRIMARY%>KP_Right") ; (gtk_accel_path "<Actions>/Editor/Smpte30" "") ; (gtk_accel_path "<Actions>/Editor/playhead-to-range-start" "") ; (gtk_accel_path "<Actions>/Editor/Subframes" "") ; (gtk_accel_path "<Actions>/Editor/Smpte2997drop" "") ; (gtk_accel_path "<Actions>/Main/AddTrackBus" "") -(gtk_accel_path "<Actions>/Editor/align-regions-end" "<Control><Mod2>a") +(gtk_accel_path "<Actions>/Editor/align-regions-end" "<%PRIMARY%><%LEVEL4%>a") ; (gtk_accel_path "<Actions>/JACK/JACKDisconnect" "") ; (gtk_accel_path "<Actions>/options/MeterFalloffFast" "") ; (gtk_accel_path "<Actions>/options/FileDataFormatFloat" "") @@ -59,16 +61,16 @@ ; (gtk_accel_path "<Actions>/options/DoNotRunPluginsWhileRecording" "") ; (gtk_accel_path "<Actions>/Editor/PullupNone" "") (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-range" "r") -(gtk_accel_path "<Actions>/Editor/jump-backward-to-mark" "<Control>KP_Left") +(gtk_accel_path "<Actions>/Editor/jump-backward-to-mark" "<%PRIMARY%>KP_Left") ; (gtk_accel_path "<Actions>/Main/AudioFileFormatData" "") ; (gtk_accel_path "<Actions>/options/MeterFalloffFastest" "") ; (gtk_accel_path "<Actions>/Editor/audition-at-mouse" "") -(gtk_accel_path "<Actions>/Transport/Forward" "<Control>rightarrow") +(gtk_accel_path "<Actions>/Transport/Forward" "<%PRIMARY%>rightarrow") ; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-seconds" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-frame" "") ; (gtk_accel_path "<Actions>/Main/ExportSelection" "") ; (gtk_accel_path "<Actions>/options/StopPluginsWithTransport" "") -(gtk_accel_path "<Actions>/Editor/editor-paste" "<Control>v") +(gtk_accel_path "<Actions>/Editor/editor-paste" "<%PRIMARY%>v") (gtk_accel_path "<Actions>/Editor/scroll-tracks-down" "Page_Down") ; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-minutes" "") ; (gtk_accel_path "<Actions>/Main/FlushWastebasket" "") @@ -82,10 +84,9 @@ ; (gtk_accel_path "<Actions>/options/MeterHoldOff" "") ; (gtk_accel_path "<Actions>/options/OutputAutoConnectMaster" "") ; (gtk_accel_path "<Actions>/JACK/JACKLatency64" "") -(gtk_accel_path "<Actions>/Editor/undo" "<Control>z") +(gtk_accel_path "<Actions>/Editor/undo" "<%PRIMARY%>z") (gtk_accel_path "<Actions>/Editor/insert-region" "i") ; (gtk_accel_path "<Actions>/Editor/center-playhead" "") -(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-start" "bracketright") ; (gtk_accel_path "<Actions>/Snap/snap-to-region-start" "") ; (gtk_accel_path "<Actions>/Editor/View" "") ; (gtk_accel_path "<Actions>/Editor/Layering" "") @@ -94,7 +95,6 @@ (gtk_accel_path "<Actions>/Editor/set-edit-point" "e") ; (gtk_accel_path "<Actions>/Editor/Smpte30drop" "") ; (gtk_accel_path "<Actions>/Zoom/zoom-focus-edit" "") -(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-start" "comma") ; (gtk_accel_path "<Actions>/Editor/EditCursorMovementOptions" "") ; (gtk_accel_path "<Actions>/processormenu/activate_all" "") ; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsTapeTrack" "") @@ -112,14 +112,14 @@ ; (gtk_accel_path "<Actions>/Editor/toggle-xfades-visible" "") (gtk_accel_path "<Actions>/Editor/extend-range-to-end-of-region" "rightanglebracket") (gtk_accel_path "<Actions>/Editor/scroll-backward" "leftarrow") -(gtk_accel_path "<Actions>/Editor/start-range" "F1") +(gtk_accel_path "<Actions>/Editor/start-range" "<%PRIMARY%>KP_Down") ; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsSemitones" "") ; (gtk_accel_path "<Actions>/JACK/JACKLatency128" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-beat" "") ; (gtk_accel_path "<Actions>/Editor/RegionEditOps" "") ; (gtk_accel_path "<Actions>/Editor/snap-magnetic" "") ; (gtk_accel_path "<Actions>/Editor/playhead-to-range-end" "") -(gtk_accel_path "<Actions>/Editor/scroll-playhead-forward" "<Shift>rightarrow") +(gtk_accel_path "<Actions>/Editor/scroll-playhead-forward" "<%TERTIARY%>rightarrow") (gtk_accel_path "<Actions>/Editor/align-regions-sync-relative" "a") ; (gtk_accel_path "<Actions>/Editor/EditSelectRegionOptions" "") (gtk_accel_path "<Actions>/Editor/crop" "c") @@ -128,63 +128,62 @@ ; (gtk_accel_path "<Actions>/Editor/MeterFalloff" "") ; (gtk_accel_path "<Actions>/RegionList/rlRemove" "") (gtk_accel_path "<Actions>/Transport/GotoStart" "Home") -(gtk_accel_path "<Actions>/Editor/scroll-playhead-backward" "<Shift>leftarrow") +(gtk_accel_path "<Actions>/Editor/scroll-playhead-backward" "<%TERTIARY%>leftarrow") (gtk_accel_path "<Actions>/Editor/split-region" "s") ; (gtk_accel_path "<Actions>/Transport/ToggleAutoInput" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-thirtyseconds" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-minutes" "") -(gtk_accel_path "<Actions>/Editor/align-regions-sync" "<Mod2>a") +(gtk_accel_path "<Actions>/Editor/align-regions-sync" "<%LEVEL4%>a") ; (gtk_accel_path "<Actions>/Main/Windows" "") ; (gtk_accel_path "<Actions>/Main/CleanupUnused" "") ; (gtk_accel_path "<Actions>/processormenu/deselectall" "") ; (gtk_accel_path "<Actions>/options/SoloViaBus" "") -(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "z") +(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "<Shift>z") ; (gtk_accel_path "<Actions>/RegionList/rlAudition" "") (gtk_accel_path "<Actions>/Editor/set-region-sync-position" "v") ; (gtk_accel_path "<Actions>/Editor/PullupPlus4Plus1" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-region-boundary" "") ; (gtk_accel_path "<Actions>/JACK/JACK" "") -(gtk_accel_path "<Actions>/Editor/editor-cut" "<Control>x") +(gtk_accel_path "<Actions>/Editor/editor-cut" "<%PRIMARY%>x") ; (gtk_accel_path "<Actions>/RegionList/SortAscending" "") ; (gtk_accel_path "<Actions>/Main/Help" "") ; (gtk_accel_path "<Actions>/options/UseExternalMonitoring" "") ; (gtk_accel_path "<Actions>/Editor/Smpte23976" "") -(gtk_accel_path "<Actions>/Common/goto-editor" "<Alt>e") -(gtk_accel_path "<Actions>/Editor/select-all" "<Control>a") -(gtk_accel_path "<Actions>/Editor/nudge-next-forward" "<Control>KP_Add") +(gtk_accel_path "<Actions>/Common/goto-editor" "<%WINDOW%>e") +(gtk_accel_path "<Actions>/Editor/select-all" "<%PRIMARY%>a") +(gtk_accel_path "<Actions>/Editor/nudge-next-forward" "<%PRIMARY%>KP_Add") ; (gtk_accel_path "<Actions>/options/ShowSoloMutes" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-eighths" "") -(gtk_accel_path "<Actions>/Editor/select-all-after-playhead" "<Shift><Control>p") +(gtk_accel_path "<Actions>/Editor/select-all-after-playhead" "<%TERTIARY%><%PRIMARY%>p") (gtk_accel_path "<Actions>/Common/ToggleMaximalEditor" "F11") ; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileLength" "") ; (gtk_accel_path "<Actions>/Editor/Timecode" "") ; (gtk_accel_path "<Actions>/Transport/PlaySelection" "") ; (gtk_accel_path "<Actions>/Editor/PullupMinus4Minus1" "") -(gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<Shift><Control>e") +(gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<%TERTIARY%><%PRIMARY%>e") ; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileName" "") -(gtk_accel_path "<Actions>/Editor/finish-range" "F2") -(gtk_accel_path "<Actions>/Editor/select-range-between-cursors" "F3") +(gtk_accel_path "<Actions>/Editor/finish-range" "<%PRIMARY%>KP_Up") (gtk_accel_path "<Actions>/Transport/Loop" "l") ; (gtk_accel_path "<Actions>/Editor/CrossfadesFull" "") -(gtk_accel_path "<Actions>/Editor/finish-add-range" "<Shift><Control>KP_Up") +(gtk_accel_path "<Actions>/Editor/finish-add-range" "<%TERTIARY%><%PRIMARY%>KP_Up") ; (gtk_accel_path "<Actions>/Transport/ToggleClick" "") ; (gtk_accel_path "<Actions>/options/SendMTC" "") ; (gtk_accel_path "<Actions>/Transport/TogglePunchOut" "") -(gtk_accel_path "<Actions>/Editor/select-all-in-loop-range" "<Control>l") -(gtk_accel_path "<Actions>/Editor/show-editor-mixer" "<Shift>e") +(gtk_accel_path "<Actions>/Editor/select-all-in-loop-range" "<%PRIMARY%>l") +(gtk_accel_path "<Actions>/Editor/show-editor-mixer" "<%TERTIARY%>e") (gtk_accel_path "<Actions>/Editor/show-editor-list" "<Shift>l") ; (gtk_accel_path "<Actions>/options/SoloInPlace" "") ; (gtk_accel_path "<Actions>/Main/Options" "") ; (gtk_accel_path "<Actions>/options/MeterFalloffMedium" "") (gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "f") ; (gtk_accel_path "<Actions>/Main/SaveTemplate" "") -(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<Control>uparrow") +(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<%PRIMARY%>uparrow") ; (gtk_accel_path "<Actions>/RegionList/SortByRegionStartinFile" "") ; (gtk_accel_path "<Actions>/options/GainReduceFastTransport" "") ; (gtk_accel_path "<Actions>/Common/ToggleInspector" "") ; (gtk_accel_path "<Actions>/Transport/ToggleAutoPlay" "") ; (gtk_accel_path "<Actions>/Editor/playhead-to-next-region-sync" "") -(gtk_accel_path "<Actions>/Editor/edit-to-playhead" "<Alt>Return") +(gtk_accel_path "<Actions>/Editor/edit-to-playhead" "<%SECONDARY%>Return") ; (gtk_accel_path "<Actions>/Editor/LayerMoveAddHigher" "") ; (gtk_accel_path "<Actions>/Editor/Smpte60" "") ; (gtk_accel_path "<Actions>/Main/Open" "") @@ -196,20 +195,20 @@ ; (gtk_accel_path "<Actions>/Transport/ToggleAutoReturn" "") ; (gtk_accel_path "<Actions>/Editor/Smpte2997" "") ; (gtk_accel_path "<Actions>/Editor/ToggleWaveformVisibility" "") -(gtk_accel_path "<Actions>/Editor/redo" "<Control>r") +(gtk_accel_path "<Actions>/Editor/redo" "<%PRIMARY%>r") ; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsRegion" "") ; (gtk_accel_path "<Actions>/Main/ExportSession" "") ; (gtk_accel_path "<Actions>/options/InputAutoConnectPhysical" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-edit-cursor" "") (gtk_accel_path "<Actions>/Editor/temporal-zoom-in" "minus") ; (gtk_accel_path "<Actions>/JACK/Latency" "") -(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-end" "<Shift>F2") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-end" "F2") ; (gtk_accel_path "<Actions>/processormenu/rename" "") ; (gtk_accel_path "<Actions>/RegionList/rlShowAuto" "") -(gtk_accel_path "<Actions>/Editor/select-all-before-playhead" "<Control>p") +(gtk_accel_path "<Actions>/Editor/select-all-before-playhead" "<%PRIMARY%>p") ; (gtk_accel_path "<Actions>/Editor/addExistingAudioFiles" "") ; (gtk_accel_path "<Actions>/Main/Session" "") -(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "<Shift>F1") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "F1") ; (gtk_accel_path "<Actions>/Main/AudioFileFormat" "") ; (gtk_accel_path "<Actions>/Transport/Transport" "") (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t") @@ -219,37 +218,37 @@ (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-gain" "g") ; (gtk_accel_path "<Actions>/Snap/snap-to-frame" "") ; (gtk_accel_path "<Actions>/Editor/SnapTo" "") -(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<Control>downarrow") +(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<%PRIMARY%>downarrow") ; (gtk_accel_path "<Actions>/Editor/Crossfades" "") ; (gtk_accel_path "<Actions>/Editor/PullupPlus4" "") (gtk_accel_path "<Actions>/Editor/add-location-from-playhead" "KP_Enter") -(gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-end" "<Control>bracketleft") +(gtk_accel_path "<Actions>/Editor/edit-cursor-to-previous-region-end" "<%PRIMARY%>bracketleft") ; (gtk_accel_path "<Actions>/Main/MeteringHoldTime" "") ; (gtk_accel_path "<Actions>/Editor/PullupPlus1" "") ; (gtk_accel_path "<Actions>/Editor/Smpte24976" "") ; (gtk_accel_path "<Actions>/options/FileDataFormat24bit" "") ; (gtk_accel_path "<Actions>/Editor/SnapMode" "") -(gtk_accel_path "<Actions>/Common/ToggleOptionsEditor" "<Control>o") +(gtk_accel_path "<Actions>/Common/ToggleOptionsEditor" "<%WINDOW%>o") ; (gtk_accel_path "<Actions>/Editor/PullupMinus4" "") -(gtk_accel_path "<Actions>/Common/goto-mixer" "<Alt>m") +(gtk_accel_path "<Actions>/Common/goto-mixer" "<%WINDOW%>m") ; (gtk_accel_path "<Actions>/Editor/addExternalAudioToTrack" "") ; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileCreationDate" "") ; (gtk_accel_path "<Actions>/processormenu/activate" "") (gtk_accel_path "<Actions>/Editor/extend-range-to-start-of-region" "leftanglebracket") ; (gtk_accel_path "<Actions>/Editor/PullupMinus1" "") ; (gtk_accel_path "<Actions>/Editor/snap-normal" "") -; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsTrack" "") -(gtk_accel_path "<Actions>/Common/ToggleBigClock" "<Alt>b") +(gtk_accel_path "<Actions>/Common/ToggleBigClock" "<%WINDOW%>b") +(gtk_accel_path "<Actions>/Common/ToggleKeyEditor" "<%WINDOW%>k") ; (gtk_accel_path "<Actions>/Snap/snap-to-asixteenthbeat" "") -(gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<Control>d") +(gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<%PRIMARY%>d") ; (gtk_accel_path "<Actions>/processormenu/edit" "") (gtk_accel_path "<Actions>/Editor/duplicate-region" "d") ; (gtk_accel_path "<Actions>/JACK/JACKLatency2048" "") ; (gtk_accel_path "<Actions>/Editor/ToggleWaveformsWhileRecording" "") ; (gtk_accel_path "<Actions>/Zoom/zoom-focus-right" "") -(gtk_accel_path "<Actions>/Editor/remove-last-capture" "<Control>Delete") +(gtk_accel_path "<Actions>/Editor/remove-last-capture" "<%PRIMARY%>Delete") ; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE" "") -(gtk_accel_path "<Actions>/Transport/GotoZero" "KP_Insert") +(gtk_accel_path "<Actions>/Transport/GotoZero" "KP_0") (gtk_accel_path "<Actions>/Transport/GotoEnd" "End") ; (gtk_accel_path "<Actions>/processormenu/cut" "") ; (gtk_accel_path "<Actions>/processormenu/newinsert" "") @@ -265,28 +264,28 @@ ; (gtk_accel_path "<Actions>/Transport/ToggleVideoSync" "") (gtk_accel_path "<Actions>/Transport/ToggleRoll" "space") ; (gtk_accel_path "<Actions>/RegionList/SortBySourceFilesystem" "") -(gtk_accel_path "<Actions>/Common/ToggleColorManager" "<Alt>c") +(gtk_accel_path "<Actions>/Common/ToggleColorManager" "<%WINDOW%>c") ; (gtk_accel_path "<Actions>/Common/About" "") ; (gtk_accel_path "<Actions>/JACK/JACKLatency32" "") (gtk_accel_path "<Actions>/Editor/playhead-to-edit" "Return") ; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE64" "") -(gtk_accel_path "<Actions>/Editor/brush-at-mouse" "<Control>b") +(gtk_accel_path "<Actions>/Editor/brush-at-mouse" "<%PRIMARY%>b") ; (gtk_accel_path "<Actions>/RegionList/rlShowAll" "") -(gtk_accel_path "<Actions>/Transport/Rewind" "<Control>leftarrow") +(gtk_accel_path "<Actions>/Transport/Rewind" "<%PRIMARY%>leftarrow") ; (gtk_accel_path "<Actions>/RegionList/SortByRegionTimestamp" "") ; (gtk_accel_path "<Actions>/options/VerifyRemoveLastCapture" "") ; (gtk_accel_path "<Actions>/options/OutputAutoConnectPhysical" "") (gtk_accel_path "<Actions>/Editor/step-tracks-up" "uparrow") -(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-start" "period") +(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-boundary" "period") ; (gtk_accel_path "<Actions>/options/SendMMC" "") ; (gtk_accel_path "<Actions>/Editor/toggle-auto-xfades" "") ; (gtk_accel_path "<Actions>/Main/AudioFileFormatHeader" "") ; (gtk_accel_path "<Actions>/options/MeterHoldShort" "") ; (gtk_accel_path "<Actions>/options/MeterHoldMedium" "") -(gtk_accel_path "<Actions>/Editor/select-all-before-edit-cursor" "<Control>e") +(gtk_accel_path "<Actions>/Editor/select-all-before-edit-cursor" "<%PRIMARY%>e") ; (gtk_accel_path "<Actions>/Editor/Subframes80" "") ; (gtk_accel_path "<Actions>/options/FileHeaderFormatCAF" "") -(gtk_accel_path "<Actions>/Common/ToggleLocations" "<Alt>l") +(gtk_accel_path "<Actions>/Common/ToggleLocations" "<%WINDOW%>l") ; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurface" "") (gtk_accel_path "<Actions>/Editor/editor-delete" "Delete") ; (gtk_accel_path "<Actions>/JACK/JACKLatency256" "") @@ -300,7 +299,7 @@ ; (gtk_accel_path "<Actions>/Snap/snap-to-bar" "") ; (gtk_accel_path "<Actions>/Editor/LayerLaterHigher" "") ; (gtk_accel_path "<Actions>/processormenu/selectall" "") -(gtk_accel_path "<Actions>/Editor/editor-copy" "<Control>c") +(gtk_accel_path "<Actions>/Editor/editor-copy" "<%PRIMARY%>c") ; (gtk_accel_path "<Actions>/Snap/snap-to-quarters" "") (gtk_accel_path "<Actions>/Editor/temporal-zoom-out" "equal") ; (gtk_accel_path "<Actions>/options/UseSoftwareMonitoring" "") @@ -313,13 +312,35 @@ ; (gtk_accel_path "<Actions>/Editor/ToggleGeneric MIDISurfaceFeedback" "") ; (gtk_accel_path "<Actions>/Editor/PullupPlus4Minus1" "") ; (gtk_accel_path "<Actions>/JACK/JACKLatency512" "") -(gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-end" "<Control>bracketright") ; (gtk_accel_path "<Actions>/Main/Recent" "") ; (gtk_accel_path "<Actions>/processormenu/newplugin" "") ; (gtk_accel_path "<Actions>/options/InputAutoConnectManual" "") ; (gtk_accel_path "<Actions>/options/MeterHoldLong" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-seconds" "") +(gtk_accel_path "<Actions>/Editor/cycle-edit-point" "grave") +(gtk_accel_path "<Actions>/Editor/toggle-edit-mode" "1") +(gtk_accel_path "<Actions>/Editor/cycle-snap-mode" "2") +(gtk_accel_path "<Actions>/Editor/cycle-snap-choice" "3") (gtk_accel_path "<Actions>/Editor/set-fade-in-length" "slash") (gtk_accel_path "<Actions>/Editor/set-fade-out-length" "backslash") -(gtk_accel_path "<Actions>/Editor/trim-from-start" "<Shift>braceleft") -(gtk_accel_path "<Actions>/Editor/trim-to-end" "<Shift>braceright") +(gtk_accel_path "<Actions>/Editor/trim-from-start" "<%TERTIARY%>braceleft") +(gtk_accel_path "<Actions>/Editor/trim-to-end" "<%TERTIARY%>braceright") +;(gtk_accel_path "<Actions>/Editor/trim-front" "a") +;(gtk_accel_path "<Actions>/Editor/trim-back" "s") +(gtk_accel_path "<Actions>/Editor/goto-mark-1" "KP_1") +(gtk_accel_path "<Actions>/Editor/goto-mark-2" "KP_2") +(gtk_accel_path "<Actions>/Editor/goto-mark-3" "KP_3") +(gtk_accel_path "<Actions>/Editor/goto-mark-4" "KP_4") +(gtk_accel_path "<Actions>/Editor/goto-mark-5" "KP_5") +(gtk_accel_path "<Actions>/Editor/goto-mark-6" "KP_6") +(gtk_accel_path "<Actions>/Editor/goto-mark-7" "KP_7") +(gtk_accel_path "<Actions>/Editor/goto-mark-8" "KP_8") +(gtk_accel_path "<Actions>/Editor/goto-mark-9" "KP_9") +(gtk_accel_path "<Actions>/Transport/ToggleClick" "5") +(gtk_accel_path "<Actions>/Transport/ToggleAutoReturn" "4") +(gtk_accel_path "<Actions>/Transport/focus-on-clock" "KP_Divide") +(gtk_accel_path "<Actions>/Editor/set-loop-from-edit-range" "bracketright") +(gtk_accel_path "<Actions>/Editor/set-punch-from-edit-range" "bracketleft") +(gtk_accel_path "<Actions>/Editor/set-loop-from-region" "<%PRIMARY%><%SECONDARY%>bracketright") +(gtk_accel_path "<Actions>/Editor/toggle-zoom" "<%TERTIARY%>z") +(gtk_accel_path "<Actions>/Editor/zoom-to-region" "z") diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index 6bcc0d7898..11e75137dd 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -30,9 +30,14 @@ </menu> <menu name='Transport' action='Transport'> <menuitem action='ToggleRoll'/> + <menuitem action='play-from-edit-point-and-return'/> + <menuitem action='play-edit-range'/> + <menuitem action='record-roll'/> <menuitem action='ToggleRollForgetCapture'/> <menuitem action='Loop'/> + <menuitem action='loop-region'/> <menuitem action='PlaySelection'/> + <menuitem action='play-edit-range'/> <menuitem action='Forward'/> <menuitem action='Rewind'/> <menuitem action='GotoZero'/> @@ -48,10 +53,8 @@ <menuitem action='jump-backward-to-mark'/> <menuitem action='add-location-from-playhead'/> <separator/> - <menuitem action='playhead-to-next-region-start'/> - <menuitem action='playhead-to-next-region-end'/> - <menuitem action='playhead-to-previous-region-start'/> - <menuitem action='playhead-to-previous-region-end'/> + <menuitem action='playhead-to-next-region-boundary'/> + <menuitem action='playhead-to-previous-region-boundary'/> <menuitem action='playhead-to-next-region-sync'/> <menuitem action='playhead-to-previous-region-sync'/> <menuitem action='center-playhead'/> @@ -59,6 +62,17 @@ <separator/> <menuitem action='playhead-to-range-start'/> <menuitem action='playhead-to-range-end'/> + <menuitem action='focus-on-clock'/> + <separator/> + <menuitem action='goto-mark-1'/> + <menuitem action='goto-mark-2'/> + <menuitem action='goto-mark-3'/> + <menuitem action='goto-mark-4'/> + <menuitem action='goto-mark-5'/> + <menuitem action='goto-mark-6'/> + <menuitem action='goto-mark-7'/> + <menuitem action='goto-mark-8'/> + <menuitem action='goto-mark-9'/> <menu action='TransportOptions'> <menuitem action='ToggleTimeMaster'/> <menuitem action='TogglePunchIn'/> @@ -70,6 +84,9 @@ <menuitem action='toggle-follow-playhead'/> <menuitem action='ToggleVideoSync'/> </menu> + <menuitem action='set-loop-from-edit-range'/> + <menuitem action='set-loop-from-region'/> + <menuitem action='set-punch-from-edit-range'/> </menu> <menu name='Edit' action='Edit'> <menuitem action='undo'/> @@ -78,6 +95,11 @@ <menuitem action='editor-delete'/> <menuitem action='editor-copy'/> <menuitem action='editor-paste'/> + <separator/> + <menuitem action='editor-separate'/> + <menuitem action='editor-crop'/> + <menuitem action='split-region'/> + <separator/> <menuitem action='remove-last-capture'/> <separator/> <menu action='EditCursorMovementOptions'> @@ -93,12 +115,11 @@ <menuitem action='edit-cursor-to-range-end'/> </menu> <menu name='KeyMouse Actions' action='KeyMouse Actions'> - <menuitem action='audition-at-mouse'/> + <menuitem action='play-selected-regions'/> <menuitem action='brush-at-mouse'/> <menuitem action='set-edit-point'/> <menuitem action='mute-unmute-region'/> <menuitem action='set-playhead'/> - <menuitem action='split-region'/> <menuitem action='set-region-sync-position'/> <separator/> <menuitem action='set-mouse-mode-object'/> @@ -106,6 +127,10 @@ <menuitem action='set-mouse-mode-gain'/> <menuitem action='set-mouse-mode-zoom'/> <menuitem action='set-mouse-mode-timefx'/> + <separator/> + <menuitem action='cycle-edit-point'/> + <menuitem action='cycle-edit-point-with-marker'/> + <menuitem action='toggle-edit-mode'/> </menu> </menu> <menu name='Select' action='Select'> @@ -117,6 +142,8 @@ <menuitem action='finish-add-range'/> <separator/> <menuitem action='select-all'/> + <menuitem action='deselect-all'/> + <menuitem action='invert-selection'/> <menuitem action='select-all-after-edit-cursor'/> <menuitem action='select-all-before-edit-cursor'/> <menuitem action='select-all-after-playhead'/> @@ -125,10 +152,14 @@ <menuitem action='select-all-within-cursors'/> <menuitem action='select-all-in-punch-range'/> <menuitem action='select-all-in-loop-range'/> + <separator/> + <menuitem action='select-next-route'/> + <menuitem action='select-prev-route'/> </menu> <menu name='Regions' action='Regions'> <menuitem action='crop'/> <menuitem action='duplicate-region'/> + <menuitem action='multi-duplicate-region'/> <menuitem action='insert-region'/> <menuitem action='normalize-region'/> <separator/> @@ -148,11 +179,17 @@ <separator/> <menuitem action='set-fade-in-length'/> <menuitem action='set-fade-out-length'/> + <menuitem action='toggle-fade-in-active'/> + <menuitem action='toggle-fade-out-active'/> <separator/> + <menuitem action='trim-back'/> + <menuitem action='trim-front'/> <menuitem action='trim-from-start'/> <menuitem action='trim-to-end'/> <menuitem action='trim-region-to-loop'/> <menuitem action='trim-region-to-punch'/> + <separator/> + <menuitem action='pitch-shift-region'/> </menu> <menu name='View' action = 'View'> <menu name='ZoomFocus' action='ZoomFocus'> @@ -164,11 +201,14 @@ <menuitem action='zoom-focus-mouse'/> </menu> <menu name='SnapMode' action='SnapMode'> + <menuitem action='snap-off'/> <menuitem action='snap-normal'/> <menuitem action='snap-magnetic'/> + <separator/> + <menuitem action='cycle-snap-mode'/> + <menuitem action='cycle-snap-choice'/> </menu> <menu name='SnapTo' action='SnapTo'> - <menuitem action='snap-to-frame'/> <menuitem action='snap-to-cd-frame'/> <menuitem action='snap-to-smpte-frame'/> <menuitem action='snap-to-smpte-seconds'/> @@ -183,7 +223,6 @@ <menuitem action='snap-to-beat'/> <menuitem action='snap-to-bar'/> <menuitem action='snap-to-mark'/> - <menuitem action='snap-to-edit-cursor'/> <menuitem action='snap-to-region-start'/> <menuitem action='snap-to-region-end'/> <menuitem action='snap-to-region-sync'/> @@ -210,6 +249,8 @@ <menuitem action='temporal-zoom-in'/> <menuitem action='temporal-zoom-out'/> <menuitem action='zoom-to-session'/> + <menuitem action='zoom-to-region'/> + <menuitem action='toggle-zoom'/> <menuitem action='scroll-tracks-down'/> <menuitem action='scroll-tracks-up'/> <menuitem action='scroll-tracks-down'/> @@ -387,6 +428,8 @@ <menuitem action='SecondaryClockDeltaEditCursor'/> <menuitem action='ShowTrackMeters'/> <menuitem action='OnlyCopyImportedFiles'/> + <menuitem action='ShowTrackMeters'/> + <menuitem action='link-region-and-track-selection'/> <separator/> </menu> <menu name='Help' action='Help'> diff --git a/gtk2_ardour/ardour2_ui_default.conf b/gtk2_ardour/ardour2_ui_default.conf index 108782953b..80f53f7181 100644 --- a/gtk2_ardour/ardour2_ui_default.conf +++ b/gtk2_ardour/ardour2_ui_default.conf @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <Ardour> + <UI> + <Option name="ui-rc-file" value="ardour2_ui_dark.rc"/> + </UI> <Canvas> <Option name="waveform" value="000000cc"/> <Option name="clipped waveform" value="ff0000e5"/> @@ -8,7 +11,7 @@ <Option name="audio track base" value="c6d3d868"/> <Option name="audio bus base" value="dbd1ea68"/> <Option name="midi track base" value="c67e7e5f"/> - <Option name="midi bus base" value="ffceea40"/> + <Option name="midi bus base" value="ffceea40"/> <Option name="time stretch fill" value="e2b5b596"/> <Option name="time stretch outline" value="63636396"/> <Option name="automation line" value="44bc59ff"/> @@ -41,11 +44,12 @@ <Option name="verbose canvas cursor" value="f4f214bc"/> <Option name="marker label" value="000000ff"/> <Option name="marker bar separator" value="aaaaaa77"/> - <Option name="meter bar" value="666672ff"/> <Option name="tempo bar" value="72727fff"/> - <Option name="range marker bar" value="7f7f8cff"/> + <Option name="meter bar" value="666672ff"/> + <Option name="marker bar" value="a1a1adff"/> + <Option name="cd marker bar" value="9898a3ff"/> + <Option name="range marker bar" value="7f7f8cff"/> <Option name="transport marker bar" value="8c8c96ff"/> - <Option name="marker bar" value="9898a3ff"/> <Option name="range drag bar rect" value="969696c6"/> <Option name="range drag rect" value="82c696c6"/> <Option name="transport drag rect" value="969696c6"/> @@ -83,9 +87,9 @@ <Option name="trim handle" value="1900ff44"/> <Option name="edit point" value="0000ffff"/> <Option name="play head" value="ff0000ff"/> - <Option name="meter fill min" value="0000ffff"/> - <Option name="meter fill mid" value="73f9baff"/> - <Option name="meter fill max" value="00fd5dff"/> + <Option name="meter fill min" value="33dd33ff"/> + <Option name="meter fill mid" value="eeee33ff"/> + <Option name="meter fill max" value="ee3333ff"/> <Option name="meter fill clip" value="ff0000ff"/> <Option name="midi select rect outline" value="5555ffff"/> <Option name="midi select rect fill" value="8888ff88"/> @@ -98,4 +102,3 @@ <Option name="midi note selected outline" value="5566ffee"/> </Canvas> </Ardour> - diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 31df728263..d0261849f6 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -37,6 +37,7 @@ #include <pbd/error.h> #include <pbd/misc.h> +#include <pbd/basename.h> #include <pbd/compose.h> #include <pbd/failed_constructor.h> #include <pbd/enumwriter.h> @@ -70,6 +71,7 @@ #include <ardour/audio_track.h> #include <ardour/midi_track.h> #include <ardour/filesystem_paths.h> +#include <ardour/filename_extensions.h> #include "actions.h" #include "ardour_ui.h" @@ -123,7 +125,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) /* big clock */ - big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true), + big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true), /* transport */ @@ -199,7 +201,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) have_disk_speed_dialog_displayed = false; session_loaded = false; last_speed_displayed = -1.0f; - ab_direction = true; sys::path key_bindings_file; @@ -256,7 +257,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) starting.connect (mem_fun(*this, &ARDOUR_UI::startup)); stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown)); - platform_specific (); + platform_setup (); } int @@ -502,6 +503,7 @@ ARDOUR_UI::save_ardour_state () Config->add_extra_xml (*node); Config->add_extra_xml (get_transport_controllable_state()); Config->save_state(); + ui_config->save_state (); XMLNode enode(static_cast<Stateful*>(editor)->get_state()); XMLNode mnode(mixer->get_state()); @@ -621,9 +623,18 @@ ARDOUR_UI::startup () /* Load session or start the new session dialog */ if (find_session (ARDOUR_COMMAND_LINE::session_name, path, name, isnew)) { - error << string_compose(_("could not load command line session \"%1\""), - ARDOUR_COMMAND_LINE::session_name) << endmsg; - return; + + MessageDialog msg (string_compose(_("Could not find command line session \"%1\""), + ARDOUR_COMMAND_LINE::session_name), + true, + Gtk::MESSAGE_ERROR, + Gtk::BUTTONS_OK); + + msg.set_position (Gtk::WIN_POS_MOUSE); + msg.present (); + msg.run (); + + exit (1); } if (!ARDOUR_COMMAND_LINE::new_session) { @@ -631,70 +642,34 @@ ARDOUR_UI::startup () /* Supposed to be loading an existing 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; - return; + MessageDialog msg (string_compose (_("\n\nNo session named \"%1\" exists.\n" + "To create it from the command line, start ardour as:\n ardour --new %1"), path), + true, + Gtk::MESSAGE_ERROR, + Gtk::BUTTONS_OK); + + msg.set_position (Gtk::WIN_POS_MOUSE); + msg.present (); + msg.run (); + + exit (1); } } - - new_session_dialog->set_session_name (name); - new_session_dialog->set_session_folder (Glib::path_get_basename (path)); - _session_is_new = isnew; } hide_splash (); bool have_backend = EngineControl::engine_running(); - bool need_nsd; - bool load_needed = false; - - if (have_backend) { - - /* backend audio is working */ - - if (ARDOUR_COMMAND_LINE::session_name.empty() || ARDOUR_COMMAND_LINE::new_session) { - /* need NSD to get session name and other info */ - need_nsd = true; - } else { - need_nsd = false; - } - - } else { - - XMLNode* audio_setup = Config->extra_xml ("AudioSetup"); - - if (audio_setup) { - new_session_dialog->engine_control.set_state (*audio_setup); - } - - /* no backend audio, must bring up NSD to check configuration */ - - need_nsd = true; - } - - if (need_nsd) { - - if (!get_session_parameters (ARDOUR_COMMAND_LINE::session_name, have_backend, ARDOUR_COMMAND_LINE::new_session)) { - return; - } - - } else { - - if (create_engine ()) { - backend_audio_error (false); - exit (1); - } - - load_needed = true; + XMLNode* audio_setup = Config->extra_xml ("AudioSetup"); + + if (audio_setup) { + new_session_dialog->engine_control.set_state (*audio_setup); } - if (load_needed) { - if (load_session (ARDOUR_COMMAND_LINE::session_name, name)) { - return; - } + if (!get_session_parameters (ARDOUR_COMMAND_LINE::session_name, have_backend, ARDOUR_COMMAND_LINE::new_session)) { + return; } - + show (); } @@ -1458,7 +1433,7 @@ ARDOUR_UI::remove_last_capture() } void -ARDOUR_UI::transport_record () +ARDOUR_UI::transport_record (bool roll) { if (session) { switch (session->record_status()) { @@ -1469,8 +1444,18 @@ ARDOUR_UI::transport_record () return; } session->maybe_enable_record (); + if (roll) { + transport_roll (); + } break; case Session::Recording: + if (roll) { + session->request_stop(); + } else { + session->disable_record (false, true); + } + break; + case Session::Enabled: session->disable_record (false, true); } @@ -1925,6 +1910,14 @@ ARDOUR_UI::primary_clock_value_changed () } void +ARDOUR_UI::big_clock_value_changed () +{ + if (session) { + session->request_locate (big_clock.current_time ()); + } +} + +void ARDOUR_UI::secondary_clock_value_changed () { if (session) { @@ -2027,12 +2020,40 @@ ARDOUR_UI::save_template () } } +void +ARDOUR_UI::fontconfig_dialog () +{ +#ifdef GTKOSX + /* X11 users will always have fontconfig info around, but new GTK-OSX users + may not and it can take a while to build it. Warn them. + */ + + Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig"); + + if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) { + MessageDialog msg (*new_session_dialog, + _("Welcome to Ardour.\n\n" + "The program will take a bit longer to start up\n" + "while the system fonts are checked.\n\n" + "This will only be done once, and you will\n" + "not see this message again\n"), + true, + Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK); + msg.show_all (); + msg.present (); + msg.run (); + } +#endif +} + bool ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_engine, bool should_be_new) { - string session_name; - string session_path; - string template_name; + bool existing_session = false; + Glib::ustring session_name; + Glib::ustring session_path; + Glib::ustring template_name; if (!loading_dialog) { loading_dialog = new MessageDialog (*new_session_dialog, @@ -2041,41 +2062,117 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE); } - + + int response = Gtk::RESPONSE_NONE; - new_session_dialog->set_modal(true); - new_session_dialog->set_name (predetermined_path); - new_session_dialog->reset_recent(); + if (predetermined_path.length()) { + + /* before we start, lets see if the given path looks like + an existing ardour session. if it does, skip the + tabs that we don't need + */ + + if (Glib::file_test (predetermined_path, Glib::FILE_TEST_IS_DIR)) { + session_path = predetermined_path; + existing_session = true; + } else if (Glib::file_test (predetermined_path, Glib::FILE_TEST_IS_REGULAR)) { + session_path = Glib::path_get_dirname (string (predetermined_path)); + existing_session = true; + } else { + /* it doesn't exist, assume the best */ + session_path = Glib::path_get_dirname (string (predetermined_path)); + } + + session_name = basename_nosuffix (string (predetermined_path)); + + new_session_dialog->set_session_name (session_name); + new_session_dialog->set_session_folder (session_path); + new_session_dialog->set_modal (true); + + if (existing_session) { + + if (session_name.length() == 0 || session_path.length() == 0) { + error << string_compose (_("Ardour cannot understand \"%1\" as a session name"), predetermined_path) << endmsg; + return false; + } + + if (Glib::file_test (predetermined_path, Glib::FILE_TEST_IS_DIR)) { + Glib::ustring predicted_session_file; + + predicted_session_file = predetermined_path; + predicted_session_file += '/'; + predicted_session_file += session_name; + predicted_session_file += ARDOUR::statefile_suffix; + + if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) { + existing_session = true; + } + + } else if (Glib::file_test (predetermined_path, Glib::FILE_TEST_EXISTS)) { + + if (predetermined_path.find (ARDOUR::statefile_suffix) == predetermined_path.length() - 7) { + /* existing .ardour file */ + existing_session = true; + } + } else { + existing_session = false; + } + + if (existing_session && have_engine) { + /* lets just try to load it */ + + loading_dialog->set_message (_("Starting audio engine")); + loading_dialog->show_all (); + flush_pending (); + + if (create_engine ()) { + backend_audio_error (!have_engine, new_session_dialog); + loading_dialog->hide (); + return false; + } + + if (load_session (session_path, session_name) == 0) { + goto done; + } + } + } + } + + /* loading failed, or we need the NSD for something */ + new_session_dialog->set_position (WIN_POS_CENTER); new_session_dialog->set_current_page (0); + new_session_dialog->set_existing_session (existing_session); + new_session_dialog->reset_recent(); do { new_session_dialog->set_have_engine (have_engine); - - new_session_dialog->show(); new_session_dialog->present (); - response = new_session_dialog->run (); - + response = new_session_dialog->run (); + loading_dialog->hide (); + _session_is_new = false; + + /* handle possible negative responses */ if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) { - + if (!session) { quit(); } new_session_dialog->hide (); return false; - + } else if (response == Gtk::RESPONSE_NONE) { - - /* Clear was pressed */ - new_session_dialog->reset(); - continue; + /* "Clear" was pressed */ + + goto try_again; } - /* first things first ... if we're here to help set up audio parameters - this is where want to do that. + fontconfig_dialog(); + + /* if we're here to help set up audio parameters this is where want to do that. */ if (!have_engine) { @@ -2083,45 +2180,24 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e new_session_dialog->hide (); return false; } - } - -#ifdef GTKOSX - /* X11 users will always have fontconfig info around, but new GTK-OSX users - may not and it can take a while to build it. Warn them. - */ - Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig"); - - if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) { - MessageDialog msg (*new_session_dialog, - _("Welcome to Ardour.\n\n" - "The program will take a bit longer to start up\n" - "while the system fonts are checked.\n\n" - "This will only be done once, and you will\n" - "not see this message again\n"), - true, - Gtk::MESSAGE_INFO, - Gtk::BUTTONS_OK); - msg.show_all (); - msg.present (); - msg.run (); + loading_dialog->set_message (_("Starting audio engine")); + loading_dialog->show_all (); + flush_pending (); } -#endif - loading_dialog->set_message (_("Starting audio engine")); - loading_dialog->show_all (); - flush_pending (); - + if (create_engine ()) { backend_audio_error (!have_engine, new_session_dialog); loading_dialog->hide (); flush_pending (); /* audio setup page */ + new_session_dialog->set_existing_session (false); new_session_dialog->set_current_page (2); - /* try again */ response = Gtk::RESPONSE_NONE; - continue; + goto try_again; } + loading_dialog->hide (); have_engine = true; /* now handle possible affirmative responses */ @@ -2134,16 +2210,22 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e if (session_name.empty()) { response = Gtk::RESPONSE_NONE; - continue; + goto try_again; } if (session_name[0] == '/' || (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') || (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) { - load_session (Glib::path_get_dirname (session_name), session_name); + if (load_session (Glib::path_get_dirname (session_name), session_name)) { + response = Gtk::RESPONSE_NONE; + goto try_again; + } } else { session_path = new_session_dialog->session_folder(); - load_session (session_path, session_name); + if (load_session (session_path, session_name)) { + response = Gtk::RESPONSE_NONE; + goto try_again; + } } } else if (response == Gtk::RESPONSE_OK) { @@ -2154,9 +2236,9 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e if (session_name.empty()) { response = Gtk::RESPONSE_NONE; - continue; + goto try_again; } - + switch (new_session_dialog->get_current_page()) { case 1: /* recent session selector */ case 2: /* audio engine control */ @@ -2164,10 +2246,19 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e if (session_name[0] == '/' || (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') || (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) { - load_session (Glib::path_get_dirname (session_name), session_name); + cerr << "here\n"; + if (load_session (Glib::path_get_dirname (session_name), session_name)) { + response = Gtk::RESPONSE_NONE; + goto try_again; + } + } else { session_path = new_session_dialog->session_folder(); - load_session (session_path, session_name); + cerr << "there\n"; + if (load_session (session_path, session_name)) { + response = Gtk::RESPONSE_NONE; + goto try_again; + } } break; @@ -2191,15 +2282,19 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e session_path = new_session_dialog->session_folder(); } - + //XXX This is needed because session constructor wants a //non-existant path. hopefully this will be fixed at some point. session_path = Glib::build_filename (session_path, session_name); - + if (!should_be_new) { - load_session (session_path, session_name); + if (load_session (session_path, session_name)) { + response = Gtk::RESPONSE_NONE; + goto try_again; + } + continue; /* leaves while() loop because response != NONE */ } else if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) { @@ -2222,12 +2317,17 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e new_session_dialog->hide (); goto_editor_window (); flush_pending (); - load_session (session_path, session_name); + if (load_session (session_path, session_name)) { + response = Gtk::RESPONSE_NONE; + goto try_again; + } goto done; break; default: response = RESPONSE_NONE; new_session_dialog->reset (); + new_session_dialog->set_existing_session (false); + loading_dialog->hide (); continue; } } @@ -2242,7 +2342,11 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e goto_editor_window (); flush_pending (); - load_session (session_path, session_name, &template_name); + if (load_session (session_path, session_name, template_name)) { + response = Gtk::RESPONSE_NONE; + goto try_again; + } + } else { @@ -2298,10 +2402,6 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e nphysout = (uint32_t) new_session_dialog->output_limit_count(); } - new_session_dialog->hide (); - goto_editor_window (); - flush_pending (); - if (build_session (session_path, session_name, cchns, @@ -2313,9 +2413,12 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e engine->frame_rate() * 60 * 5)) { response = Gtk::RESPONSE_NONE; - new_session_dialog->reset (); - continue; + goto try_again; } + + new_session_dialog->hide (); + goto_editor_window (); + flush_pending (); } break; @@ -2323,6 +2426,13 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e break; } } + + try_again: + if (response == Gtk::RESPONSE_NONE) { + loading_dialog->hide (); + new_session_dialog->set_existing_session (false); + new_session_dialog->reset (); + } } while (response == Gtk::RESPONSE_NONE); @@ -2346,7 +2456,7 @@ ARDOUR_UI::close_session() } int -ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template) +ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template) { Session *new_session; int unload_status; @@ -2369,7 +2479,7 @@ 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)) { + if (Glib::file_test (path.c_str(), Glib::FILE_TEST_EXISTS) && ::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.")); msg.run (); @@ -2387,8 +2497,55 @@ ARDOUR_UI::load_session (const string & path, const string & snap_name, string* new_session = new Session (*engine, path, snap_name, mix_template); } + /* this one is special */ + + catch (AudioEngine::PortRegistrationFailure& err) { + + MessageDialog msg (err.what(), + true, + Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK_CANCEL); + + msg.set_title (_("Loading Error")); + msg.set_secondary_text (_("Click the OK button to try again.")); + msg.set_position (Gtk::WIN_POS_CENTER); + msg.present (); + + int response = msg.run (); + + msg.hide (); + + switch (response) { + case RESPONSE_CANCEL: + exit (1); + default: + break; + } + goto out; + } + catch (...) { - error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg; + cerr << "Caught something\n"; + MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name), + true, + Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK_CANCEL); + + msg.set_title (_("Loading Error")); + msg.set_secondary_text (_("Click the OK button to try again.")); + msg.set_position (Gtk::WIN_POS_CENTER); + msg.present (); + + int response = msg.run (); + + msg.hide (); + + switch (response) { + case RESPONSE_CANCEL: + exit (1); + default: + break; + } goto out; } @@ -2413,7 +2570,7 @@ ARDOUR_UI::load_session (const string & path, const string & snap_name, string* } int -ARDOUR_UI::build_session (const string & path, const string & snap_name, +ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name, uint32_t control_channels, uint32_t master_channels, AutoConnectOption input_connect, @@ -3202,41 +3359,3 @@ ARDOUR_UI::setup_profile () } } -void -ARDOUR_UI::disable_all_plugins () -{ - if (!session) { - return; - } - - // session->begin_reversible_command (_("Disable all plugins")); - - boost::shared_ptr<Session::RouteList> routes = session->get_routes (); - - for (Session::RouteList::iterator i = routes->begin(); i != routes->end(); ++i) { - // XMLNode& before = (*i)->get_redirect_state (); - // session->add_command (new MementoCommand<Route>(**i, &before, 0)); - (*i)->disable_plugins (); - // XMLNode& after = (*i)->get_redirect_state (); - // session->add_command (new MementoCommand<Route>(**i, 0, &after)); - - } - - // session->commit_reversible_command (); -} - -void -ARDOUR_UI::ab_all_plugins () -{ - if (!session) { - return; - } - - boost::shared_ptr<Session::RouteList> routes = session->get_routes (); - - for (Session::RouteList::iterator i = routes->begin(); i != routes->end(); ++i) { - (*i)->ab_plugins (ab_direction); - } - - ab_direction = !ab_direction; -} diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 0cbc9935bf..996349c990 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -112,10 +112,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI void show_splash (); void hide_splash (); - int load_session (const string & path, const string & snapshot, string* mix_template = 0); + int load_session (const Glib::ustring & path, const Glib::ustring& snapshot, Glib::ustring mix_template = Glib::ustring()); bool session_loaded; - /// @return zero if building the session was successful - int build_session (const string & path, const string & snapshot, + int build_session (const Glib::ustring& path, const Glib::ustring& snapshot, uint32_t ctl_chns, uint32_t master_chns, ARDOUR::AutoConnectOption input_connect, @@ -155,7 +154,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI PublicEditor& the_editor(){return *editor;} Mixer_UI* the_mixer() { return mixer; } - + + ARDOUR::AudioEngine& the_engine() const { return *engine; } + void toggle_key_editor (); void toggle_location_window (); void toggle_theme_manager (); @@ -280,8 +281,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI ARDOUR::AudioEngine *engine; ARDOUR::Session *session; - bool check_audioengine(); - Gtk::Tooltips _tooltips; void goto_editor_window (); @@ -482,6 +481,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI void solo_alert_toggle (); void audition_alert_toggle (); + void big_clock_value_changed (); void primary_clock_value_changed (); void secondary_clock_value_changed (); @@ -578,7 +578,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI void transport_goto_end (); void transport_stop (); void transport_stop_and_forget_capture (); - void transport_record (); + void transport_record (bool roll); void transport_roll (); void transport_play_selection(); void transport_forward (int option); @@ -753,10 +753,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI void no_memory_warning (); void check_memory_locking (); - bool ab_direction; - void disable_all_plugins (); - void ab_all_plugins (); - + bool check_audioengine(); void audioengine_setup (); void display_message (const char *prefix, gint prefix_len, @@ -766,6 +763,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI Gtk::MessageDialog* loading_dialog; void platform_specific (); + void platform_setup (); + void fontconfig_dialog (); }; #endif /* __ardour_gui_h__ */ diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index fcb721a9f0..ca0615cbef 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -316,6 +316,7 @@ ARDOUR_UI::setup_transport () primary_clock.ValueChanged.connect (mem_fun(*this, &ARDOUR_UI::primary_clock_value_changed)); secondary_clock.ValueChanged.connect (mem_fun(*this, &ARDOUR_UI::secondary_clock_value_changed)); + big_clock.ValueChanged.connect (mem_fun(*this, &ARDOUR_UI::big_clock_value_changed)); ARDOUR_UI::instance()->tooltips().set_tip (primary_clock, _("Primary clock")); ARDOUR_UI::instance()->tooltips().set_tip (secondary_clock, _("secondary clock")); @@ -398,7 +399,9 @@ ARDOUR_UI::setup_transport () transport_tearoff_hbox.pack_start (*svbox, false, false, 3); transport_tearoff_hbox.pack_start (auto_loop_button, false, false); - transport_tearoff_hbox.pack_start (play_selection_button, false, false); + if (!Profile->get_sae()) { + transport_tearoff_hbox.pack_start (play_selection_button, false, false); + } transport_tearoff_hbox.pack_start (roll_button, false, false); transport_tearoff_hbox.pack_start (stop_button, false, false); transport_tearoff_hbox.pack_start (rec_button, false, false, 6); @@ -408,12 +411,16 @@ ARDOUR_UI::setup_transport () if (!ARDOUR::Profile->get_small_screen()) { clock_box->pack_start (secondary_clock, false, false); } - VBox* time_controls_box = manage (new VBox); - time_controls_box->pack_start (sync_option_combo, false, false); - time_controls_box->pack_start (time_master_button, false, false); - clock_box->pack_start (*time_controls_box, false, false, 1); + + if (!Profile->get_sae()) { + VBox* time_controls_box = manage (new VBox); + time_controls_box->pack_start (sync_option_combo, false, false); + time_controls_box->pack_start (time_master_button, false, false); + clock_box->pack_start (*time_controls_box, false, false, 1); + } + transport_tearoff_hbox.pack_start (*clock_box, false, false, 0); - + HBox* toggle_box = manage(new HBox); VBox* punch_box = manage (new VBox); @@ -443,6 +450,11 @@ ARDOUR_UI::setup_transport () transport_tearoff_hbox.pack_start (*toggle_box, false, false, 4); transport_tearoff_hbox.pack_start (alert_box, false, false); + + if (Profile->get_sae()) { + Image* img = manage (new Image ((::get_icon (X_("sae"))))); + transport_tearoff_hbox.pack_end (*img, false, false, 6); + } } void diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc index 6464c52967..dd0889b786 100644 --- a/gtk2_ardour/ardour_ui_dependents.cc +++ b/gtk2_ardour/ardour_ui_dependents.cc @@ -51,7 +51,7 @@ ARDOUR_UI::shutdown () session->remove_pending_capture_state (); session = 0; } - + ui_config->save_state(); } void diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 38aae959cf..af8206ceac 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -82,7 +82,7 @@ ARDOUR_UI::install_actions () /* menus + submenus that need action items */ ActionManager::register_action (main_actions, X_("Session"), _("Session")); - ActionManager::register_action (main_actions, X_("Files"), _("Files")); + ActionManager::register_action (main_actions, X_("Files"), _("Import/Export")); ActionManager::register_action (main_actions, X_("Regions"), _("Regions")); ActionManager::register_action (main_actions, X_("Cleanup"), _("Cleanup")); ActionManager::register_action (main_actions, X_("Sync"), _("Sync")); @@ -269,7 +269,9 @@ ARDOUR_UI::install_actions () ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - act = ActionManager::register_action (transport_actions, X_("Record"), _("Enable Record"), mem_fun(*this, &ARDOUR_UI::transport_record)); + act = ActionManager::register_action (transport_actions, X_("Record"), _("Enable Record"), bind (mem_fun(*this, &ARDOUR_UI::transport_record), false)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (transport_actions, X_("record-roll"), _("Start Recording"), bind (mem_fun(*this, &ARDOUR_UI::transport_record), true)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); act = ActionManager::register_action (transport_actions, X_("Rewind"), _("Rewind"), bind (mem_fun(*this, &ARDOUR_UI::transport_rewind), 0)); @@ -300,6 +302,10 @@ ARDOUR_UI::install_actions () ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); + act = ActionManager::register_action (transport_actions, X_("focus-on-clock"), _("Focus On Clock"), mem_fun(primary_clock, &AudioClock::focus)); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::transport_sensitive_actions.push_back (act); + act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchIn"), _("Punch In"), mem_fun(*this, &ARDOUR_UI::toggle_punch_in)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); @@ -420,7 +426,7 @@ ARDOUR_UI::install_actions () ActionManager::register_toggle_action (option_actions, X_("RegionEquivalentsOverlap"), _("Region equivalents overlap"), mem_fun (*this, &ARDOUR_UI::toggle_RegionEquivalentsOverlap)); ActionManager::register_toggle_action (option_actions, X_("PrimaryClockDeltaEditCursor"), _("Primary Clock delta to edit point"), mem_fun (*this, &ARDOUR_UI::toggle_PrimaryClockDeltaEditCursor)); ActionManager::register_toggle_action (option_actions, X_("SecondaryClockDeltaEditCursor"), _("Secondary Clock delta to edit point"), mem_fun (*this, &ARDOUR_UI::toggle_SecondaryClockDeltaEditCursor)); - ActionManager::register_toggle_action (option_actions, X_("ShowTrackMeters"), _("Display Editor Meters"), mem_fun (*this, &ARDOUR_UI::toggle_ShowTrackMeters)); + ActionManager::register_toggle_action (option_actions, X_("ShowTrackMeters"), _("Enable Editor Meters"), mem_fun (*this, &ARDOUR_UI::toggle_ShowTrackMeters)); ActionManager::register_toggle_action (option_actions, X_("OnlyCopyImportedFiles"), _("Always copy imported files"), mem_fun (*this, &ARDOUR_UI::toggle_only_copy_imported_files)); RadioAction::Group denormal_group; @@ -464,17 +470,16 @@ ARDOUR_UI::install_actions () act = ActionManager::register_toggle_action (option_actions, X_("DoNotRunPluginsWhileRecording"), _("Do not run plugins while recording"), mem_fun (*this, &ARDOUR_UI::toggle_DoNotRunPluginsWhileRecording)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_toggle_action (option_actions, X_("LatchedSolo"), _("Latched solo"), mem_fun (*this, &ARDOUR_UI::toggle_LatchedSolo)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_toggle_action (option_actions, X_("ShowSoloMutes"), _("Show solo muting"), mem_fun (*this, &ARDOUR_UI::toggle_ShowSoloMutes)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (option_actions, X_("DisableAllPlugins"), _("Disable All Plugins"), mem_fun (*this, &ARDOUR_UI::disable_all_plugins)); + /*act = ActionManager::register_action (option_actions, X_("DisableAllPlugins"), _("Disable All Plugins"), mem_fun (*this, &ARDOUR_UI::disable_all_plugins)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (option_actions, X_("ABAllPlugins"), _("A/B All Plugins"), mem_fun (*this, &ARDOUR_UI::ab_all_plugins)); - ActionManager::session_sensitive_actions.push_back (act); + ActionManager::session_sensitive_actions.push_back (act);*/ /* !!! REMEMBER THAT RADIO ACTIONS HAVE TO BE HANDLED WITH MORE FINESSE THAN SIMPLE TOGGLES !!! */ diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc index 56c4ac649f..a76e3725a0 100644 --- a/gtk2_ardour/ardour_ui_options.cc +++ b/gtk2_ardour/ardour_ui_options.cc @@ -33,6 +33,7 @@ #include "ardour_ui.h" #include "actions.h" #include "gui_thread.h" +#include "public_editor.h" #include "i18n.h" @@ -1118,6 +1119,9 @@ ARDOUR_UI::parameter_changed (const char* parameter_name) ActionManager::map_some_state ("options", "SecondaryClockDeltaEditCursor", &Configuration::get_secondary_clock_delta_edit_cursor); } else if (PARAM_IS ("only-copy-imported-files")) { map_only_copy_imported_files (); + } else if (PARAM_IS ("show-track-meters")) { + ActionManager::map_some_state ("options", "ShowTrackMeters", &Configuration::get_show_track_meters); + editor->toggle_meter_updating(); } #undef PARAM_IS diff --git a/gtk2_ardour/au_pluginui.cc b/gtk2_ardour/au_pluginui.cc deleted file mode 100644 index 84d39393fe..0000000000 --- a/gtk2_ardour/au_pluginui.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Written by Taybin Rutkin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <ardour/audio_unit.h> -#include <ardour/processor.h> - -#include <gtkmm2ext/doi.h> - -#include "au_pluginui.h" -#include "gui_thread.h" - -#include <appleutility/CAAudioUnit.h> -#include <appleutility/CAComponent.h> - -#include <AudioUnit/AudioUnit.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert) -{ - if ((au = boost::dynamic_pointer_cast<AUPlugin> (insert->plugin())) == 0) { - error << _("unknown type of editor-supplying plugin (note: no AudioUnit support in this version of ardour)") << endmsg; - throw failed_constructor (); - } - - OSStatus err = noErr; - - CAComponentDescription desc; - Component carbonViewComponent = NULL; - AudioUnitCarbonView carbonView = NULL; - - GetComponentInfo(au->get_comp()->Comp(), &desc, 0, 0, 0); - carbonViewComponent = get_carbon_view_component(desc.componentSubType); - err = OpenAComponent(carbonViewComponent, &carbonView); - - Rect rec; - rec.top = 0; - rec.left = 0; - rec.bottom = 400; - rec.right = 500; - - ProcessSerialNumber ourPSN; - - /* Here we will set the MacOSX native section of the process to the foreground for putting up this - * dialog box. First step is to get our process serial number. We do this by calling - * GetCurrentProcess. - * First Argument: On success this PSN will be our PSN on return. - * Return Value: A Macintosh error indicating success or failure. - */ - err = GetCurrentProcess(&ourPSN); - - //If no error then set this process to be frontmost. - if (err == noErr) { - /* Calling SetFrontProcess to make us frontmost. - * First Argument: The Process Serial Number of the process we want to make frontmost. Here - * of course we pass our process serial number - * Return Value: An error value indicating success or failure. We just ignore the return - * value here. - */ - (void)SetFrontProcess(&ourPSN); - } else { - error << "couldn't get current process" << endmsg; - } - - err = CreateNewWindow (kDocumentWindowClass, kWindowStandardFloatingAttributes, &rec, &wr); - - ComponentResult auResult; - ControlRef rootControl = NULL; - GetRootControl(wr, &rootControl); - - int width = 500; - int height = 400; - Float32Point location = {30, 30}; - Float32Point size = {width, height}; - ControlRef audioUnitControl = NULL; - - auResult = AudioUnitCarbonViewCreate(carbonView, - au->get_au()->AU(), - wr, - rootControl, - &location, - &size, - &audioUnitControl); - - ShowWindow (wr); - BringToFront (wr); -// AudioUnitCarbonViewSetEventListener(carbonView, EventListener, this); -#if 0 - set_name ("PluginEditor"); - add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - - signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this))); -#endif - - insert->GoingAway.connect (mem_fun(*this, &AUPluginUI::plugin_going_away)); - - info << "AUPluginUI created" << endmsg; -} - -AUPluginUI::~AUPluginUI () -{ - // nothing to do here - plugin destructor destroys the GUI -} - -void -AUPluginUI::plugin_going_away (ARDOUR::IOProcessor* ignored) -{ - ENSURE_GUI_THREAD(bind (mem_fun(*this, &AUPluginUI::plugin_going_away), ignored)); - - delete_when_idle (this); -} - -Component -AUPluginUI::get_carbon_view_component(OSType subtype) -{ - ComponentDescription desc; - Component component; - - desc.componentType = kAudioUnitCarbonViewComponentType; // 'auvw' - desc.componentSubType = subtype; - desc.componentManufacturer = 0; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - - // First see if we can find a carbon view designed specifically for this - // plug-in: - - component = FindNextComponent(NULL, &desc); - if (component) - return component; - - // If not, grab the generic carbon view, which will create a GUI for - // any Audio Unit. - - desc.componentSubType = kAUCarbonViewSubType_Generic; - component = FindNextComponent(NULL, &desc); - - return component; -} - diff --git a/gtk2_ardour/au_pluginui.h b/gtk2_ardour/au_pluginui.h index d757ea3bf0..0e31b35e03 100644 --- a/gtk2_ardour/au_pluginui.h +++ b/gtk2_ardour/au_pluginui.h @@ -1,29 +1,18 @@ -/* - Copyright (C) 2006 Paul Davis +#ifndef __gtk2_ardour_auplugin_ui_h__ +#define __gtk2_ardour_auplugin_ui_h__ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#include <AppKit/AppKit.h> +#include <Carbon/Carbon.h> +#include <AudioUnit/AudioUnit.h> -*/ +/* fix up stupid apple macros */ -#ifndef __au_plugin_ui_h__ -#define __au_plugin_ui_h__ +#undef check +#undef require +#undef verify -#include <boost/shared_ptr.hpp> - -#include <Carbon/Carbon.h> -#include <AudioUnit/AudioUnit.h> +#include <gtkmm/box.h> +#include "plugin_ui.h" namespace ARDOUR { class AUPlugin; @@ -31,18 +20,58 @@ namespace ARDOUR { class IOProcessor; } -class AUPluginUI +class AUPluginUI : public PlugUIBase, public Gtk::VBox { public: AUPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>); ~AUPluginUI (); + gint get_preferred_height () { return prefheight; } + gint get_preferred_width () { return prefwidth; } + bool start_updating(GdkEventAny*); + bool stop_updating(GdkEventAny*); + + virtual void activate (); + virtual void deactivate (); + + void on_realize (); + void on_show (); + + OSStatus carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event); + private: WindowRef wr; boost::shared_ptr<ARDOUR::AUPlugin> au; + int prefheight; + int prefwidth; + + /* Cocoa */ + + NSWindow* cocoa_window; + NSScrollView* scroll_view; + NSView* au_view; + + /* Carbon */ + + NSWindow* cocoa_parent; + ComponentDescription carbon_descriptor; + AudioUnitCarbonView editView; + WindowRef carbon_window; + EventHandlerRef carbon_event_handler; + bool carbon_parented; + bool cocoa_parented; + + void test_view_support (bool&, bool&); + bool test_cocoa_view_support (); + bool test_carbon_view_support (); + int create_carbon_view (bool generic); + int create_cocoa_view (); + + int parent_carbon_window (); + int parent_cocoa_window (); + NSWindow* get_nswindow(); - void plugin_going_away (ARDOUR::IOProcessor*); - Component get_carbon_view_component(OSType subtype); + bool plugin_class_valid (Class pluginClass); }; -#endif // __au_plugin_ui_h__ +#endif /* __gtk2_ardour_auplugin_ui_h__ */ diff --git a/gtk2_ardour/au_pluginui.mm b/gtk2_ardour/au_pluginui.mm new file mode 100644 index 0000000000..51f73199f7 --- /dev/null +++ b/gtk2_ardour/au_pluginui.mm @@ -0,0 +1,567 @@ +#include <pbd/error.h> +#include <ardour/audio_unit.h> +#include <ardour/insert.h> + +#include <gdk/gdkquartz.h> + +#include "au_pluginui.h" +#include "gui_thread.h" + +#include <appleutility/CAAudioUnit.h> +#include <appleutility/CAComponent.h> + +#import <AudioUnit/AUCocoaUIView.h> +#import <CoreAudioKit/AUGenericView.h> + +#include "i18n.h" + +using namespace ARDOUR; +using namespace Gtk; +using namespace sigc; +using namespace std; +using namespace PBD; + +static const float kOffsetForAUView_X = 220; +static const float kOffsetForAUView_Y = 90; + +AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert) + : PlugUIBase (insert) +{ + if ((au = boost::dynamic_pointer_cast<AUPlugin> (insert->plugin())) == 0) { + error << _("unknown type of editor-supplying plugin (note: no AudioUnit support in this version of ardour)") << endmsg; + throw failed_constructor (); + } + + bool has_carbon; + bool has_cocoa; + + carbon_parented = false; + cocoa_parented = false; + cocoa_parent = 0; + cocoa_window = 0; + + test_view_support (has_carbon, has_cocoa); + + if (has_cocoa) { + create_cocoa_view (); + } else if (has_carbon) { + create_carbon_view (has_carbon); + } else { + /* fallback to cocoa */ + create_cocoa_view (); + } +} + + +AUPluginUI::~AUPluginUI () +{ + if (carbon_parented) { + NSWindow* win = get_nswindow(); + RemoveEventHandler(carbon_event_handler); + [win removeChildWindow:cocoa_parent]; + } +} + +void +AUPluginUI::test_view_support (bool& has_carbon, bool& has_cocoa) +{ + has_carbon = test_carbon_view_support(); + has_cocoa = test_cocoa_view_support(); +} + +bool +AUPluginUI::test_carbon_view_support () +{ + bool ret = false; + + carbon_descriptor.componentType = kAudioUnitCarbonViewComponentType; + carbon_descriptor.componentSubType = 'gnrc'; + carbon_descriptor.componentManufacturer = 'appl'; + carbon_descriptor.componentFlags = 0; + carbon_descriptor.componentFlagsMask = 0; + + OSStatus err; + + // ask the AU for its first editor component + UInt32 propertySize; + err = AudioUnitGetPropertyInfo(*au->get_au(), kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, &propertySize, NULL); + if (!err) { + int nEditors = propertySize / sizeof(ComponentDescription); + ComponentDescription *editors = new ComponentDescription[nEditors]; + err = AudioUnitGetProperty(*au->get_au(), kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, editors, &propertySize); + if (!err) { + // just pick the first one for now + carbon_descriptor = editors[0]; + ret = true; + } + delete[] editors; + } + + return ret; +} + +bool +AUPluginUI::test_cocoa_view_support () +{ + UInt32 dataSize = 0; + Boolean isWritable = 0; + OSStatus err = AudioUnitGetPropertyInfo(*au->get_au(), + kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, + 0, &dataSize, &isWritable); + + return dataSize > 0 && err == noErr; +} + +bool +AUPluginUI::plugin_class_valid (Class pluginClass) +{ + if([pluginClass conformsToProtocol: @protocol(AUCocoaUIBase)]) { + if([pluginClass instancesRespondToSelector: @selector(interfaceVersion)] && + [pluginClass instancesRespondToSelector: @selector(uiViewForAudioUnit:withSize:)]) { + return true; + } + } + return false; +} + +int +AUPluginUI::create_cocoa_view () +{ + BOOL wasAbleToLoadCustomView = NO; + AudioUnitCocoaViewInfo* cocoaViewInfo = NULL; + UInt32 numberOfClasses = 0; + UInt32 dataSize; + Boolean isWritable; + NSString* factoryClassName = 0; + NSURL* CocoaViewBundlePath; + + OSStatus result = AudioUnitGetPropertyInfo (*au->get_au(), + kAudioUnitProperty_CocoaUI, + kAudioUnitScope_Global, + 0, + &dataSize, + &isWritable ); + + numberOfClasses = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef); + + // Does view have custom Cocoa UI? + + if ((result == noErr) && (numberOfClasses > 0) ) { + cocoaViewInfo = (AudioUnitCocoaViewInfo *)malloc(dataSize); + if(AudioUnitGetProperty(*au->get_au(), + kAudioUnitProperty_CocoaUI, + kAudioUnitScope_Global, + 0, + cocoaViewInfo, + &dataSize) == noErr) { + + CocoaViewBundlePath = (NSURL *)cocoaViewInfo->mCocoaAUViewBundleLocation; + + // we only take the first view in this example. + factoryClassName = (NSString *)cocoaViewInfo->mCocoaAUViewClass[0]; + + } else { + + if (cocoaViewInfo != NULL) { + free (cocoaViewInfo); + cocoaViewInfo = NULL; + } + } + } + + NSRect crect = { { 0, 0 }, { 1, 1} }; + + // [A] Show custom UI if view has it + + if (CocoaViewBundlePath && factoryClassName) { + NSBundle *viewBundle = [NSBundle bundleWithPath:[CocoaViewBundlePath path]]; + if (viewBundle == nil) { + error << _("AUPluginUI: error loading AU view's bundle") << endmsg; + return -1; + } else { + Class factoryClass = [viewBundle classNamed:factoryClassName]; + if (!factoryClass) { + error << _("AUPluginUI: error getting AU view's factory class from bundle") << endmsg; + return -1; + } + + // make sure 'factoryClass' implements the AUCocoaUIBase protocol + if (!plugin_class_valid (factoryClass)) { + error << _("AUPluginUI: U view's factory class does not properly implement the AUCocoaUIBase protocol") << endmsg; + return -1; + } + // make a factory + id factoryInstance = [[[factoryClass alloc] init] autorelease]; + if (factoryInstance == nil) { + error << _("AUPluginUI: Could not create an instance of the AU view factory") << endmsg; + return -1; + } + + // make a view + au_view = [factoryInstance uiViewForAudioUnit:*au->get_au() withSize:crect.size]; + + // cleanup + [CocoaViewBundlePath release]; + if (cocoaViewInfo) { + UInt32 i; + for (i = 0; i < numberOfClasses; i++) + CFRelease(cocoaViewInfo->mCocoaAUViewClass[i]); + + free (cocoaViewInfo); + } + wasAbleToLoadCustomView = YES; + } + } + + if (!wasAbleToLoadCustomView) { + // [B] Otherwise show generic Cocoa view + au_view = [[AUGenericView alloc] initWithAudioUnit:*au->get_au()]; + [(AUGenericView *)au_view setShowsExpertParameters:YES]; + } + + /* make a child cocoa window */ + + cocoa_window = [[NSWindow alloc] + initWithContentRect:crect + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:NO]; + + return 0; +} + +int +AUPluginUI::create_carbon_view (bool generic) +{ + OSStatus err; + ControlRef root_control; + + Component editComponent = FindNextComponent(NULL, &carbon_descriptor); + + OpenAComponent(editComponent, &editView); + if (!editView) { + error << _("AU Carbon view: cannot open AU Component") << endmsg; + return -1; + } + + Rect r = { 100, 100, 100, 100 }; + WindowAttributes attr = WindowAttributes (kWindowStandardHandlerAttribute | + kWindowCompositingAttribute| + kWindowNoShadowAttribute| + kWindowNoTitleBarAttribute); + + if ((err = CreateNewWindow(kDocumentWindowClass, attr, &r, &carbon_window)) != noErr) { + error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg; + return -1; + } + + if ((err = GetRootControl(carbon_window, &root_control)) != noErr) { + error << string_compose (_("AUPlugin: cannot get root control of carbon window (err: %1)"), err) << endmsg; + return -1; + } + + ControlRef viewPane; + Float32Point location = { 0.0, 0.0 }; + Float32Point size = { 0.0, 0.0 } ; + + if ((err = AudioUnitCarbonViewCreate (editView, *au->get_au(), carbon_window, root_control, &location, &size, &viewPane)) != noErr) { + error << string_compose (_("AUPluginUI: cannot create carbon plugin view (err: %1)"), err) << endmsg; + return -1; + } + + // resize window + + Rect bounds; + GetControlBounds(viewPane, &bounds); + size.x = bounds.right-bounds.left; + size.y = bounds.bottom-bounds.top; + SizeWindow(carbon_window, (short) (size.x + 0.5), (short) (size.y + 0.5), true); + + prefwidth = (int) (size.x + 0.5); + prefheight = (int) (size.y + 0.5); + +#if 0 + mViewPaneResizer->WantEventTypes (GetControlEventTarget(mAUViewPane), GetEventTypeCount(resizeEvent), resizeEvent); +#endif + return 0; +} + +NSWindow* +AUPluginUI::get_nswindow () +{ + Gtk::Container* toplevel = get_toplevel(); + + if (!toplevel || !toplevel->is_toplevel()) { + error << _("AUPluginUI: no top level window!") << endmsg; + return 0; + } + + NSWindow* true_parent = gdk_quartz_window_get_nswindow (toplevel->get_window()->gobj()); + + if (!true_parent) { + error << _("AUPluginUI: no top level window!") << endmsg; + return 0; + } + + return true_parent; +} + +void +AUPluginUI::activate () +{ + NSWindow* win = get_nswindow (); + [win setLevel:NSFloatingWindowLevel]; + + if (carbon_parented) { + [cocoa_parent makeKeyAndOrderFront:nil]; + ActivateWindow (carbon_window, TRUE); + } +} + +void +AUPluginUI::deactivate () +{ + /* nothing to do here */ +} + + +OSStatus +_carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData) +{ + return ((AUPluginUI*)userData)->carbon_event (nextHandlerRef, event); +} + +OSStatus +AUPluginUI::carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event) +{ + UInt32 eventKind = GetEventKind(event); + ClickActivationResult howToHandleClick; + NSWindow* win = get_nswindow (); + + switch (eventKind) { + case kEventWindowHandleActivate: + [win makeMainWindow]; + return eventNotHandledErr; + break; + + case kEventWindowHandleDeactivate: + return eventNotHandledErr; + break; + + case kEventWindowGetClickActivation: + howToHandleClick = kActivateAndHandleClick; + SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult, + sizeof(ClickActivationResult), &howToHandleClick); + break; + } + + return noErr; +} + +int +AUPluginUI::parent_carbon_window () +{ + NSWindow* win = get_nswindow (); + int x, y; + + if (!win) { + return -1; + } + + Gtk::Container* toplevel = get_toplevel(); + + if (!toplevel || !toplevel->is_toplevel()) { + error << _("AUPluginUI: no top level window!") << endmsg; + return -1; + } + + toplevel->get_window()->get_root_origin (x, y); + + /* compute how tall the title bar is, because we have to offset the position of the carbon window + by that much. + */ + + NSRect content_frame = [NSWindow contentRectForFrameRect:[win frame] styleMask:[win styleMask]]; + NSRect wm_frame = [NSWindow frameRectForContentRect:content_frame styleMask:[win styleMask]]; + + int titlebar_height = wm_frame.size.height - content_frame.size.height; + + MoveWindow (carbon_window, x, y + titlebar_height, false); + ShowWindow (carbon_window); + + // create the cocoa window for the carbon one and make it visible + cocoa_parent = [[NSWindow alloc] initWithWindowRef: carbon_window]; + + EventTypeSpec windowEventTypes[] = { + {kEventClassWindow, kEventWindowGetClickActivation }, + {kEventClassWindow, kEventWindowHandleDeactivate }, + {kEventClassWindow, kEventWindowHandleActivate } + }; + + EventHandlerUPP ehUPP = NewEventHandlerUPP(_carbon_event); + OSStatus result = InstallWindowEventHandler (carbon_window, ehUPP, + sizeof(windowEventTypes) / sizeof(EventTypeSpec), + windowEventTypes, this, &carbon_event_handler); + if (result != noErr) { + return -1; + } + + [win addChildWindow:cocoa_parent ordered:NSWindowAbove]; + [win setLevel:NSFloatingWindowLevel]; + [win setHidesOnDeactivate:YES]; + + carbon_parented = true; + + return 0; +} + +int +AUPluginUI::parent_cocoa_window () +{ + NSWindow* win = get_nswindow (); + + if (!win) { + return -1; + } + + Gtk::Container* toplevel = get_toplevel(); + + if (!toplevel || !toplevel->is_toplevel()) { + error << _("AUPluginUI: no top level window!") << endmsg; + return -1; + } + + // Get the size of the new AU View's frame + NSRect au_view_frame = [au_view frame]; + + if (au_view_frame.size.width > 500 || au_view_frame.size.height > 500) { + + /* its too big - use a scrollview */ + + NSRect frameRect = [[cocoa_window contentView] frame]; + scroll_view = [[[NSScrollView alloc] initWithFrame:frameRect] autorelease]; + [scroll_view setDrawsBackground:NO]; + [scroll_view setHasHorizontalScroller:YES]; + [scroll_view setHasVerticalScroller:YES]; + + NSSize frameSize = [NSScrollView frameSizeForContentSize:au_view_frame.size + hasHorizontalScroller:[scroll_view hasHorizontalScroller] + hasVerticalScroller:[scroll_view hasVerticalScroller] + borderType:[scroll_view borderType]]; + + // Create a new frame with same origin as current + // frame but size equal to the size of the new view + NSRect newFrame; + newFrame.origin = [scroll_view frame].origin; + newFrame.size = frameSize; + + // Set the new frame and document views on the scroll view + NSRect currentFrame = [scroll_view frame]; + [scroll_view setFrame:newFrame]; + [scroll_view setDocumentView:au_view]; + + cerr << "scroll view size is " << newFrame.size.width << " x " << newFrame.size.height << endl; + + NSSize oldContentSize = [[cocoa_window contentView] frame].size; + NSSize newContentSize = oldContentSize; + + cerr << "original size is " << newContentSize.width << " x " << newContentSize.height << endl; + + newContentSize.width += (newFrame.size.width - currentFrame.size.width); + newContentSize.height += (newFrame.size.height - currentFrame.size.height); + + [cocoa_window setContentSize:newContentSize]; + [cocoa_window setContentView:scroll_view]; + + } else { + + [cocoa_window setContentSize:au_view_frame.size]; + [cocoa_window setContentView:au_view]; + + } + + /* compute how tall the title bar is, because we have to offset the position of the child window + by that much. + */ + + NSRect content_frame = [NSWindow contentRectForFrameRect:[win frame] styleMask:[win styleMask]]; + NSRect wm_frame = [NSWindow frameRectForContentRect:content_frame styleMask:[win styleMask]]; + int titlebar_height = wm_frame.size.height - content_frame.size.height; + + // move cocoa window into position relative to the toplevel window + + NSRect view_frame = [[cocoa_window contentView] frame]; + view_frame.origin.x = content_frame.origin.x; + view_frame.origin.y = content_frame.origin.y; + + [cocoa_window setFrame:view_frame display:NO]; + + /* make top level window big enough to hold cocoa window and titlebar */ + + content_frame.size.width = view_frame.size.width; + content_frame.size.height = view_frame.size.height + titlebar_height; + + [win setFrame:content_frame display:NO]; + + /* now make cocoa window a child of this top level */ + + [win addChildWindow:cocoa_window ordered:NSWindowAbove]; + // [win setLevel:NSFloatingWindowLevel]; + [win setHidesOnDeactivate:YES]; + + cocoa_parented = true; + + return 0; +} + +void +AUPluginUI::on_realize () +{ + VBox::on_realize (); + + if (cocoa_window) { + + if (parent_cocoa_window ()) { + } + + } else if (carbon_window) { + + if (parent_carbon_window ()) { + // ShowWindow (carbon_window); + } + } +} + +void +AUPluginUI::on_show () +{ + cerr << "AU plugin window shown\n"; + + VBox::on_show (); + + if (cocoa_window) { + [cocoa_window setIsVisible:YES]; + } else if (carbon_window) { + [cocoa_parent setIsVisible:YES]; + } +} + +bool +AUPluginUI::start_updating (GdkEventAny* any) +{ + return false; +} + +bool +AUPluginUI::stop_updating (GdkEventAny* any) +{ + return false; +} + +PlugUIBase* +create_au_gui (boost::shared_ptr<PluginInsert> plugin_insert, VBox** box) +{ + AUPluginUI* aup = new AUPluginUI (plugin_insert); + (*box) = aup; + return aup; +} diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index 7a2606114c..43862c9d0b 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -599,10 +599,15 @@ AudioClock::set_smpte (nframes_t when, bool force) smpte_upper_info_label->set_text (buf); - if (session->smpte_drop_frames()) { - sprintf (buf, "DF"); + if ((fabs(smpte_frames - 29.97) < 0.0001) || smpte_frames == 30) { + if (session->smpte_drop_frames()) { + sprintf (buf, "DF"); + } else { + sprintf (buf, "NDF"); + } } else { - sprintf (buf, "NDF"); + // there is no drop frame alternative + buf[0] = '\0'; } smpte_lower_info_label->set_text (buf); @@ -654,6 +659,32 @@ AudioClock::set_session (Session *s) } } +void +AudioClock::focus () +{ + switch (_mode) { + case SMPTE: + hours_ebox.grab_focus (); + break; + + case BBT: + bars_ebox.grab_focus (); + break; + + case MinSec: + ms_hours_ebox.grab_focus (); + break; + + case Frames: + frames_ebox.grab_focus (); + break; + + case Off: + break; + } +} + + bool AudioClock::field_key_press_event (GdkEventKey *ev, Field field) { @@ -1020,7 +1051,7 @@ AudioClock::field_button_release_event (GdkEventButton *ev, Field field) if (dragging) { gdk_pointer_ungrab (GDK_CURRENT_TIME); dragging = false; - if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)){ + if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){ // we actually dragged so return without setting editing focus, or we shift clicked return true; } @@ -1100,7 +1131,7 @@ AudioClock::field_button_press_event (GdkEventButton *ev, Field field) switch (ev->button) { case 1: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { set (frames, true); ValueChanged (); /* EMIT_SIGNAL */ } @@ -1116,7 +1147,7 @@ AudioClock::field_button_press_event (GdkEventButton *ev, Field field) break; case 2: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { set (frames, true); ValueChanged (); /* EMIT_SIGNAL */ } @@ -1149,7 +1180,7 @@ AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field) case GDK_SCROLL_UP: frames = get_frames (field); if (frames != 0) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { frames *= 10; } set (current_time() + frames, true); @@ -1160,7 +1191,7 @@ AudioClock::field_button_scroll_event (GdkEventScroll *ev, Field field) case GDK_SCROLL_DOWN: frames = get_frames (field); if (frames != 0) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { frames *= 10; } @@ -1192,13 +1223,13 @@ AudioClock::field_motion_notify_event (GdkEventMotion *ev, Field field) float pixel_frame_scale_factor = 0.2f; /* - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { pixel_frame_scale_factor = 0.1f; } if (Keyboard::modifier_state_contains (ev->state, - Keyboard::Control|Keyboard::Alt)) { + Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) { pixel_frame_scale_factor = 0.025f; } @@ -1853,7 +1884,7 @@ AudioClock::build_ops_menu () ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE))); ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT))); ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec))); - ops_items.push_back (MenuElem (_("Audio Frames"), bind (mem_fun(*this, &AudioClock::set_mode), Frames))); + ops_items.push_back (MenuElem (_("Samples"), bind (mem_fun(*this, &AudioClock::set_mode), Frames))); ops_items.push_back (MenuElem (_("Off"), bind (mem_fun(*this, &AudioClock::set_mode), Off))); } diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h index 21a2755588..1aa721b864 100644 --- a/gtk2_ardour/audio_clock.h +++ b/gtk2_ardour/audio_clock.h @@ -45,7 +45,9 @@ class AudioClock : public Gtk::HBox 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 focus (); + void set (nframes_t, bool force = false, nframes_t offset = 0, char which = 0); void set_mode (Mode); diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index f101905012..96b8a57261 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -1,7 +1,7 @@ /* Copyright (C) 2001-2006 Paul Davis - This program is free software; you can redistribute it and/or modify + This program is free software; you can r>edistribute 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. @@ -411,8 +411,8 @@ void AudioRegionView::set_y_position_and_height (double y, double h) { //RegionView::set_y_position_and_height(y, h - 1); - RegionView::set_height (height); - + RegionView::set_height (h); + const uint32_t wcnt = waves.size(); _y_position = y; @@ -1205,3 +1205,35 @@ AudioRegionView::color_handler () envelope_active_changed(); } + +void +AudioRegionView::set_frame_color () +{ + if (!frame) { + return; + } + + if (_region->opaque()) { + fill_opacity = 130; + } else { + fill_opacity = 0; + } + + uint32_t r,g,b,a; + + if (_selected && should_show_selection) { + frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_WaveForm.get(); + + UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a); + for (vector<ArdourCanvas::WaveView*>::iterator w = waves.begin(); w != waves.end(); ++w) { + (*w)->property_wave_color() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);// Lets still use the theme's opacity value if Opaque is not set + } + } else { + UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a); + frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a); + + for (vector<ArdourCanvas::WaveView*>::iterator w = waves.begin(); w != waves.end(); ++w) { + (*w)->property_wave_color() = ARDOUR_UI::config()->canvasvar_WaveForm.get(); + } + } +} diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h index c8734da59b..f5110e6a72 100644 --- a/gtk2_ardour/audio_region_view.h +++ b/gtk2_ardour/audio_region_view.h @@ -161,7 +161,8 @@ class AudioRegionView : public RegionView void compute_colors (Gdk::Color&); void reset_width_dependent_items (double pixel_width); void set_waveview_data_src(); - + void set_frame_color (); + void color_handler (); vector<GnomeCanvasWaveViewCache*> wave_caches; diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index c571cb1a7c..a21de27b46 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -73,8 +73,6 @@ AudioStreamView::AudioStreamView (AudioTimeAxisView& tv) _amplitude_above_axis = 1.0; use_rec_regions = tv.editor.show_waveforms_recording (); - - } AudioStreamView::~AudioStreamView () diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index de99d25ae1..34566d4de2 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -43,6 +43,7 @@ #include <ardour/location.h> #include <ardour/panner.h> #include <ardour/playlist.h> +#include <ardour/profile.h> #include <ardour/session.h> #include <ardour/session_playlist.h> #include <ardour/utils.h> @@ -156,8 +157,10 @@ AudioTimeAxisView::append_extra_display_menu_items () MenuList& items = display_menu->items(); // crossfade stuff - items.push_back (MenuElem (_("Hide all crossfades"), mem_fun(*this, &AudioTimeAxisView::hide_all_xfades))); - items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades))); + if (!Profile->get_sae()) { + items.push_back (MenuElem (_("Hide all crossfades"), mem_fun(*this, &AudioTimeAxisView::hide_all_xfades))); + items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades))); + } // waveform menu Menu *waveform_menu = manage(new Menu); @@ -177,8 +180,12 @@ AudioTimeAxisView::append_extra_display_menu_items () waveform_items.push_back (RadioMenuElem (group, _("Traditional"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Traditional))); traditional_item = static_cast<RadioMenuItem *> (&waveform_items.back()); - waveform_items.push_back (RadioMenuElem (group, _("Rectified"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Rectified))); - rectified_item = static_cast<RadioMenuItem *> (&waveform_items.back()); + if (!Profile->get_sae()) { + waveform_items.push_back (RadioMenuElem (group, _("Rectified"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Rectified))); + rectified_item = static_cast<RadioMenuItem *> (&waveform_items.back()); + } else { + rectified_item = 0; + } waveform_items.push_back (SeparatorElem()); @@ -194,9 +201,11 @@ AudioTimeAxisView::append_extra_display_menu_items () AudioStreamView* asv = audio_view(); if (asv) { ignore_toggle = true; - if (asv->get_waveform_shape() == Rectified) + if (asv->get_waveform_shape() == Rectified && rectified_item) { rectified_item->set_active(true); - else traditional_item->set_active(true); + } else { + traditional_item->set_active(true); + } if (asv->get_waveform_scale() == LogWaveform) logscale_item->set_active(true); diff --git a/gtk2_ardour/canvas_vars.h b/gtk2_ardour/canvas_vars.h index fc73d49608..7d291b7a5d 100644 --- a/gtk2_ardour/canvas_vars.h +++ b/gtk2_ardour/canvas_vars.h @@ -41,6 +41,7 @@ CANVAS_VARIABLE(canvasvar_MarkerBarSeparator, "marker bar separator") CANVAS_VARIABLE(canvasvar_TempoBar, "tempo bar") CANVAS_VARIABLE(canvasvar_MeterBar, "meter bar") CANVAS_VARIABLE(canvasvar_MarkerBar, "marker bar") +CANVAS_VARIABLE(canvasvar_CDMarkerBar, "cd marker bar") CANVAS_VARIABLE(canvasvar_RangeMarkerBar, "range marker bar") CANVAS_VARIABLE(canvasvar_TransportMarkerBar, "transport marker bar") CANVAS_VARIABLE(canvasvar_RangeDragBarRect, "range drag bar rect") diff --git a/gtk2_ardour/cocoacarbon.mm b/gtk2_ardour/cocoacarbon.mm new file mode 100644 index 0000000000..b60352eb47 --- /dev/null +++ b/gtk2_ardour/cocoacarbon.mm @@ -0,0 +1,122 @@ +/* + Copyright (C) 2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <Carbon/Carbon.h> +#undef check // stupid, stupid carbon + +#include "ardour_ui.h" +#include "actions.h" +#include "opts.h" +#include "sync-menu.h" + +#include <Appkit/Appkit.h> + +sigc::signal<void,bool> ApplicationActivationChanged; +static EventHandlerRef application_event_handler_ref; + +/* Called for clicks on the dock icon. Can be used to unminimize or + * create a new window for example. + */ + +static OSErr +handle_reopen_application (const AppleEvent *inAppleEvent, + AppleEvent *outAppleEvent, + long inHandlerRefcon) +{ + cerr << "reopen app\n"; + return noErr; +} + +static OSErr +handle_quit_application (const AppleEvent *inAppleEvent, + AppleEvent *outAppleEvent, + long inHandlerRefcon) +{ + cerr << "quit app\n"; + ARDOUR_UI::instance()->quit (); + + return noErr; +} + +static OSStatus +application_event_handler (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData) +{ + UInt32 eventKind = GetEventKind (event); + + switch (eventKind) { + case kEventAppActivated: + ApplicationActivationChanged (true); // EMIT SIGNAL + return eventNotHandledErr; + + case kEventAppDeactivated: + ApplicationActivationChanged (false); // EMIT SIGNAL + return eventNotHandledErr; + + default: + // pass-thru all kEventClassApplication events we're not interested in. + break; + } + return eventNotHandledErr; +} + +void +ARDOUR_UI::platform_specific () +{ + AEInstallEventHandler (kCoreEventClass, kAEReopenApplication, + handle_reopen_application, 0, true); + + AEInstallEventHandler (kCoreEventClass, kAEQuitApplication, + handle_quit_application, 0, true); + + Gtk::Widget* widget = ActionManager::get_widget ("/ui/Main/Session/Quit"); + if (widget) { + ige_mac_menu_set_quit_menu_item ((GtkMenuItem*) widget->gobj()); + } + + IgeMacMenuGroup* group = ige_mac_menu_add_app_menu_group (); + + widget = ActionManager::get_widget ("/ui/Main/Session/About"); + if (widget) { + ige_mac_menu_add_app_menu_item (group, (GtkMenuItem*) widget->gobj(), 0); + } + widget = ActionManager::get_widget ("/ui/Main/Session/ToggleOptionsEditor"); + if (widget) { + ige_mac_menu_add_app_menu_item (group, (GtkMenuItem*) widget->gobj(), 0); + } + + EventTypeSpec applicationEventTypes[] = { + {kEventClassApplication, kEventAppActivated }, + {kEventClassApplication, kEventAppDeactivated } + }; + + EventHandlerUPP ehUPP = NewEventHandlerUPP (application_event_handler); + + InstallApplicationEventHandler (ehUPP, sizeof(applicationEventTypes) / sizeof(EventTypeSpec), + applicationEventTypes, 0, &application_event_handler_ref); +} + +void +ARDOUR_UI::platform_setup () +{ + if (!ARDOUR_COMMAND_LINE::finder_invoked_ardour) { + + /* if invoked from the command line, make sure we're visible */ + + [NSApp activateIgnoringOtherApps:YES]; + } +} diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc index 8e9c4f07dd..b5aebdfb8d 100644 --- a/gtk2_ardour/crossfade_edit.cc +++ b/gtk2_ardour/crossfade_edit.cc @@ -637,9 +637,15 @@ CrossfadeEditor::redraw () for (list<Point*>::iterator i = fade[current].points.begin(); i != fade[current].points.end(); ++i) { fade[current].normative_curve.add ((*i)->x, (*i)->y); - fade[current].gain_curve.add (((*i)->x * len), (*i)->y); + double offset; + if (current==In) + offset = xfade->in()->start(); + else + offset = xfade->out()->start()+xfade->out()->length()-xfade->length(); + fade[current].gain_curve.add (((*i)->x * len) + offset, (*i)->y); } + size_t npoints = (size_t) effective_width(); float vec[npoints]; @@ -1079,6 +1085,11 @@ CrossfadeEditor::make_waves (boost::shared_ptr<AudioRegion> region, WhichFade wh waveview->property_amplitude_above_axis() = 2.0; waveview->property_wave_color() = color; + if (which==In) + waveview->property_region_start() = region->start(); + else + waveview->property_region_start() = region->start()+region->length()-xfade->length(); + waveview->lower_to_bottom(); fade[which].waves.push_back (waveview); } @@ -1110,13 +1121,13 @@ CrossfadeEditor::audition_both () nframes_t left_length; if (preroll_button.get_active()) { - preroll = ARDOUR_UI::instance()->preroll_clock.current_duration (); + preroll = session.frame_rate() * 2; //2 second hardcoded preroll for now } else { preroll = 0; } if (postroll_button.get_active()) { - postroll = ARDOUR_UI::instance()->postroll_clock.current_duration (); + postroll = session.frame_rate() * 2; //2 second hardcoded postroll for now } else { postroll = 0; } diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h index b48f97c8da..1cbb2decd8 100644 --- a/gtk2_ardour/editing_syms.h +++ b/gtk2_ardour/editing_syms.h @@ -18,7 +18,6 @@ */ /* Changing this order will break the menu */ -SNAPTYPE(SnapToFrame) SNAPTYPE(SnapToCDFrame) SNAPTYPE(SnapToSMPTEFrame) SNAPTYPE(SnapToSMPTESeconds) @@ -33,13 +32,13 @@ SNAPTYPE(SnapToAThirdBeat) SNAPTYPE(SnapToBeat) SNAPTYPE(SnapToBar) SNAPTYPE(SnapToMark) -SNAPTYPE(SnapToEditPoint) SNAPTYPE(SnapToRegionStart) SNAPTYPE(SnapToRegionEnd) SNAPTYPE(SnapToRegionSync) SNAPTYPE(SnapToRegionBoundary) /* Changing this order will break the menu */ +SNAPMODE(SnapOff) SNAPMODE(SnapNormal) SNAPMODE(SnapMagnetic) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index e0f8b24b53..613c34f551 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -110,7 +110,6 @@ const double Editor::timebar_height = 15.0; #include "editor_xpms" static const gchar *_snap_type_strings[] = { - N_("None"), N_("CD Frames"), N_("SMPTE Frames"), N_("SMPTE Seconds"), @@ -125,7 +124,6 @@ static const gchar *_snap_type_strings[] = { N_("Beats"), N_("Bars"), N_("Marks"), - N_("Edit Point"), N_("Region starts"), N_("Region ends"), N_("Region syncs"), @@ -134,7 +132,8 @@ static const gchar *_snap_type_strings[] = { }; static const gchar *_snap_mode_strings[] = { - N_("Normal"), + N_("No Grid"), + N_("Grid"), N_("Magnetic"), 0 }; @@ -152,7 +151,7 @@ static const gchar *_zoom_focus_strings[] = { N_("Center"), N_("Playhead"), N_("Mouse"), - N_("Marker"), + N_("Edit Point"), 0 }; @@ -186,14 +185,15 @@ Editor::Editor () minsec_label (_("Mins:Secs")), bbt_label (_("Bars:Beats")), smpte_label (_("Timecode")), - frame_label (_("Frames")), + frame_label (_("Samples")), tempo_label (_("Tempo")), meter_label (_("Meter")), mark_label (_("Location Markers")), range_mark_label (_("Range Markers")), transport_mark_label (_("Loop/Punch Ranges")), + cd_mark_label (_("CD Markers")), - edit_packer (3, 3, false), + edit_packer (3, 3, true), /* the values here don't matter: layout widgets reset them as needed. @@ -221,7 +221,8 @@ Editor::Editor () /* nudge */ - nudge_clock (X_("nudge"), false, X_("NudgeClock"), true, true) + nudge_clock (X_("nudge"), false, X_("NudgeClock"), true, true), + meters_running(false) { constructed = false; @@ -246,7 +247,6 @@ Editor::Editor () clicked_routeview = 0; clicked_crossfadeview = 0; clicked_control_point = 0; - latest_regionview = 0; last_update_frame = 0; drag_info.item = 0; current_mixer_strip = 0; @@ -257,15 +257,6 @@ Editor::Editor () zoom_focus_strings = I18N (_zoom_focus_strings); edit_point_strings = I18N (_edit_point_strings); - snap_type = SnapToFrame; - set_snap_to (snap_type); - - snap_mode = SnapNormal; - set_snap_mode (snap_mode); - - _edit_point = EditAtMouse; - set_edit_point_preference (_edit_point); - snap_threshold = 5.0; bbt_beat_subdivision = 4; canvas_width = 0; @@ -292,7 +283,8 @@ Editor::Editor () verbose_cursor_on = true; route_removal = false; show_automatic_regions_in_region_list = true; - region_list_sort_type = (Editing::RegionListSortType) 0; + + region_list_sort_type = (Editing::RegionListSortType) 0; have_pending_keyboard_selection = false; _follow_playhead = true; _xfade_visibility = true; @@ -322,7 +314,7 @@ Editor::Editor () entered_marker = 0; clear_entered_track = false; _new_regionviews_show_envelope = false; - current_timestretch = 0; + current_timefx = 0; in_edit_group_row_change = false; last_canvas_frame = 0; playhead_cursor = 0; @@ -331,6 +323,8 @@ Editor::Editor () _dragging_playhead = false; _dragging_edit_point = false; _dragging_hscrollbar = false; + select_new_marker = false; + zoomed_to_region = false; scrubbing_direction = 0; @@ -350,6 +344,8 @@ Editor::Editor () set_midi_edit_mode (MidiEditPencil, true); set_mouse_mode (MouseObject, true); + last_visual_state.frames_per_unit = 0; + frames_per_unit = 2048; /* too early to use reset_zoom () */ reset_hscrollbar_stepping (); @@ -361,7 +357,7 @@ Editor::Editor () initialize_canvas (); edit_controls_vbox.set_spacing (0); - horizontal_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::canvas_horizontally_scrolled)); + horizontal_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::canvas_horizontally_scrolled), false); vertical_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::tie_vertical_scrolling), true); track_canvas.set_hadjustment (horizontal_adjustment); @@ -438,6 +434,10 @@ Editor::Editor () mark_label.set_size_request (-1, (int)timebar_height); mark_label.set_alignment (1.0, 0.5); mark_label.set_padding (5,0); + cd_mark_label.set_name ("EditorTimeButton"); + cd_mark_label.set_size_request (-1, (int)timebar_height); + cd_mark_label.set_alignment (1.0, 0.5); + cd_mark_label.set_padding (5,0); range_mark_label.set_name ("EditorTimeButton"); range_mark_label.set_size_request (-1, (int)timebar_height); range_mark_label.set_alignment (1.0, 0.5); @@ -510,7 +510,7 @@ Editor::Editor () CellRendererToggle* route_list_visible_cell = dynamic_cast<CellRendererToggle*>(route_list_display.get_column_cell_renderer (0)); route_list_visible_cell->property_activatable() = true; route_list_visible_cell->property_radio() = false; - + route_display_model->signal_row_deleted().connect (mem_fun (*this, &Editor::route_list_delete)); route_display_model->signal_row_changed().connect (mem_fun (*this, &Editor::route_list_change)); @@ -599,6 +599,10 @@ Editor::Editor () region_list_display.append_column (_("Regions"), region_list_columns.name); region_list_display.set_headers_visible (false); + CellRendererText* region_name_cell = dynamic_cast<CellRendererText*>(region_list_display.get_column_cell_renderer (0)); + region_name_cell->property_editable() = true; + region_name_cell->signal_edited().connect (mem_fun (*this, &Editor::region_name_edit)); + region_list_display.get_selection()->set_select_function (mem_fun (*this, &Editor::region_list_selection_filter)); TreeViewColumn* tv_col = region_list_display.get_column(0); @@ -675,9 +679,12 @@ Editor::Editor () nlabel = manage (new Label (_("Edit Groups"))); nlabel->set_angle (-90); the_notebook.append_page (*edit_group_display_packer, *nlabel); - nlabel = manage (new Label (_("Chunks"))); - nlabel->set_angle (-90); - the_notebook.append_page (named_selection_scroller, *nlabel); + + if (!Profile->get_sae()) { + nlabel = manage (new Label (_("Chunks"))); + nlabel->set_angle (-90); + the_notebook.append_page (named_selection_scroller, *nlabel); + } the_notebook.set_show_tabs (true); the_notebook.set_scrollable (true); @@ -713,7 +720,14 @@ Editor::Editor () /* register actions now so that set_state() can find them and set toggles/checks etc */ register_actions (); - + + snap_type = SnapToBeat; + set_snap_to (snap_type); + snap_mode = SnapOff; + set_snap_mode (snap_mode); + _edit_point = EditAtMouse; + set_edit_point_preference (_edit_point); + XMLNode* node = ARDOUR_UI::instance()->editor_settings(); set_state (*node); @@ -882,19 +896,6 @@ Editor::tie_vertical_scrolling () } controls_layout.get_vadjustment()->set_value (y1); - -#ifdef GTKOSX - /* the way idle updates and immediate window flushing work on GTK-Quartz - requires that we force an immediate redraw right here. The controls - layout will do the same all by itself, as does the canvas widget, but - most of the time, the canvas itself hasn't updated itself because its - idle handler hasn't run. consequently, the call that its layout makes - to gdk_window_process_updates() finds nothing to do. here, we force - the update to happen, then request a flush of the new window state. - */ - track_canvas.update_now (); - gdk_window_process_updates (GTK_LAYOUT(track_canvas.gobj())->bin_window, true); -#endif } void @@ -1277,6 +1278,8 @@ Editor::connect_to_session (Session *t) /* register for undo history */ session->register_with_memento_command_factory(_id, this); + + start_updating (); } void @@ -1320,6 +1323,14 @@ Editor::build_cursors () transparent_cursor = new Gdk::Cursor (bits, bits, c, c, 0, 0); } + { + RefPtr<Bitmap> bits; + char pix[4] = { 0, 0, 0, 0 }; + bits = Bitmap::create (pix, 2, 2); + Gdk::Color c; + transparent_cursor = new Gdk::Cursor (bits, bits, c, c, 0, 0); + } + grabber_cursor = new Gdk::Cursor (HAND2); cross_hair_cursor = new Gdk::Cursor (CROSSHAIR); trimmer_cursor = new Gdk::Cursor (SB_H_DOUBLE_ARROW); @@ -1602,10 +1613,21 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) items.push_back (MenuElem (_("Sync points"), *sync_point_menu)); - add_item_with_sensitivity (items, MenuElem (_("Audition"), mem_fun(*this, &Editor::audition_selected_region)), selection->regions.size() == 1); + //add_item_with_sensitivity (items, MenuElem (_("Audition"), mem_fun(*this, &Editor::audition_selected_region)), selection->regions.size() == 1); add_item_with_sensitivity (items, MenuElem (_("Export"), mem_fun(*this, &Editor::export_region)), selection->regions.size() == 1); + items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region))); + items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region))); + items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top))); + items.push_back (MenuElem (_("Lower to bottom layer"), mem_fun (*this, &Editor::lower_region_to_bottom))); + items.push_back (SeparatorElem()); + items.push_back (MenuElem (_("Define sync point"), mem_fun(*this, &Editor::set_region_sync_from_edit_point))); + items.push_back (MenuElem (_("Remove sync point"), mem_fun(*this, &Editor::remove_region_sync))); + items.push_back (SeparatorElem()); + + items.push_back (MenuElem (_("Audition"), mem_fun(*this, &Editor::play_selected_region))); + items.push_back (MenuElem (_("Export"), mem_fun(*this, &Editor::export_region))); items.push_back (MenuElem (_("Bounce"), mem_fun(*this, &Editor::bounce_region_selection))); #ifdef FFT_ANALYSIS @@ -1779,7 +1801,8 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) items.push_back (MenuElem (_("Trim"), *trim_menu)); items.push_back (MenuElem (_("Split"), (mem_fun(*this, &Editor::split_region)))); items.push_back (MenuElem (_("Make mono regions"), (mem_fun(*this, &Editor::split_multichannel_region)))); - items.push_back (MenuElem (_("Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), true)))); + items.push_back (MenuElem (_("Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), false)))); + items.push_back (MenuElem (_("Multi-Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), true)))); items.push_back (MenuElem (_("Fill track"), (mem_fun(*this, &Editor::region_fill_track)))); items.push_back (SeparatorElem()); items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_selected_regions))); @@ -1990,8 +2013,15 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items void Editor::set_snap_to (SnapType st) { + unsigned int snap_ind = (unsigned int)st; snap_type = st; - string str = snap_type_strings[(int) st]; + + if ( snap_ind > snap_type_strings.size() - 1 ) { + snap_ind = 0; + snap_type = (SnapType)snap_ind; + } + + string str = snap_type_strings[snap_ind]; if (str != snap_type_selector.get_active_text()) { snap_type_selector.set_active_text (str); @@ -2029,6 +2059,8 @@ Editor::set_snap_mode (SnapMode mode) void Editor::set_edit_point_preference (EditPoint ep) { + bool changed = _edit_point != ep; + _edit_point = ep; string str = edit_point_strings[(int)ep]; @@ -2036,6 +2068,33 @@ Editor::set_edit_point_preference (EditPoint ep) edit_point_selector.set_active_text (str); } + if (!changed) { + return; + } + + if (Profile->get_sae()) { + + switch (zoom_focus) { + case ZoomFocusMouse: + case ZoomFocusPlayhead: + case ZoomFocusEdit: + switch (_edit_point) { + case EditAtMouse: + set_zoom_focus (ZoomFocusMouse); + break; + case EditAtPlayhead: + set_zoom_focus (ZoomFocusPlayhead); + break; + case EditAtSelectedMarker: + set_zoom_focus (ZoomFocusEdit); + break; + } + break; + default: + break; + } + } + instant_save (); } @@ -2314,7 +2373,7 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark) Location* before = 0; Location* after = 0; - if (!session) { + if (!session || snap_mode == SnapOff) { return; } @@ -2325,9 +2384,6 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark) nframes64_t presnap = start; switch (snap_type) { - case SnapToFrame: - break; - case SnapToCDFrame: if (direction) { start = (nframes_t) ceil ((double) start / (one_second / 75)) * (one_second / 75); @@ -2429,10 +2485,6 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark) start = session->tempo_map().round_to_beat_subdivision (start, 3); break; - case SnapToEditPoint: - start = get_preferred_edit_position (); - break; - case SnapToMark: if (for_mark) { return; @@ -2513,6 +2565,7 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark) } default: + /* handled at entry */ return; } @@ -2563,8 +2616,11 @@ Editor::setup_toolbar () { string pixmap_path; +#ifdef GTKOSX + const guint32 FUDGE = 38; // Combo's are stupid - they steal space from the entry for the button +#else const guint32 FUDGE = 18; // Combo's are stupid - they steal space from the entry for the button - +#endif /* Mode Buttons (tool selection) */ @@ -2573,12 +2629,17 @@ Editor::setup_toolbar () mouse_move_button.add (*(manage (new Image (::get_icon("tool_object"))))); mouse_move_button.set_relief(Gtk::RELIEF_NONE); mouse_mode_buttons.push_back (&mouse_move_button); - mouse_select_button.add (*(manage (new Image (get_xpm("tool_range.xpm"))))); - mouse_select_button.set_relief(Gtk::RELIEF_NONE); - mouse_mode_buttons.push_back (&mouse_select_button); - mouse_gain_button.add (*(manage (new Image (::get_icon("tool_gain"))))); - mouse_gain_button.set_relief(Gtk::RELIEF_NONE); - mouse_mode_buttons.push_back (&mouse_gain_button); + + if (!Profile->get_sae()) { + mouse_select_button.add (*(manage (new Image (get_xpm("tool_range.xpm"))))); + mouse_select_button.set_relief(Gtk::RELIEF_NONE); + mouse_mode_buttons.push_back (&mouse_select_button); + + mouse_gain_button.add (*(manage (new Image (::get_icon("tool_gain"))))); + mouse_gain_button.set_relief(Gtk::RELIEF_NONE); + mouse_mode_buttons.push_back (&mouse_gain_button); + } + mouse_zoom_button.add (*(manage (new Image (::get_icon("tool_zoom"))))); mouse_zoom_button.set_relief(Gtk::RELIEF_NONE); mouse_mode_buttons.push_back (&mouse_zoom_button); @@ -2599,9 +2660,13 @@ Editor::setup_toolbar () mode_box->set_spacing(4); mouse_mode_button_box.set_spacing(1); mouse_mode_button_box.pack_start(mouse_move_button, true, true); - mouse_mode_button_box.pack_start(mouse_select_button, true, true); + if (!Profile->get_sae()) { + mouse_mode_button_box.pack_start(mouse_select_button, true, true); + } mouse_mode_button_box.pack_start(mouse_zoom_button, true, true); - mouse_mode_button_box.pack_start(mouse_gain_button, true, true); + if (!Profile->get_sae()) { + mouse_mode_button_box.pack_start(mouse_gain_button, true, true); + } mouse_mode_button_box.pack_start(mouse_timefx_button, true, true); mouse_mode_button_box.pack_start(mouse_audition_button, true, true); mouse_mode_button_box.pack_start(mouse_note_button, true, true); @@ -2692,7 +2757,7 @@ Editor::setup_toolbar () ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session")); zoom_focus_selector.set_name ("ZoomFocusSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Playhead", FUDGE, 0); + Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, _("Playhead"), 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")); @@ -2706,19 +2771,19 @@ Editor::setup_toolbar () snap_box.set_border_width (2); snap_type_selector.set_name ("SnapTypeSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, "SMPTE Seconds", 2+FUDGE, 10); + Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, _("SMPTE Seconds"), 2+FUDGE, 10); set_popdown_strings (snap_type_selector, snap_type_strings); snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Snap/Grid Units")); snap_mode_selector.set_name ("SnapModeSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "Magnetic Snap", 2+FUDGE, 10); + Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, _("Magnetic Snap"), 2+FUDGE, 10); set_popdown_strings (snap_mode_selector, snap_mode_strings); snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (snap_mode_selector, _("Snap/Grid Mode")); edit_point_selector.set_name ("SnapModeSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (edit_point_selector, "Playhead", 2+FUDGE, 10); + Gtkmm2ext::set_size_request_to_display_given_text (edit_point_selector, _("Playhead"), 2+FUDGE, 10); set_popdown_strings (edit_point_selector, edit_point_strings); edit_point_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_point_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (edit_point_selector, _("Edit point")); @@ -3090,50 +3155,67 @@ Editor::history_changed () } void -Editor::duplicate_dialog (bool dup_region) +Editor::duplicate_dialog (bool with_dialog) { - if (selection->regions.empty() && (selection->time.length() == 0)) { - return; - } - - ArdourDialog win ("duplicate dialog"); - Label label (_("Duplicate how many times?")); - Adjustment adjustment (1.0, 1.0, 1000000.0, 1.0, 5.0); - SpinButton spinner (adjustment); + float times = 1.0f; - win.get_vbox()->set_spacing (12); - win.get_vbox()->pack_start (label); - - /* dialogs have ::add_action_widget() but that puts the spinner in the wrong - place, visually. so do this by hand. - */ - - win.get_vbox()->pack_start (spinner); - spinner.signal_activate().connect (sigc::bind (mem_fun (win, &ArdourDialog::response), RESPONSE_ACCEPT)); + if (mouse_mode == MouseRange) { + if (selection->time.length() == 0) { + return; + } + } - label.show (); - spinner.show (); + + if (mouse_mode != MouseRange) { - win.add_button (Stock::CANCEL, RESPONSE_CANCEL); - win.add_button (Stock::OK, RESPONSE_ACCEPT); + ensure_entered_region_selected (true); - win.set_position (WIN_POS_MOUSE); + if (selection->regions.empty()) { + return; + } + } - spinner.grab_focus (); + if (with_dialog) { - switch (win.run ()) { - case RESPONSE_ACCEPT: - break; - default: - return; + ArdourDialog win ("duplicate dialog"); + Label label (_("Duplicate how many times?")); + Adjustment adjustment (1.0, 1.0, 1000000.0, 1.0, 5.0); + SpinButton spinner (adjustment); + + win.get_vbox()->set_spacing (12); + win.get_vbox()->pack_start (label); + + /* dialogs have ::add_action_widget() but that puts the spinner in the wrong + place, visually. so do this by hand. + */ + + win.get_vbox()->pack_start (spinner); + spinner.signal_activate().connect (sigc::bind (mem_fun (win, &ArdourDialog::response), RESPONSE_ACCEPT)); + + label.show (); + spinner.show (); + + win.add_button (Stock::OK, RESPONSE_ACCEPT); + win.add_button (Stock::CANCEL, RESPONSE_CANCEL); + + win.set_position (WIN_POS_MOUSE); + + spinner.grab_focus (); + + switch (win.run ()) { + case RESPONSE_ACCEPT: + break; + default: + return; + } + + times = adjustment.get_value(); } - float times = adjustment.get_value(); - - if (!selection->regions.empty()) { - duplicate_some_regions (selection->regions, times); - } else { + if (mouse_mode == MouseRange) { duplicate_selection (times); + } else { + duplicate_some_regions (selection->regions, times); } } @@ -3170,6 +3252,25 @@ Editor::set_verbose_canvas_cursor_text (const string & txt) } void +Editor::set_edit_mode (EditMode m) +{ + Config->set_edit_mode (m); +} + +void +Editor::cycle_edit_mode () +{ + switch (Config->get_edit_mode()) { + case Slide: + Config->set_edit_mode (Splice); + break; + case Splice: + Config->set_edit_mode (Slide); + break; + } +} + +void Editor::edit_mode_selection_done () { if (session == 0) { @@ -3192,7 +3293,7 @@ void Editor::snap_type_selection_done () { string choice = snap_type_selector.get_active_text(); - SnapType snaptype = SnapToFrame; + SnapType snaptype = SnapToBeat; if (choice == _("Beats/3")) { snaptype = SnapToAThirdBeat; @@ -3210,8 +3311,6 @@ Editor::snap_type_selection_done () snaptype = SnapToBar; } else if (choice == _("Marks")) { snaptype = SnapToMark; - } else if (choice == _("Edit Point")) { - snaptype = SnapToEditPoint; } else if (choice == _("Region starts")) { snaptype = SnapToRegionStart; } else if (choice == _("Region ends")) { @@ -3232,8 +3331,6 @@ Editor::snap_type_selection_done () snaptype = SnapToSeconds; } else if (choice == _("Minutes")) { snaptype = SnapToMinutes; - } else if (choice == _("None")) { - snaptype = SnapToFrame; } RefPtr<RadioAction> ract = snap_type_action (snaptype); @@ -3248,7 +3345,9 @@ Editor::snap_mode_selection_done () string choice = snap_mode_selector.get_active_text(); SnapMode mode = SnapNormal; - if (choice == _("Normal")) { + if (choice == _("No Grid")) { + mode = SnapOff; + } else if (choice == _("Grid")) { mode = SnapNormal; } else if (choice == _("Magnetic")) { mode = SnapMagnetic; @@ -3262,17 +3361,37 @@ Editor::snap_mode_selection_done () } void +Editor::cycle_edit_point (bool with_marker) +{ + switch (_edit_point) { + case EditAtMouse: + set_edit_point_preference (EditAtPlayhead); + break; + case EditAtPlayhead: + if (with_marker) { + set_edit_point_preference (EditAtSelectedMarker); + } else { + set_edit_point_preference (EditAtMouse); + } + break; + case EditAtSelectedMarker: + set_edit_point_preference (EditAtMouse); + break; + } +} + +void Editor::edit_point_selection_done () { string choice = edit_point_selector.get_active_text(); EditPoint ep = EditAtSelectedMarker; if (choice == _("Marker")) { - _edit_point = EditAtSelectedMarker; + set_edit_point_preference (EditAtSelectedMarker); } else if (choice == _("Playhead")) { - _edit_point = EditAtPlayhead; + set_edit_point_preference (EditAtPlayhead); } else { - _edit_point = EditAtMouse; + set_edit_point_preference (EditAtMouse); } RefPtr<RadioAction> ract = edit_point_action (ep); @@ -3925,6 +4044,13 @@ Editor::on_key_press_event (GdkEventKey* ev) return key_press_focus_accelerator_handler (*this, ev); } +bool +Editor::on_key_release_event (GdkEventKey* ev) +{ + return Gtk::Window::on_key_release_event (ev); + // return key_press_focus_accelerator_handler (*this, ev); +} + void Editor::reset_x_origin (nframes_t frame) { @@ -3945,10 +4071,26 @@ Editor::reposition_and_zoom (nframes_t frame, double fpu) } void -Editor::set_frames_per_unit (double fpu) +Editor::swap_visual_state () { - nframes_t frames; + if (last_visual_state.frames_per_unit == 0) { + // never set + return; + } + /* note: the correct functionality here is very dependent on the ordering of + setting zoom focus, horizontal position and finally zoom. this is because + it is set_frames_per_unit() that overwrites last_visual_state. + */ + + set_zoom_focus (last_visual_state.zoom_focus); + reposition_and_zoom (last_visual_state.leftmost_frame, last_visual_state.frames_per_unit); + zoomed_to_region = false; +} + +void +Editor::set_frames_per_unit (double fpu) +{ /* this is the core function that controls the zoom level of the canvas. it is called whenever one or more calls are made to reset_zoom(). it executes in an idle handler. */ @@ -3961,9 +4103,6 @@ Editor::set_frames_per_unit (double fpu) fpu = 2.0; } - // convert fpu to frame count - - frames = (nframes_t) floor (fpu * canvas_width); /* don't allow zooms that fit more than the maximum number of frames into an 800 pixel wide space. @@ -3976,8 +4115,25 @@ Editor::set_frames_per_unit (double fpu) if (fpu == frames_per_unit) { return; } + + last_visual_state.frames_per_unit = frames_per_unit; + last_visual_state.leftmost_frame = leftmost_frame; + last_visual_state.zoom_focus = zoom_focus; frames_per_unit = fpu; + post_zoom (); +} + +void +Editor::post_zoom () +{ + // convert fpu to frame count + + nframes_t frames = (nframes_t) floor (frames_per_unit * canvas_width); + + if (frames_per_unit != zoom_range_clock.current_duration()) { + zoom_range_clock.set (frames); + } if (mouse_mode == MouseRange && selection->time.start () != selection->time.end_frame ()) { if (!selection->tracks.empty()) { @@ -3995,7 +4151,7 @@ Editor::set_frames_per_unit (double fpu) reset_hscrollbar_stepping (); reset_scrolling_region (); - + if (playhead_cursor) playhead_cursor->set_position (playhead_cursor->current_frame); instant_save (); @@ -4006,7 +4162,7 @@ Editor::queue_visual_change (nframes_t where) { pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin); pending_visual_change.time_origin = where; - + if (pending_visual_change.idle_handler_id < 0) { pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this); } @@ -4036,7 +4192,7 @@ Editor::idle_visual_changer () VisualChange::Type p = pending_visual_change.pending; pending_visual_change.pending = (VisualChange::Type) 0; - + if (p & VisualChange::ZoomLevel) { set_frames_per_unit (pending_visual_change.frames_per_unit); @@ -4046,9 +4202,11 @@ Editor::idle_visual_changer () update_tempo_based_rulers (); } if (p & VisualChange::TimeOrigin) { - if (pending_visual_change.time_origin != leftmost_frame) { + + nframes_t time_origin = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit); + + if (time_origin != pending_visual_change.time_origin) { horizontal_adjustment.set_value (pending_visual_change.time_origin/frames_per_unit); - /* the signal handler will do the rest */ } else { update_fixed_rulers(); redisplay_tempo (true); @@ -4073,22 +4231,35 @@ Editor::sort_track_selection () } nframes64_t -Editor::get_preferred_edit_position() +Editor::get_preferred_edit_position (bool ignore_playhead) { bool ignored; nframes64_t where = 0; + EditPoint ep = _edit_point; - switch (_edit_point) { + if (entered_marker) { + return entered_marker->position(); + } + + if (ignore_playhead && ep == EditAtPlayhead) { + ep = EditAtSelectedMarker; + } + + switch (ep) { case EditAtPlayhead: where = session->audible_frame(); break; case EditAtSelectedMarker: if (!selection->markers.empty()) { - bool whocares; - Location* loc = find_location_from_marker (selection->markers.front(), whocares); + bool is_start; + Location* loc = find_location_from_marker (selection->markers.front(), is_start); if (loc) { - where = loc->start(); + if (is_start) { + where = loc->start(); + } else { + where = loc->end(); + } break; } } @@ -4204,6 +4375,48 @@ Editor::get_regions_at (nframes64_t where, const TrackSelection& ts) const return rs; } + +RegionSelection +Editor::get_regions_after (nframes64_t where, const TrackSelection& ts) const +{ + RegionSelection rs; + const TrackSelection* tracks; + + if (ts.empty()) { + tracks = &track_views; + } else { + tracks = &ts; + } + + for (TrackSelection::const_iterator t = tracks->begin(); t != tracks->end(); ++t) { + + AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*t); + + if (atv) { + boost::shared_ptr<Diskstream> ds; + boost::shared_ptr<Playlist> pl; + + if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) { + + Playlist::RegionList* regions = pl->regions_touched ((nframes_t) floor ( (double)where * ds->speed()), max_frames); + + for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) { + + RegionView* rv = atv->audio_view()->find_view (*i); + + if (rv) { + rs.push_back (rv); + } + } + + delete regions; + } + } + } + + return rs; +} + RegionSelection& Editor::get_regions_for_action () { @@ -4215,3 +4428,37 @@ Editor::get_regions_for_action () tmp_regions = get_regions_at (where, selection->tracks); return tmp_regions; } + +void +Editor::get_regions_corresponding_to (boost::shared_ptr<Region> region, vector<RegionView*>& regions) +{ + + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + + RouteTimeAxisView* tatv; + + if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) { + + boost::shared_ptr<Playlist> pl; + vector<boost::shared_ptr<Region> > results; + RegionView* marv; + boost::shared_ptr<Diskstream> ds; + + if ((ds = tatv->get_diskstream()) == 0) { + /* bus */ + continue; + } + + if ((pl = (ds->playlist())) != 0) { + pl->get_region_list_equivalent_regions (region, results); + } + + for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) { + if ((marv = tatv->view()->find_view (*ir)) != 0) { + regions.push_back (marv); + } + } + + } + } +} diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index faefda51ab..69f7e18a7f 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -46,8 +46,8 @@ #include <pbd/stateful.h> #include <ardour/session.h> -#include <ardour/stretch.h> #include <ardour/tempo.h> +#include <ardour/stretch.h> #include <ardour/location.h> #include <ardour/audioregion.h> @@ -136,6 +136,8 @@ class Editor : public PublicEditor return (nframes_t) floor (canvas_width * frames_per_unit); } + void cycle_snap_mode (); + void cycle_snap_choice (); void set_snap_to (Editing::SnapType); void set_snap_mode (Editing::SnapMode); void set_snap_threshold (double pixel_distance) {snap_threshold = pixel_distance;} @@ -177,6 +179,7 @@ class Editor : public PublicEditor /* things that need to be public to be used in the main menubar */ void new_region_from_selection (); + void separate_regions_between (const TimeSelection&); void separate_region_from_selection (); void separate_regions_using_location (ARDOUR::Location&); void toggle_playback (bool with_abort); @@ -222,6 +225,8 @@ class Editor : public PublicEditor return (gulong) rint ((frame / (frames_per_unit * GNOME_CANVAS(track_canvas.gobj())->pixels_per_unit))); } + void flush_canvas (); + /* selection */ Selection& get_selection() const { return *selection; } @@ -234,6 +239,7 @@ class Editor : public PublicEditor void select_all (Selection::Operation op); void invert_selection_in_selected_tracks (); void invert_selection (); + void deselect_all (); /* tempo */ @@ -260,7 +266,7 @@ class Editor : public PublicEditor void set_zoom_focus (Editing::ZoomFocus); Editing::ZoomFocus get_zoom_focus () const { return zoom_focus; } - gdouble get_current_zoom () { return frames_per_unit; } + double get_current_zoom () const { return frames_per_unit; } void temporal_zoom_step (bool coarser); @@ -268,8 +274,6 @@ class Editor : public PublicEditor PlaylistSelector& playlist_selector() const; void route_name_changed (TimeAxisView *); - gdouble frames_per_unit; - nframes_t leftmost_frame; void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>); void new_playlists (TimeAxisView* v); @@ -330,6 +334,8 @@ class Editor : public PublicEditor /* layers */ void set_layer_model (ARDOUR::LayerModel); void update_layering_model (); + + void toggle_link_region_and_track_selection (); /* redirect shared ops menu. caller must free returned menu */ @@ -354,11 +360,13 @@ class Editor : public PublicEditor void reset_zoom (double); void reposition_and_zoom (nframes_t, double); - nframes64_t get_preferred_edit_position (); + nframes64_t get_preferred_edit_position (bool ignore_playhead = false); bool update_mouse_speed (); bool decelerate_mouse_speed (); + void toggle_meter_updating(); + protected: void map_transport_state (); void map_position_change (nframes_t); @@ -377,9 +385,24 @@ class Editor : public PublicEditor PlaylistSelector* _playlist_selector; - void set_frames_per_unit (double); + struct VisualState { + double frames_per_unit; + nframes_t leftmost_frame; + Editing::ZoomFocus zoom_focus; + }; + + VisualState last_visual_state; + + nframes_t leftmost_frame; + double frames_per_unit; + Editing::ZoomFocus zoom_focus; + + void use_visual_state (const VisualState&); + void set_frames_per_unit (double); + void swap_visual_state (); + void post_zoom (); - Editing::MouseMode mouse_mode; + Editing::MouseMode mouse_mode; Editing::MidiEditMode midi_edit_mode; int post_maximal_editor_width; @@ -406,6 +429,7 @@ class Editor : public PublicEditor void location_gone (ARDOUR::Location *); void remove_marker (ArdourCanvas::Item&, GdkEvent*); gint really_remove_marker (ARDOUR::Location* loc); + void goto_nth_marker (int nth); uint32_t location_marker_color; uint32_t location_range_color; @@ -438,7 +462,9 @@ class Editor : public PublicEditor void hide_marker (ArdourCanvas::Item*, GdkEvent*); void clear_marker_display (); - void mouse_add_new_marker (nframes_t where); + void mouse_add_new_marker (nframes_t where, bool is_cd=false); + void update_cd_marker_display (); + void ensure_cd_marker_updated (LocationMarkers * lam, ARDOUR::Location * location); TimeAxisView* clicked_axisview; RouteTimeAxisView* clicked_routeview; @@ -447,8 +473,7 @@ class Editor : public PublicEditor * editor_canvas_events.cc */ RegionView* clicked_regionview; - - RegionView* latest_regionview; + RegionSelection latest_regionviews; uint32_t clicked_selection; CrossfadeView* clicked_crossfadeview; ControlPoint* clicked_control_point; @@ -473,11 +498,12 @@ class Editor : public PublicEditor void catch_vanishing_regionview (RegionView *); - bool set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false); + void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false); void select_all_tracks (); bool set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool no_remove=false); - bool set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false); + void set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false); + void set_selected_track_as_side_effect (bool force = false); bool set_selected_regionview_from_click (bool press, Selection::Operation op = Selection::Set, bool no_track_remove=false); void set_selected_regionview_from_region_list (boost::shared_ptr<ARDOUR::Region> region, Selection::Operation op = Selection::Set); @@ -539,6 +565,7 @@ class Editor : public PublicEditor ArdourCanvas::Group *marker_group; ArdourCanvas::Group *range_marker_group; ArdourCanvas::Group *transport_marker_group; + ArdourCanvas::Group* cd_marker_group; enum { ruler_metric_smpte = 0, @@ -551,15 +578,17 @@ class Editor : public PublicEditor ruler_time_marker = 6, ruler_time_range_marker = 7, ruler_time_transport_marker = 8, + ruler_time_cd_marker = 9, }; static GtkCustomMetric ruler_metrics[4]; - bool ruler_shown[9]; + bool ruler_shown[10]; bool no_ruler_shown_update; gint ruler_button_press (GdkEventButton*); gint ruler_button_release (GdkEventButton*); gint ruler_mouse_motion (GdkEventMotion*); + bool ruler_scroll (GdkEventScroll* event); gint ruler_pressed_button; Gtk::Widget * ruler_grabbed_widget; @@ -655,7 +684,8 @@ class Editor : public PublicEditor ArdourCanvas::SimpleRect* marker_bar; ArdourCanvas::SimpleRect* range_marker_bar; ArdourCanvas::SimpleRect* transport_marker_bar; - + ArdourCanvas::SimpleRect* cd_marker_bar; + Gtk::Label minsec_label; Gtk::Label bbt_label; Gtk::Label smpte_label; @@ -665,6 +695,7 @@ class Editor : public PublicEditor Gtk::Label mark_label; Gtk::Label range_mark_label; Gtk::Label transport_mark_label; + Gtk::Label cd_mark_label; Gtk::VBox time_button_vbox; @@ -692,17 +723,23 @@ class Editor : public PublicEditor Cursor* playhead_cursor; ArdourCanvas::Group* cursor_group; + void cursor_to_region_boundary (Cursor*, int32_t dir); + void cursor_to_next_region_boundary (Cursor*); + void cursor_to_previous_region_boundary (Cursor*); void cursor_to_next_region_point (Cursor*, ARDOUR::RegionPoint); void cursor_to_previous_region_point (Cursor*, ARDOUR::RegionPoint); void cursor_to_region_point (Cursor*, ARDOUR::RegionPoint, int32_t dir); void cursor_to_selection_start (Cursor *); void cursor_to_selection_end (Cursor *); - void edit_point_to_next_region_point (ARDOUR::RegionPoint); - void edit_point_to_previous_region_point (ARDOUR::RegionPoint); - void edit_point_to_region_point (ARDOUR::RegionPoint, int32_t dir); - void edit_point_to_selection_start (); - void edit_point_to_selection_end (); + void selected_marker_to_region_boundary (int32_t dir); + void selected_marker_to_next_region_boundary (); + void selected_marker_to_previous_region_boundary (); + void selected_marker_to_next_region_point (ARDOUR::RegionPoint); + void selected_marker_to_previous_region_point (ARDOUR::RegionPoint); + void selected_marker_to_region_point (ARDOUR::RegionPoint, int32_t dir); + void selected_marker_to_selection_start (); + void selected_marker_to_selection_end (); void select_all_selectables_using_cursor (Cursor *, bool); void select_all_selectables_using_edit (bool); @@ -710,6 +747,7 @@ class Editor : public PublicEditor void select_range_between (); boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0); + nframes64_t find_next_region_boundary (nframes64_t, int32_t dir, const TrackViewList&); vector<nframes_t> region_boundary_cache; void build_region_boundary_cache (); @@ -761,8 +799,7 @@ class Editor : public PublicEditor void tie_vertical_scrolling (); void canvas_horizontally_scrolled (); - static int _idle_canvas_horizontally_scrolled (void *arg); - bool idle_canvas_horizontally_scrolled (); + void canvas_scroll_to (nframes64_t); struct VisualChange { enum Type { @@ -803,8 +840,7 @@ class Editor : public PublicEditor RegionListDisplayModelColumns region_list_columns; Gtkmm2ext::DnDTreeView<boost::shared_ptr<ARDOUR::Region> > region_list_display; - std::list<sigc::connection> region_state_changed_connections; - + Glib::RefPtr<Gtk::TreeStore> region_list_model; Glib::RefPtr<Gtk::ToggleAction> toggle_full_region_list_action; Glib::RefPtr<Gtk::ToggleAction> toggle_show_auto_regions_action; @@ -812,6 +848,8 @@ class Editor : public PublicEditor void region_list_region_changed (ARDOUR::Change, boost::weak_ptr<ARDOUR::Region>); void region_list_selection_changed (); bool region_list_selection_filter (const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::Path& path, bool yn); + void region_name_edit (const Glib::ustring&, const Glib::ustring&); + void get_regions_corresponding_to (boost::shared_ptr<ARDOUR::Region> region, std::vector<RegionView*>& regions); Gtk::Menu *region_list_menu; Gtk::ScrolledWindow region_list_scroller; @@ -961,14 +999,16 @@ class Editor : public PublicEditor void toggle_region_lock (); void toggle_region_opaque (); void toggle_region_position_lock (); + void raise_region (); void raise_region_to_top (); + void lower_region (); void lower_region_to_bottom (); void split_region (); void split_region_at (nframes_t); void split_regions_at (nframes_t, RegionSelection&); void crop_region_to_selection (); void crop_region_to (nframes_t start, nframes_t end); - void set_a_regions_sync_position (boost::shared_ptr<ARDOUR::Region>, nframes_t); + void set_sync_point (nframes64_t, const RegionSelection&); void set_region_sync_from_edit_point (); void remove_region_sync(); void align_selection (ARDOUR::RegionPoint, nframes_t position, const RegionSelection&); @@ -978,6 +1018,7 @@ class Editor : public PublicEditor void remove_selected_regions (); void remove_clicked_region (); void edit_region (); + void rename_region (); void duplicate_some_regions (RegionSelection&, float times); void duplicate_selection (float times); void region_fill_selection (); @@ -1010,28 +1051,24 @@ class Editor : public PublicEditor int get_prefix (float&, bool&); void keyboard_paste (); - void keyboard_duplicate_region (); - void keyboard_duplicate_selection (); void keyboard_insert_region_list_selection (); void region_from_selection (); void create_region_from_selection (std::vector<boost::shared_ptr<ARDOUR::AudioRegion> >&); - bool region_renamed; - void rename_region (); - void rename_region_finished (bool); - void play_from_start (); void play_from_edit_point (); + void play_from_edit_point_and_return (); void play_selected_region (); - void audition_selected_region (); + void play_edit_range (); void loop_selected_region (); void play_location (ARDOUR::Location&); void loop_location (ARDOUR::Location&); - Editing::ZoomFocus zoom_focus; - void temporal_zoom_selection (); + void temporal_zoom_region (); + void toggle_zoom_region (); + bool zoomed_to_region; void temporal_zoom_session (); void temporal_zoom (gdouble scale); void temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & op); @@ -1137,15 +1174,21 @@ class Editor : public PublicEditor void set_selection_from_loop (); void set_selection_from_audio_region (); + void add_location_mark (nframes64_t where); void add_location_from_audio_region (); void add_location_from_selection (); void set_loop_from_selection (bool play); void set_punch_from_selection (); + void set_loop_from_edit_range (bool play); + void set_loop_from_region (bool play); + void set_punch_from_edit_range (); + void set_loop_range (nframes_t start, nframes_t end, std::string cmd); void set_punch_range (nframes_t start, nframes_t end, std::string cmd); void add_location_from_playhead_cursor (); + bool select_new_marker; void reverse_selection (); void edit_envelope (); @@ -1199,15 +1242,20 @@ class Editor : public PublicEditor void set_fade_out_shape (ARDOUR::AudioRegion::FadeShape); void set_fade_length (bool in); - + void toggle_fade_active (bool in); void set_fade_in_active (bool); void set_fade_out_active (bool); std::set<boost::shared_ptr<ARDOUR::Playlist> > motion_frozen_playlists; + RegionSelection pre_drag_region_selection; void region_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*); void region_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*); void create_region_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*); void create_region_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*); + bool check_region_drag_possible (RouteTimeAxisView**); + void possibly_copy_regions_during_grab (GdkEvent*); + void region_drag_splice_motion_callback (ArdourCanvas::Item*, GdkEvent*); + void region_drag_splice_finished_callback (ArdourCanvas::Item*, GdkEvent*); bool _dragging_playhead; bool _dragging_edit_point; @@ -1282,6 +1330,7 @@ class Editor : public PublicEditor bool canvas_marker_bar_event (GdkEvent* event, ArdourCanvas::Item*); bool canvas_range_marker_bar_event (GdkEvent* event, ArdourCanvas::Item*); bool canvas_transport_marker_bar_event (GdkEvent* event, ArdourCanvas::Item*); + bool canvas_cd_marker_bar_event (GdkEvent* event, ArdourCanvas::Item*); bool canvas_imageframe_item_view_event(GdkEvent* event, ArdourCanvas::Item*,ImageFrameView*); bool canvas_imageframe_view_event(GdkEvent* event, ArdourCanvas::Item*,ImageFrameTimeAxis*); @@ -1296,12 +1345,15 @@ class Editor : public PublicEditor bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*); bool track_canvas_scroll (GdkEventScroll* event); + bool time_canvas_scroll (GdkEventScroll* event); bool track_canvas_scroll_event (GdkEventScroll* event); bool track_canvas_button_press_event (GdkEventButton* event); bool track_canvas_button_release_event (GdkEventButton* event); bool track_canvas_motion_notify_event (GdkEventMotion* event); + bool time_canvas_scroll_event (GdkEventScroll* event); + Gtk::Allocation canvas_allocation; bool canvas_idle_queued; void track_canvas_allocate (Gtk::Allocation alloc); @@ -1311,11 +1363,8 @@ class Editor : public PublicEditor void kbd_driver (sigc::slot<void,GdkEvent*>, bool use_track_canvas = true, bool use_time_canvas = true, bool can_select = true); void kbd_mute_unmute_region (); - void kbd_set_sync_position (); void kbd_brush (); - void kbd_audition (); - void kbd_do_set_sync_position (GdkEvent* ev); void kbd_do_brush (GdkEvent*); void kbd_do_audition (GdkEvent*); @@ -1396,6 +1445,7 @@ class Editor : public PublicEditor Gtk::Menu* range_marker_menu; Gtk::Menu* transport_marker_menu; Gtk::Menu* new_transport_marker_menu; + Gtk::Menu* cd_marker_menu; ArdourCanvas::Item* marker_menu_item; typedef list<Marker*> Marks; @@ -1463,6 +1513,8 @@ class Editor : public PublicEditor Gtk::ComboBoxText edit_mode_selector; Gtk::VBox edit_mode_box; + void set_edit_mode (ARDOUR::EditMode); + void cycle_edit_mode (); void edit_mode_selection_done (); Gtk::ComboBoxText snap_type_selector; @@ -1553,7 +1605,8 @@ class Editor : public PublicEditor /* transport range select process */ enum RangeMarkerOp { CreateRangeMarker, - CreateTransportMarker + CreateTransportMarker, + CreateCDMarker } range_marker_op; void start_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event, RangeMarkerOp); @@ -1629,6 +1682,13 @@ class Editor : public PublicEditor bool ignore_route_order_sync; bool route_list_display_button_press (GdkEventButton*); + void route_list_display_drag_data_received (const Glib::RefPtr<Gdk::DragContext>& context, + gint x, + gint y, + const Gtk::SelectionData& data, + guint info, + guint time); + bool route_list_selection_filter (const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::Path& path, bool yn); void route_list_change (const Gtk::TreeModel::Path&,const Gtk::TreeModel::iterator&); @@ -1724,7 +1784,11 @@ class Editor : public PublicEditor void trim_finished_callback (ArdourCanvas::Item*, GdkEvent*); void thaw_region_after_trim (RegionView& rv); - + + void trim_region_front(); + void trim_region_back(); + void trim_region (bool front); + void trim_region_to_edit_point (); void trim_region_from_edit_point (); void trim_region_to_loop (); @@ -1842,7 +1906,7 @@ class Editor : public PublicEditor /* duplication */ - void duplicate_dialog (bool for_region); + void duplicate_dialog (bool with_dialog); nframes64_t event_frame (GdkEvent*, double* px = 0, double* py = 0) const; @@ -1854,9 +1918,16 @@ class Editor : public PublicEditor void start_time_fx (ArdourCanvas::Item*, GdkEvent*); void end_time_fx (ArdourCanvas::Item*, GdkEvent*); - struct TimeStretchDialog : public ArdourDialog { - ARDOUR::TimeStretchRequest request; + struct TimeFXDialog : public ArdourDialog { + ARDOUR::TimeFXRequest request; Editor& editor; + bool pitching; + Gtk::Adjustment pitch_octave_adjustment; + Gtk::Adjustment pitch_semitone_adjustment; + Gtk::Adjustment pitch_cent_adjustment; + Gtk::SpinButton pitch_octave_spinner; + Gtk::SpinButton pitch_semitone_spinner; + Gtk::SpinButton pitch_cent_spinner; RegionSelection regions; Gtk::ProgressBar progress_bar; Gtk::ToggleButton quick_button; @@ -1867,24 +1938,28 @@ class Editor : public PublicEditor Gtk::VBox packer; int status; - TimeStretchDialog (Editor& e); + TimeFXDialog (Editor& e, bool for_pitch); gint update_progress (); sigc::connection first_cancel; sigc::connection first_delete; - void cancel_timestretch_in_progress (); - gint delete_timestretch_in_progress (GdkEventAny*); + void cancel_in_progress (); + gint delete_in_progress (GdkEventAny*); }; /* "whats mine is yours" */ - friend class TimeStretchDialog; + friend class TimeFXDialog; - TimeStretchDialog* current_timestretch; + TimeFXDialog* current_timefx; - static void* timestretch_thread (void *arg); - int run_timestretch (RegionSelection&, float fraction); - void do_timestretch (TimeStretchDialog&); + static void* timefx_thread (void *arg); + void do_timefx (TimeFXDialog&); + + int time_stretch (RegionSelection&, float fraction); + int pitch_shift (RegionSelection&, float cents); + void pitch_shift_regions (); + int time_fx (RegionSelection&, float val, bool pitching); /* editor-mixer strip */ @@ -1986,7 +2061,8 @@ class Editor : public PublicEditor TimeAxisView* entered_track; RegionView* entered_regionview; - void ensure_entered_selected (); + void ensure_entered_region_selected (bool op_acts_on_objects = false); + void ensure_entered_track_selected (bool op_acts_on_objects = false); bool clear_entered_track; gint left_track_canvas (GdkEventCrossing*); void set_entered_track (TimeAxisView*); @@ -2007,6 +2083,7 @@ class Editor : public PublicEditor Gtk::CheckMenuItem* region_opaque_item; bool on_key_press_event (GdkEventKey*); + bool on_key_release_event (GdkEventKey*); void session_state_saved (string); @@ -2022,6 +2099,7 @@ class Editor : public PublicEditor Gtk::ComboBoxText edit_point_selector; void set_edit_point_preference (Editing::EditPoint ep); + void cycle_edit_point (bool with_marker); void set_edit_point (); void edit_point_selection_done (); void edit_point_chosen (Editing::EditPoint); @@ -2035,6 +2113,7 @@ class Editor : public PublicEditor bool get_edit_op_range (nframes64_t& start, nframes64_t& end) const; RegionSelection get_regions_at (nframes64_t where, const TrackSelection& ts) const; + RegionSelection get_regions_after (nframes64_t where, const TrackSelection& ts) const; RegionSelection tmp_regions; @@ -2043,10 +2122,11 @@ class Editor : public PublicEditor sigc::connection fast_screen_update_connection; gint start_updating (); gint stop_updating (); - void toggle_meter_updating(); void fast_update_strips (); - bool meters_running; + + void select_next_route (); + void select_prev_route (); }; #endif /* __ardour_editor_h__ */ diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 8b607f5080..fd95fd46b9 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -63,10 +63,13 @@ Editor::register_actions () 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_("LocateToMarker"), _("Locate To Markers")); /* add named actions for the editor */ + ActionManager::register_toggle_action (editor_actions, "link-region-and-track-selection", _("Link Region/Track Selection"), mem_fun (*this, &Editor::toggle_link_region_and_track_selection)); + act = ActionManager::register_toggle_action (editor_actions, "show-editor-mixer", _("Show Editor Mixer"), mem_fun (*this, &Editor::editor_mixer_button_toggled)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_toggle_action (editor_actions, "show-editor-list", _("Show Editor List"), mem_fun (*this, &Editor::editor_list_button_toggled)); @@ -86,6 +89,11 @@ Editor::register_actions () 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); + act = ActionManager::register_action (editor_actions, "playhead-to-next-region-boundary", _("Playhead to Next Region Boundary"), bind (mem_fun(*this, &Editor::cursor_to_next_region_boundary), playhead_cursor)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "playhead-to-previous-region-boundary", _("Playhead to Previous Region Boundary"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_boundary), playhead_cursor)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "playhead-to-next-region-start", _("Playhead to Next Region Start"), bind (mem_fun(*this, &Editor::cursor_to_next_region_point), playhead_cursor, RegionPoint (Start))); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "playhead-to-next-region-end", _("Playhead to Next Region End"), bind (mem_fun(*this, &Editor::cursor_to_next_region_point), playhead_cursor, RegionPoint (End))); @@ -100,23 +108,28 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "playhead-to-previous-region-sync", _("Playhead to Previous Region Sync"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_point), playhead_cursor, RegionPoint (SyncPoint))); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-start", _("Edit Cursor to Next Region Start"), bind (mem_fun(*this, &Editor::edit_point_to_next_region_point), RegionPoint (Start))); + act = ActionManager::register_action (editor_actions, "selected-marker-to-next-region-boundary", _("to Next Region Boundary"), mem_fun(*this, &Editor::selected_marker_to_next_region_boundary)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "selected-marker-to-previous-region-boundary", _("to Previous Region Boundary"), mem_fun(*this, &Editor::selected_marker_to_previous_region_boundary)); + ActionManager::session_sensitive_actions.push_back (act); + + act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-start", _("to Next Region Start"), bind (mem_fun(*this, &Editor::selected_marker_to_next_region_point), RegionPoint (Start))); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-end", _("Edit Cursor to Next Region End"), bind (mem_fun(*this, &Editor::edit_point_to_next_region_point), RegionPoint (End))); + act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-end", _("to Next Region End"), bind (mem_fun(*this, &Editor::selected_marker_to_next_region_point), RegionPoint (End))); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-sync", _("Edit Cursor to Next Region Sync"), bind (mem_fun(*this, &Editor::edit_point_to_next_region_point), RegionPoint (SyncPoint))); + act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-sync", _("to Next Region Sync"), bind (mem_fun(*this, &Editor::selected_marker_to_next_region_point), RegionPoint (SyncPoint))); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-start", _("Edit Cursor to Previous Region Start"), bind (mem_fun(*this, &Editor::edit_point_to_previous_region_point), RegionPoint (Start))); + act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-start", _("to Previous Region Start"), bind (mem_fun(*this, &Editor::selected_marker_to_previous_region_point), RegionPoint (Start))); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-end", _("Edit Cursor to Previous Region End"), bind (mem_fun(*this, &Editor::edit_point_to_previous_region_point), RegionPoint (End))); + act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-end", _("to Previous Region End"), bind (mem_fun(*this, &Editor::selected_marker_to_previous_region_point), RegionPoint (End))); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-sync", _("Edit Cursor to Previous Region Sync"), bind (mem_fun(*this, &Editor::edit_point_to_previous_region_point), RegionPoint (SyncPoint))); + act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-sync", _("to Previous Region Sync"), bind (mem_fun(*this, &Editor::selected_marker_to_previous_region_point), RegionPoint (SyncPoint))); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-cursor-to-range-start", _("Edit Cursor to Range Start"), mem_fun(*this, &Editor::edit_point_to_selection_start)); + act = ActionManager::register_action (editor_actions, "edit-cursor-to-range-start", _("to Range Start"), mem_fun(*this, &Editor::selected_marker_to_selection_start)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-cursor-to-range-end", _("Edit Cursor to Range End"), mem_fun(*this, &Editor::edit_point_to_selection_end)); + act = ActionManager::register_action (editor_actions, "edit-cursor-to-range-end", _("to Range End"), mem_fun(*this, &Editor::selected_marker_to_selection_end)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "playhead-to-range-start", _("Playhead to Range Start"), bind (mem_fun(*this, &Editor::cursor_to_selection_start), playhead_cursor)); @@ -126,9 +139,13 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "select-all", _("Select All"), bind (mem_fun(*this, &Editor::select_all), Selection::Set)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "select-all-after-edit-cursor", _("Select All After Edit Cursor"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), true)); + act = ActionManager::register_action (editor_actions, "deselect-all", _("Deselect All"), mem_fun(*this, &Editor::deselect_all)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "select-all-before-edit-cursor", _("Select All Before Edit Cursor"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), false)); + act = ActionManager::register_action (editor_actions, "invert-selection", _("Invert Selection"), mem_fun(*this, &Editor::invert_selection)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "select-all-after-edit-cursor", _("Select All After Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), true)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "select-all-before-edit-cursor", _("Select All Before Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), false)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "select-all-after-playhead", _("Select All After Playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true)); @@ -137,7 +154,7 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "select-all-between-cursors", _("Select All Between Playhead & Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_between), false)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "select-all-within-cursors", _("Select All Between Playhead & Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_between), true)); + act = ActionManager::register_action (editor_actions, "select-all-within-cursors", _("Select All Within Playhead & Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_between), true)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "select-range-between-cursors", _("Select Range Between Playhead & Edit Point"), mem_fun(*this, &Editor::select_range_between)); @@ -147,6 +164,31 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "select-all-in-loop-range", _("Select All in Loop Range"), mem_fun(*this, &Editor::select_all_selectables_using_loop)); ActionManager::session_sensitive_actions.push_back (act); + + act = ActionManager::register_action (editor_actions, "select-next-route", _("Select Next Track/Bus"), mem_fun(*this, &Editor::select_next_route)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "select-prev-route", _("Select Previous Track/Bus"), mem_fun(*this, &Editor::select_prev_route)); + ActionManager::session_sensitive_actions.push_back (act); + + + act = ActionManager::register_action (editor_actions, "goto-mark-1", _("Locate to Mark 1"), bind (mem_fun (*this, &Editor::goto_nth_marker), 0)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "goto-mark-2", _("Locate to Mark 2"), bind (mem_fun (*this, &Editor::goto_nth_marker), 1)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "goto-mark-3", _("Locate to Mark 3"), bind (mem_fun (*this, &Editor::goto_nth_marker), 2)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "goto-mark-4", _("Locate to Mark 4"), bind (mem_fun (*this, &Editor::goto_nth_marker), 3)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "goto-mark-5", _("Locate to Mark 5"), bind (mem_fun (*this, &Editor::goto_nth_marker), 4)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "goto-mark-6", _("Locate to Mark 6"), bind (mem_fun (*this, &Editor::goto_nth_marker), 5)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "goto-mark-7", _("Locate to Mark 7"), bind (mem_fun (*this, &Editor::goto_nth_marker), 6)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "goto-mark-8", _("Locate to Mark 8"), bind (mem_fun (*this, &Editor::goto_nth_marker), 7)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "goto-mark-9", _("Locate to Mark 9"), bind (mem_fun (*this, &Editor::goto_nth_marker), 8)); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "jump-forward-to-mark", _("Jump Forward to Mark"), mem_fun(*this, &Editor::jump_forward_to_mark)); ActionManager::session_sensitive_actions.push_back (act); @@ -164,12 +206,17 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "nudge-next-backward", _("Nudge Next Backward"), bind (mem_fun(*this, &Editor::nudge_backward), true)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "temporal-zoom-out", _("Zoom Out"), bind (mem_fun(*this, &Editor::temporal_zoom_step), true)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "temporal-zoom-in", _("Zoom In"), bind (mem_fun(*this, &Editor::temporal_zoom_step), false)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "zoom-to-session", _("Zoom to Session"), mem_fun(*this, &Editor::temporal_zoom_session)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "zoom-to-region", _("Zoom to Region"), mem_fun(*this, &Editor::toggle_zoom_region)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "toggle-zoom", _("Toggle Zoom State"), mem_fun(*this, &Editor::swap_visual_state)); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "scroll-tracks-up", _("Scroll Tracks Up"), mem_fun(*this, &Editor::scroll_tracks_up)); ActionManager::session_sensitive_actions.push_back (act); @@ -186,9 +233,9 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "goto", _("goto"), mem_fun(*this, &Editor::goto_frame)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "center-playhead", _("Center Playhead"), mem_fun(*this, &Editor::center_playhead)); + act = ActionManager::register_action (editor_actions, "center-playhead", _("to Center"), mem_fun(*this, &Editor::center_playhead)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "center-edit-cursor", _("Center Edit Point"), mem_fun(*this, &Editor::center_edit_point)); + act = ActionManager::register_action (editor_actions, "center-edit-cursor", _("to Center"), mem_fun(*this, &Editor::center_edit_point)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "scroll-playhead-forward", _("Playhead forward"), bind (mem_fun(*this, &Editor::scroll_playhead), true));; @@ -196,11 +243,15 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "scroll-playhead-backward", _("Playhead Backward"), bind (mem_fun(*this, &Editor::scroll_playhead), false)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "playhead-to-edit", _("Playhead to Edit"), bind (mem_fun(*this, &Editor::cursor_align), true)); + act = ActionManager::register_action (editor_actions, "playhead-to-edit", _("to Edit"), bind (mem_fun(*this, &Editor::cursor_align), true)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-to-playhead", _("Edit to Playhead"), bind (mem_fun(*this, &Editor::cursor_align), false)); + act = ActionManager::register_action (editor_actions, "edit-to-playhead", _("to Playhead"), bind (mem_fun(*this, &Editor::cursor_align), false)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "trim-front", _("Trim start at edit point"), mem_fun(*this, &Editor::trim_region_front)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "trim-back", _("Trim end at edit point"), mem_fun(*this, &Editor::trim_region_back)); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "trim-from-start", _("Start to edit point"), mem_fun(*this, &Editor::trim_region_from_edit_point)); ActionManager::session_sensitive_actions.push_back (act); @@ -210,11 +261,28 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "trim-region-to-punch", _("Trim To Punch"), mem_fun(*this, &Editor::trim_region_to_punch)); ActionManager::session_sensitive_actions.push_back (act); + + act = ActionManager::register_action (editor_actions, "set-loop-from-edit-range", _("Set Loop From Edit Range"), bind (mem_fun(*this, &Editor::set_loop_from_edit_range), false)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "set-loop-from-region", _("Set Loop From Region"), bind (mem_fun(*this, &Editor::set_loop_from_region), false)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "loop-region", _("Loop Region"), bind (mem_fun(*this, &Editor::set_loop_from_region), true)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "set-punch-from-edit-range", _("Set Punch From Edit Range"), mem_fun(*this, &Editor::set_punch_from_edit_range)); + ActionManager::session_sensitive_actions.push_back (act); + + + act = ActionManager::register_action (editor_actions, "pitch-shift-region", _("Transpose"), mem_fun(*this, &Editor::pitch_shift_regions)); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "set-fade-in-length", _("Set Fade In Length"), bind (mem_fun(*this, &Editor::set_fade_length), true)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "toggle-fade-in-active", _("Toggle Fade In Active"), bind (mem_fun(*this, &Editor::toggle_fade_active), true)); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "set-fade-out-length", _("Set Fade Out Length"), bind (mem_fun(*this, &Editor::set_fade_length), false)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "toggle-fade-out-active", _("Toggle Fade Out Active"), bind (mem_fun(*this, &Editor::toggle_fade_active), false)); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "align-regions-start", _("Align Regions Start"), bind (mem_fun(*this, &Editor::align), ARDOUR::Start)); ActionManager::session_sensitive_actions.push_back (act); @@ -229,15 +297,19 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "align-regions-sync-relative", _("Align Regions Sync Relative"), bind (mem_fun(*this, &Editor::align_relative), ARDOUR::SyncPoint)); ActionManager::session_sensitive_actions.push_back (act); - - act = ActionManager::register_action (editor_actions, "audition-at-mouse", _("Audition at Mouse"), mem_fun(*this, &Editor::kbd_audition)); + + act = ActionManager::register_action (editor_actions, "play-from-edit-point", _("Play From Edit Point"), mem_fun(*this, &Editor::play_from_edit_point)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "play-from-edit-point-and-return", _("Play from Edit Point & Return"), mem_fun(*this, &Editor::play_from_edit_point_and_return)); + ActionManager::session_sensitive_actions.push_back (act); + + act = ActionManager::register_action (editor_actions, "play-edit-range", _("Play Edit Range"), mem_fun(*this, &Editor::play_edit_range)); + act = ActionManager::register_action (editor_actions, "play-selected-regions", _("Play Selected Region(s)"), mem_fun(*this, &Editor::play_selected_region)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "brush-at-mouse", _("Brush at Mouse"), mem_fun(*this, &Editor::kbd_brush)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "mute-unmute-region", _("Mute/Unmute Region"), mem_fun(*this, &Editor::kbd_mute_unmute_region)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "set-region-sync-position", _("Set Region Sync Position"), mem_fun(*this, &Editor::kbd_set_sync_position)); - ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "set-playhead", _("Set Playhead"), mem_fun(*this, &Editor::set_playhead_cursor)); ActionManager::session_sensitive_actions.push_back (act); @@ -245,6 +317,8 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "split-region", _("Split Region"), mem_fun(*this, &Editor::split)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "set-region-sync-position", _("Set Region Sync Position"), mem_fun(*this, &Editor::set_region_sync_from_edit_point)); + ActionManager::session_sensitive_actions.push_back (act); undo_action = act = ActionManager::register_action (editor_actions, "undo", _("Undo"), bind (mem_fun(*this, &Editor::undo), 1U)); ActionManager::session_sensitive_actions.push_back (act); @@ -256,6 +330,10 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "export-range", _("Export Range"), mem_fun(*this, &Editor::export_selection)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "editor-separate", _("Separate"), mem_fun(*this, &Editor::separate_region_from_selection)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "editor-crop", _("Crop"), mem_fun(*this, &Editor::crop_region_to_selection)); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "editor-cut", _("Cut"), mem_fun(*this, &Editor::cut)); ActionManager::session_sensitive_actions.push_back (act); /* Note: for now, editor-delete does the exact same thing as editor-cut */ @@ -265,9 +343,11 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "editor-paste", _("Paste"), mem_fun(*this, &Editor::keyboard_paste)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "duplicate-region", _("Duplicate Region"), mem_fun(*this, &Editor::keyboard_duplicate_region)); + act = ActionManager::register_action (editor_actions, "duplicate-region", _("Duplicate Region"), bind (mem_fun(*this, &Editor::duplicate_dialog), false)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "multi-duplicate-region", _("Multi-Duplicate Region"), bind (mem_fun(*this, &Editor::duplicate_dialog), true)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "duplicate-range", _("Duplicate Range"), mem_fun(*this, &Editor::keyboard_duplicate_selection)); + act = ActionManager::register_action (editor_actions, "duplicate-range", _("Duplicate Range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "insert-region", _("Insert Region"), mem_fun(*this, &Editor::keyboard_insert_region_list_selection)); ActionManager::session_sensitive_actions.push_back (act); @@ -333,17 +413,27 @@ Editor::register_actions () ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-mouse"), _("Mouse"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead))); ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-selected-marker"), _("Marker"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead))); + ActionManager::register_action (editor_actions, "cycle-edit-point", _("Change edit point"), bind (mem_fun (*this, &Editor::cycle_edit_point), false)); + ActionManager::register_action (editor_actions, "cycle-edit-point-with-marker", _("Change edit point (w/Marker)"), bind (mem_fun (*this, &Editor::cycle_edit_point), true)); + + ActionManager::register_action (editor_actions, "set-edit-splice", _("Splice"), bind (mem_fun (*this, &Editor::set_edit_mode), Splice)); + ActionManager::register_action (editor_actions, "set-edit-slide", _("Slide"), bind (mem_fun (*this, &Editor::set_edit_mode), Slide)); + ActionManager::register_action (editor_actions, "toggle-edit-mode", _("Toggle Edit Mode"), mem_fun (*this, &Editor::cycle_edit_mode)); + ActionManager::register_action (editor_actions, X_("SnapTo"), _("Snap To")); ActionManager::register_action (editor_actions, X_("SnapMode"), _("Snap Mode")); RadioAction::Group snap_mode_group; - ActionManager::register_radio_action (editor_actions, snap_mode_group, X_("snap-normal"), _("Normal"), (bind (mem_fun(*this, &Editor::snap_mode_chosen), Editing::SnapNormal))); + ActionManager::register_radio_action (editor_actions, snap_mode_group, X_("snap-off"), _("No Grid"), (bind (mem_fun(*this, &Editor::snap_mode_chosen), Editing::SnapOff))); + ActionManager::register_radio_action (editor_actions, snap_mode_group, X_("snap-normal"), _("Grid"), (bind (mem_fun(*this, &Editor::snap_mode_chosen), Editing::SnapNormal))); ActionManager::register_radio_action (editor_actions, snap_mode_group, X_("snap-magnetic"), _("Magnetic"), (bind (mem_fun(*this, &Editor::snap_mode_chosen), Editing::SnapMagnetic))); + ActionManager::register_action (editor_actions, X_("cycle-snap-mode"), _("Next Snap Mode"), mem_fun (*this, &Editor::cycle_snap_mode)); + ActionManager::register_action (editor_actions, X_("cycle-snap-choice"), _("Next Snap Choice"), mem_fun (*this, &Editor::cycle_snap_choice)); + Glib::RefPtr<ActionGroup> snap_actions = ActionGroup::create (X_("Snap")); RadioAction::Group snap_choice_group; - ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-frame"), _("Snap to frame"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToFrame))); ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-cd-frame"), _("Snap to cd frame"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToCDFrame))); ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-smpte-frame"), _("Snap to SMPTE frame"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToSMPTEFrame))); ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-smpte-seconds"), _("Snap to SMPTE seconds"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToSMPTESeconds))); @@ -358,7 +448,6 @@ Editor::register_actions () ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-beat"), _("Snap to beat"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToBeat))); ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-bar"), _("Snap to bar"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToBar))); ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-mark"), _("Snap to mark"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToMark))); - ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-edit-cursor"), _("Snap to edit point"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToEditPoint))); ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-region-start"), _("Snap to region start"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToRegionStart))); ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-region-end"), _("Snap to region end"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToRegionEnd))); ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-region-sync"), _("Snap to region sync"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToRegionSync))); @@ -567,6 +656,7 @@ Editor::update_crossfade_model () } } + void Editor::update_smpte_mode () { @@ -721,9 +811,6 @@ Editor::snap_type_action (SnapType type) RefPtr<Action> act; switch (type) { - case Editing::SnapToFrame: - action = "snap-to-frame"; - break; case Editing::SnapToCDFrame: action = "snap-to-cd-frame"; break; @@ -766,9 +853,6 @@ Editor::snap_type_action (SnapType type) case Editing::SnapToMark: action = "snap-to-mark"; break; - case Editing::SnapToEditPoint: - action = "snap-to-edit-cursor"; - break; case Editing::SnapToRegionStart: action = "snap-to-region-start"; break; @@ -799,6 +883,67 @@ Editor::snap_type_action (SnapType type) } void +Editor::cycle_snap_choice() +{ + switch (snap_type) { + case Editing::SnapToCDFrame: + set_snap_to (Editing::SnapToSMPTEFrame); + break; + case Editing::SnapToSMPTEFrame: + set_snap_to (Editing::SnapToSMPTESeconds); + break; + case Editing::SnapToSMPTESeconds: + set_snap_to (Editing::SnapToSMPTEMinutes); + break; + case Editing::SnapToSMPTEMinutes: + set_snap_to (Editing::SnapToSeconds); + break; + case Editing::SnapToSeconds: + set_snap_to (Editing::SnapToMinutes); + break; + case Editing::SnapToMinutes: + set_snap_to (Editing::SnapToAThirtysecondBeat); + break; + case Editing::SnapToAThirtysecondBeat: + set_snap_to (Editing::SnapToASixteenthBeat); + break; + case Editing::SnapToASixteenthBeat: + set_snap_to (Editing::SnapToAEighthBeat); + break; + case Editing::SnapToAEighthBeat: + set_snap_to (Editing::SnapToAQuarterBeat); + break; + case Editing::SnapToAQuarterBeat: + set_snap_to (Editing::SnapToAThirdBeat); + break; + case Editing::SnapToAThirdBeat: + set_snap_to (Editing::SnapToBeat); + break; + case Editing::SnapToBeat: + set_snap_to (Editing::SnapToBar); + break; + case Editing::SnapToBar: + set_snap_to (Editing::SnapToMark); + break; + case Editing::SnapToMark: + set_snap_to (Editing::SnapToRegionStart); + break; + case Editing::SnapToRegionStart: + set_snap_to (Editing::SnapToRegionEnd); + break; + case Editing::SnapToRegionEnd: + set_snap_to (Editing::SnapToRegionSync); + break; + case Editing::SnapToRegionSync: + set_snap_to (Editing::SnapToRegionBoundary); + break; + case Editing::SnapToRegionBoundary: + set_snap_to (Editing::SnapToCDFrame); + break; + } +} + +void Editor::snap_type_chosen (SnapType type) { /* this is driven by a toggle on a radio group, and so is invoked twice, @@ -820,6 +965,9 @@ Editor::snap_mode_action (SnapMode mode) RefPtr<Action> act; switch (mode) { + case Editing::SnapOff: + action = X_("snap-off"); + break; case Editing::SnapNormal: action = X_("snap-normal"); break; @@ -844,6 +992,22 @@ Editor::snap_mode_action (SnapMode mode) } void +Editor::cycle_snap_mode () +{ + switch (snap_mode) { + case SnapOff: + set_snap_mode (SnapNormal); + break; + case SnapNormal: + set_snap_mode (SnapMagnetic); + break; + case SnapMagnetic: + set_snap_mode (SnapOff); + break; + } +} + +void Editor::snap_mode_chosen (SnapMode mode) { /* this is driven by a toggle on a radio group, and so is invoked twice, @@ -1171,6 +1335,12 @@ Editor::toggle_xfade_visibility () ActionManager::toggle_config_state ("Editor", "toggle-xfades-visible", &Configuration::set_xfades_visible, &Configuration::get_xfades_visible); } +void +Editor::toggle_link_region_and_track_selection () +{ + ActionManager::toggle_config_state ("Editor", "link-region-and-track-selection", &Configuration::set_link_region_and_track_selection, &Configuration::get_link_region_and_track_selection); +} + /** A Configuration parameter has changed. * @param parameter_name Name of the changed parameter. */ @@ -1178,7 +1348,7 @@ void Editor::parameter_changed (const char* parameter_name) { #define PARAM_IS(x) (!strcmp (parameter_name, (x))) - + //cerr << "Editor::parameter_changed: " << parameter_name << endl; ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::parameter_changed), parameter_name)); if (PARAM_IS ("auto-loop")) { @@ -1210,7 +1380,9 @@ Editor::parameter_changed (const char* parameter_name) update_just_smpte (); } else if (PARAM_IS ("show-track-meters")) { toggle_meter_updating(); - } + } else if (PARAM_IS ("link-region-and-track-selection")) { + ActionManager::map_some_state ("Editor", "link-region-and-track-selection", &Configuration::get_link_region_and_track_selection); + } #undef PARAM_IS } diff --git a/gtk2_ardour/editor_audiotrack.cc b/gtk2_ardour/editor_audiotrack.cc index 43f63eed79..cfb8f0a557 100644 --- a/gtk2_ardour/editor_audiotrack.cc +++ b/gtk2_ardour/editor_audiotrack.cc @@ -34,37 +34,6 @@ using namespace ARDOUR; using namespace PBD; void -Editor::set_loop_from_selection (bool play) -{ - if (session == 0 || selection->time.empty()) { - return; - } - - nframes_t start = selection->time[clicked_selection].start; - nframes_t end = selection->time[clicked_selection].end; - - set_loop_range (start, end, _("set loop range from selection")); - - if (play) { - session->request_play_loop (true); - session->request_locate (start, true); - } -} - -void -Editor::set_punch_from_selection () -{ - if (session == 0 || selection->time.empty()) { - return; - } - - nframes_t start = selection->time[clicked_selection].start; - nframes_t end = selection->time[clicked_selection].end; - - set_punch_range (start, end, _("set punch range from selection")); -} - -void Editor::set_show_waveforms (bool yn) { AudioTimeAxisView* atv; diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 40f6b05026..87a92790bc 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -113,6 +113,9 @@ Editor::initialize_canvas () track_canvas.signal_button_press_event().connect (mem_fun (*this, &Editor::track_canvas_button_press_event)); track_canvas.signal_button_release_event().connect (mem_fun (*this, &Editor::track_canvas_button_release_event)); + /* just scroll stuff for the timecanvas */ + time_canvas.signal_scroll_event().connect (mem_fun (*this, &Editor::time_canvas_scroll_event)); + track_canvas.set_name ("EditorMainCanvas"); track_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK|Gdk::SCROLL_MASK); track_canvas.signal_leave_notify_event().connect (mem_fun(*this, &Editor::left_track_canvas)); @@ -173,6 +176,7 @@ Editor::initialize_canvas () range_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 2.0); transport_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 3.0); marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 4.0); + cd_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 5.0); tempo_bar = new ArdourCanvas::SimpleRect (*tempo_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); tempo_bar->property_outline_what() = (0x1 | 0x8); @@ -185,6 +189,10 @@ Editor::initialize_canvas () marker_bar = new ArdourCanvas::SimpleRect (*marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); marker_bar->property_outline_what() = (0x1 | 0x8); marker_bar->property_outline_pixels() = 1; + + cd_marker_bar = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + cd_marker_bar->property_outline_what() = (0x1 | 0x8); + cd_marker_bar->property_outline_pixels() = 1; range_marker_bar = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); range_marker_bar->property_outline_what() = (0x1 | 0x8); @@ -252,6 +260,7 @@ Editor::initialize_canvas () tempo_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_tempo_bar_event), tempo_bar)); meter_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_meter_bar_event), meter_bar)); marker_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_marker_bar_event), marker_bar)); + cd_marker_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_cd_marker_bar_event), cd_marker_bar)); range_marker_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_range_marker_bar_event), range_marker_bar)); transport_marker_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_transport_marker_bar_event), transport_marker_bar)); @@ -291,7 +300,6 @@ Editor::track_canvas_allocate (Gtk::Allocation alloc) } initial_ruler_update_required = false; - track_canvas_size_allocated (); } @@ -327,8 +335,10 @@ Editor::track_canvas_size_allocated () reset_scrolling_region (); if (playhead_cursor) playhead_cursor->set_length (canvas_height); - - // EDIT CURSOR XXX set line height for selected markers here + + for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) { + (*x)->set_line_length (canvas_height); + } if (range_marker_drag_rect) { range_marker_drag_rect->property_y1() = 0.0; @@ -355,6 +365,7 @@ Editor::track_canvas_size_allocated () transport_punchout_line->property_y2() = canvas_height; } compute_fixed_ruler_scale (); + update_fixed_rulers(); redisplay_tempo (true); @@ -382,12 +393,20 @@ Editor::reset_scrolling_region (Gtk::Allocation* alloc) } } - double last_canvas_unit = last_canvas_frame / frames_per_unit; + double last_canvas_unit = max ((last_canvas_frame / frames_per_unit), canvas_width); - track_canvas.set_scroll_region (0.0, 0.0, max (last_canvas_unit, canvas_width), pos); + track_canvas.set_scroll_region (0.0, 0.0, last_canvas_unit, pos); // XXX what is the correct height value for the time canvas ? this overstates it - time_canvas.set_scroll_region ( 0.0, 0.0, max (last_canvas_unit, canvas_width), canvas_height); + time_canvas.set_scroll_region ( 0.0, 0.0, last_canvas_unit, canvas_height); + + range_marker_drag_rect->property_y2() = canvas_height; + transport_loop_range_rect->property_y2() = canvas_height; + transport_punch_range_rect->property_y2() = canvas_height; + transport_punchin_line->property_y2() = canvas_height; + transport_punchout_line->property_y2() = canvas_height; + + update_punch_range_view (true); controls_layout.queue_resize(); } @@ -399,8 +418,8 @@ Editor::controls_layout_size_request (Requisition* req) TreeModel::Children::iterator i; double pos; - for (pos = 0, i = rows.begin(); i != rows.end(); ++i) { - TimeAxisView *tv = (*i)[route_display_columns.tv]; + for (pos = 0, i = rows.begin(); i != rows.end(); ++i) { + TimeAxisView *tv = (*i)[route_display_columns.tv]; if (tv != 0) { pos += tv->effective_height; } @@ -412,12 +431,9 @@ Editor::controls_layout_size_request (Requisition* req) screen = Gdk::Screen::get_default(); } - /* never let the width of the controls area shrink horizontally */ - edit_controls_vbox.check_resize(); - req->width = max (edit_controls_vbox.get_width(), controls_layout.get_width()); - + /* don't get too big. the fudge factors here are just guesses */ req->width = min (req->width, screen->get_width() - 300); @@ -426,8 +442,13 @@ Editor::controls_layout_size_request (Requisition* req) /* this one is important: it determines how big the layout thinks it really is, as opposed to what it displays on the screen */ + + controls_layout.set_size (edit_controls_vbox.get_width(), (gint) pos); + controls_layout.set_size_request(edit_controls_vbox.get_width(), -1); + zoom_box.set_size_request(edit_controls_vbox.get_width(), -1); + time_button_frame.set_size_request(edit_controls_vbox.get_width() + edit_vscrollbar.get_width(), -1); - controls_layout.set_size (req->width, (gint) pos); + //cerr << "sizes = " << req->width << " " << edit_controls_vbox.get_width() << " " << controls_layout.get_width() << " " << zoom_box.get_width() << " " << time_button_frame.get_width() << endl;//DEBUG } bool @@ -700,17 +721,19 @@ Editor::left_track_canvas (GdkEventCrossing *ev) void Editor::canvas_horizontally_scrolled () { - cerr << "chs\n"; + nframes64_t time_origin = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit); - /* this is the core function that controls horizontal scrolling of the canvas. it is called - whenever the horizontal_adjustment emits its "value_changed" signal. it typically executes in an - idle handler, which is important because tempo_map_changed() should issue redraws immediately - and not defer them to an idle handler. - */ + if (time_origin != leftmost_frame) { + canvas_scroll_to (time_origin); + } +} - leftmost_frame = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit); +void +Editor::canvas_scroll_to (nframes64_t time_origin) +{ + leftmost_frame = time_origin; nframes_t rightmost_frame = leftmost_frame + current_page_frames (); - + if (rightmost_frame > last_canvas_frame) { last_canvas_frame = rightmost_frame; reset_scrolling_region (); @@ -740,6 +763,9 @@ Editor::color_handler() marker_bar->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MarkerBar.get(); marker_bar->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_MarkerBarSeparator.get(); + cd_marker_bar->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CDMarkerBar.get(); + cd_marker_bar->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_MarkerBarSeparator.get(); + range_marker_bar->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_RangeMarkerBar.get(); range_marker_bar->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_MarkerBarSeparator.get(); diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index ef11f546ef..ec43d1bac0 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -52,10 +52,13 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) { int x, y; double wx, wy; + nframes_t xdelta; + int direction = ev->direction; - switch (ev->direction) { + retry: + switch (direction) { case GDK_SCROLL_UP: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { //if (ev->state == GDK_CONTROL_MASK) { /* XXX the ev->x will be out of step with the canvas @@ -75,7 +78,10 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) nframes_t where = event_frame (&event, 0, 0); temporal_zoom_to_frame (false, where); return true; - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { + direction = GDK_SCROLL_LEFT; + goto retry; + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { if (!current_stepping_trackview) { step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) { @@ -90,8 +96,9 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) return true; } break; + case GDK_SCROLL_DOWN: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { //if (ev->state == GDK_CONTROL_MASK) { track_canvas.get_pointer (x, y); track_canvas.window_to_world (x, y, wx, wy); @@ -106,7 +113,10 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) nframes_t where = event_frame (&event, 0, 0); temporal_zoom_to_frame (true, where); return true; - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { + direction = GDK_SCROLL_RIGHT; + goto retry; + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { if (!current_stepping_trackview) { step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) { @@ -122,8 +132,26 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) } break; + case GDK_SCROLL_LEFT: + xdelta = (current_page_frames() / 2); + if (leftmost_frame > xdelta) { + reset_x_origin (leftmost_frame - xdelta); + } else { + reset_x_origin (0); + } + break; + + case GDK_SCROLL_RIGHT: + xdelta = (current_page_frames() / 2); + if (max_frames - xdelta > leftmost_frame) { + reset_x_origin (leftmost_frame + xdelta); + } else { + reset_x_origin (max_frames - current_page_frames()); + } + break; + default: - /* no left/right handling yet */ + /* what? */ break; } @@ -139,8 +167,58 @@ Editor::track_canvas_scroll_event (GdkEventScroll *event) } bool +Editor::time_canvas_scroll (GdkEventScroll* ev) +{ + nframes_t xdelta; + int direction = ev->direction; + + switch (direction) { + case GDK_SCROLL_UP: + temporal_zoom_step (true); + break; + + case GDK_SCROLL_DOWN: + temporal_zoom_step (false); + break; + + case GDK_SCROLL_LEFT: + xdelta = (current_page_frames() / 2); + if (leftmost_frame > xdelta) { + reset_x_origin (leftmost_frame - xdelta); + } else { + reset_x_origin (0); + } + break; + + case GDK_SCROLL_RIGHT: + xdelta = (current_page_frames() / 2); + if (max_frames - xdelta > leftmost_frame) { + reset_x_origin (leftmost_frame + xdelta); + } else { + reset_x_origin (max_frames - current_page_frames()); + } + break; + + default: + /* what? */ + break; + } + + return false; +} + +bool +Editor::time_canvas_scroll_event (GdkEventScroll *event) +{ + time_canvas.grab_focus(); + time_canvas_scroll (event); + return false; +} + +bool Editor::track_canvas_button_press_event (GdkEventButton *event) { + selection->clear (); track_canvas.grab_focus(); return false; } @@ -170,6 +248,11 @@ Editor::track_canvas_motion (GdkEvent *ev) verbose_canvas_cursor->property_x() = ev->motion.x + 20; verbose_canvas_cursor->property_y() = ev->motion.y + 20; } + +#ifdef GTKOSX + flush_canvas (); +#endif + return false; } @@ -235,10 +318,12 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg break; case GDK_ENTER_NOTIFY: + set_entered_track (&rv->get_time_axis_view ()); set_entered_regionview (rv); break; case GDK_LEAVE_NOTIFY: + set_entered_track (0); set_entered_regionview (0); break; @@ -274,6 +359,11 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Rou break; case GDK_ENTER_NOTIFY: + set_entered_track (tv); + break; + + case GDK_LEAVE_NOTIFY: + set_entered_track (0); break; default: @@ -283,8 +373,6 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Rou return ret; } - - bool Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv) { @@ -806,6 +894,12 @@ Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* } bool +Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item) +{ + return typed_event (item, event, CdMarkerBarItem); +} + +bool Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker) { return typed_event (item, event, TempoMarkerItem); diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index 3ab2012588..157494b846 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -103,7 +103,7 @@ Editor::export_region () ExportDialog* dialog = new ExportRegionDialog (*this, r); dialog->connect_to_session (session); - dialog->set_range (r->first_frame(), r->last_frame()); + dialog->set_range (clicked_regionview->region()->first_frame(), clicked_regionview->region()->last_frame()); dialog->start_export(); } diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h index aa68f37720..042fd20852 100644 --- a/gtk2_ardour/editor_items.h +++ b/gtk2_ardour/editor_items.h @@ -27,6 +27,7 @@ enum ItemType { MarkerItem, MarkerBarItem, RangeMarkerBarItem, + CdMarkerBarItem, TransportMarkerBarItem, SelectionItem, ControlPointItem, diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc index 2912e2f4ee..4a5d55d879 100644 --- a/gtk2_ardour/editor_keyboard.cc +++ b/gtk2_ardour/editor_keyboard.cc @@ -91,29 +91,6 @@ Editor::kbd_mute_unmute_region () } void -Editor::kbd_set_sync_position () -{ - kbd_driver (mem_fun(*this, &Editor::kbd_do_set_sync_position), true, true, false); -} - -void -Editor::kbd_do_set_sync_position (GdkEvent* ev) -{ - if (entered_regionview) { - nframes64_t where = event_frame (ev); - snap_to (where); - - set_a_regions_sync_position (entered_regionview->region(), where); - - } else if (entered_marker) { - - if (!selection->regions.empty()) { - set_a_regions_sync_position (selection->regions.front()->region(), entered_marker->position()); - } - } -} - -void Editor::kbd_do_brush (GdkEvent *ev) { brush (event_frame (ev, 0, 0)); @@ -125,14 +102,3 @@ Editor::kbd_brush () kbd_driver (mem_fun(*this, &Editor::kbd_do_brush), true, true, false); } -void -Editor::kbd_do_audition (GdkEvent *ignored) -{ - audition_selected_region (); -} - -void -Editor::kbd_audition () -{ - kbd_driver (mem_fun(*this, &Editor::kbd_do_audition), true, false, true); -} diff --git a/gtk2_ardour/editor_keys.cc b/gtk2_ardour/editor_keys.cc index d06b9f85aa..efbe0cb522 100644 --- a/gtk2_ardour/editor_keys.cc +++ b/gtk2_ardour/editor_keys.cc @@ -25,6 +25,7 @@ #include <ardour/session.h> #include <ardour/region.h> +#include <gtkmm/treeview.h> #include "ardour_ui.h" #include "editor.h" @@ -41,8 +42,6 @@ using namespace sigc; void Editor::keyboard_selection_finish (bool add) { - cerr << "here\n"; - if (session && have_pending_keyboard_selection) { nframes64_t end; @@ -87,59 +86,16 @@ Editor::keyboard_selection_begin () } void -Editor::keyboard_duplicate_region () -{ - if (selection->regions.empty()) { - return; - } - - float prefix = 0; - bool was_floating; - - if (get_prefix (prefix, was_floating) == 0) { - duplicate_some_regions (selection->regions, prefix); - } else { - duplicate_some_regions (selection->regions, 1); - } -} - -void -Editor::keyboard_duplicate_selection () -{ - float prefix = 0; - bool was_floating; - - if (get_prefix (prefix, was_floating) == 0) { - duplicate_selection (prefix); - } else { - duplicate_selection (1); - } -} - -void Editor::keyboard_paste () { - float prefix = 0; - bool was_floating; - - if (get_prefix (prefix, was_floating) == 0) { - paste (prefix); - } else { - paste (1); - } + ensure_entered_track_selected (true); + paste (1); } void Editor::keyboard_insert_region_list_selection () { - float prefix = 0; - bool was_floating; - - if (get_prefix (prefix, was_floating) == 0) { - insert_region_list_selection (prefix); - } else { - insert_region_list_selection (1); - } + insert_region_list_selection (1); } int diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 75776a7844..68ce914025 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -26,6 +26,7 @@ #include <gtkmm2ext/window_title.h> #include <ardour/location.h> +#include <ardour/profile.h> #include <pbd/memento_command.h> #include "editor.h" @@ -77,9 +78,15 @@ Editor::add_new_location (Location *location) } if (location->is_mark()) { - lam->start = new Marker (*this, *marker_group, color, location->name(), Marker::Mark, location->start()); - lam->end = 0; + if (location->is_cd_marker() && ruler_shown[ruler_time_cd_marker]) { + lam->start = new Marker (*this, *cd_marker_group, color, location->name(), Marker::Mark, location->start()); + } + else { + lam->start = new Marker (*this, *marker_group, color, location->name(), Marker::Mark, location->start()); + } + lam->end = 0; + } else if (location->is_auto_loop()) { // transport marker lam->start = new Marker (*this, *transport_marker_group, color, @@ -95,12 +102,20 @@ Editor::add_new_location (Location *location) location->name(), Marker::PunchOut, location->end()); } else { - // range marker - lam->start = new Marker (*this, *range_marker_group, color, - location->name(), Marker::Start, location->start()); - lam->end = new Marker (*this, *range_marker_group, color, - location->name(), Marker::End, location->end()); + if (location->is_cd_marker() && ruler_shown[ruler_time_cd_marker]) { + lam->start = new Marker (*this, *cd_marker_group, color, + location->name(), Marker::Start, location->start()); + lam->end = new Marker (*this, *cd_marker_group, color, + location->name(), Marker::End, location->end()); + } + else { + + lam->start = new Marker (*this, *range_marker_group, color, + location->name(), Marker::Start, location->start()); + lam->end = new Marker (*this, *range_marker_group, color, + location->name(), Marker::End, location->end()); + } } if (location->is_hidden ()) { @@ -121,6 +136,11 @@ Editor::add_new_location (Location *location) newpair.second = lam; location_markers.insert (newpair); + + if (select_new_marker && location->is_mark()) { + selection->set (lam->start); + select_new_marker = false; + } } void @@ -157,6 +177,9 @@ Editor::location_flags_changed (Location *location, void *src) return; } + // move cd markers to/from cd marker bar as appropriate + ensure_cd_marker_updated (lam, location); + if (location->is_cd_marker()) { lam->set_color_rgba (location_cd_marker_color); } else if (location->is_mark()) { @@ -176,6 +199,52 @@ Editor::location_flags_changed (Location *location, void *src) } } +void Editor::update_cd_marker_display () +{ + for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) { + LocationMarkers * lam = i->second; + Location * location = i->first; + + ensure_cd_marker_updated (lam, location); + } +} + +void Editor::ensure_cd_marker_updated (LocationMarkers * lam, Location * location) +{ + if (location->is_cd_marker() + && (ruler_shown[ruler_time_cd_marker] && lam->start->get_parent() != cd_marker_group)) + { + //cerr << "reparenting non-cd marker so it can be relocated: " << location->name() << endl; + if (lam->start) { + lam->start->reparent (*cd_marker_group); + } + if (lam->end) { + lam->end->reparent (*cd_marker_group); + } + } + else if ( (!location->is_cd_marker() || !ruler_shown[ruler_time_cd_marker]) + && (lam->start->get_parent() == cd_marker_group)) + { + //cerr << "reparenting non-cd marker so it can be relocated: " << location->name() << endl; + if (location->is_mark()) { + if (lam->start) { + lam->start->reparent (*marker_group); + } + if (lam->end) { + lam->end->reparent (*marker_group); + } + } + else { + if (lam->start) { + lam->start->reparent (*range_marker_group); + } + if (lam->end) { + lam->end->reparent (*range_marker_group); + } + } + } +} + Editor::LocationMarkers::~LocationMarkers () { if (start) { @@ -319,12 +388,14 @@ Editor::LocationMarkers::set_color_rgba (uint32_t rgba) } void -Editor::mouse_add_new_marker (nframes_t where) +Editor::mouse_add_new_marker (nframes_t where, bool is_cd) { string markername; + int flags = (is_cd ? Location::IsCDMarker|Location::IsMark : Location::IsMark); + if (session) { session->locations()->next_available_name(markername,"mark"); - Location *location = new Location (where, where, markername, Location::IsMark); + Location *location = new Location (where, where, markername, (Location::Flags) flags); session->begin_reversible_command (_("add marker")); XMLNode &before = session->locations()->get_state(); session->locations()->add (location, true); @@ -353,6 +424,10 @@ Editor::remove_marker (ArdourCanvas::Item& item, GdkEvent* event) /*NOTREACHED*/ } + if (entered_marker == marker) { + entered_marker = NULL; + } + Location* loc = find_location_from_marker (marker, is_start); if (session && loc) { @@ -535,19 +610,21 @@ Editor::build_range_marker_menu (bool loop_or_punch) MenuList& items = markerMenu->items(); markerMenu->set_name ("ArdourContextMenu"); + items.push_back (MenuElem (_("Play Range"), mem_fun(*this, &Editor::marker_menu_play_range))); 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))); 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))); + if (!Profile->get_sae()) { + 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))); if (! loop_or_punch) { + items.push_back (MenuElem (_("Hide Range"), mem_fun(*this, &Editor::marker_menu_hide))); items.push_back (MenuElem (_("Rename Range"), mem_fun(*this, &Editor::marker_menu_rename))); items.push_back (MenuElem (_("Remove Range"), mem_fun(*this, &Editor::marker_menu_remove))); } @@ -556,8 +633,9 @@ Editor::build_range_marker_menu (bool loop_or_punch) 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))); - items.push_back (MenuElem (_("Select Range"), mem_fun(*this, &Editor::marker_menu_select_using_range))); - + if (!Profile->get_sae()) { + items.push_back (MenuElem (_("Select Range"), mem_fun(*this, &Editor::marker_menu_select_using_range))); + } } void @@ -736,13 +814,13 @@ Editor::marker_menu_set_from_playhead () if ((l = find_location_from_marker (marker, is_start)) != 0) { if (l->is_mark()) { - l->set_start (session->transport_frame ()); + l->set_start (session->audible_frame ()); } else { if (is_start) { - l->set_start (session->transport_frame ()); + l->set_start (session->audible_frame ()); } else { - l->set_end (session->transport_frame ()); + l->set_end (session->audible_frame ()); } } } @@ -1027,9 +1105,15 @@ Editor::update_punch_range_view (bool visibility) double x1 = frame_to_pixel (tpl->start()); double x2 = frame_to_pixel (tpl->end()); + guint track_canvas_width,track_canvas_height; + track_canvas.get_size(track_canvas_width,track_canvas_height); + transport_punch_range_rect->property_x1() = x1; transport_punch_range_rect->property_x2() = x2; + transport_punch_range_rect->property_x1() = (Config->get_punch_in() ? x1 : 0); + transport_punch_range_rect->property_x2() = (Config->get_punch_out() ? x2 : track_canvas_width); + if (visibility) { transport_punch_range_rect->show(); } @@ -1108,3 +1192,33 @@ Editor::selected_marker_moved (Location* loc) { edit_point_clock.set (loc->start()); } + +struct SortLocationsByPosition { + bool operator() (Location* a, Location* b) { + return a->start() < b->start(); + } +}; + +void +Editor::goto_nth_marker (int n) +{ + if (!session) { + return; + } + const Locations::LocationList& l (session->locations()->list()); + Locations::LocationList ordered; + ordered = l; + + SortLocationsByPosition cmp; + ordered.sort (cmp); + + for (Locations::LocationList::iterator i = ordered.begin(); n >= 0 && i != ordered.end(); ++i) { + if ((*i)->is_mark() && !(*i)->is_hidden() && !(*i)->is_start()) { + if (n == 0) { + session->request_locate ((*i)->start(), session->transport_rolling()); + break; + } + --n; + } + } +} diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index 7264df552d..0f432cc628 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -198,7 +198,7 @@ Editor::update_current_screen () /* only update if the playhead is on screen or we are following it */ - if (_follow_playhead) { + if (_follow_playhead && session->requested_return_frame() < 0) { playhead_cursor->canvas_item.show(); @@ -316,7 +316,6 @@ Editor::session_going_away () clicked_crossfadeview = 0; entered_regionview = 0; entered_track = 0; - latest_regionview = 0; last_update_frame = 0; drag_info.item = 0; last_canvas_frame = 0; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 78fdf5d2b2..35f410eb25 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -271,7 +271,11 @@ Editor::set_mouse_mode (MouseMode m, bool force) case MouseObject: mouse_move_button.set_active (true); - current_canvas_cursor = grabber_cursor; + if (Profile->get_sae()) { + current_canvas_cursor = timebar_cursor; + } else { + current_canvas_cursor = grabber_cursor; + } break; case MouseGain: @@ -445,8 +449,6 @@ Editor::set_midi_edit_cursor (MidiEditMode m) void Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) { - bool commit = false; - /* in object/audition/timefx mode, any button press sets the selection if the object can be selected. this is a bit of hack, because we want to avoid this if the @@ -485,18 +487,18 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it switch (item_type) { case RegionItem: if (mouse_mode != MouseRange) { - commit = set_selected_regionview_from_click (press, op, true); + set_selected_regionview_from_click (press, op, true); } else if (event->type == GDK_BUTTON_PRESS) { - commit = set_selected_track_from_click (press, op, false); + set_selected_track_as_side_effect (); } break; case RegionViewNameHighlight: case RegionViewName: if (mouse_mode != MouseRange) { - commit = set_selected_regionview_from_click (press, op, true); + set_selected_regionview_from_click (press, op, true); } else if (event->type == GDK_BUTTON_PRESS) { - commit = set_selected_track_from_click (press, op, false); + set_selected_track_as_side_effect (); } break; @@ -506,43 +508,35 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it case FadeOutHandleItem: case FadeOutItem: if (mouse_mode != MouseRange) { - commit = set_selected_regionview_from_click (press, op, true); + set_selected_regionview_from_click (press, op, true); } else if (event->type == GDK_BUTTON_PRESS) { - commit = set_selected_track_from_click (press, op, false); + set_selected_track_as_side_effect (); } break; - case CrossfadeViewItem: - commit = set_selected_track_from_click (press, op, false); - break; - case ControlPointItem: - commit = set_selected_track_from_click (press, op, true); + set_selected_track_as_side_effect (); if (mouse_mode != MouseRange) { - commit |= set_selected_control_point_from_click (op, false); + set_selected_control_point_from_click (op, false); } break; case StreamItem: /* for context click or range selection, select track */ if (event->button.button == 3) { - commit = set_selected_track_from_click (press, op, true); + set_selected_track_as_side_effect (); } else if (event->type == GDK_BUTTON_PRESS && mouse_mode == MouseRange) { - commit = set_selected_track_from_click (press, op, false); + set_selected_track_as_side_effect (); } break; case AutomationTrackItem: - commit = set_selected_track_from_click (press, op, true); + set_selected_track_as_side_effect (true); break; default: break; } - -// if (commit) { -// commit_reversible_command (); -// } } bool @@ -586,7 +580,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp return true; case MarkerItem: - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask(Keyboard::Control|Keyboard::Shift))) { + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { hide_marker (item, event); } else { start_marker_grab (item, event); @@ -594,7 +588,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp return true; case TempoMarkerItem: - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) { start_tempo_marker_copy_grab (item, event); } else { start_tempo_marker_grab (item, event); @@ -602,7 +596,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp return true; case MeterMarkerItem: - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) { start_meter_marker_copy_grab (item, event); } else { start_meter_marker_grab (item, event); @@ -620,6 +614,11 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp return true; break; + case CdMarkerBarItem: + start_range_markerbar_op (item, event, CreateCDMarker); + return true; + break; + case TransportMarkerBarItem: start_range_markerbar_op (item, event, CreateTransportMarker); return true; @@ -643,10 +642,10 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp case SelectionItem: if (Keyboard::modifier_state_contains - (event->button.state, Keyboard::ModifierMask(Keyboard::Alt))) { + (event->button.state, Keyboard::ModifierMask(Keyboard::SecondaryModifier))) { // contains and not equals because I can't use alt as a modifier alone. start_selection_grab (item, event); - } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { + } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { /* grab selection for moving */ start_selection_op (item, event, SelectionMove); } else { @@ -663,7 +662,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp break; case MouseObject: - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::Control|Keyboard::Alt)) && + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) && event->type == GDK_BUTTON_PRESS) { start_rubberband_select (item, event); @@ -680,7 +679,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp return true; case RegionItem: - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) { start_region_copy_grab (item, event); } else if (Keyboard::the_keyboard().key_is_down (GDK_b)) { start_region_brush_grab (item, event); @@ -832,12 +831,12 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp if (event->type == GDK_BUTTON_PRESS) { switch (item_type) { case RegionItem: - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) { start_region_copy_grab (item, event); } else { start_region_grab (item, event); } - + return true; break; case ControlPointItem: start_control_point_grab (item, event); @@ -876,7 +875,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp case MouseZoom: - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { temporal_zoom_session(); } else { temporal_zoom_to_frame (true, event_frame(event)); @@ -990,7 +989,8 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case MarkerBarItem: case RangeMarkerBarItem: - case TransportMarkerBarItem: + case TransportMarkerBarItem: + case CdMarkerBarItem: case TempoBarItem: case MeterBarItem: popup_ruler_menu (pixel_to_frame(event->button.x), item_type); @@ -1088,6 +1088,14 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT mouse_add_new_marker (where); return true; + case CdMarkerBarItem: + // if we get here then a dragged range wasn't done + if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { + snap_to (where, 0, true); + } + mouse_add_new_marker (where, true); + return true; + case TempoBarItem: if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { snap_to (where); @@ -1151,7 +1159,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT /* no drag, just a click */ switch (item_type) { case RegionItem: - audition_selected_region (); + play_selected_region (); break; default: break; @@ -1174,6 +1182,25 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case 2: switch (mouse_mode) { + case MouseObject: + switch (item_type) { + case RegionItem: + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) { + raise_region (); + } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask (Keyboard::TertiaryModifier|Keyboard::SecondaryModifier))) { + lower_region (); + } else { + // Button2 click is unused + } + return true; + + break; + + default: + break; + } + break; + case MouseRange: // x_style_paste (where, 1.0); @@ -1220,12 +1247,12 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ set_verbose_canvas_cursor (cp->line().get_verbose_cursor_string (fraction), at_x, at_y); show_verbose_canvas_cursor (); - if (is_drawable()) { - track_canvas.get_window()->set_cursor (*fader_cursor); + if (is_drawable() && !_scrubbing) { + track_canvas.get_window()->set_cursor (*fader_cursor); } } break; - + case GainLineItem: if (mouse_mode == MouseGain) { ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item); @@ -1317,6 +1344,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case MarkerBarItem: case RangeMarkerBarItem: case TransportMarkerBarItem: + case CdMarkerBarItem: case MeterBarItem: case TempoBarItem: if (is_drawable()) { @@ -1442,6 +1470,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case RangeMarkerBarItem: case TransportMarkerBarItem: + case CdMarkerBarItem: case MeterBarItem: case TempoBarItem: case MarkerBarItem: @@ -1508,19 +1537,21 @@ Editor::left_automation_track () bool Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type, bool from_autoscroll) { - gint x, y; + if (event->motion.is_hint) { + gint x, y; + + /* We call this so that MOTION_NOTIFY events continue to be + delivered to the canvas. We need to do this because we set + Gdk::POINTER_MOTION_HINT_MASK on the canvas. This reduces + the density of the events, at the expense of a round-trip + to the server. Given that this will mostly occur on cases + where DISPLAY = :0.0, and given the cost of what the motion + event might do, its a good tradeoff. + */ + + track_canvas.get_pointer (x, y); + } - /* We call this so that MOTION_NOTIFY events continue to be - delivered to the canvas. We need to do this because we set - Gdk::POINTER_MOTION_HINT_MASK on the canvas. This reduces - the density of the events, at the expense of a round-trip - to the server. Given that this will mostly occur on cases - where DISPLAY = :0.0, and given the cost of what the motion - event might do, its a good tradeoff. - */ - - track_canvas.get_pointer (x, y); - if (current_stepping_trackview) { /* don't keep the persistent stepped trackview if the mouse moves */ current_stepping_trackview = 0; @@ -1727,7 +1758,7 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor) // if dragging with button2, the motion is x constrained, with Alt-button2 it is y constrained if (event->button.button == 2) { - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Alt)) { + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::SecondaryModifier)) { drag_info.y_constrained = true; drag_info.x_constrained = false; } else { @@ -2102,7 +2133,7 @@ Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { - if (cursor == playhead_cursor && snap_type != SnapToEditPoint) { + if (cursor == playhead_cursor) { snap_to (adjusted_frame); } } @@ -2255,7 +2286,7 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) f_delta = copy_location->end() - copy_location->start(); - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { move_both = true; } @@ -2681,7 +2712,7 @@ Editor::control_point_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* double dx = drag_info.current_pointer_x - drag_info.last_pointer_x; double dy = drag_info.current_pointer_y - drag_info.last_pointer_y; - if (event->button.state & Keyboard::Alt) { + if (event->button.state & Keyboard::SecondaryModifier) { dx *= 0.1; dy *= 0.1; } @@ -2728,7 +2759,7 @@ Editor::control_point_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* bool push; - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier)) { push = true; } else { push = false; @@ -2750,7 +2781,7 @@ Editor::control_point_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent /* just a click */ - if ((event->type == GDK_BUTTON_RELEASE) && (event->button.button == 1) && Keyboard::modifier_state_equals (event->button.state, Keyboard::Shift)) { + if ((event->type == GDK_BUTTON_RELEASE) && (event->button.button == 1) && Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) { reset_point_selection (); } @@ -2831,7 +2862,7 @@ Editor::line_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) double dy = drag_info.current_pointer_y - drag_info.last_pointer_y; - if (event->button.state & Keyboard::Alt) { + if (event->button.state & Keyboard::SecondaryModifier) { dy *= 0.1; } @@ -2861,7 +2892,7 @@ Editor::line_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) bool push; - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier)) { push = false; } else { push = true; @@ -2890,8 +2921,14 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event) drag_info.copy = false; drag_info.item = item; drag_info.data = clicked_regionview; - drag_info.motion_callback = &Editor::region_drag_motion_callback; - drag_info.finished_callback = &Editor::region_drag_finished_callback; + + if (Config->get_edit_mode() == Splice) { + drag_info.motion_callback = &Editor::region_drag_splice_motion_callback; + drag_info.finished_callback = &Editor::region_drag_splice_finished_callback; + } else { + drag_info.motion_callback = &Editor::region_drag_motion_callback; + drag_info.finished_callback = &Editor::region_drag_finished_callback; + } start_grab (event); @@ -2961,7 +2998,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) void Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) { - if (selection->regions.empty() || clicked_regionview == 0) { + if (selection->regions.empty() || clicked_regionview == 0 || Config->get_edit_mode() == Splice) { return; } @@ -2992,18 +3029,8 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) } void -Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) +Editor::possibly_copy_regions_during_grab (GdkEvent* event) { - double x_delta; - double y_delta = 0; - RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data); - nframes_t pending_region_position = 0; - int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order; - int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen - bool clamp_y_axis = false; - vector<int32_t> height_list(512) ; - vector<int32_t>::iterator j; - if (drag_info.copy && drag_info.move_threshold_passed && drag_info.want_move_threshold) { drag_info.want_move_threshold = false; // don't copy again @@ -3049,24 +3076,123 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time); } +} +bool +Editor::check_region_drag_possible (RouteTimeAxisView** tv) +{ /* Which trackview is this ? */ TimeAxisView* tvp = trackview_by_y_position (drag_info.current_pointer_y); - RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); + (*tv) = dynamic_cast<RouteTimeAxisView*>(tvp); /* The region motion is only processed if the pointer is over an audio track. */ - if (!tv || !tv->is_track()) { + if (!(*tv) || !(*tv)->is_track()) { /* To make sure we hide the verbose canvas cursor when the mouse is - not held over a track. + not held over and audiotrack. */ hide_verbose_canvas_cursor (); - return; + return false; } + return true; +} + +struct RegionSelectionByPosition { + bool operator() (RegionView*a, RegionView* b) { + return a->region()->position () < b->region()->position(); + } +}; + +void +Editor::region_drag_splice_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) +{ + RouteTimeAxisView* tv; + + if (!check_region_drag_possible (&tv)) { + return; + } + + if (!drag_info.move_threshold_passed) { + return; + } + + int dir; + + if (drag_info.current_pointer_x - drag_info.grab_x > 0) { + dir = 1; + } else { + dir = -1; + } + + RegionSelection copy (selection->regions); + + RegionSelectionByPosition cmp; + copy.sort (cmp); + + for (RegionSelection::iterator i = copy.begin(); i != copy.end(); ++i) { + + RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*> (&(*i)->get_time_axis_view()); + + if (!atv) { + continue; + } + + boost::shared_ptr<Playlist> playlist; + + if ((playlist = atv->playlist()) == 0) { + continue; + } + + if (!playlist->region_is_shuffle_constrained ((*i)->region())) { + continue; + } + + if (dir > 0) { + if (drag_info.current_pointer_frame < (*i)->region()->last_frame() + 1) { + continue; + } + } else { + if (drag_info.current_pointer_frame > (*i)->region()->first_frame()) { + continue; + } + } + + + playlist->shuffle ((*i)->region(), dir); + + drag_info.grab_x = drag_info.current_pointer_x; + } +} + +void +Editor::region_drag_splice_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) +{ +} + +void +Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) +{ + double x_delta; + double y_delta = 0; + RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data); + nframes_t pending_region_position = 0; + int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order; + int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen + bool clamp_y_axis = false; + vector<int32_t> height_list(512) ; + vector<int32_t>::iterator j; + RouteTimeAxisView* tv; + + possibly_copy_regions_during_grab (event); + + if (!check_region_drag_possible (&tv)) { + return; + } + original_pointer_order = drag_info.last_trackview->order; /************************************************************ @@ -3078,7 +3204,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) pointer_y_span = 0; goto y_axis_done; } - + if ((pointer_y_span = (drag_info.last_trackview->order - tv->order)) != 0) { int32_t children = 0, numtracks = 0; @@ -3253,7 +3379,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } if (sync_frame - sync_offset <= sync_frame) { - pending_region_position = sync_frame - (sync_dir*sync_offset); + pending_region_position = sync_frame + (sync_dir*sync_offset); } else { pending_region_position = 0; } @@ -3270,7 +3396,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) if (pending_region_position != drag_info.last_frame_position && !drag_info.x_constrained) { - /* now compute the canvas unit distance we need to move the regiondrag_info.last_trackview->order + /* now compute the canvas unit distance we need to move the regionview to make it appear at the new location. */ @@ -3449,7 +3575,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) rv->fake_set_opaque (true); } - + if (drag_info.brushing) { mouse_brush_insert_region (rv, pending_region_position); } else { @@ -3503,6 +3629,11 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event region_drag_motion_callback (item, event); + if (Config->get_edit_mode() == Splice && !pre_drag_region_selection.empty()) { + selection->set (pre_drag_region_selection); + pre_drag_region_selection.clear (); + } + if (drag_info.brushing) { /* all changes were made during motion event handlers */ @@ -3551,6 +3682,8 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event /* moved to a different audio track. */ + vector<RegionView*> new_selection; + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ) { RegionView* rv = (*i); @@ -3624,9 +3757,17 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event copies.push_back (rv); } - latest_regionview = 0; + latest_regionviews.clear (); + sigc::connection c = rtv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0)); to_playlist->add_region (new_region, where); + session->add_command (new MementoCommand<Playlist>(*to_playlist, 0, &to_playlist->get_state())); + c.disconnect (); + + if (!latest_regionviews.empty()) { + new_selection.insert (new_selection.end(), latest_regionviews.begin(), latest_regionviews.end()); + } /* OK, this is where it gets tricky. If the playlist was being used by >1 tracks, and the region was selected in all of them, then removing it from the playlist will have removed all @@ -3723,12 +3864,16 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event /* add it */ - to_playlist->add_region (newregion, (nframes_t) (where * from_rtv->get_diskstream()->speed())); - - /* if the original region was locked, we don't care for the new one */ + latest_regionviews.clear (); + sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + to_playlist->add_region (newregion, (nframes_t) (where * rtv->get_diskstream()->speed())); + c.disconnect (); - newregion->set_locked (false); - copies.push_back (rv); + if (!latest_regionviews.empty()) { + // XXX why just the first one ? we only expect one + rtv->reveal_dependent_views (*latest_regionviews.front()); + selection->add (latest_regionviews); + } } else { @@ -3833,7 +3978,7 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event) this is an alignment click (control used) */ - if (Keyboard::modifier_state_contains (event->state, Keyboard::Control)) { + if (Keyboard::modifier_state_contains (event->state, Keyboard::PrimaryModifier)) { TimeAxisView* tv = &rv.get_time_axis_view(); RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(tv); double speed = 1.0; @@ -3845,11 +3990,11 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event) if (where >= 0) { - if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) { + if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) { align_region (rv.region(), SyncPoint, (nframes_t) (where * speed)); - } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) { + } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { align_region (rv.region(), End, (nframes_t) (where * speed)); @@ -3988,14 +4133,14 @@ Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double off void Editor::collect_new_region_view (RegionView* rv) { - latest_regionview = rv; + latest_regionviews.push_back (rv); } void Editor::collect_and_select_new_region_view (RegionView* rv) { selection->add(rv); - latest_regionview = rv; + latest_regionviews.push_back (rv); } void @@ -4025,7 +4170,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) set the regionview we want to then drag. */ - latest_regionview = 0; + latest_regionviews.clear(); sigc::connection c = clicked_routeview->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); /* A selection grab currently creates two undo/redo operations, one for @@ -4045,24 +4190,25 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) c.disconnect (); - if (latest_regionview == 0) { + if (latest_regionviews.empty()) { /* something went wrong */ return; } /* we need to deselect all other regionviews, and select this one - i'm ignoring undo stuff, because the region creation will take care of it */ - //selection->set (latest_regionview); + i'm ignoring undo stuff, because the region creation will take care of it + */ + selection->set (latest_regionviews); - drag_info.item = latest_regionview->get_canvas_group(); - drag_info.data = latest_regionview; + drag_info.item = latest_regionviews.front()->get_canvas_group(); + drag_info.data = latest_regionviews.front(); drag_info.motion_callback = &Editor::region_drag_motion_callback; drag_info.finished_callback = &Editor::region_drag_finished_callback; start_grab (event); drag_info.last_trackview = clicked_axisview; - drag_info.last_frame_position = latest_regionview->region()->position(); + drag_info.last_frame_position = latest_regionviews.front()->region()->position(); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; show_verbose_time_cursor (drag_info.last_frame_position, 10); @@ -4074,10 +4220,8 @@ Editor::cancel_selection () for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { (*i)->hide_selection (); } - begin_reversible_command (_("cancel selection")); selection->clear (); clicked_selection = 0; - commit_reversible_command (); } void @@ -4098,7 +4242,7 @@ Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, Selection switch (op) { case CreateSelection: - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Shift)) { + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) { drag_info.copy = true; } else { drag_info.copy = false; @@ -4313,7 +4457,7 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event) start_grab (event, trimmer_cursor); - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { trim_op = ContentsTrim; } else { /* These will get overridden for a point trim.*/ @@ -4441,7 +4585,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { bool swap_direction = false; - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { swap_direction = true; } @@ -4582,7 +4726,7 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) if (!drag_info.first_move) { trim_motion_callback (item, event); - if (!clicked_regionview->get_selected()) { + if (!selection->selected (clicked_regionview)) { thaw_region_after_trim (*clicked_regionview); } else { @@ -4624,7 +4768,7 @@ Editor::point_trim (GdkEvent* event) trim_op = StartTrim; begin_reversible_command (_("Start point trim")); - if (rv->get_selected()) { + if (selection->selected (rv)) { for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) @@ -4656,7 +4800,7 @@ Editor::point_trim (GdkEvent* event) trim_op = EndTrim; begin_reversible_command (_("End point trim")); - if (rv->get_selected()) { + if (selection->selected (rv)) { for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { @@ -4742,8 +4886,9 @@ Editor::start_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event, Ran switch (op) { case CreateRangeMarker: case CreateTransportMarker: - - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Shift)) { + case CreateCDMarker: + + if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) { drag_info.copy = true; } else { drag_info.copy = false; @@ -4776,6 +4921,7 @@ Editor::drag_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event) switch (range_marker_op) { case CreateRangeMarker: case CreateTransportMarker: + case CreateCDMarker: if (drag_info.first_move) { snap_to (drag_info.grab_frame); } @@ -4833,17 +4979,25 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event) { Location * newloc = 0; string rangename; + int flags; if (!drag_info.first_move) { drag_range_markerbar_op (item, event); switch (range_marker_op) { case CreateRangeMarker: + case CreateCDMarker: { begin_reversible_command (_("new range marker")); XMLNode &before = session->locations()->get_state(); session->locations()->next_available_name(rangename,"unnamed"); - newloc = new Location(temp_location->start(), temp_location->end(), rangename, Location::IsRangeMarker); + if (range_marker_op == CreateCDMarker) { + flags = Location::IsRangeMarker|Location::IsCDMarker; + } + else { + flags = Location::IsRangeMarker; + } + newloc = new Location(temp_location->start(), temp_location->end(), rangename, (Location::Flags) flags); session->locations()->add (newloc, true); XMLNode &after = session->locations()->get_state(); session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after)); @@ -4863,7 +5017,7 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event) } else { /* just a click, no pointer movement. remember that context menu stuff was handled elsewhere */ - if (Keyboard::no_modifier_keys_pressed (&event->button)) { + if (Keyboard::no_modifier_keys_pressed (&event->button) && range_marker_op != CreateCDMarker) { nframes_t start; nframes_t end; @@ -5179,11 +5333,20 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event) } nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region()->position(); +#ifdef USE_RUBBERBAND + float percentage = (float) ((double) newlen / (double) clicked_regionview->region()->length()); +#else float percentage = (float) ((double) newlen - (double) clicked_regionview->region()->length()) / ((double) newlen) * 100.0f; - +#endif + begin_reversible_command (_("timestretch")); - if (run_timestretch (selection->regions, percentage) == 0) { + // XXX how do timeFX on multiple regions ? + + RegionSelection rs; + rs.add (clicked_regionview); + + if (time_stretch (rs, percentage) == 0) { session->commit_reversible_command (); } } @@ -5205,9 +5368,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos) } switch (snap_type) { - case SnapToFrame: case SnapToMark: - case SnapToEditPoint: return; default: diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index dd5f2b4599..9cee32cebb 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -30,6 +30,7 @@ #include <pbd/basename.h> #include <pbd/pthread_utils.h> #include <pbd/memento_command.h> +#include <pbd/whitespace.h> #include <gtkmm2ext/utils.h> #include <gtkmm2ext/choice.h> @@ -112,6 +113,10 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions) { list <boost::shared_ptr<Playlist > > used_playlists; + if (regions.empty()) { + return; + } + begin_reversible_command (_("split")); // if splitting a single region, and snap-to is using @@ -336,7 +341,7 @@ Editor::nudge_forward (bool next) if (!selection->regions.empty()) { - begin_reversible_command (_("nudge forward")); + begin_reversible_command (_("nudge regions forward")); for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { boost::shared_ptr<Region> r ((*i)->region()); @@ -355,6 +360,44 @@ Editor::nudge_forward (bool next) commit_reversible_command (); + + } else if (!selection->markers.empty()) { + + bool is_start; + Location* loc = find_location_from_marker (selection->markers.front(), is_start); + + if (loc) { + + begin_reversible_command (_("nudge location forward")); + + XMLNode& before (loc->get_state()); + + if (is_start) { + distance = get_nudge_distance (loc->start(), next_distance); + if (next) { + distance = next_distance; + } + if (max_frames - distance > loc->start() + loc->length()) { + loc->set_start (loc->start() + distance); + } else { + loc->set_start (max_frames - loc->length()); + } + } else { + distance = get_nudge_distance (loc->end(), next_distance); + if (next) { + distance = next_distance; + } + if (max_frames - distance > loc->end()) { + loc->set_end (loc->end() + distance); + } else { + loc->set_end (max_frames); + } + } + XMLNode& after (loc->get_state()); + session->add_command (new MementoCommand<Location>(*loc, &before, &after)); + commit_reversible_command (); + } + } else { distance = get_nudge_distance (playhead_cursor->current_frame, next_distance); session->request_locate (playhead_cursor->current_frame + distance); @@ -371,7 +414,7 @@ Editor::nudge_backward (bool next) if (!selection->regions.empty()) { - begin_reversible_command (_("nudge forward")); + begin_reversible_command (_("nudge regions backward")); for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { boost::shared_ptr<Region> r ((*i)->region()); @@ -395,6 +438,44 @@ Editor::nudge_backward (bool next) commit_reversible_command (); + } else if (!selection->markers.empty()) { + + bool is_start; + Location* loc = find_location_from_marker (selection->markers.front(), is_start); + + if (loc) { + + begin_reversible_command (_("nudge location forward")); + XMLNode& before (loc->get_state()); + + if (is_start) { + distance = get_nudge_distance (loc->start(), next_distance); + if (next) { + distance = next_distance; + } + if (distance < loc->start()) { + loc->set_start (loc->start() - distance); + } else { + loc->set_start (0); + } + } else { + distance = get_nudge_distance (loc->end(), next_distance); + + if (next) { + distance = next_distance; + } + + if (distance < loc->end() - loc->length()) { + loc->set_end (loc->end() - distance); + } else { + loc->set_end (loc->length()); + } + } + + XMLNode& after (loc->get_state()); + session->add_command (new MementoCommand<Location>(*loc, &before, &after)); + } + } else { distance = get_nudge_distance (playhead_cursor->current_frame, next_distance); @@ -543,12 +624,15 @@ Editor::build_region_boundary_cache () case Start: rpos = r->first_frame(); break; + case End: rpos = r->last_frame(); break; + case SyncPoint: rpos = r->adjust_to_sync (r->first_frame()); break; + default: break; } @@ -635,6 +719,7 @@ Editor::find_next_region (nframes_t frame, RegionPoint point, int32_t dir, Track rpos = r->adjust_to_sync (r->first_frame()); break; } + // rpos is a "track frame", converting it to "session frame" rpos = track_frame_to_session_frame(rpos, track_speed); @@ -655,6 +740,85 @@ Editor::find_next_region (nframes_t frame, RegionPoint point, int32_t dir, Track return ret; } +nframes64_t +Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackViewList& tracks) +{ + nframes64_t distance = max_frames; + nframes64_t current_nearest = -1; + + for (TrackViewList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) { + nframes64_t contender; + nframes64_t d; + + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i); + + if (!rtv) { + continue; + } + + if ((contender = rtv->find_next_region_boundary (pos, dir)) < 0) { + continue; + } + + d = ::llabs (pos - contender); + + if (d < distance) { + current_nearest = contender; + distance = d; + } + } + + return current_nearest; +} + +void +Editor::cursor_to_region_boundary (Cursor* cursor, int32_t dir) +{ + nframes64_t pos = cursor->current_frame; + nframes64_t target; + + if (!session) { + return; + } + + // so we don't find the current region again.. + if (dir > 0 || pos > 0) { + pos += dir; + } + + if (!selection->tracks.empty()) { + + target = find_next_region_boundary (pos, dir, selection->tracks); + + } else { + + target = find_next_region_boundary (pos, dir, track_views); + } + + if (target < 0) { + return; + } + + + if (cursor == playhead_cursor) { + session->request_locate (target); + } else { + cursor->set_position (target); + } +} + +void +Editor::cursor_to_next_region_boundary (Cursor* cursor) +{ + cursor_to_region_boundary (cursor, 1); +} + +void +Editor::cursor_to_previous_region_boundary (Cursor* cursor) +{ + cursor_to_region_boundary (cursor, -1); +} + void Editor::cursor_to_region_point (Cursor* cursor, RegionPoint point, int32_t dir) { @@ -793,7 +957,68 @@ Editor::cursor_to_selection_end (Cursor *cursor) } void -Editor::edit_point_to_region_point (RegionPoint point, int32_t dir) +Editor::selected_marker_to_region_boundary (int32_t dir) +{ + nframes64_t target; + Location* loc; + bool ignored; + + if (!session) { + return; + } + + if (selection->markers.empty()) { + nframes64_t mouse; + bool ignored; + + if (!mouse_frame (mouse, ignored)) { + return; + } + + add_location_mark (mouse); + } + + if ((loc = find_location_from_marker (selection->markers.front(), ignored)) == 0) { + return; + } + + nframes64_t pos = loc->start(); + + // so we don't find the current region again.. + if (dir > 0 || pos > 0) { + pos += dir; + } + + if (!selection->tracks.empty()) { + + target = find_next_region_boundary (pos, dir, selection->tracks); + + } else { + + target = find_next_region_boundary (pos, dir, track_views); + } + + if (target < 0) { + return; + } + + loc->move_to (target); +} + +void +Editor::selected_marker_to_next_region_boundary () +{ + selected_marker_to_region_boundary (1); +} + +void +Editor::selected_marker_to_previous_region_boundary () +{ + selected_marker_to_region_boundary (-1); +} + +void +Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir) { boost::shared_ptr<Region> r; nframes_t pos; @@ -858,19 +1083,19 @@ Editor::edit_point_to_region_point (RegionPoint point, int32_t dir) } void -Editor::edit_point_to_next_region_point (RegionPoint point) +Editor::selected_marker_to_next_region_point (RegionPoint point) { - edit_point_to_region_point (point, 1); + selected_marker_to_region_point (point, 1); } void -Editor::edit_point_to_previous_region_point (RegionPoint point) +Editor::selected_marker_to_previous_region_point (RegionPoint point) { - edit_point_to_region_point (point, -1); + selected_marker_to_region_point (point, -1); } void -Editor::edit_point_to_selection_start () +Editor::selected_marker_to_selection_start () { nframes_t pos = 0; Location* loc; @@ -905,7 +1130,7 @@ Editor::edit_point_to_selection_start () } void -Editor::edit_point_to_selection_end () +Editor::selected_marker_to_selection_end () { nframes_t pos = 0; Location* loc; @@ -1282,15 +1507,18 @@ Editor::temporal_zoom (gdouble fpu) nframes64_t current_leftmost = leftmost_frame; nframes64_t current_rightmost; nframes64_t current_center; - nframes64_t new_page; + nframes64_t new_page_size; + nframes64_t half_page_size; nframes64_t leftmost_after_zoom = 0; nframes64_t where; bool in_track_canvas; double nfpu; + double l; nfpu = fpu; - new_page = (nframes_t) floor (canvas_width * nfpu); + new_page_size = (nframes_t) floor (canvas_width * nfpu); + half_page_size = new_page_size / 2; switch (zoom_focus) { case ZoomFocusLeft: @@ -1299,28 +1527,35 @@ Editor::temporal_zoom (gdouble fpu) case ZoomFocusRight: current_rightmost = leftmost_frame + current_page; - if (current_rightmost > new_page) { - leftmost_after_zoom = current_rightmost - new_page; - } else { + if (current_rightmost < new_page_size) { leftmost_after_zoom = 0; + } else { + leftmost_after_zoom = current_rightmost - new_page_size; } break; case ZoomFocusCenter: current_center = current_leftmost + (current_page/2); - if (current_center > (new_page/2)) { - leftmost_after_zoom = current_center - (new_page / 2); - } else { + if (current_center < half_page_size) { leftmost_after_zoom = 0; + } else { + leftmost_after_zoom = current_center - half_page_size; } break; case ZoomFocusPlayhead: - /* try to keep the playhead in the center */ - if (playhead_cursor->current_frame > new_page/2) { - leftmost_after_zoom = playhead_cursor->current_frame - (new_page/2); - } else { + /* try to keep the playhead in the same place */ + + where = playhead_cursor->current_frame; + + l = - ((new_page_size * ((where - current_leftmost)/(double)current_page)) - where); + + if (l < 0) { leftmost_after_zoom = 0; + } else if (l > max_frames) { + leftmost_after_zoom = max_frames - new_page_size; + } else { + leftmost_after_zoom = (nframes64_t) l; } break; @@ -1331,20 +1566,20 @@ Editor::temporal_zoom (gdouble fpu) /* use playhead instead */ where = playhead_cursor->current_frame; - if (where > new_page/2) { - leftmost_after_zoom = where - (new_page/2); - } else { + if (where < half_page_size) { leftmost_after_zoom = 0; + } else { + leftmost_after_zoom = where - half_page_size; } } else { - double l = - ((new_page * ((where - current_leftmost)/(double)current_page)) - where); + l = - ((new_page_size * ((where - current_leftmost)/(double)current_page)) - where); if (l < 0) { leftmost_after_zoom = 0; } else if (l > max_frames) { - leftmost_after_zoom = max_frames - new_page; + leftmost_after_zoom = max_frames - new_page_size; } else { leftmost_after_zoom = (nframes64_t) l; } @@ -1353,11 +1588,24 @@ Editor::temporal_zoom (gdouble fpu) break; case ZoomFocusEdit: - /* try to keep the edit point in the center */ - if (get_preferred_edit_position() > new_page/2) { - leftmost_after_zoom = get_preferred_edit_position() - (new_page/2); + /* try to keep the edit point in the same place */ + where = get_preferred_edit_position (); + + if (where > 0) { + + double l = - ((new_page_size * ((where - current_leftmost)/(double)current_page)) - where); + + if (l < 0) { + leftmost_after_zoom = 0; + } else if (l > max_frames) { + leftmost_after_zoom = max_frames - new_page_size; + } else { + leftmost_after_zoom = (nframes64_t) l; + } + } else { - leftmost_after_zoom = 0; + /* edit point not defined */ + return; } break; @@ -1365,17 +1613,71 @@ Editor::temporal_zoom (gdouble fpu) // leftmost_after_zoom = min (leftmost_after_zoom, session->current_end_frame()); -// begin_reversible_command (_("zoom")); -// session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), current_leftmost, frames_per_unit)); -// session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_after_zoom, nfpu)); -// commit_reversible_command (); - - // cerr << "repos & zoom to " << leftmost_after_zoom << " @ " << nfpu << endl; - reposition_and_zoom (leftmost_after_zoom, nfpu); } void +Editor::temporal_zoom_region () +{ + + nframes64_t start = max_frames; + nframes64_t end = 0; + + ensure_entered_region_selected (true); + + if (selection->regions.empty()) { + info << _("cannot set loop: no region selected") << endmsg; + return; + } + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + if ((*i)->region()->position() < start) { + start = (*i)->region()->position(); + } + if ((*i)->region()->last_frame() + 1 > end) { + end = (*i)->region()->last_frame() + 1; + } + } + + /* now comes an "interesting" hack ... make sure we leave a little space + at each end of the editor so that the zoom doesn't fit the region + precisely to the screen. + */ + + GdkScreen* screen = gdk_screen_get_default (); + gint pixwidth = gdk_screen_get_width (screen); + gint mmwidth = gdk_screen_get_width_mm (screen); + double pix_per_mm = (double) pixwidth/ (double) mmwidth; + double one_centimeter_in_pixels = pix_per_mm * 10.0; + nframes_t extra_samples = unit_to_frame (one_centimeter_in_pixels); + + if (start > extra_samples) { + start -= extra_samples; + } else { + start = 0; + } + + if (max_frames - extra_samples > end) { + end += extra_samples; + } else { + end = max_frames; + } + + temporal_zoom_by_frame (start, end, "zoom to region"); + zoomed_to_region = true; +} + +void +Editor::toggle_zoom_region () +{ + if (zoomed_to_region) { + swap_visual_state (); + } else { + temporal_zoom_region (); + } +} + +void Editor::temporal_zoom_selection () { if (!selection) return; @@ -1493,12 +1795,12 @@ Editor::add_location_from_selection () } void -Editor::add_location_from_playhead_cursor () +Editor::add_location_mark (nframes64_t where) { string markername; - nframes_t where = session->audible_frame(); - + select_new_marker = true; + session->locations()->next_available_name(markername,"mark"); Location *location = new Location (where, where, markername, Location::IsMark); session->begin_reversible_command (_("add marker")); @@ -1510,6 +1812,12 @@ Editor::add_location_from_playhead_cursor () } void +Editor::add_location_from_playhead_cursor () +{ + add_location_mark (session->audible_frame()); +} + +void Editor::add_location_from_audio_region () { if (selection->regions.empty()) { @@ -1760,11 +2068,17 @@ Editor::insert_region_list_selection (float times) RouteTimeAxisView *tv = 0; boost::shared_ptr<Playlist> playlist; - if (selection->tracks.empty()) { - return; - } - - if ((tv = dynamic_cast<RouteTimeAxisView*>(selection->tracks.front())) == 0) { + if (clicked_routeview != 0) { + tv = clicked_routeview; + } else if (!selection->tracks.empty()) { + if ((tv = dynamic_cast<RouteTimeAxisView*>(selection->tracks.front())) == 0) { + return; + } + } else if (entered_track != 0) { + if ((tv = dynamic_cast<RouteTimeAxisView*>(entered_track)) == 0) { + return; + } + } else { return; } @@ -1881,23 +2195,32 @@ Editor::play_from_edit_point () } void -Editor::play_selection () +Editor::play_from_edit_point_and_return () { - if (selection->time.empty()) { - return; + nframes64_t start_frame; + nframes64_t return_frame; + + /* don't reset the return frame if its already set */ + + if ((return_frame = session->requested_return_frame()) < 0) { + return_frame = session->audible_frame(); } - session->request_play_range (true); + start_frame = get_preferred_edit_position (true); + + if (start_frame >= 0) { + session->request_roll_at_and_return (start_frame, return_frame); + } } void -Editor::play_selected_region () +Editor::play_selection () { - if (!selection->regions.empty()) { - RegionView *rv = *(selection->regions.begin()); - - session->request_bounded_roll (rv->region()->position(), rv->region()->last_frame()); + if (selection->time.empty()) { + return; } + + session->request_play_range (true); } void @@ -1949,12 +2272,24 @@ Editor::loop_location (Location& location) } void +Editor::raise_region () +{ + selection->foreach_region (&Region::raise); +} + +void Editor::raise_region_to_top () { selection->foreach_region (&Region::raise_to_top); } void +Editor::lower_region () +{ + selection->foreach_region (&Region::lower); +} + +void Editor::lower_region_to_bottom () { selection->foreach_region (&Region::lower_to_bottom); @@ -1968,58 +2303,54 @@ Editor::edit_region () } void -Editor::rename_region () +Editor::rename_region() { - Dialog dialog; - Entry entry; - Button ok_button (_("OK")); - Button cancel_button (_("Cancel")); - if (selection->regions.empty()) { return; } - WindowTitle title(Glib::get_application_name()); + WindowTitle title (Glib::get_application_name()); title += _("Rename Region"); - dialog.set_title (title.get_string()); - dialog.set_name ("RegionRenameWindow"); - dialog.set_size_request (300, -1); - dialog.set_position (Gtk::WIN_POS_MOUSE); - dialog.set_modal (true); + ArdourDialog d (*this, title.get_string(), true, false); + Entry entry; + Label label (_("New name:")); + HBox hbox; - dialog.get_vbox()->set_border_width (10); - dialog.get_vbox()->pack_start (entry); - dialog.get_action_area()->pack_start (ok_button); - dialog.get_action_area()->pack_start (cancel_button); + hbox.set_spacing (6); + hbox.pack_start (label, false, false); + hbox.pack_start (entry, true, true); - entry.set_name ("RegionNameDisplay"); - ok_button.set_name ("EditorGTKButton"); - cancel_button.set_name ("EditorGTKButton"); + d.get_vbox()->set_border_width (12); + d.get_vbox()->pack_start (hbox, false, false); - region_renamed = false; + d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); + d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - entry.signal_activate().connect (bind (mem_fun(*this, &Editor::rename_region_finished), true)); - ok_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::rename_region_finished), true)); - cancel_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::rename_region_finished), false)); + d.set_size_request (300, -1); + d.set_position (Gtk::WIN_POS_MOUSE); - /* recurse */ + entry.set_text (selection->regions.front()->region()->name()); + entry.select_region (0, -1); - dialog.show_all (); - Main::run (); + entry.signal_activate().connect (bind (mem_fun (d, &Dialog::response), RESPONSE_OK)); + + d.show_all (); + + entry.grab_focus(); - if (region_renamed) { - (*selection->regions.begin())->region()->set_name (entry.get_text()); - redisplay_regions (); - } -} + int ret = d.run(); -void -Editor::rename_region_finished (bool status) + d.hide (); -{ - region_renamed = status; - Main::quit (); + if (ret == RESPONSE_OK) { + std::string str = entry.get_text(); + strip_whitespace_edges (str); + if (!str.empty()) { + selection->regions.front()->region()->set_name (str); + redisplay_regions (); + } + } } void @@ -2043,12 +2374,37 @@ Editor::audition_playlist_region_via_route (boost::shared_ptr<Region> region, Ro /** Start an audition of the first selected region */ void -Editor::audition_selected_region () +Editor::play_edit_range () { - if (!selection->regions.empty()) { - RegionView* rv = *(selection->regions.begin()); - session->audition_region (rv->region()); + nframes64_t start, end; + + if (get_edit_op_range (start, end)) { + session->request_bounded_roll (start, end); + } +} + +void +Editor::play_selected_region () +{ + nframes64_t start = max_frames; + nframes64_t end = 0; + + ensure_entered_region_selected (true); + + if (selection->regions.empty()) { + return; } + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + if ((*i)->region()->position() < start) { + start = (*i)->region()->position(); + } + if ((*i)->region()->last_frame() + 1 > end) { + end = (*i)->region()->last_frame() + 1; + } + } + + session->request_bounded_roll (start, end); } void @@ -2194,18 +2550,23 @@ Editor::new_region_from_selection () cancel_selection (); } -void -Editor::separate_region_from_selection () +static void +add_if_covered (RegionView* rv, const AudioRange* ar, RegionSelection* rs) { - // FIXME: TYPE - - bool doing_undo = false; - - if (selection->time.empty()) { - return; + switch (rv->region()->coverage (ar->start, ar->end - 1)) { + case OverlapNone: + break; + default: + rs->push_back (rv); } +} +void +Editor::separate_regions_between (const TimeSelection& ts) +{ + bool in_command = false; boost::shared_ptr<Playlist> playlist; + RegionSelection new_selection; sort_track_selection (); @@ -2220,99 +2581,112 @@ Editor::separate_region_from_selection () if (t != 0 && ! t->diskstream()->destructive()) { if ((playlist = rtv->playlist()) != 0) { - if (!doing_undo) { - begin_reversible_command (_("separate")); - doing_undo = true; - } + + XMLNode *before = &(playlist->get_state()); + bool got_some = false; - XMLNode *before; - if (doing_undo) - before = &(playlist->get_state()); - /* XXX need to consider musical time selections here at some point */ double speed = t->diskstream()->speed(); - for (list<AudioRange>::iterator t = selection->time.begin(); t != selection->time.end(); ++t) { + + for (list<AudioRange>::const_iterator t = ts.begin(); t != ts.end(); ++t) { + + sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + latest_regionviews.clear (); + playlist->partition ((nframes_t)((*t).start * speed), (nframes_t)((*t).end * speed), true); + + c.disconnect (); + + if (!latest_regionviews.empty()) { + + got_some = true; + + rtv->view()->foreach_regionview (bind (sigc::ptr_fun (add_if_covered), &(*t), &new_selection)); + + if (!in_command) { + begin_reversible_command (_("separate")); + in_command = true; + } + + session->add_command(new MementoCommand<Playlist>(*playlist, before, &playlist->get_state())); + + } } - if (doing_undo) - session->add_command(new MementoCommand<Playlist>(*playlist, before, &playlist->get_state())); + if (!got_some) { + delete before; + } } } } } - if (doing_undo) commit_reversible_command (); + if (in_command) { + selection->set (new_selection); + set_mouse_mode (MouseObject); + + commit_reversible_command (); + } } void -Editor::separate_regions_using_location (Location& loc) +Editor::separate_region_from_selection () { - // FIXME: TYPE - - bool doing_undo = false; - - if (loc.is_mark()) { - return; - } - - boost::shared_ptr<Playlist> playlist; - - /* XXX i'm unsure as to whether this should operate on selected tracks only - or the entire enchillada. uncomment the below line to correct the behaviour - (currently set for all tracks) + /* preferentially use *all* ranges in the time selection if we're in range mode + to allow discontiguous operation, since get_edit_op_range() currently + returns a single range. */ + if (mouse_mode == MouseRange && !selection->time.empty()) { - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - //for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { + separate_regions_between (selection->time); - RouteTimeAxisView* rtv; + } else { + + nframes64_t start; + nframes64_t end; - if ((rtv = dynamic_cast<RouteTimeAxisView*> ((*i))) != 0) { + if (get_edit_op_range (start, end)) { + + AudioRange ar (start, end, 1); + TimeSelection ts; + ts.push_back (ar); - boost::shared_ptr<Track> t = rtv->track(); + /* force track selection */ - if (t != 0 && ! t->diskstream()->destructive()) { - - if ((playlist = rtv->playlist()) != 0) { - - XMLNode *before; - if (!doing_undo) { - begin_reversible_command (_("separate")); - doing_undo = true; - } - if (doing_undo) - before = &(playlist->get_state()); - + ensure_entered_region_selected (); - /* XXX need to consider musical time selections here at some point */ + separate_regions_between (ts); + } + } +} - double speed = rtv->get_diskstream()->speed(); +void +Editor::separate_regions_using_location (Location& loc) +{ + if (loc.is_mark()) { + return; + } + AudioRange ar (loc.start(), loc.end(), 1); + TimeSelection ts; - playlist->partition ((nframes_t)(loc.start() * speed), (nframes_t)(loc.end() * speed), true); - if (doing_undo) - session->add_command(new MementoCommand<Playlist>(*playlist, before, &playlist->get_state())); - } - } - } - } + ts.push_back (ar); - if (doing_undo) commit_reversible_command (); + separate_regions_between (ts); } void Editor::crop_region_to_selection () { - ensure_entered_selected (); + ensure_entered_region_selected (true); if (!selection->time.empty()) { crop_region_to (selection->time.start(), selection->time.end_frame()); - } else if (_edit_point != EditAtPlayhead) { + } else { nframes64_t start; nframes64_t end; @@ -2331,8 +2705,6 @@ Editor::crop_region_to (nframes_t start, nframes_t end) boost::shared_ptr<Playlist> playlist; TrackSelection* ts; - ensure_entered_selected (); - if (selection->tracks.empty()) { ts = &track_views; } else { @@ -2490,49 +2862,40 @@ Editor::region_fill_selection () } void -Editor::set_a_regions_sync_position (boost::shared_ptr<Region> region, nframes_t position) +Editor::set_region_sync_from_edit_point () { - - if (!region->covers (position)) { - error << _("Programming error. that region doesn't cover that position") << __FILE__ << " +" << __LINE__ << endmsg; - return; - } - begin_reversible_command (_("set region sync position")); - XMLNode &before = region->playlist()->get_state(); - region->set_sync_position (position); - XMLNode &after = region->playlist()->get_state(); - session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after)); - commit_reversible_command (); + nframes64_t where = get_preferred_edit_position (); + ensure_entered_region_selected (true); + set_sync_point (where, selection->regions); } -/** Set the sync position of the selection using the position of the edit cursor */ void -Editor::set_region_sync_from_edit_point () +Editor::set_sync_point (nframes64_t where, const RegionSelection& rs) { - /* Check that at the edit cursor is in at least one of the selected regions */ - RegionSelection::const_iterator i = selection->regions.begin(); + bool in_command = false; - while (i != selection->regions.end() && !(*i)->region()->covers (get_preferred_edit_position())) { - ++i; - } + for (RegionSelection::const_iterator r = rs.begin(); r != rs.end(); ++r) { + + if (!(*r)->region()->covers (where)) { + continue; + } - /* Give the user a hint if not */ - if (i == selection->regions.end()) { - error << _("Place the edit point at the desired sync point") << endmsg; - return; - } + boost::shared_ptr<Region> region ((*r)->region()); - begin_reversible_command (_("set sync from edit point")); - - for (RegionSelection::iterator j = selection->regions.begin(); j != selection->regions.end(); ++j) { - boost::shared_ptr<Region> r = (*j)->region(); - XMLNode &before = r->playlist()->get_state(); - r->set_sync_position (get_preferred_edit_position()); - XMLNode &after = r->playlist()->get_state(); - session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after)); + if (!in_command) { + begin_reversible_command (_("set sync point")); + in_command = true; + } + + XMLNode &before = region->playlist()->get_state(); + region->set_sync_position (get_preferred_edit_position()); + XMLNode &after = region->playlist()->get_state(); + session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after)); } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } /** Remove the sync positions of the selection */ @@ -2571,7 +2934,7 @@ Editor::naturalize () void Editor::align (RegionPoint what) { - ensure_entered_selected (); + ensure_entered_region_selected (); nframes64_t where = get_preferred_edit_position(); @@ -2737,7 +3100,7 @@ Editor::trim_region_to_punch () void Editor::trim_region_to_location (const Location& loc, const char* str) { - ensure_entered_selected (); + ensure_entered_region_selected (); RegionSelection& rs (get_regions_for_action ()); @@ -3082,12 +3445,13 @@ Editor::cut_copy (CutCopyOp op) switch (current_mouse_mode()) { case MouseObject: + cerr << "cutting in object mode\n"; if (!selection->regions.empty() || !selection->points.empty()) { begin_reversible_command (opname + _(" objects")); if (!selection->regions.empty()) { - + cerr << "have regions to cut" << endl; cut_copy_regions (op); if (op == Cut) { @@ -3106,6 +3470,7 @@ Editor::cut_copy (CutCopyOp op) commit_reversible_command (); break; // terminate case statement here } + cerr << "nope, now cutting time range" << endl; if (!selection->time.empty()) { /* don't cause suprises */ break; @@ -3115,10 +3480,12 @@ Editor::cut_copy (CutCopyOp op) case MouseRange: if (selection->time.empty()) { nframes64_t start, end; + cerr << "no time selection, get edit op range" << endl; if (!get_edit_op_range (start, end)) { + cerr << "no edit op range" << endl; return; } - selection->set (0, start, end); + selection->set ((TimeAxisView*) 0, start, end); } begin_reversible_command (opname + _(" range")); @@ -3347,7 +3714,7 @@ Editor::paste_internal (nframes_t position, float times) { bool commit = false; - if (cut_buffer->empty() || selection->tracks.empty()) { + if (cut_buffer->empty()) { return; } @@ -3357,14 +3724,21 @@ Editor::paste_internal (nframes_t position, float times) begin_reversible_command (_("paste")); + TrackSelection ts; TrackSelection::iterator i; size_t nth; /* get everything in the correct order */ - sort_track_selection (); - for (nth = 0, i = selection->tracks.begin(); i != selection->tracks.end(); ++i, ++nth) { + if (!selection->tracks.empty()) { + sort_track_selection (); + ts = selection->tracks; + } else if (entered_track) { + ts.push_back (entered_track); + } + + for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) { /* undo/redo is handled by individual tracks */ @@ -3438,8 +3812,9 @@ void Editor::duplicate_some_regions (RegionSelection& regions, float times) { boost::shared_ptr<Playlist> playlist; - RegionSelection sel = regions; // clear (below) will clear the argument list - + RegionSelection sel = regions; // clear (below) may clear the argument list if its the current region selection + RegionSelection foo; + begin_reversible_command (_("duplicate region")); selection->clear_regions (); @@ -3450,6 +3825,7 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times) TimeAxisView& tv = (*i)->get_time_axis_view(); RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (&tv); + latest_regionviews.clear (); sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); playlist = (*i)->region()->playlist(); @@ -3458,14 +3834,15 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times) session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state())); c.disconnect (); - - if (latest_regionview) { - selection->add (latest_regionview); - } - } + foo.insert (foo.end(), latest_regionviews.begin(), latest_regionviews.end()); + } commit_reversible_command (); + + if (!foo.empty()) { + selection->set (foo); + } } void @@ -3915,7 +4292,7 @@ Editor::toggle_region_opaque () void Editor::set_fade_length (bool in) { - ensure_entered_selected (); + ensure_entered_region_selected (true); /* we need a region to measure the offset from the start */ @@ -3976,6 +4353,51 @@ Editor::set_fade_length (bool in) commit_reversible_command (); } + +void +Editor::toggle_fade_active (bool in) +{ + ensure_entered_region_selected (true); + + if (selection->regions.empty()) { + return; + } + + const char* cmd = (in ? _("toggle fade in active") : _("toggle fade out active")); + bool have_switch = false; + bool yn; + bool in_command = false; + + begin_reversible_command (cmd); + + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x); + + if (!tmp) { + return; + } + + boost::shared_ptr<AudioRegion> region (tmp->audio_region()); + + /* make the behaviour consistent across all regions */ + + if (!have_switch) { + yn = region->fade_in_active(); + have_switch = true; + } + + XMLNode &before = region->get_state(); + region->set_fade_in_active (!yn); + XMLNode &after = region->get_state(); + session->add_command(new MementoCommand<AudioRegion>(*region.get(), &before, &after)); + in_command = true; + } + + if (in_command) { + commit_reversible_command (); + } +} + void Editor::set_fade_in_shape (AudioRegion::FadeShape shape) { @@ -4141,8 +4563,8 @@ Editor::set_playhead_cursor () void Editor::split () { - ensure_entered_selected (); - + ensure_entered_region_selected (); + nframes64_t where = get_preferred_edit_position(); if (!selection->regions.empty()) { @@ -4158,11 +4580,253 @@ Editor::split () } void -Editor::ensure_entered_selected () +Editor::ensure_entered_track_selected (bool op_really_wants_one_track_if_none_are_selected) { - if (entered_regionview) { - if (find (selection->regions.begin(), selection->regions.end(), entered_regionview) == selection->regions.end()) { - selection->set (entered_regionview); + if (entered_track && mouse_mode == MouseObject) { + if (!selection->tracks.empty()) { + if (!selection->selected (entered_track)) { + selection->add (entered_track); + } + } else { + /* there is no selection, but this operation requires/prefers selected objects */ + + if (op_really_wants_one_track_if_none_are_selected) { + selection->set (entered_track); + } + } + } +} + +void +Editor::ensure_entered_region_selected (bool op_really_wants_one_region_if_none_are_selected) +{ + if (entered_regionview && mouse_mode == MouseObject) { + + /* heuristic: + + - if there is no existing selection, don't change it. the operation will thus apply to "all" + + - if there is an existing selection, but the entered regionview isn't in it, add it. this + avoids key-mouse ops on unselected regions from interfering with an existing selection, + but also means that the operation will apply to the pointed-at region. + */ + + if (!selection->regions.empty()) { + if (find (selection->regions.begin(), selection->regions.end(), entered_regionview) != selection->regions.end()) { + selection->add (entered_regionview); + } + } else { + /* there is no selection, but this operation requires/prefers selected objects */ + + if (op_really_wants_one_region_if_none_are_selected) { + selection->set (entered_regionview, false); + } } } } + +void +Editor::trim_region_front () +{ + trim_region (true); +} + +void +Editor::trim_region_back () +{ + trim_region (false); +} + +void +Editor::trim_region (bool front) +{ + nframes64_t where = get_preferred_edit_position(); + RegionSelection& rs = get_regions_for_action (); + + if (rs.empty()) { + return; + } + + begin_reversible_command (front ? _("trim front") : _("trim back")); + + for (list<RegionView*>::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) { + if (!(*i)->region()->locked()) { + boost::shared_ptr<Playlist> pl = (*i)->region()->playlist(); + XMLNode &before = pl->get_state(); + if (front) { + (*i)->region()->trim_front (where, this); + } else { + (*i)->region()->trim_end (where, this); + } + XMLNode &after = pl->get_state(); + session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after)); + } + } + commit_reversible_command (); +} + +struct EditorOrderRouteSorter { + bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { + /* use of ">" forces the correct sort order */ + return a->order_key ("editor") < b->order_key ("editor"); + } +}; + +void +Editor::select_next_route() +{ + if (selection->tracks.empty()) { + selection->set (track_views.front()); + return; + } + + TimeAxisView* current = selection->tracks.front(); + + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + if (*i == current) { + ++i; + if (i != track_views.end()) { + selection->set (*i); + } else { + selection->set (*(track_views.begin())); + } + break; + } + } +} + +void +Editor::select_prev_route() +{ + if (selection->tracks.empty()) { + selection->set (track_views.front()); + return; + } + + TimeAxisView* current = selection->tracks.front(); + + for (TrackViewList::reverse_iterator i = track_views.rbegin(); i != track_views.rend(); ++i) { + if (*i == current) { + ++i; + if (i != track_views.rend()) { + selection->set (*i); + } else { + selection->set (*(track_views.rbegin())); + } + break; + } + } +} + +void +Editor::set_loop_from_selection (bool play) +{ + if (session == 0 || selection->time.empty()) { + return; + } + + nframes_t start = selection->time[clicked_selection].start; + nframes_t end = selection->time[clicked_selection].end; + + set_loop_range (start, end, _("set loop range from selection")); + + if (play) { + session->request_play_loop (true); + session->request_locate (start, true); + } +} + +void +Editor::set_loop_from_edit_range (bool play) +{ + if (session == 0) { + return; + } + + nframes64_t start; + nframes64_t end; + + if (!get_edit_op_range (start, end)) { + return; + } + + set_loop_range (start, end, _("set loop range from edit range")); + + if (play) { + session->request_play_loop (true); + session->request_locate (start, true); + } +} + +void +Editor::set_loop_from_region (bool play) +{ + nframes64_t start = max_frames; + nframes64_t end = 0; + + ensure_entered_region_selected (true); + + if (selection->regions.empty()) { + info << _("cannot set loop: no region selected") << endmsg; + return; + } + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + if ((*i)->region()->position() < start) { + start = (*i)->region()->position(); + } + if ((*i)->region()->last_frame() + 1 > end) { + end = (*i)->region()->last_frame() + 1; + } + } + + set_loop_range (start, end, _("set loop range from region")); + + if (play) { + session->request_play_loop (true); + session->request_locate (start, true); + } +} + +void +Editor::set_punch_from_selection () +{ + if (session == 0 || selection->time.empty()) { + return; + } + + nframes_t start = selection->time[clicked_selection].start; + nframes_t end = selection->time[clicked_selection].end; + + set_punch_range (start, end, _("set punch range from selection")); +} + +void +Editor::set_punch_from_edit_range () +{ + if (session == 0) { + return; + } + + nframes64_t start; + nframes64_t end; + + if (!get_edit_op_range (start, end)) { + return; + } + + set_punch_range (start, end, _("set punch range from edit range")); +} + +void +Editor::pitch_shift_regions () +{ + ensure_entered_region_selected (true); + + if (selection->regions.empty()) { + return; + } + + pitch_shift (selection->regions, 1.2); +} + diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc index 3e47d26cd6..e15ee6448c 100644 --- a/gtk2_ardour/editor_region_list.cc +++ b/gtk2_ardour/editor_region_list.cc @@ -38,6 +38,7 @@ #include "ardour_ui.h" #include "gui_thread.h" #include "actions.h" +#include "region_view.h" #include "utils.h" #include "i18n.h" @@ -89,10 +90,6 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region) Gdk::Color c; bool missing_source; - region_state_changed_connections.push_back ( - region->StateChanged.connect (bind (mem_fun (*this, &Editor::region_list_region_changed), boost::weak_ptr<Region> (region))) - ); - missing_source = boost::dynamic_pointer_cast<SilentFileSource>(region->source()); if (!show_automatic_regions_in_region_list && region->automatic()) { @@ -309,13 +306,6 @@ Editor::redisplay_regions () { if (session) { - for (std::list<connection>::iterator i = region_state_changed_connections.begin(); - i != region_state_changed_connections.end(); - ++i) - { - i->disconnect (); - } - region_list_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0)); region_list_model->clear (); @@ -419,6 +409,8 @@ Editor::region_list_display_button_press (GdkEventButton *ev) int cellx; int celly; + cerr << "Button press release, button = " << ev->button << endl; + if (region_list_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { if ((iter = region_list_model->get_iter (path))) { region = (*iter)[region_list_columns.region]; @@ -427,27 +419,25 @@ Editor::region_list_display_button_press (GdkEventButton *ev) if (Keyboard::is_context_menu_event (ev)) { show_region_list_display_context_menu (ev->button, ev->time); + cerr << "\tcontext menu event, event handled\n"; return true; } if (region == 0) { + cerr << "\tno region, event not handled\n"; return false; } switch (ev->button) { case 1: - /* audition on double click */ - if (ev->type == GDK_2BUTTON_PRESS) { - consider_auditioning (region); - return true; - } - return false; break; case 2: - if (!Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + // audition on middle click (stop audition too) + if (!Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { consider_auditioning (region); } + cerr << "\taudition, event handled\n"; return true; break; @@ -455,6 +445,7 @@ Editor::region_list_display_button_press (GdkEventButton *ev) break; } + cerr << "\tnot handled\n"; return false; } @@ -674,6 +665,12 @@ Editor::region_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& { vector<ustring> paths; + if (data.get_target() == "GTK_TREE_MODEL_ROW") { + cerr << "Delete drag data drop to treeview\n"; + region_list_display.on_drag_data_received (context, x, y, data, info, time); + return; + } + if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) { nframes64_t pos = 0; do_embed (paths, Editing::ImportDistinctFiles, ImportAsRegion, pos); @@ -697,3 +694,30 @@ Editor::region_list_selection_filter (const RefPtr<TreeModel>& model, const Tree return true; } + +void +Editor::region_name_edit (const Glib::ustring& path, const Glib::ustring& new_text) +{ + boost::shared_ptr<Region> region; + TreeIter iter; + + if ((iter = region_list_model->get_iter (path))) { + region = (*iter)[region_list_columns.region]; + (*iter)[region_list_columns.name] = new_text; + } + + /* now mapover everything */ + + if (region) { + vector<RegionView*> equivalents; + get_regions_corresponding_to (region, equivalents); + + for (vector<RegionView*>::iterator i = equivalents.begin(); i != equivalents.end(); ++i) { + if (new_text != (*i)->region()->name()) { + (*i)->region()->set_name (new_text); + } + } + } + +} + diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index b700f9e469..c422a43859 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -41,6 +41,7 @@ using namespace sigc; using namespace ARDOUR; using namespace PBD; using namespace Gtk; +using namespace Glib; void @@ -70,7 +71,7 @@ Editor::handle_new_route (Session::RouteList& routes) tv = new MidiTimeAxisView (*this, *session, route, track_canvas); else throw unknown_type(); - + //cerr << "Editor::handle_new_route() called on " << route->name() << endl;//DEBUG #if 0 if (route_display_model->children().size() == 0) { @@ -155,42 +156,10 @@ Editor::remove_route (TimeAxisView *tv) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::remove_route), tv)); + TrackViewList::iterator i; TreeModel::Children rows = route_display_model->children(); TreeModel::Children::iterator ri; - /* find the track view that's being deleted */ - TrackViewList::iterator i = find (track_views.begin(), track_views.end(), tv); - - /* set up `nearby' to be a suitable nearby track to select once - this one has gone */ - TrackViewList::iterator nearby = track_views.end (); - if (i != track_views.end()) { - - nearby = i; - - if (nearby != track_views.begin()) { - /* go to the previous track if there is one */ - nearby--; - } else { - /* otherwise the next track */ - nearby++; - } - - /* and remove the track view that's going */ - track_views.erase (i); - - if (nearby != track_views.end()) { - /* we've got another track to select, so select it */ - set_selected_track (**nearby, Selection::Set); - } else { - /* we've got no other track, so the editor mixer will disappear */ - editor_mixer_button.set_active (false); - ActionManager::uncheck_toggleaction ("<Actions>/Editor/show-editor-mixer"); - editor_mixer_button.set_sensitive (false); - editor_list_button.set_sensitive (false); - } - } - /* Decrement old order keys for tracks `above' the one that is being removed */ for (ri = rows.begin(); ri != rows.end(); ++ri) { TimeAxisView* v = (*ri)[route_display_columns.tv]; @@ -205,6 +174,23 @@ Editor::remove_route (TimeAxisView *tv) break; } } + + if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) { + track_views.erase (i); + } + + /* since the editor mixer goes away when you remove a route, set the + * button to inactive and untick the menu option + */ + + editor_mixer_button.set_active(false); + ActionManager::uncheck_toggleaction ("<Actions>/Editor/show-editor-mixer"); + + /* and disable if all tracks and/or routes are gone */ + + if (track_views.size() == 0) { + editor_mixer_button.set_sensitive(false); + } } void @@ -609,3 +595,21 @@ Editor::route_list_delete (const Gtk::TreeModel::Path& path) session->set_remote_control_ids(); redisplay_route_list (); } + + +void +Editor::route_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& context, + int x, int y, + const SelectionData& data, + guint info, guint time) +{ + cerr << "RouteLD::dddr target = " << data.get_target() << endl; + + if (data.get_target() == "GTK_TREE_MODEL_ROW") { + cerr << "Delete drag data drop to treeview\n"; + route_list_display.on_drag_data_received (context, x, y, data, info, time); + return; + } + cerr << "some other kind of drag\n"; + context->drag_finish (true, false, time); +} diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc index 4eb684c48a..f0624ccbb2 100644 --- a/gtk2_ardour/editor_rulers.cc +++ b/gtk2_ardour/editor_rulers.cc @@ -23,6 +23,7 @@ #include <string> #include <ardour/tempo.h> +#include <ardour/profile.h> #include <gtkmm2ext/gtk_ui.h> #include "editor.h" @@ -91,33 +92,64 @@ Editor::initialize_rulers () ruler_shown[ruler_time_marker] = true; ruler_shown[ruler_time_range_marker] = true; ruler_shown[ruler_time_transport_marker] = true; + if (Profile->get_sae()) { + ruler_shown[ruler_time_cd_marker] = false; + } else { + ruler_shown[ruler_time_cd_marker] = true; + } ruler_shown[ruler_metric_frames] = false; ruler_shown[ruler_metric_minsec] = false; - smpte_ruler->set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - bbt_ruler->set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - frames_ruler->set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - minsec_ruler->set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - - smpte_ruler->signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_button_release)); - bbt_ruler->signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_button_release)); - frames_ruler->signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_button_release)); - minsec_ruler->signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_button_release)); - - smpte_ruler->signal_button_press_event().connect (mem_fun(*this, &Editor::ruler_button_press)); - bbt_ruler->signal_button_press_event().connect (mem_fun(*this, &Editor::ruler_button_press)); - frames_ruler->signal_button_press_event().connect (mem_fun(*this, &Editor::ruler_button_press)); - minsec_ruler->signal_button_press_event().connect (mem_fun(*this, &Editor::ruler_button_press)); - - smpte_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion)); - bbt_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion)); - frames_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion)); - minsec_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion)); - visible_timebars = 7; /* 4 here, 3 in time_canvas */ ruler_pressed_button = 0; } +bool +Editor::ruler_scroll (GdkEventScroll* event) +{ + nframes_t xdelta; + int direction = event->direction; + bool handled = false; + + switch (direction) { + case GDK_SCROLL_UP: + temporal_zoom_step (true); + handled = true; + break; + + case GDK_SCROLL_DOWN: + temporal_zoom_step (false); + handled = true; + break; + + case GDK_SCROLL_LEFT: + xdelta = (current_page_frames() / 2); + if (leftmost_frame > xdelta) { + reset_x_origin (leftmost_frame - xdelta); + } else { + reset_x_origin (0); + } + handled = true; + break; + + case GDK_SCROLL_RIGHT: + xdelta = (current_page_frames() / 2); + if (max_frames - xdelta > leftmost_frame) { + reset_x_origin (leftmost_frame + xdelta); + } else { + reset_x_origin (max_frames - current_page_frames()); + } + handled = true; + break; + + default: + /* what? */ + break; + } + + return handled; +} + gint Editor::ruler_button_press (GdkEventButton* ev) @@ -165,9 +197,7 @@ Editor::ruler_button_press (GdkEventButton* ev) case 2: /* edit point */ - if (snap_type != Editing::SnapToEditPoint) { - snap_to (where); - } + snap_to (where); break; default: @@ -206,9 +236,7 @@ Editor::ruler_button_release (GdkEventButton* ev) case 2: /* edit point */ - if (snap_type != Editing::SnapToEditPoint) { - snap_to (where); - } + snap_to (where); break; case 3: @@ -338,7 +366,7 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t) switch (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 (_("New location marker"), bind ( mem_fun(*this, &Editor::mouse_add_new_marker), where, false))); 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 ()); @@ -353,7 +381,13 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t) case TransportMarkerBarItem: break; + + case CdMarkerBarItem: + // TODO + ruler_items.push_back (MenuElem (_("New CD track marker"), bind ( mem_fun(*this, &Editor::mouse_add_new_marker), where, true))); + break; + case TempoBarItem: ruler_items.push_back (MenuElem (_("New Tempo"), bind ( mem_fun(*this, &Editor::mouse_add_new_tempo_event), where))); ruler_items.push_back (MenuElem (_("Clear tempo"))); @@ -382,7 +416,7 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t) mitem->set_active(true); } - ruler_items.push_back (CheckMenuElem (_("Frames"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_frames))); + ruler_items.push_back (CheckMenuElem (_("Samples"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_frames))); mitem = (CheckMenuItem *) &ruler_items.back(); if (ruler_shown[ruler_metric_frames]) { mitem->set_active(true); @@ -414,9 +448,17 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t) mitem->set_active(true); } - ruler_items.push_back (CheckMenuElem (_("Range Markers"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_range_marker))); + if (!Profile->get_sae()) { + ruler_items.push_back (CheckMenuElem (_("Range Markers"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_range_marker))); + mitem = (CheckMenuItem *) &ruler_items.back(); + if (ruler_shown[ruler_time_range_marker]) { + mitem->set_active(true); + } + } + + ruler_items.push_back (CheckMenuElem (_("CD Markers"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_cd_marker))); mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_time_range_marker]) { + if (ruler_shown[ruler_time_cd_marker]) { mitem->set_active(true); } @@ -468,6 +510,7 @@ Editor::store_ruler_visibility () node->add_property (X_("marker"), ruler_shown[ruler_time_marker] ? "yes": "no"); node->add_property (X_("rangemarker"), ruler_shown[ruler_time_range_marker] ? "yes": "no"); node->add_property (X_("transportmarker"), ruler_shown[ruler_time_transport_marker] ? "yes": "no"); + node->add_property (X_("cdmarker"), ruler_shown[ruler_time_cd_marker] ? "yes": "no"); session->add_extra_xml (*node); session->set_dirty (); @@ -528,6 +571,7 @@ Editor::restore_ruler_visibility () else ruler_shown[ruler_time_range_marker] = false; } + if ((prop = node->property ("transportmarker")) != 0) { if (prop->value() == "yes") ruler_shown[ruler_time_transport_marker] = true; @@ -535,6 +579,29 @@ Editor::restore_ruler_visibility () ruler_shown[ruler_time_transport_marker] = false; } + if ((prop = node->property ("cdmarker")) != 0) { + if (prop->value() == "yes") + ruler_shown[ruler_time_cd_marker] = true; + else + ruler_shown[ruler_time_cd_marker] = false; + + cerr << "cd marker ruler set to " << ruler_shown[ruler_time_cd_marker] << endl; + + } else { + // this session doesn't yet know about the cdmarker ruler + // as a benefit to the user who doesn't know the feature exists, show the ruler if + // any cd marks exist + ruler_shown[ruler_time_cd_marker] = false; + const Locations::LocationList & locs = session->locations()->list(); + for (Locations::LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) { + if ((*i)->is_cd_marker()) { + ruler_shown[ruler_time_cd_marker] = true; + break; + } + } + cerr << "cd marker ruler default to " << ruler_shown[ruler_time_cd_marker] << endl; + } + } update_ruler_visibility (); @@ -583,11 +650,10 @@ Editor::update_ruler_visibility () minsec_ruler->set_size_request (-1, (int)timebar_height); gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_minsec_ruler), &ruler_metrics[ruler_metric_minsec]); - - smpte_ruler->set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - bbt_ruler->set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - frames_ruler->set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - minsec_ruler->set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); + smpte_ruler->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK); + bbt_ruler->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK); + frames_ruler->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK); + minsec_ruler->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK); smpte_ruler->signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_button_release)); bbt_ruler->signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_button_release)); @@ -606,6 +672,13 @@ Editor::update_ruler_visibility () ruler_children.insert (canvaspos, Element(*_ruler_separator, PACK_SHRINK, PACK_START)); + smpte_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll)); + bbt_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll)); + frames_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll)); + minsec_ruler->signal_scroll_event().connect (mem_fun(*this, &Editor::ruler_scroll)); + + ruler_children.insert (canvaspos, Element(*_ruler_separator, PACK_SHRINK, PACK_START)); + if (ruler_shown[ruler_metric_minsec]) { lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*minsec_ruler, PACK_SHRINK, PACK_START)); @@ -662,7 +735,7 @@ Editor::update_ruler_visibility () tempo_group->hide(); } - if (ruler_shown[ruler_time_range_marker]) { + if (!Profile->get_sae() && ruler_shown[ruler_time_range_marker]) { lab_children.push_back (Element(range_mark_label, PACK_SHRINK, PACK_START)); old_unit_pos = range_marker_group->property_y(); if (tbpos != old_unit_pos) { @@ -671,8 +744,7 @@ Editor::update_ruler_visibility () range_marker_group->show(); tbpos += timebar_height; visible_timebars++; - } - else { + } else { range_marker_group->hide(); } @@ -689,6 +761,24 @@ Editor::update_ruler_visibility () else { transport_marker_group->hide(); } + + if (ruler_shown[ruler_time_cd_marker]) { + lab_children.push_back (Element(cd_mark_label, PACK_SHRINK, PACK_START)); + old_unit_pos = cd_marker_group->property_y(); + if (tbpos != old_unit_pos) { + cd_marker_group->move (0.0, tbpos - old_unit_pos); + } + cd_marker_group->show(); + tbpos += timebar_height; + visible_timebars++; + // make sure all cd markers show up in their respective places + update_cd_marker_display(); + } + else { + cd_marker_group->hide(); + // make sure all cd markers show up in their respective places + update_cd_marker_display(); + } if (ruler_shown[ruler_time_marker]) { lab_children.push_back (Element(mark_label, PACK_SHRINK, PACK_START)); diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 554f5c341d..5fcdb8ef32 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -17,6 +17,9 @@ */ +#include <algorithm> +#include <stdlib.h> + #include <pbd/stacktrace.h> #include <ardour/diskstream.h> @@ -160,36 +163,47 @@ Editor::select_all_tracks () selection->set (track_views); } -bool +void +Editor::set_selected_track_as_side_effect (bool force) +{ + if (!clicked_routeview) { + return; + } + + if (!selection->tracks.empty()) { + if (!selection->selected (clicked_routeview)) { + selection->add (clicked_routeview); + } + + } else if (force) { + selection->set (clicked_routeview); + } +} + +void Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no_remove) { - bool commit = false; switch (op) { case Selection::Toggle: if (selection->selected (&view)) { if (!no_remove) { selection->remove (&view); - commit = true; } } else { selection->add (&view); - commit = false; } break; case Selection::Add: if (!selection->selected (&view)) { selection->add (&view); - commit = true; } break; case Selection::Set: - if (selection->selected (&view) && selection->tracks.size() == 1) { - /* no commit necessary */ - } else { - + if (selection->selected (&view) && selection->tracks.size() > 1) { + /* reset track selection if there is only 1 other track selected OR if no_remove is not set (its there to prevent deselecting a multi-track selection @@ -199,34 +213,30 @@ Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no if (selection->tracks.empty()) { selection->set (&view); - commit = true; } else if (selection->tracks.size() == 1 || !no_remove) { selection->set (&view); - commit = true; } } break; case Selection::Extend: - commit = extend_selection_to_track (view); + extend_selection_to_track (view); break; } - - return commit; } -bool +void Editor::set_selected_track_from_click (bool press, Selection::Operation op, bool no_remove) { if (!clicked_routeview) { - return false; + return; } if (!press) { - return false; + return; } - return set_selected_track (*clicked_routeview, op, no_remove); + set_selected_track (*clicked_routeview, op, no_remove); } bool @@ -386,7 +396,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, switch (op) { case Selection::Toggle: - if (clicked_regionview->get_selected()) { + if (selection->selected (clicked_regionview)) { if (press) { /* whatever was clicked was selected already; do nothing here but allow @@ -436,7 +446,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, break; case Selection::Set: - if (!clicked_regionview->get_selected()) { + if (!selection->selected (clicked_regionview)) { selection->set (clicked_regionview); commit = true; } else { @@ -455,6 +465,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, list<Selectable*> results; nframes_t last_frame; nframes_t first_frame; + bool same_track = false; /* 1. find the last selected regionview in the track that was clicked in */ @@ -471,63 +482,183 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, if ((*x)->region()->first_frame() < first_frame) { first_frame = (*x)->region()->first_frame(); } + + same_track = true; } } - /* 2. figure out the boundaries for our search for new objects */ + if (same_track) { - switch (clicked_regionview->region()->coverage (first_frame, last_frame)) { - case OverlapNone: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); - } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); + /* 2. figure out the boundaries for our search for new objects */ + + switch (clicked_regionview->region()->coverage (first_frame, last_frame)) { + case OverlapNone: + if (last_frame < clicked_regionview->region()->first_frame()) { + first_frame = last_frame; + last_frame = clicked_regionview->region()->last_frame(); + } else { + last_frame = first_frame; + first_frame = clicked_regionview->region()->first_frame(); + } + break; + + case OverlapExternal: + if (last_frame < clicked_regionview->region()->first_frame()) { + first_frame = last_frame; + last_frame = clicked_regionview->region()->last_frame(); + } else { + last_frame = first_frame; + first_frame = clicked_regionview->region()->first_frame(); + } + break; + + case OverlapInternal: + if (last_frame < clicked_regionview->region()->first_frame()) { + first_frame = last_frame; + last_frame = clicked_regionview->region()->last_frame(); + } else { + last_frame = first_frame; + first_frame = clicked_regionview->region()->first_frame(); + } + break; + + case OverlapStart: + case OverlapEnd: + /* nothing to do except add clicked region to selection, since it + overlaps with the existing selection in this track. + */ + break; } - break; - case OverlapExternal: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); - } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); - } - break; + } else { - case OverlapInternal: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); - } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); + /* click in a track that has no regions selected, so extend vertically + to pick out all regions that are defined by the existing selection + plus this one. + */ + + + first_frame = entered_regionview->region()->position(); + last_frame = entered_regionview->region()->last_frame(); + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + if ((*i)->region()->position() < first_frame) { + first_frame = (*i)->region()->position(); + } + if ((*i)->region()->last_frame() + 1 > last_frame) { + last_frame = (*i)->region()->last_frame(); + } } - break; + } + + /* 2. find all the tracks we should select in */ + + set<RouteTimeAxisView*> relevant_tracks; + set<RouteTimeAxisView*> already_in_selection; + + get_relevant_tracks (relevant_tracks); + + if (relevant_tracks.empty()) { - case OverlapStart: - case OverlapEnd: - /* nothing to do except add clicked region to selection, since it - overlaps with the existing selection in this track. + /* no relevant tracks -> no tracks selected .. thus .. if + the regionview we're in isn't selected (i.e. we're + about to extend to it), then find all tracks between + the this one and any selected ones. */ - break; + + if (!selection->selected (entered_regionview)) { + + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (&entered_regionview->get_time_axis_view()); + + if (rtv) { + + /* add this track to the ones we will search */ + + relevant_tracks.insert (rtv); + + /* find the track closest to this one that + already a selected region. + */ + + RouteTimeAxisView* closest = 0; + int distance = INT_MAX; + int key = rtv->route()->order_key ("editor"); + + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + + RouteTimeAxisView* artv = dynamic_cast<RouteTimeAxisView*>(&(*x)->get_time_axis_view()); + + if (artv && artv != rtv) { + + pair<set<RouteTimeAxisView*>::iterator,bool> result; + + result = already_in_selection.insert (artv); + + if (result.second) { + /* newly added to already_in_selection */ + + + int d = artv->route()->order_key ("editor"); + + d -= key; + + if (abs (d) < distance) { + distance = abs (d); + closest = artv; + } + } + } + } + + if (closest) { + + /* now add all tracks between that one and this one */ + + int okey = closest->route()->order_key ("editor"); + + if (okey > key) { + swap (okey, key); + } + + for (TrackViewList::iterator x = track_views.begin(); x != track_views.end(); ++x) { + RouteTimeAxisView* artv = dynamic_cast<RouteTimeAxisView*>(*x); + if (artv && artv != rtv) { + + int k = artv->route()->order_key ("editor"); + + if (k >= okey && k <= key) { + + /* in range but don't add it if + it already has tracks selected. + this avoids odd selection + behaviour that feels wrong. + */ + + if (find (already_in_selection.begin(), + already_in_selection.end(), + artv) == already_in_selection.end()) { + + relevant_tracks.insert (artv); + } + } + } + } + } + } + } } - /* 2. find all selectable objects (regionviews in this case) between that one and the end of the - one that was clicked. + /* 3. find all selectable objects (regionviews in this case) between that one and the end of the + one that was clicked. */ - set<RouteTimeAxisView*> relevant_tracks; - get_relevant_tracks (relevant_tracks); for (set<RouteTimeAxisView*>::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) { (*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results); } - /* 3. convert to a vector of audio regions */ + /* 4. convert to a vector of regions */ vector<RegionView*> regions; @@ -549,40 +680,18 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, return commit; } + void Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> region, Selection::Operation op) { vector<RegionView*> all_equivalent_regions; - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - - RouteTimeAxisView* tatv; - - if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) { - - boost::shared_ptr<Playlist> pl; - vector<boost::shared_ptr<Region> > results; - RegionView* marv; - boost::shared_ptr<Diskstream> ds; - - if ((ds = tatv->get_diskstream()) == 0) { - /* bus */ - continue; - } - - if ((pl = (ds->playlist())) != 0) { - pl->get_region_list_equivalent_regions (region, results); - } - - for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) { - if ((marv = tatv->view()->find_view (*ir)) != 0) { - all_equivalent_regions.push_back (marv); - } - } - - } + get_regions_corresponding_to (region, all_equivalent_regions); + + if (all_equivalent_regions.empty()) { + return; } - + begin_reversible_command (_("set selected regions")); switch (op) { @@ -655,6 +764,8 @@ Editor::region_selection_changed () for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { (*i)->set_selected_regionviews (selection->regions); } + + zoomed_to_region = false; } void @@ -1031,7 +1142,7 @@ Editor::select_range_between () } set_mouse_mode (MouseRange); - selection->set (0, start, end); + selection->set ((TimeAxisView*) 0, start, end); } bool @@ -1077,10 +1188,36 @@ Editor::get_edit_op_range (nframes64_t& start, nframes64_t& end) const break; case EditAtMouse: + /* use mouse + selected marker */ + if (selection->markers.empty()) { + start = m; + end = session->audible_frame(); + } else { + start = selection->markers.front()->position(); + end = m; + } + break; + case EditAtSelectedMarker: /* use mouse + selected marker */ if (selection->markers.empty()) { - return false; + + MessageDialog win (_("No edit range defined"), + false, + MESSAGE_INFO, + BUTTONS_OK); + + win.set_secondary_text ( + _("the edit point is Selected Marker\nbut there is no selected marker.")); + + + win.set_default_response (RESPONSE_CLOSE); + win.set_position (Gtk::WIN_POS_MOUSE); + win.show_all(); + + win.run (); + + return false; // NO RANGE } start = selection->markers.front()->position(); end = m; @@ -1098,3 +1235,9 @@ Editor::get_edit_op_range (nframes64_t& start, nframes64_t& end) const return true; } + +void +Editor::deselect_all () +{ + selection->clear (); +} diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 831fe3b727..f18392ce38 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -235,13 +235,14 @@ Editor::mouse_add_new_tempo_event (nframes_t frame) BBT_Time requested; bpm = tempo_dialog.get_bpm (); + double nt = tempo_dialog.get_note_type(); bpm = max (0.01, bpm); tempo_dialog.get_bbt_time (requested); begin_reversible_command (_("add tempo mark")); XMLNode &before = map.get_state(); - map.add_tempo (Tempo (bpm), requested); + map.add_tempo (Tempo (bpm,nt), requested); XMLNode &after = map.get_state(); session->add_command(new MementoCommand<TempoMap>(map, &before, &after)); commit_reversible_command (); @@ -356,13 +357,14 @@ Editor::edit_tempo_section (TempoSection* section) } double bpm = tempo_dialog.get_bpm (); + double nt = tempo_dialog.get_note_type (); BBT_Time when; tempo_dialog.get_bbt_time(when); bpm = max (0.01, bpm); begin_reversible_command (_("replace tempo mark")); XMLNode &before = session->tempo_map().get_state(); - session->tempo_map().replace_tempo (*section, Tempo (bpm)); + session->tempo_map().replace_tempo (*section, Tempo (bpm,nt)); session->tempo_map().move_tempo (*section, when); XMLNode &after = session->tempo_map().get_state(); session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), &before, &after)); diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc index df0a73c965..015a265a9b 100644 --- a/gtk2_ardour/editor_timefx.cc +++ b/gtk2_ardour/editor_timefx.cc @@ -40,6 +40,7 @@ #include <ardour/audioregion.h> #include <ardour/audio_diskstream.h> #include <ardour/stretch.h> +#include <ardour/pitch.h> #include "i18n.h" @@ -49,50 +50,88 @@ using namespace sigc; using namespace Gtk; using namespace Gtkmm2ext; -Editor::TimeStretchDialog::TimeStretchDialog (Editor& e) - : ArdourDialog ("time stretch dialog"), +Editor::TimeFXDialog::TimeFXDialog (Editor& e, bool pitch) + : ArdourDialog (X_("time fx dialog")), editor (e), + pitching (pitch), + pitch_octave_adjustment (0.0, 0.0, 4.0, 1, 2.0), + pitch_semitone_adjustment (0.0, 0.0, 12.0, 1.0, 4.0), + pitch_cent_adjustment (0.0, 0.0, 150.0, 5.0, 15.0), + pitch_octave_spinner (pitch_octave_adjustment), + pitch_semitone_spinner (pitch_semitone_adjustment), + pitch_cent_spinner (pitch_cent_adjustment), quick_button (_("Quick but Ugly")), antialias_button (_("Skip Anti-aliasing")) { set_modal (true); set_position (Gtk::WIN_POS_MOUSE); - set_name (N_("TimeStretchDialog")); + set_name (N_("TimeFXDialog")); WindowTitle title(Glib::get_application_name()); - title += _("Timestretch"); + if (pitching) { + title += _("Pitch Shift"); + } else { + title += _("Time Stretch"); + } set_title(title.get_string()); + cancel_button = add_button (_("Cancel"), Gtk::RESPONSE_CANCEL); + get_vbox()->set_spacing (5); - get_vbox()->set_border_width (5); - get_vbox()->pack_start (upper_button_box); + get_vbox()->set_border_width (12); + get_vbox()->pack_start (upper_button_box, false, false); get_vbox()->pack_start (progress_bar); - upper_button_box.set_homogeneous (true); - upper_button_box.set_spacing (5); - upper_button_box.set_border_width (5); - upper_button_box.pack_start (quick_button, true, true); - upper_button_box.pack_start (antialias_button, true, true); + if (pitching) { - action_button = add_button (_("Stretch/Shrink it"), Gtk::RESPONSE_ACCEPT); - cancel_button = add_button (_("Cancel"), Gtk::RESPONSE_CANCEL); + upper_button_box.set_spacing (5); + upper_button_box.set_border_width (5); + + Gtk::Label* l; + + l = manage (new Label (_("Octaves"))); + upper_button_box.pack_start (*l, false, false); + upper_button_box.pack_start (pitch_octave_spinner, false, false); - quick_button.set_name (N_("TimeStretchButton")); - antialias_button.set_name (N_("TimeStretchButton")); - progress_bar.set_name (N_("TimeStretchProgress")); + l = manage (new Label (_("Semitones (12TET)"))); + upper_button_box.pack_start (*l, false, false); + upper_button_box.pack_start (pitch_semitone_spinner, false, false); + + l = manage (new Label (_("Cents"))); + upper_button_box.pack_start (*l, false, false); + upper_button_box.pack_start (pitch_cent_spinner, false, false); + + pitch_cent_spinner.set_digits (1); + + add_button (_("Shift"), Gtk::RESPONSE_ACCEPT); + + } else { + + upper_button_box.set_homogeneous (true); + upper_button_box.set_spacing (5); + upper_button_box.set_border_width (5); + upper_button_box.pack_start (quick_button, true, true); + upper_button_box.pack_start (antialias_button, true, true); + + add_button (_("Stretch/Shrink"), Gtk::RESPONSE_ACCEPT); + } + + quick_button.set_name (N_("TimeFXButton")); + antialias_button.set_name (N_("TimeFXButton")); + progress_bar.set_name (N_("TimeFXProgress")); show_all_children (); } gint -Editor::TimeStretchDialog::update_progress () +Editor::TimeFXDialog::update_progress () { progress_bar.set_fraction (request.progress); return !request.done; } void -Editor::TimeStretchDialog::cancel_timestretch_in_progress () +Editor::TimeFXDialog::cancel_in_progress () { status = -2; request.cancel = true; @@ -100,7 +139,7 @@ Editor::TimeStretchDialog::cancel_timestretch_in_progress () } gint -Editor::TimeStretchDialog::delete_timestretch_in_progress (GdkEventAny* ev) +Editor::TimeFXDialog::delete_in_progress (GdkEventAny* ev) { status = -2; request.cancel = true; @@ -109,72 +148,121 @@ Editor::TimeStretchDialog::delete_timestretch_in_progress (GdkEventAny* ev) } int -Editor::run_timestretch (RegionSelection& regions, float fraction) +Editor::time_stretch (RegionSelection& regions, float fraction) +{ + return time_fx (regions, fraction, false); +} + +int +Editor::pitch_shift (RegionSelection& regions, float fraction) { - if (current_timestretch == 0) { - current_timestretch = new TimeStretchDialog (*this); + return time_fx (regions, fraction, true); +} + +int +Editor::time_fx (RegionSelection& regions, float val, bool pitching) +{ + if (current_timefx != 0) { + delete current_timefx; } - current_timestretch->progress_bar.set_fraction (0.0f); + current_timefx = new TimeFXDialog (*this, pitching); + + current_timefx->progress_bar.set_fraction (0.0f); - switch (current_timestretch->run ()) { + switch (current_timefx->run ()) { case RESPONSE_ACCEPT: break; default: - current_timestretch->hide (); + current_timefx->hide (); return 1; } - current_timestretch->status = 0; - current_timestretch->regions = regions; - current_timestretch->request.fraction = fraction; - current_timestretch->request.quick_seek = current_timestretch->quick_button.get_active(); - current_timestretch->request.antialias = !current_timestretch->antialias_button.get_active(); - current_timestretch->request.progress = 0.0f; - current_timestretch->request.done = false; - current_timestretch->request.cancel = false; + current_timefx->status = 0; + current_timefx->regions = regions; + + if (pitching) { + + float cents = current_timefx->pitch_octave_adjustment.get_value() * 1200.0; + cents += current_timefx->pitch_semitone_adjustment.get_value() * 100.0; + cents += current_timefx->pitch_cent_adjustment.get_value(); + + if (cents == 0.0) { + // user didn't change anything + current_timefx->hide (); + return 0; + } + + // we now have the pitch shift in cents. divide by 1200 to get octaves + // then multiply by 2.0 because 1 octave == doubling the frequency + + cents /= 1200.0; + cents /= 2.0; + + // add 1.0 to convert to RB scale + + cents += 1.0; + + current_timefx->request.time_fraction = 1.0; + current_timefx->request.pitch_fraction = cents; + + } else { + + current_timefx->request.time_fraction = val; + current_timefx->request.pitch_fraction = 1.0; + + } + + current_timefx->request.quick_seek = current_timefx->quick_button.get_active(); + current_timefx->request.antialias = !current_timefx->antialias_button.get_active(); + current_timefx->request.progress = 0.0f; + current_timefx->request.done = false; + current_timefx->request.cancel = false; /* re-connect the cancel button and delete events */ - current_timestretch->first_cancel.disconnect(); - current_timestretch->first_delete.disconnect(); + current_timefx->first_cancel.disconnect(); + current_timefx->first_delete.disconnect(); - current_timestretch->first_cancel = current_timestretch->cancel_button->signal_clicked().connect - (mem_fun (current_timestretch, &TimeStretchDialog::cancel_timestretch_in_progress)); - current_timestretch->first_delete = current_timestretch->signal_delete_event().connect - (mem_fun (current_timestretch, &TimeStretchDialog::delete_timestretch_in_progress)); - - if (pthread_create_and_store ("timestretch", ¤t_timestretch->request.thread, 0, timestretch_thread, current_timestretch)) { - current_timestretch->hide (); - error << _("timestretch cannot be started - thread creation error") << endmsg; + current_timefx->first_cancel = current_timefx->cancel_button->signal_clicked().connect + (mem_fun (current_timefx, &TimeFXDialog::cancel_in_progress)); + current_timefx->first_delete = current_timefx->signal_delete_event().connect + (mem_fun (current_timefx, &TimeFXDialog::delete_in_progress)); + + if (pthread_create_and_store ("timefx", ¤t_timefx->request.thread, 0, timefx_thread, current_timefx)) { + current_timefx->hide (); + error << _("timefx cannot be started - thread creation error") << endmsg; return -1; } - pthread_detach (current_timestretch->request.thread); + pthread_detach (current_timefx->request.thread); - sigc::connection c = Glib::signal_timeout().connect (mem_fun (current_timestretch, &TimeStretchDialog::update_progress), 100); + sigc::connection c = Glib::signal_timeout().connect (mem_fun (current_timefx, &TimeFXDialog::update_progress), 100); - while (!current_timestretch->request.done) { + while (!current_timefx->request.done) { gtk_main_iteration (); } c.disconnect (); - current_timestretch->hide (); - return current_timestretch->status; + current_timefx->hide (); + return current_timefx->status; } void -Editor::do_timestretch (TimeStretchDialog& dialog) +Editor::do_timefx (TimeFXDialog& dialog) { Track* t; boost::shared_ptr<Playlist> playlist; boost::shared_ptr<Region> new_region; - + bool in_command = false; + for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) { AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i); - if (!arv) + + if (!arv) { continue; + } boost::shared_ptr<AudioRegion> region (arv->audio_region()); TimeAxisView* tv = &(arv->get_time_axis_view()); @@ -205,16 +293,28 @@ Editor::do_timestretch (TimeStretchDialog& dialog) return; } - Stretch stretch (*session, dialog.request); + Filter* fx; - if (stretch.run (region)) { + if (dialog.pitching) { + fx = new Pitch (*session, dialog.request); + } else { + fx = new Stretch (*session, dialog.request); + } + + if (fx->run (region)) { dialog.status = -1; dialog.request.done = true; + delete fx; return; } - if (!stretch.results.empty()) { - new_region = stretch.results.front(); + if (!fx->results.empty()) { + new_region = fx->results.front(); + + if (!in_command) { + begin_reversible_command (dialog.pitching ? _("pitch shift") : _("time stretch")); + in_command = true; + } XMLNode &before = playlist->get_state(); playlist->replace_region (region, new_region, region->position()); @@ -223,6 +323,11 @@ Editor::do_timestretch (TimeStretchDialog& dialog) } i = tmp; + delete fx; + } + + if (in_command) { + commit_reversible_command (); } dialog.status = 0; @@ -230,15 +335,15 @@ Editor::do_timestretch (TimeStretchDialog& dialog) } void* -Editor::timestretch_thread (void *arg) +Editor::timefx_thread (void *arg) { PBD::ThreadCreated (pthread_self(), X_("TimeFX")); - TimeStretchDialog* tsd = static_cast<TimeStretchDialog*>(arg); + TimeFXDialog* tsd = static_cast<TimeFXDialog*>(arg); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); - tsd->editor.do_timestretch (*tsd); + tsd->editor.do_timefx (*tsd); return 0; } diff --git a/gtk2_ardour/evtest.cc b/gtk2_ardour/evtest.cc new file mode 100644 index 0000000000..db8d502e70 --- /dev/null +++ b/gtk2_ardour/evtest.cc @@ -0,0 +1,91 @@ +#include <gtkmm.h> +#include <iostream> + +using namespace std; + +bool +print_event (GdkEvent* event) +{ + cerr << hex; + cerr << "Event: type = " << event->type << ' '; + + switch (event->type) { + case GDK_BUTTON_PRESS: + cerr << "Button press, button = " + << event->button.button + << " state " + << event->button.state + << endl; + break; + + case GDK_BUTTON_RELEASE: + cerr << "Button release, button = " + << event->button.button + << " state " + << event->button.state + << endl; + break; + + case GDK_SCROLL: + cerr << "Scroll: direction = " + << event->scroll.direction + << " state = " + << event->scroll.state + << endl; + break; + + case GDK_KEY_PRESS: + cerr << "Key press, keycode = " + << event->key.keyval + << " name " + << gdk_keyval_name (event->key.keyval) + << " state = " + << event->key.state + << " hw keycode = " + << event->key.hardware_keycode + << " string = " + << (event->key.string ? event->key.string : "not defined") + << endl; + break; + + case GDK_KEY_RELEASE: + cerr << "Key release, keycode = " + << event->key.keyval + << " name " + << gdk_keyval_name (event->key.keyval) + << " state = " + << event->key.state + << " hw keycode = " + << event->key.hardware_keycode + << " string = " + << (event->key.string ? event->key.string : "not defined") + << endl; + break; + + default: + cerr << endl; + break; + } + cerr << dec; + + return false; +} + +int +main (int argc, char* argv[]) +{ + Gtk::Main app (&argc, &argv); + Gtk::Window window; + Gtk::EventBox eventbox; + + window.add (eventbox); + window.set_size_request (250, 250); + + eventbox.signal_event().connect (sigc::ptr_fun (print_event)); + eventbox.add_events (Gdk::SCROLL_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); + eventbox.set_flags (Gtk::CAN_FOCUS); + + eventbox.show (); + window.show (); + app.run(); +} diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc index cbaee3d6d2..97e545bddd 100644 --- a/gtk2_ardour/export_dialog.cc +++ b/gtk2_ardour/export_dialog.cc @@ -24,7 +24,6 @@ #include <fstream> #include <samplerate.h> - #include <pbd/convert.h> #include <pbd/xml++.h> @@ -40,6 +39,7 @@ #include <ardour/audiofilesource.h> #include <ardour/gdither.h> #include <ardour/utils.h> +#include <ardour/profile.h> #include "export_dialog.h" #include "ardour_ui.h" @@ -338,8 +338,12 @@ ExportDialog::ExportDialog(PublicEditor& e) format_table.set_col_spacings (5); format_table.set_row_spacings (5); - format_table.attach (channel_count_label, 0, 1, 0, 1, FILL, FILL); - format_table.attach (channel_count_combo, 1, 2, 0, 1, FILL, FILL); + int row = 0; + + format_table.attach (channel_count_label, 0, 1, row, row+1); + format_table.attach (channel_count_combo, 1, 2, row, row+1); + + row++; format_table.attach (header_format_label, 0, 1, 1, 2, FILL, FILL); format_table.attach (header_format_combo, 1, 2, 1, 2, FILL, FILL); @@ -347,21 +351,42 @@ ExportDialog::ExportDialog(PublicEditor& e) format_table.attach (bitdepth_format_label, 0, 1, 2, 3, FILL, FILL); format_table.attach (bitdepth_format_combo, 1, 2, 2, 3, FILL, FILL); - format_table.attach (endian_format_label, 0, 1, 3, 4, FILL, FILL); - format_table.attach (endian_format_combo, 1, 2, 3, 4, FILL, FILL); + format_table.attach (bitdepth_format_label, 0, 1, row, row+1); + format_table.attach (bitdepth_format_combo, 1, 2, row, row+1); + + row++; + + if (!Profile->get_sae()) { + format_table.attach (endian_format_label, 0, 1, row, row+1); + format_table.attach (endian_format_combo, 1, 2, row, row+1); + row++; + } + + format_table.attach (sample_rate_label, 0, 1, row, row+1); + format_table.attach (sample_rate_combo, 1, 2, row, row+1); + + row++; + + if (!Profile->get_sae()) { + format_table.attach (src_quality_label, 0, 1, row, row+1); + format_table.attach (src_quality_combo, 1, 2, row, row+1); + row++; + } - format_table.attach (sample_rate_label, 0, 1, 4, 5, FILL, FILL); - format_table.attach (sample_rate_combo, 1, 2, 4, 5, FILL, FILL); + format_table.attach (dither_type_label, 0, 1, row, row+1); + format_table.attach (dither_type_combo, 1, 2, row, row+1); - format_table.attach (src_quality_label, 0, 1, 5, 6, FILL, FILL); - format_table.attach (src_quality_combo, 1, 2, 5, 6, FILL, FILL); + row++; - format_table.attach (dither_type_label, 0, 1, 6, 7, FILL, FILL); - format_table.attach (dither_type_combo, 1, 2, 6, 7, FILL, FILL); + if (!Profile->get_sae()) { + format_table.attach (cue_file_label, 0, 1, row, row+1); + format_table.attach (cue_file_combo, 1, 2, row, row+1); + row++; + + format_table.attach (cuefile_only_checkbox, 0, 2, row, row+1); + } - format_table.attach (cue_file_label, 0, 1, 7, 8, FILL, FILL); - format_table.attach (cue_file_combo, 1, 2, 7, 8, FILL, FILL); - format_table.attach (cuefile_only_checkbox, 0, 2, 8, 9, FILL, FILL); + file_entry.set_name ("ExportFileDisplay"); signal_delete_event().connect (mem_fun(*this, &ExportDialog::window_closed)); @@ -651,10 +676,9 @@ ExportDialog::export_toc_file (Locations::LocationList& locations, const string& return; } - string filepath = path + ".toc"; + string filepath = path + ".toc"; ofstream out (filepath.c_str()); long unsigned int last_end_time = spec.start_frame, last_start_time = spec.start_frame; - int numtracks = 0; gchar buf[18]; if (!out) { @@ -669,102 +693,110 @@ ExportDialog::export_toc_file (Locations::LocationList& locations, const string& Locations::LocationList temp; for (i = locations.begin(); i != locations.end(); ++i) { - if ((*i)->start() >= spec.start_frame && (*i)->end() <= spec.end_frame && (*i)->is_cd_marker() && !(*i)->is_end()) { - temp.push_back (*i); - if (!(*i)->is_mark()) { - numtracks ++; - } - } + if ((*i)->start() >= spec.start_frame && (*i)->end() <= spec.end_frame && (*i)->is_cd_marker() && !(*i)->is_end()) { + temp.push_back (*i); + } } - if (numtracks == 0 ) { - /* the user supplied no track markers. - we now treat the session as one track.*/ - - out << endl << "TRACK AUDIO" << endl; - - out << "COPY" << endl; - - out << "NO PRE_EMPHASIS" << endl; - - /* XXX add session properties for catalog etc. - (so far only the session name is used) */ - - out << "CD_TEXT {" << endl << " LANGUAGE 0 {" << endl << " TITLE \"" << session->name() << "\"" << endl; - out << " }" << endl << "}" << endl; - - out << "FILE \"" << path << "\" "; - out << "00:00:00 " ; - frames_to_cd_frames_string (buf, spec.end_frame - spec.start_frame, session->frame_rate()); - out << buf << endl; - out << "START 00:00:00" << endl; - - last_start_time = spec.start_frame; - last_end_time = spec.end_frame; - } - - if (temp.size()) { + if (temp.size() > 0) { LocationSortByStart cmp; temp.sort (cmp); + Location * curr_range = 0; + Locations::LocationList::iterator nexti; for (i = temp.begin(); i != temp.end(); ++i) { - - if (!(*i)->is_mark()) { - /*this is a track */ - out << endl << "TRACK AUDIO" << endl; - - if ((*i)->cd_info.find("scms") != (*i)->cd_info.end()) { - out << "NO "; - } - out << "COPY" << endl; - if ((*i)->cd_info.find("preemph") != (*i)->cd_info.end()) { - out << "PRE_EMPHASIS" << endl; - } else { - out << "NO PRE_EMPHASIS" << endl; - } - - if ((*i)->cd_info.find("isrc") != (*i)->cd_info.end()) { - out << "ISRC \"" << (*i)->cd_info["isrc"] << "\"" << endl; - } + if ((*i)->start() >= last_end_time) + { + /* this is a track, defined by a cd range marker or a cd location marker outside of a cd range */ + out << endl << "TRACK AUDIO" << endl; + + if ((*i)->cd_info.find("scms") != (*i)->cd_info.end()) { + out << "NO "; + } + out << "COPY" << endl; + + if ((*i)->cd_info.find("preemph") != (*i)->cd_info.end()) { + out << "PRE_EMPHASIS" << endl; + } else { + out << "NO PRE_EMPHASIS" << endl; + } + + if ((*i)->cd_info.find("isrc") != (*i)->cd_info.end()) { + out << "ISRC \"" << (*i)->cd_info["isrc"] << "\"" << endl; + } + + out << "CD_TEXT {" << endl << " LANGUAGE 0 {" << endl << " TITLE \"" << (*i)->name() << "\"" << endl; + if ((*i)->cd_info.find("performer") != (*i)->cd_info.end()) { + out << " PERFORMER \"" << (*i)->cd_info["performer"] << "\"" << endl; + } + if ((*i)->cd_info.find("string_composer") != (*i)->cd_info.end()) { + out << " COMPOSER \"" << (*i)->cd_info["string_composer"] << "\"" << endl; + } + + if ((*i)->cd_info.find("isrc") != (*i)->cd_info.end()) { + out << " ISRC \""; + out << (*i)->cd_info["isrc"].substr(0,2) << "-"; + out << (*i)->cd_info["isrc"].substr(2,3) << "-"; + out << (*i)->cd_info["isrc"].substr(5,2) << "-"; + out << (*i)->cd_info["isrc"].substr(7,5) << "\"" << endl; + } + + out << " }" << endl << "}" << endl; + + frames_to_cd_frames_string (buf, last_end_time - spec.start_frame, session->frame_rate()); + out << "FILE \"" << path << "\" " << buf; + + if ((*i)->is_mark()) { + // a mark track location needs to look ahead to the next marker's start to determine length + nexti = i; + ++nexti; + if (nexti != temp.end()) { + frames_to_cd_frames_string (buf, (*nexti)->start() - last_end_time, session->frame_rate()); + out << buf << endl; + + frames_to_cd_frames_string (buf, (*i)->start() - last_end_time, session->frame_rate()); + out << "START" << buf << endl; + + last_start_time = (*i)->start(); + last_end_time = (*nexti)->start(); + } + else { + // this was the last marker, use session end + frames_to_cd_frames_string (buf, spec.end_frame - last_end_time, session->frame_rate()); + out << buf << endl; + + frames_to_cd_frames_string (buf, (*i)->start() - last_end_time, session->frame_rate()); + out << "START" << buf << endl; + + last_start_time = (*i)->start(); + last_end_time = spec.end_frame; + } - out << "CD_TEXT {" << endl << " LANGUAGE 0 {" << endl << " TITLE \"" << (*i)->name() << "\"" << endl; - if ((*i)->cd_info.find("performer") != (*i)->cd_info.end()) { - out << " PERFORMER \"" << (*i)->cd_info["performer"] << "\"" << endl; - } - if ((*i)->cd_info.find("string_composer") != (*i)->cd_info.end()) { - out << " COMPOSER \"" << (*i)->cd_info["string_composer"] << "\"" << endl; + curr_range = 0; + } + else { + // range + frames_to_cd_frames_string (buf, (*i)->end() - last_end_time, session->frame_rate()); + out << buf << endl; + + frames_to_cd_frames_string (buf, (*i)->start() - last_end_time, session->frame_rate()); + out << "START" << buf << endl; + + last_start_time = (*i)->start(); + last_end_time = (*i)->end(); + + curr_range = (*i); + } + } - - if ((*i)->cd_info.find("isrc") != (*i)->cd_info.end()) { - out << " ISRC \""; - out << (*i)->cd_info["isrc"].substr(0,2) << "-"; - out << (*i)->cd_info["isrc"].substr(2,3) << "-"; - out << (*i)->cd_info["isrc"].substr(5,2) << "-"; - out << (*i)->cd_info["isrc"].substr(7,5) << "\"" << endl; + else if ((*i)->is_mark()) + { + /* this is an index within a track */ + + frames_to_cd_frames_string (buf, (*i)->start() - last_start_time, session->frame_rate()); + out << "INDEX" << buf << endl; } - - out << " }" << endl << "}" << endl; - - frames_to_cd_frames_string (buf, last_end_time - spec.start_frame, session->frame_rate()); - out << "FILE \"" << path << "\" " << buf; - - frames_to_cd_frames_string (buf, (*i)->end() - last_end_time, session->frame_rate()); - out << buf << endl; - - frames_to_cd_frames_string (buf, (*i)->start() - last_end_time, session->frame_rate()); - out << "START" << buf << endl; - - last_start_time = (*i)->start(); - last_end_time = (*i)->end(); - - - } else if ((*i)->start() < last_end_time) { - /* this is an index within a track */ - - frames_to_cd_frames_string (buf, (*i)->start() - last_start_time, session->frame_rate()); - out << "INDEX" << buf << endl; - } } } @@ -809,7 +841,7 @@ ExportDialog::export_cue_file (Locations::LocationList& locations, const string& out << "FILE " << path << ' ' << (header_format_combo.get_active_text()) << endl; } - if (numtracks == 0) { + if (false && numtracks == 0) { /* the user has supplied no track markers. the entire export is treated as one track. */ @@ -840,58 +872,78 @@ ExportDialog::export_cue_file (Locations::LocationList& locations, const string& if (temp.size()) { LocationSortByStart cmp; temp.sort (cmp); + Location * curr_range = 0; + Locations::LocationList::iterator nexti; for ( i = temp.begin(); i != temp.end(); ++i) { - if (!(*i)->is_mark() && ((*i)->start() >= last_track_end)) { - /* this is a track and it doesn't start inside another one*/ - - tracknum++; - indexnum = 0; - out << endl << "TRACK " << tracknum << " AUDIO" << endl; - out << "FLAGS " ; - - if ((*i)->cd_info.find("scms") != (*i)->cd_info.end()) { - out << "SCMS "; - } else { - out << "DCP "; - } - - if ((*i)->cd_info.find("preemph") != (*i)->cd_info.end()) { - out << "PRE"; - } - out << endl; - - if ((*i)->cd_info.find("isrc") != (*i)->cd_info.end()) { - out << "ISRC " << (*i)->cd_info["isrc"] << endl; - - } - if ((*i)->name() != "") { - out << "TITLE \"" << (*i)->name() << "\"" << endl; - } - - if ((*i)->cd_info.find("performer") != (*i)->cd_info.end()) { - out << "PERFORMER \"" << (*i)->cd_info["performer"] << "\"" << endl; - } - - if ((*i)->cd_info.find("string_composer") != (*i)->cd_info.end()) { - out << "SONGWRITER \"" << (*i)->cd_info["string_composer"] << "\"" << endl; - } - snprintf (buf, sizeof(buf), "INDEX %02d", indexnum); - out << buf; - frames_to_cd_frames_string (buf, last_track_end - spec.start_frame, session->frame_rate()); - out << buf << endl; - indexnum++; - last_track_end = (*i)->end(); - } - if ((tracknum > 0) && ((*i)->start() < last_track_end)) { - /*this is an index and it lies within a track*/ - snprintf (buf, sizeof(buf), "INDEX %02d", indexnum); - out << buf; - frames_to_cd_frames_string (buf,(*i)->start() - spec.start_frame, session->frame_rate()); - out << buf << endl; - indexnum++; - } + if ((*i)->start() >= last_track_end) + { + /* this is a track and it doesn't start inside another one*/ + + tracknum++; + indexnum = 0; + out << endl << "TRACK " << tracknum << " AUDIO" << endl; + out << "FLAGS " ; + + if ((*i)->cd_info.find("scms") != (*i)->cd_info.end()) { + out << "SCMS "; + } else { + out << "DCP "; + } + + if ((*i)->cd_info.find("preemph") != (*i)->cd_info.end()) { + out << "PRE"; + } + out << endl; + + if ((*i)->cd_info.find("isrc") != (*i)->cd_info.end()) { + out << "ISRC " << (*i)->cd_info["isrc"] << endl; + + } + if ((*i)->name() != "") { + out << "TITLE \"" << (*i)->name() << "\"" << endl; + } + + if ((*i)->cd_info.find("performer") != (*i)->cd_info.end()) { + out << "PERFORMER \"" << (*i)->cd_info["performer"] << "\"" << endl; + } + + if ((*i)->cd_info.find("string_composer") != (*i)->cd_info.end()) { + out << "SONGWRITER \"" << (*i)->cd_info["string_composer"] << "\"" << endl; + } + snprintf (buf, sizeof(buf), "INDEX %02d", indexnum); + out << buf; + frames_to_cd_frames_string (buf, last_track_end - spec.start_frame, session->frame_rate()); + out << buf << endl; + indexnum++; + + if ((*i)->is_mark()) { + // need to find the next start to define the end + nexti = i; + ++nexti; + if (nexti != temp.end()) { + last_track_end = (*nexti)->start(); + } + else { + last_track_end = spec.end_frame; + } + curr_range = 0; + } + else { + last_track_end = (*i)->end(); + curr_range = (*i); + } + } + + if ((tracknum > 0) && ((*i)->start() < last_track_end)) { + /*this is an index and it lies within a track*/ + snprintf (buf, sizeof(buf), "INDEX %02d", indexnum); + out << buf; + frames_to_cd_frames_string (buf,(*i)->start() - spec.start_frame, session->frame_rate()); + out << buf << endl; + indexnum++; + } } } @@ -912,12 +964,24 @@ void ExportDialog::do_export () { string filepath = file_chooser.get_filename(); - + + if (!ARDOUR_UI::instance()->the_engine().connected()) { + MessageDialog msg (*this, + _("Not connected to audioengine"), + true, + MESSAGE_ERROR, + BUTTONS_OK); + msg.set_secondary_text (_("Ardour cannot export audio when disconnected")); + msg.present (); + msg.run (); + return; + } + if(!is_filepath_valid(filepath)){ return; } - if (export_cd_markers_allowed) { + if (!Profile->get_sae() && export_cd_markers_allowed) { if (cue_file_combo.get_active_text () != _("None")) { do_export_cd_markers (file_chooser.get_filename(), cue_file_combo.get_active_text ()); } @@ -1303,10 +1367,12 @@ ExportDialog::initSpec(string &filepath) spec.format = 0; spec.format |= sndfile_header_format_from_string (header_format_combo.get_active_text ()); - - if ((spec.format & SF_FORMAT_WAV) == 0) { - /* RIFF/WAV specifies endianess */ - spec.format |= sndfile_endian_format_from_string (endian_format_combo.get_active_text ()); + + if (!Profile->get_sae()) { + if ((spec.format & SF_FORMAT_WAV) == 0) { + /* RIFF/WAV specifies endianess */ + spec.format |= sndfile_endian_format_from_string (endian_format_combo.get_active_text ()); + } } spec.format |= sndfile_bitdepth_format_from_string (bitdepth_format_combo.get_active_text ()); @@ -1328,17 +1394,21 @@ ExportDialog::initSpec(string &filepath) spec.sample_rate = session->frame_rate(); } - string src_str = src_quality_combo.get_active_text(); - if (src_str == _("fastest")) { - spec.src_quality = SRC_ZERO_ORDER_HOLD; - } else if (src_str == _("linear")) { - spec.src_quality = SRC_LINEAR; - } else if (src_str == _("better")) { - spec.src_quality = SRC_SINC_FASTEST; - } else if (src_str == _("intermediate")) { - spec.src_quality = SRC_SINC_MEDIUM_QUALITY; - } else { + if (Profile->get_sae()) { spec.src_quality = SRC_SINC_BEST_QUALITY; + } else { + string src_str = src_quality_combo.get_active_text(); + if (src_str == _("fastest")) { + spec.src_quality = SRC_ZERO_ORDER_HOLD; + } else if (src_str == _("linear")) { + spec.src_quality = SRC_LINEAR; + } else if (src_str == _("better")) { + spec.src_quality = SRC_SINC_FASTEST; + } else if (src_str == _("intermediate")) { + spec.src_quality = SRC_SINC_MEDIUM_QUALITY; + } else { + spec.src_quality = SRC_SINC_BEST_QUALITY; + } } string dither_str = dither_type_combo.get_active_text(); diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index dae51935ec..a20d8b9019 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -156,12 +156,11 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s) if ((r = dynamic_cast<Route*> (_io.get())) != 0) { /* - if we have a route (ie. we're not the click), + if we have a non-hidden route (ie. we're not the click or the auditioner), pack some route-dependent stuff. */ gain_display_box.pack_end (peak_display, true, true); - hbox.pack_end (meter_packer, true, true); using namespace Menu_Helpers; @@ -218,35 +217,14 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s) ResetGroupPeakDisplays.connect (mem_fun(*this, &GainMeter::reset_group_peak_display)); UI::instance()->theme_changed.connect (mem_fun(*this, &GainMeter::on_theme_changed)); - - fader_centering_box->show(); - fader_vbox->show(); - gain_slider->show(); - - hbox.show(); - meter_packer.show(); - gain_display.show(); - peak_display.show(); - gain_display_box.show(); - fader_box.show(); - meter_metric_area.show(); - gain_automation_style_button.show(); - gain_automation_state_button.show(); - show(); + + ColorsChanged.connect (mem_fun (*this, &GainMeter::color_handler)); + //hide_all(); } void GainMeter::set_width (Width w, int len) { - switch (w) { - case Wide: - peak_display.show(); - break; - case Narrow: - peak_display.hide(); - break; - } - _width = w; setup_meters (len); } @@ -478,15 +456,21 @@ GainMeter::setup_meters (int len) /* pack them backwards */ - if (_width == Wide) { - meter_packer.pack_end (meter_metric_area, false, false); - meter_metric_area.show_all (); - } + meter_packer.pack_end (meter_metric_area, false, false); + meter_metric_area.show_all (); + + int b = ARDOUR_UI::config()->canvasvar_MeterColorBase.get(); + int m = ARDOUR_UI::config()->canvasvar_MeterColorMid.get(); + int t = ARDOUR_UI::config()->canvasvar_MeterColorTop.get(); + int c = ARDOUR_UI::config()->canvasvar_MeterColorClip.get(); + + //cerr << "GainMeter::setup_meters() called color_changed = " << color_changed << " colors: " << hex << b << " " << m << " " << t << " " << c << endl;//DEBUG for (int32_t n = nmeters-1; nmeters && n >= 0 ; --n) { - if (meters[n].width != width || meters[n].length != len) { + if (meters[n].width != width || meters[n].length != len || color_changed) { delete meters[n].meter; - meters[n].meter = new FastMeter ((uint32_t) floor (Config->get_meter_hold()), width, FastMeter::Vertical, len); + meters[n].meter = new FastMeter ((uint32_t) floor (Config->get_meter_hold()), width, FastMeter::Vertical, len, b, m, t, c); + //cerr << "GainMeter::setup_meters() w:l = " << width << ":" << len << endl;//DEBUG meters[n].width = width; meters[n].length = len; meters[n].meter->add_events (Gdk::BUTTON_RELEASE_MASK); @@ -497,6 +481,7 @@ GainMeter::setup_meters (int len) meters[n].meter->show_all (); meters[n].packed = true; } + color_changed = false; } int @@ -522,9 +507,9 @@ GainMeter::peak_button_release (GdkEventButton* ev) { /* reset peak label */ - if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control|Keyboard::Shift)) { + if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) { ResetAllPeakDisplays (); - } else if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + } else if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { Route* r; if ((r = dynamic_cast<Route*> (_io.get())) != 0) { ResetGroupPeakDisplays (r->mix_group()); @@ -733,10 +718,10 @@ GainMeter::meter_press(GdkEventButton* ev) if (ev->button == 2) { - // ctrl-button2 click is the midi binding click + // Primary-button2 click is the midi binding click // button2-click is "momentary" - if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control))) { + if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) { wait_for_release = true; old_meter_point = _route->meter_point (); } @@ -744,9 +729,9 @@ GainMeter::meter_press(GdkEventButton* ev) if (ev->button == 1 || ev->button == 2) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { - /* ctrl-shift-click applies change to all routes */ + /* Primary+Tertiary-click applies change to all routes */ _session.begin_reversible_command (_("meter point change")); Session::GlobalMeteringStateCommand *cmd = new Session::GlobalMeteringStateCommand (_session, this); @@ -756,10 +741,10 @@ GainMeter::meter_press(GdkEventButton* ev) _session.commit_reversible_command (); - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - /* ctrl-click: solo mix group. - ctrl-button2 is MIDI learn. + /* Primary-click: solo mix group. + NOTE: Primary-button2 is MIDI learn. */ if (ev->button == 1) { @@ -985,3 +970,32 @@ GainMeter::gain_automation_state_changed () gain_watching = ARDOUR_UI::RapidScreenUpdate.connect (mem_fun (*this, &GainMeter::effective_gain_display)); } } + +void GainMeter::setup_atv_meter (int len) +{ + set_no_show_all(); + regular_meter_width = 3; + set_width(Narrow, len); + hide_all(); + + //cerr << "Config->get_show_track_meters() = " << Config->get_show_track_meters() << endl;//DEBUG + + if (Config->get_show_track_meters()) { + meter_packer.show_all(); + hbox.show(); + show(); + } +} + +void GainMeter::clear_meters () +{ + for (vector<MeterInfo>::iterator i = meters.begin(); i < meters.end(); i++) { + (*i).meter->clear(); + } +} + +void GainMeter::color_handler() +{ + color_changed = true; + setup_meters(); +} diff --git a/gtk2_ardour/gain_meter.h b/gtk2_ardour/gain_meter.h index 969757313c..669ed50906 100644 --- a/gtk2_ardour/gain_meter.h +++ b/gtk2_ardour/gain_meter.h @@ -75,6 +75,9 @@ class GainMeter : public Gtk::VBox void set_meter_strip_name (const char * name); void set_fader_name (const char * name); + void setup_atv_meter (int); + void clear_meters (); + private: friend class MixerStrip; @@ -129,9 +132,9 @@ class GainMeter : public Gtk::VBox struct MeterInfo { Gtkmm2ext::FastMeter *meter; - gint16 width; - int length; - bool packed; + gint16 width; + int length; + bool packed; MeterInfo() { meter = 0; @@ -191,6 +194,8 @@ class GainMeter : public Gtk::VBox void on_theme_changed (); bool style_changed; + bool color_changed; + void color_handler(); }; #endif /* __ardour_gtk_gain_meter_h__ */ diff --git a/gtk2_ardour/ladspa_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index b5d78387a3..7ae3f45dfb 100644 --- a/gtk2_ardour/ladspa_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -57,8 +57,8 @@ using namespace Gtkmm2ext; using namespace Gtk; using namespace sigc; -LadspaPluginUI::LadspaPluginUI (boost::shared_ptr<PluginInsert> pi, nframes64_t sample_rate, nframes64_t period_size, bool scrollable) - : PlugUIBase (pi, sample_rate, period_size), +GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrollable) + : PlugUIBase (pi), button_table (initial_button_rows, initial_button_cols), output_table (initial_output_rows, initial_output_cols), hAdjustment(0.0, 0.0, 0.0), @@ -108,14 +108,14 @@ LadspaPluginUI::LadspaPluginUI (boost::shared_ptr<PluginInsert> pi, nframes64_t pack_start (hpacker, false, false); } - pi->ActiveChanged.connect (bind(mem_fun(*this, &LadspaPluginUI::processor_active_changed), + pi->ActiveChanged.connect (bind(mem_fun(*this, &GenericPluginUI::processor_active_changed), boost::weak_ptr<Processor>(pi))); bypass_button.set_active (!pi->active()); build (); } -LadspaPluginUI::~LadspaPluginUI () +GenericPluginUI::~GenericPluginUI () { if (output_controls.size() > 0) { screen_update_connection.disconnect(); @@ -123,7 +123,7 @@ LadspaPluginUI::~LadspaPluginUI () } void -LadspaPluginUI::build () +GenericPluginUI::build () { guint32 i = 0; @@ -290,7 +290,7 @@ LadspaPluginUI::build () button_table.show_all (); } -LadspaPluginUI::ControlUI::ControlUI () +GenericPluginUI::ControlUI::ControlUI () : automate_button (X_("")) // force creation of a label { automate_button.set_name ("PluginAutomateButton"); @@ -310,7 +310,7 @@ LadspaPluginUI::ControlUI::ControlUI () meterinfo = 0; } -LadspaPluginUI::ControlUI::~ControlUI() +GenericPluginUI::ControlUI::~ControlUI() { if (meterinfo) { delete meterinfo->meter; @@ -319,7 +319,7 @@ LadspaPluginUI::ControlUI::~ControlUI() } void -LadspaPluginUI::automation_state_changed (ControlUI* cui) +GenericPluginUI::automation_state_changed (ControlUI* cui) { /* update button label */ @@ -352,13 +352,13 @@ static void integer_printer (char buf[32], Adjustment &adj, void *arg) } void -LadspaPluginUI::print_parameter (char *buf, uint32_t len, uint32_t param) +GenericPluginUI::print_parameter (char *buf, uint32_t len, uint32_t param) { plugin->print_parameter (param, buf, len); } -LadspaPluginUI::ControlUI* -LadspaPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<AutomationControl> mcontrol) +GenericPluginUI::ControlUI* +GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<AutomationControl> mcontrol) { ControlUI* control_ui = NULL; if (!mcontrol) @@ -387,15 +387,17 @@ LadspaPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automati if ((lp = boost::dynamic_pointer_cast<LadspaPlugin>(plugin)) != 0) { - lrdf_defaults* defaults = lrdf_get_scale_values(lp->unique_id(), port_index); + // FIXME: not all plugins have a numeric unique ID + uint32_t id = atol (lp->unique_id().c_str()); + lrdf_defaults* defaults = lrdf_get_scale_values(id, port_index); if (defaults && defaults->count > 0) { control_ui->combo = new Gtk::ComboBoxText; //control_ui->combo->set_value_in_list(true, false); set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui)); - control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &LadspaPluginUI::control_combo_changed), control_ui)); - mcontrol->Changed.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui)); + control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui)); + mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::parameter_changed), control_ui)); control_ui->pack_start(control_ui->label, true, true); control_ui->pack_start(*control_ui->combo, false, true); @@ -418,7 +420,7 @@ LadspaPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automati control_ui->pack_start (*control_ui->button, false, true); control_ui->pack_start (control_ui->automate_button, false, false); - control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &LadspaPluginUI::control_port_toggled), control_ui)); + control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &GenericPluginUI::control_port_toggled), control_ui)); if(plugin->get_parameter (port_index) == 1){ control_ui->button->set_active(true); @@ -461,15 +463,15 @@ LadspaPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automati Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->clickbox, "g9999999", 2, 2); control_ui->clickbox->set_print_func (integer_printer, 0); } else { - //sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &LadspaPluginUI::print_parameter), (uint32_t) port_index); + //sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &GenericPluginUI::print_parameter), (uint32_t) port_index); control_ui->controller->set_size_request (200, req.height); control_ui->controller->set_name (X_("PluginSlider")); control_ui->controller->set_style (BarController::LeftToRight); control_ui->controller->set_use_parent (true); - control_ui->controller->StartGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::start_touch), control_ui)); - control_ui->controller->StopGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::stop_touch), control_ui)); + control_ui->controller->StartGesture.connect (bind (mem_fun(*this, &GenericPluginUI::start_touch), control_ui)); + control_ui->controller->StopGesture.connect (bind (mem_fun(*this, &GenericPluginUI::stop_touch), control_ui)); } @@ -492,13 +494,13 @@ LadspaPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automati } control_ui->pack_start (control_ui->automate_button, false, false); - control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &LadspaPluginUI::astate_clicked), control_ui, (uint32_t) port_index)); + control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &GenericPluginUI::astate_clicked), control_ui, (uint32_t) port_index)); automation_state_changed (control_ui); - mcontrol->Changed.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui)); + mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::parameter_changed), control_ui)); mcontrol->list()->automation_state_changed.connect - (bind (mem_fun(*this, &LadspaPluginUI::automation_state_changed), control_ui)); + (bind (mem_fun(*this, &GenericPluginUI::automation_state_changed), control_ui)); } else if (plugin->parameter_is_output (port_index)) { @@ -547,25 +549,25 @@ LadspaPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automati output_controls.push_back (control_ui); } - mcontrol->Changed.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui)); + mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::parameter_changed), control_ui)); return control_ui; } void -LadspaPluginUI::start_touch (LadspaPluginUI::ControlUI* cui) +GenericPluginUI::start_touch (GenericPluginUI::ControlUI* cui) { cui->control->list()->start_touch (); } void -LadspaPluginUI::stop_touch (LadspaPluginUI::ControlUI* cui) +GenericPluginUI::stop_touch (GenericPluginUI::ControlUI* cui) { cui->control->list()->stop_touch (); } void -LadspaPluginUI::astate_clicked (ControlUI* cui, uint32_t port) +GenericPluginUI::astate_clicked (ControlUI* cui, uint32_t port) { using namespace Menu_Helpers; @@ -578,34 +580,34 @@ LadspaPluginUI::astate_clicked (ControlUI* cui, uint32_t port) items.clear (); items.push_back (MenuElem (_("Manual"), - bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Off, cui))); + bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Off, cui))); items.push_back (MenuElem (_("Play"), - bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Play, cui))); + bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Play, cui))); items.push_back (MenuElem (_("Write"), - bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Write, cui))); + bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Write, cui))); items.push_back (MenuElem (_("Touch"), - bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Touch, cui))); + bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Touch, cui))); automation_menu->popup (1, gtk_get_current_event_time()); } void -LadspaPluginUI::set_automation_state (AutoState state, ControlUI* cui) +GenericPluginUI::set_automation_state (AutoState state, ControlUI* cui) { insert->set_parameter_automation_state (cui->parameter(), state); } void -LadspaPluginUI::parameter_changed (ControlUI* cui) +GenericPluginUI::parameter_changed (ControlUI* cui) { if (!cui->update_pending) { cui->update_pending = true; - Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &LadspaPluginUI::update_control_display), cui)); + Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &GenericPluginUI::update_control_display), cui)); } } void -LadspaPluginUI::update_control_display (ControlUI* cui) +GenericPluginUI::update_control_display (ControlUI* cui) { /* XXX how do we handle logarithmic stuff here ? */ @@ -646,7 +648,7 @@ LadspaPluginUI::update_control_display (ControlUI* cui) } void -LadspaPluginUI::control_port_toggled (ControlUI* cui) +GenericPluginUI::control_port_toggled (ControlUI* cui) { if (!cui->ignore_change) { insert->set_parameter (cui->parameter(), cui->button->get_active()); @@ -654,7 +656,7 @@ LadspaPluginUI::control_port_toggled (ControlUI* cui) } void -LadspaPluginUI::control_combo_changed (ControlUI* cui) +GenericPluginUI::control_combo_changed (ControlUI* cui) { if (!cui->ignore_change) { string value = cui->combo->get_active_text(); @@ -665,9 +667,9 @@ LadspaPluginUI::control_combo_changed (ControlUI* cui) } void -LadspaPluginUI::processor_active_changed (boost::weak_ptr<Processor> weak_processor) +GenericPluginUI::processor_active_changed (boost::weak_ptr<Processor> weak_processor) { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &LadspaPluginUI::processor_active_changed), weak_processor)); + ENSURE_GUI_THREAD(bind (mem_fun(*this, &GenericPluginUI::processor_active_changed), weak_processor)); boost::shared_ptr<Processor> processor = weak_processor.lock(); @@ -675,18 +677,18 @@ LadspaPluginUI::processor_active_changed (boost::weak_ptr<Processor> weak_proces } bool -LadspaPluginUI::start_updating (GdkEventAny* ignored) +GenericPluginUI::start_updating (GdkEventAny* ignored) { if (output_controls.size() > 0 ) { screen_update_connection.disconnect(); screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect - (mem_fun(*this, &LadspaPluginUI::output_update)); + (mem_fun(*this, &GenericPluginUI::output_update)); } return false; } bool -LadspaPluginUI::stop_updating (GdkEventAny* ignored) +GenericPluginUI::stop_updating (GdkEventAny* ignored) { if (output_controls.size() > 0 ) { screen_update_connection.disconnect(); @@ -695,7 +697,7 @@ LadspaPluginUI::stop_updating (GdkEventAny* ignored) } void -LadspaPluginUI::output_update () +GenericPluginUI::output_update () { for (vector<ControlUI*>::iterator i = output_controls.begin(); i != output_controls.end(); ++i) { float val = plugin->get_parameter ((*i)->parameter().id()); @@ -729,13 +731,17 @@ LadspaPluginUI::output_update () } vector<string> -LadspaPluginUI::setup_scale_values(guint32 port_index, ControlUI* cui) +GenericPluginUI::setup_scale_values(guint32 port_index, ControlUI* cui) { vector<string> enums; boost::shared_ptr<LadspaPlugin> lp = boost::dynamic_pointer_cast<LadspaPlugin> (plugin); cui->combo_map = new std::map<string, float>; - lrdf_defaults* defaults = lrdf_get_scale_values(lp->unique_id(), port_index); + + // FIXME: not all plugins have a numeric unique ID + uint32_t id = atol (lp->unique_id().c_str()); + lrdf_defaults* defaults = lrdf_get_scale_values(id, port_index); + if (defaults) { for (uint32_t i = 0; i < defaults->count; ++i) { enums.push_back(defaults->items[i].label); diff --git a/gtk2_ardour/icons/sae.png b/gtk2_ardour/icons/sae.png Binary files differnew file mode 100644 index 0000000000..69af4950b4 --- /dev/null +++ b/gtk2_ardour/icons/sae.png diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc index e6eaffefcb..83b301d92e 100644 --- a/gtk2_ardour/keyboard.cc +++ b/gtk2_ardour/keyboard.cc @@ -43,10 +43,19 @@ guint Keyboard::delete_but = 3; guint Keyboard::delete_mod = GDK_SHIFT_MASK; guint Keyboard::snap_mod = GDK_MOD3_MASK; -uint32_t Keyboard::Control = GDK_CONTROL_MASK; -uint32_t Keyboard::Shift = GDK_SHIFT_MASK; -uint32_t Keyboard::Alt = GDK_MOD1_MASK; -uint32_t Keyboard::Meta; +#ifdef GTKOSX +guint Keyboard::PrimaryModifier = GDK_MOD1_MASK; // Command +guint Keyboard::SecondaryModifier = GDK_MOD5_MASK; // Alt/Option +guint Keyboard::TertiaryModifier = GDK_SHIFT_MASK; // Shift +guint Keyboard::CopyModifier = GDK_MOD5_MASK; // Alt/Option +guint Keyboard::RangeSelectModifier = GDK_SHIFT_MASK; +#else +guint Keyboard::PrimaryModifier = GDK_CONTROL_MASK; // Control +guint Keyboard::SecondaryModifier = GDK_MOD1_MASK; // Alt/Option +guint Keyboard::TertiaryModifier = GDK_SHIFT_MASK; // Shift +guint Keyboard::CopyModifier = GDK_CONTROL_MASK; +guint Keyboard::RangeSelectModifier = GDK_SHIFT_MASK; +#endif Keyboard* Keyboard::_the_keyboard = 0; Gtk::Window* Keyboard::current_window = 0; @@ -82,17 +91,11 @@ Keyboard::Keyboard () RelevantModifierKeyMask = (GdkModifierType) gtk_accelerator_get_default_mod_mask (); - /* figure out Meta */ - - uint32_t possible_meta[] = { GDK_MOD2_MASK, GDK_MOD3_MASK, GDK_MOD4_MASK, GDK_MOD5_MASK, 0}; - int i; - - for (i = 0; possible_meta[i]; ++i) { - if (!(RelevantModifierKeyMask & possible_meta[i])) { - break; - } - } - Meta = possible_meta[i]; + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | PrimaryModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | SecondaryModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | TertiaryModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | CopyModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | RangeSelectModifier); snooper_id = gtk_key_snooper_install (_snooper, (gpointer) this); @@ -164,6 +167,12 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) { uint32_t keyval; +#if 0 + cerr << "snoop widget " << widget << " key " << event->keyval << " type: " << event->type + << " state " << std::hex << event->state << std::dec + << endl; +#endif + #if KBD_DEBUG if (debug_keyboard) { cerr << "snoop widget " << widget << " key " << event->keyval << " type: " << event->type @@ -186,7 +195,7 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) if (find (state.begin(), state.end(), keyval) == state.end()) { state.push_back (keyval); sort (state.begin(), state.end()); - } + } } else if (event->type == GDK_KEY_RELEASE) { @@ -199,7 +208,7 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) } - if (event->type == GDK_KEY_RELEASE && event->keyval == GDK_w && modifier_state_equals (event->state, Control)) { + if (event->type == GDK_KEY_RELEASE && event->keyval == GDK_w && modifier_state_equals (event->state, PrimaryModifier)) { if (current_window) { current_window->hide (); current_window = 0; @@ -279,15 +288,11 @@ Keyboard::set_delete_modifier (guint mod) } void -Keyboard::set_meta_modifier (guint mod) +Keyboard::set_modifier (uint32_t newval, uint32_t& var) { - /* we don't include Meta in the RelevantModifierKeyMask because its not used - in the same way as snap_mod, delete_mod etc. the only reason we allow it to be - set at all is that X Window has no convention for the keyboard modifier - that Meta should use. Some Linux distributions bind NumLock to Mod2, which - is our default Meta modifier, and this causes severe problems. - */ - Meta = mod; + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~var); + var = newval; + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | var); } void @@ -346,9 +351,9 @@ Keyboard::selection_type (guint state) { /* note that there is no modifier for "Add" */ - if (modifier_state_equals (state, Shift)) { + if (modifier_state_equals (state, RangeSelectModifier)) { return Selection::Extend; - } else if (modifier_state_equals (state, Control)) { + } else if (modifier_state_equals (state, PrimaryModifier)) { return Selection::Toggle; } else { return Selection::Set; diff --git a/gtk2_ardour/keyboard.h b/gtk2_ardour/keyboard.h index fb22f2eca9..7c163245e7 100644 --- a/gtk2_ardour/keyboard.h +++ b/gtk2_ardour/keyboard.h @@ -46,10 +46,27 @@ class Keyboard : public sigc::trackable, PBD::Stateful typedef vector<uint32_t> State; typedef uint32_t ModifierMask; - static uint32_t Control; - static uint32_t Shift; - static uint32_t Alt; - static uint32_t Meta; + static uint32_t PrimaryModifier; + static uint32_t SecondaryModifier; + static uint32_t TertiaryModifier; + static uint32_t CopyModifier; + static uint32_t RangeSelectModifier; + + static void set_primary_modifier (uint32_t newval) { + set_modifier (newval, PrimaryModifier); + } + static void set_secondary_modifier (uint32_t newval) { + set_modifier (newval, SecondaryModifier); + } + static void set_tertiary_modifier (uint32_t newval) { + set_modifier (newval, TertiaryModifier); + } + static void set_copy_modifier (uint32_t newval) { + set_modifier (newval, CopyModifier); + } + static void set_range_select_modifier (uint32_t newval) { + set_modifier (newval, RangeSelectModifier); + } bool key_is_down (uint32_t keyval); @@ -69,8 +86,6 @@ class Keyboard : public sigc::trackable, PBD::Stateful static bool no_modifiers_active (guint state); - static void set_meta_modifier (guint); - static void set_snap_modifier (guint); static ModifierMask snap_modifier () { return ModifierMask (snap_mod); } @@ -110,6 +125,8 @@ class Keyboard : public sigc::trackable, PBD::Stateful static gint _snooper (GtkWidget*, GdkEventKey*, gpointer); gint snooper (GtkWidget*, GdkEventKey*); + static void set_modifier (uint32_t newval, uint32_t& variable); + static bool _some_magic_widget_has_focus; }; diff --git a/gtk2_ardour/keyeditor.cc b/gtk2_ardour/keyeditor.cc index f3ae77865d..4f378d2dbc 100644 --- a/gtk2_ardour/keyeditor.cc +++ b/gtk2_ardour/keyeditor.cc @@ -1,11 +1,14 @@ #include <map> +#include <ardour/profile.h> + #include <gtkmm/stock.h> #include <gtkmm/accelkey.h> #include <gtkmm/accelmap.h> #include <gtkmm/uimanager.h> #include <pbd/strsplit.h> +#include <pbd/replace_all.h> #include "actions.h" #include "keyboard.h" @@ -16,6 +19,7 @@ using namespace std; using namespace Gtk; using namespace Gdk; +using namespace PBD; KeyEditor::KeyEditor () : ArdourDialog (_("Keybinding Editor"), false) @@ -31,11 +35,11 @@ KeyEditor::KeyEditor () view.set_headers_visible (true); view.get_selection()->set_mode (SELECTION_SINGLE); view.set_reorderable (false); - view.set_size_request (300,200); + view.set_size_request (500,300); view.set_enable_search (false); view.set_rules_hint (true); view.set_name (X_("KeyEditorTree")); - + view.get_selection()->signal_changed().connect (mem_fun (*this, &KeyEditor::action_selected)); scroller.add (view); @@ -78,7 +82,7 @@ KeyEditor::on_key_press_event (GdkEventKey* ev) bool KeyEditor::on_key_release_event (GdkEventKey* ev) { - if (!can_bind || ev->state != last_state) { + if (ARDOUR::Profile->get_sae() || !can_bind || ev->state != last_state) { return false; } @@ -137,7 +141,7 @@ KeyEditor::populate () model->clear (); for (l = labels.begin(), k = keys.begin(), p = paths.begin(); l != labels.end(); ++k, ++p, ++l) { - + TreeModel::Row row; vector<string> parts; @@ -178,7 +182,16 @@ KeyEditor::populate () if (*k == ActionManager::unbound_string) { row[columns.binding] = string(); } else { + +#ifdef GTKOSX + string label = (*k); + replace_all (label, "<Mod5>", _("Command-")); + replace_all (label, "<Alt>", _("Option-")); + replace_all (label, "<Shift>", _("Shift-")); + row[columns.binding] = label; +#else row[columns.binding] = (*k); +#endif } } } diff --git a/gtk2_ardour/level_meter.cc b/gtk2_ardour/level_meter.cc index f4f8e8952f..cc1df9add5 100644 --- a/gtk2_ardour/level_meter.cc +++ b/gtk2_ardour/level_meter.cc @@ -25,6 +25,7 @@ #include <ardour/session.h> #include <ardour/session_route.h> #include <ardour/dB.h> +#include <ardour/meter.h> #include <gtkmm2ext/utils.h> #include <gtkmm2ext/fastmeter.h> @@ -43,7 +44,6 @@ #include <ardour/session.h> #include <ardour/route.h> -#include <ardour/meter.h> #include "i18n.h" @@ -146,12 +146,10 @@ LevelMeter::setup_meters (int len) if ((r = dynamic_cast<Route*> (_io.get())) != 0) { switch (r->meter_point()) { + case MeterPreFader: case MeterInput: nmeters = r->n_inputs().n_total(); break; - case MeterPreFader: - nmeters = r->pre_fader_streams().n_total(); - break; case MeterPostFader: nmeters = r->n_outputs().n_total(); break; diff --git a/gtk2_ardour/location_ui.cc b/gtk2_ardour/location_ui.cc index b9dea24313..6e0be908ae 100644 --- a/gtk2_ardour/location_ui.cc +++ b/gtk2_ardour/location_ui.cc @@ -678,6 +678,11 @@ LocationUI::~LocationUI() { } +void LocationUI::on_show() +{ + ArdourDialog::on_show(); + refresh_location_list(); +} gint LocationUI::do_location_remove (ARDOUR::Location *loc) @@ -856,6 +861,9 @@ LocationUI::refresh_location_list () ENSURE_GUI_THREAD(mem_fun(*this, &LocationUI::refresh_location_list)); using namespace Box_Helpers; + // this is just too expensive to do when window is not shown + if (!is_visible()) return; + BoxList & loc_children = location_rows.children(); BoxList & range_children = range_rows.children(); diff --git a/gtk2_ardour/location_ui.h b/gtk2_ardour/location_ui.h index 51daa6814d..de435b999f 100644 --- a/gtk2_ardour/location_ui.h +++ b/gtk2_ardour/location_ui.h @@ -145,6 +145,8 @@ class LocationUI : public ArdourDialog void set_session (ARDOUR::Session *); + void on_show(); + private: ARDOUR::LocationStack* locations; diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc index 32e14420ff..e9c8613224 100644 --- a/gtk2_ardour/main.cc +++ b/gtk2_ardour/main.cc @@ -23,6 +23,7 @@ #include <gtkmm/settings.h> #include <pbd/error.h> +#include <pbd/file_utils.h> #include <pbd/textreceiver.h> #include <pbd/failed_constructor.h> #include <pbd/pthread_utils.h> @@ -33,13 +34,15 @@ #include <ardour/ardour.h> #include <ardour/audioengine.h> #include <ardour/session_utils.h> +#include <ardour/filesystem_paths.h> #include <gtkmm/main.h> #include <gtkmm2ext/popup.h> #include <gtkmm2ext/utils.h> -#include "svn_revision.h" +#include "../svn_revision.h" #include "version.h" +#include "utils.h" #include "ardour_ui.h" #include "opts.h" #include "enums.h" @@ -222,6 +225,63 @@ fixup_bundle_environment () #endif +static void +setup_keybindings (ARDOUR_UI* ui) +{ + Glib::ustring path; + + if (keybindings_path.empty()) { + keybindings_path = "ardour"; + } + + std::string kbpath; + + if (keybindings_path.find (".bindings") == string::npos) { + + // just a style name - allow user to + // specify the layout type. + + char* layout; + + if ((layout = getenv ("ARDOUR_KEYBOARD_LAYOUT")) != 0) { + keybindings_path += '-'; + keybindings_path += layout; + } + + keybindings_path += ".bindings"; + } + + + // XXX timbyr - we need a portable test for "is-absolute" here + + if (keybindings_path[0] != '/' && keybindings_path[0] != '.') { + + /* not absolute - look in the usual places */ + + sys::path key_bindings_file; + + find_file_in_search_path (ardour_search_path() + system_config_search_path(), + keybindings_path, key_bindings_file); + + path = key_bindings_file.to_string(); + + if (path.empty()) { + warning << string_compose (_("Key bindings file \"%1\" not found. Default bindings used instead"), + keybindings_path) << endmsg; + } + + } else { + + // absolute path from user - use it as is + + path = keybindings_path; + } + + if (!path.empty()) { + ui->set_keybindings_path (path); + } +} + #ifdef VST_SUPPORT /* this is called from the entry point of a wine-compiled executable that is linked against gtk2_ardour built @@ -310,9 +370,7 @@ int main (int argc, char *argv[]) } } - if (!keybindings_path.empty()) { - ui->set_keybindings_path (keybindings_path); - } + setup_keybindings (ui); ui->run (text_receiver); ui = 0; diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index de2ceb554e..6e37908d1b 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -33,7 +33,7 @@ using namespace ARDOUR; Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, const string& annotation, Type type, nframes_t frame, bool handle_events) - : editor (ed), _type(type) + : editor (ed), _parent(&parent), _type(type) { double label_offset = 0; bool annotate_left = false; @@ -273,6 +273,7 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con } + Marker::~Marker () { drop_references (); @@ -288,6 +289,21 @@ Marker::~Marker () } } +void Marker::reparent(ArdourCanvas::Group & parent) +{ + group->reparent(parent); + _parent = &parent; +} + +void +Marker::set_line_length (double len) +{ + if (line) { + line_points->back().set_y (len); + line->property_points() = *line_points; + } +} + void Marker::add_line (ArdourCanvas::Group* group, double initial_height) { @@ -301,12 +317,13 @@ Marker::add_line (ArdourCanvas::Group* group, double initial_height) line->property_width_pixels() = 1; line->property_points() = *line_points; line->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EditPoint.get(); +#if 0 line->property_first_arrowhead() = TRUE; line->property_last_arrowhead() = TRUE; line->property_arrow_shape_a() = 11.0; line->property_arrow_shape_b() = 0.0; line->property_arrow_shape_c() = 9.0; - +#endif line->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_marker_event), mark, this)); } @@ -383,6 +400,7 @@ void Marker::set_color_rgba (uint32_t color) { mark->property_fill_color_rgba() = color; + mark->property_outline_color_rgba() = color; } /***********************************************************************/ diff --git a/gtk2_ardour/marker.h b/gtk2_ardour/marker.h index 5ffd6c5dd1..fa252571fb 100644 --- a/gtk2_ardour/marker.h +++ b/gtk2_ardour/marker.h @@ -60,6 +60,7 @@ class Marker : public PBD::Destructible void add_line (ArdourCanvas::Group*, double initial_height); void show_line (); void hide_line (); + void set_line_length (double); void set_position (nframes_t); void set_name (const string&); @@ -67,14 +68,18 @@ class Marker : public PBD::Destructible nframes64_t position() const { return frame_position; } + ArdourCanvas::Group * get_parent() { return _parent; } + void reparent (ArdourCanvas::Group & parent); + void hide (); void show (); Type type () { return _type; } - + protected: PublicEditor& editor; + ArdourCanvas::Group * _parent; ArdourCanvas::Group *group; ArdourCanvas::Polygon *mark; ArdourCanvas::Text *text; diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index eb3e7496bf..19b81ec4f9 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -41,6 +41,7 @@ #include <ardour/panner.h> #include <ardour/send.h> #include <ardour/processor.h> +#include <ardour/profile.h> #include <ardour/ladspa_plugin.h> #include <ardour/auto_bundle.h> #include <ardour/user_bundle.h> @@ -448,10 +449,6 @@ MixerStrip::set_width (Width w, void* owner) _width_owner = owner; - if (_width == w) { - return; - } - ensure_xml_node (); _width = w; @@ -819,12 +816,14 @@ void MixerStrip::input_changed (IOChange change, void *src) { Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &MixerStrip::update_input_display)); + set_width(_width, this); } void MixerStrip::output_changed (IOChange change, void *src) { Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &MixerStrip::update_output_display)); + set_width(_width, this); } @@ -1056,7 +1055,9 @@ MixerStrip::build_route_ops_menu () build_remote_control_menu (); items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu)); + if (!Profile->get_sae()) { + items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu)); + } items.push_back (SeparatorElem()); items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route))); @@ -1297,5 +1298,6 @@ MixerStrip::meter_changed (void *src) } gpm.setup_meters (); + set_width(_width, this); } diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index ad3927b8b6..8d349d8dc8 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -422,7 +422,7 @@ Mixer_UI::strip_button_release_event (GdkEventButton *ev, MixerStrip *strip) if (_selection.selected (strip->route())) { _selection.remove (strip->route()); } else { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { _selection.add (strip->route()); } else { _selection.set (strip->route()); diff --git a/gtk2_ardour/new_session_dialog.cc b/gtk2_ardour/new_session_dialog.cc index ebf520fba7..9ecc7ea2f5 100644 --- a/gtk2_ardour/new_session_dialog.cc +++ b/gtk2_ardour/new_session_dialog.cc @@ -344,10 +344,6 @@ NewSessionDialog::NewSessionDialog() open_session_vbox->pack_start(*open_session_hbox, Gtk::PACK_SHRINK, 12); m_notebook->set_flags(Gtk::CAN_FOCUS); m_notebook->set_scrollable(true); - m_notebook->append_page(*new_session_table, _("New Session")); - m_notebook->pages().back().set_tab_label_packing(false, true, Gtk::PACK_START); - m_notebook->append_page(*open_session_vbox, _("Open Session")); - m_notebook->pages().back().set_tab_label_packing(false, true, Gtk::PACK_START); get_vbox()->set_homogeneous(false); get_vbox()->set_spacing(0); get_vbox()->pack_start(*m_notebook, Gtk::PACK_SHRINK, 0); @@ -430,6 +426,8 @@ NewSessionDialog::NewSessionDialog() m_open_filechooser->signal_selection_changed ().connect (mem_fun (*this, &NewSessionDialog::file_chosen)); m_template->signal_selection_changed ().connect (mem_fun (*this, &NewSessionDialog::template_chosen)); m_name->grab_focus(); + + page_set = Pages (0); } NewSessionDialog::~NewSessionDialog() @@ -437,32 +435,74 @@ NewSessionDialog::~NewSessionDialog() in_destructor = true; } +int +NewSessionDialog::run () +{ + if (!page_set) { + /* nothing to display */ + return Gtk::RESPONSE_OK; + } + + return ArdourDialog::run (); +} + void NewSessionDialog::set_have_engine (bool yn) { - if (yn) { - m_notebook->remove_page (engine_control); - } else { - // XXX this is a bit of crude hack. if we ever add or remove - // pages from the notebook, this is going to break. - if (m_notebook->get_n_pages () != 3) { - m_notebook->append_page (engine_control, _("Audio Setup")); - m_notebook->show_all_children(); - } - } + if (yn) { + m_notebook->remove_page (engine_control); + page_set = Pages (page_set & ~EnginePage); + } else { + if (!(page_set & EnginePage)) { + m_notebook->append_page (engine_control, _("Audio Setup")); + m_notebook->show_all_children(); + page_set = Pages (page_set | EnginePage); + } + } } void -NewSessionDialog::set_session_name(const Glib::ustring& name) +NewSessionDialog::set_existing_session (bool yn) +{ + if (yn) { + + if (page_set & NewPage) { + m_notebook->remove_page (*new_session_table); + page_set = Pages (page_set & ~NewPage); + } + + if (page_set & OpenPage) { + m_notebook->remove_page (*open_session_vbox); + page_set = Pages (page_set & ~OpenPage); + } + + } else { + if (!(page_set & NewPage)) { + m_notebook->append_page(*new_session_table, _("New Session")); + m_notebook->pages().back().set_tab_label_packing(false, true, Gtk::PACK_START); + page_set = Pages (page_set | NewPage); + } + if (!(page_set & OpenPage)) { + m_notebook->append_page(*open_session_vbox, _("Open Session")); + m_notebook->pages().back().set_tab_label_packing(false, true, Gtk::PACK_START); + page_set = Pages (page_set | OpenPage); + } + + m_notebook->show_all_children(); + } +} + +void +NewSessionDialog::set_session_name (const Glib::ustring& name) { - m_name->set_text(name); + m_name->set_text (name); } void NewSessionDialog::set_session_folder(const Glib::ustring& dir) { - // XXX DO SOMETHING + m_folder->set_current_folder (dir); } std::string @@ -682,7 +722,8 @@ NewSessionDialog::file_chosen () m_treeview->get_selection()->unselect_all(); - get_window()->set_cursor(Gdk::Cursor(Gdk::WATCH)); + if (get_window()) + get_window()->set_cursor(Gdk::Cursor(Gdk::WATCH)); if (!m_open_filechooser->get_filename().empty()) { set_response_sensitive (Gtk::RESPONSE_OK, true); diff --git a/gtk2_ardour/new_session_dialog.h b/gtk2_ardour/new_session_dialog.h index 53ec3eabf2..0998f8a39a 100644 --- a/gtk2_ardour/new_session_dialog.h +++ b/gtk2_ardour/new_session_dialog.h @@ -57,6 +57,8 @@ public: NewSessionDialog(); ~NewSessionDialog (); + int run (); + void set_session_name(const Glib::ustring& name); void set_session_folder(const Glib::ustring& folder); @@ -95,6 +97,7 @@ public: EngineControl engine_control; void set_have_engine (bool yn); + void set_existing_session (bool yn); protected: @@ -167,6 +170,14 @@ protected: Gtk::Notebook* m_notebook; private: + enum Pages { + NewPage = 0x1, + OpenPage = 0x2, + EnginePage = 0x4 + }; + + Pages page_set; + struct RecentSessionModelColumns : public Gtk::TreeModel::ColumnRecord { RecentSessionModelColumns() { add (visible_name); diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc index e49b410668..0184e3a00a 100644 --- a/gtk2_ardour/option_editor.cc +++ b/gtk2_ardour/option_editor.cc @@ -1079,6 +1079,23 @@ static const struct { const char *name; guint modifier; } modifiers[] = { + +#ifdef GTKOSX + + /* Command = Mod1 + Option/Alt = Mod5 + */ + + { "Shift", GDK_SHIFT_MASK }, + { "Command", GDK_MOD1_MASK }, + { "Control", GDK_CONTROL_MASK }, + { "Option", GDK_MOD5_MASK }, + { "Command-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK }, + { "Command-Option", GDK_MOD1_MASK|GDK_MOD5_MASK }, + { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD5_MASK }, + { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK }, + +#else { "Shift", GDK_SHIFT_MASK }, { "Control", GDK_CONTROL_MASK }, { "Alt (Mod1)", GDK_MOD1_MASK }, @@ -1090,6 +1107,7 @@ static const struct { { "Mod3", GDK_MOD3_MASK }, { "Mod4", GDK_MOD4_MASK }, { "Mod5", GDK_MOD5_MASK }, +#endif { 0, 0 } }; diff --git a/gtk2_ardour/opts.cc b/gtk2_ardour/opts.cc index 8da0fb9ca1..00aa5cf94e 100644 --- a/gtk2_ardour/opts.cc +++ b/gtk2_ardour/opts.cc @@ -21,6 +21,8 @@ #include <iostream> #include <cstdlib> +#include <ardour/session.h> + #include "opts.h" #include "i18n.h" @@ -38,6 +40,7 @@ char* ARDOUR_COMMAND_LINE::curvetest_file = 0; bool ARDOUR_COMMAND_LINE::try_hw_optimization = true; string ARDOUR_COMMAND_LINE::keybindings_path = ""; /* empty means use builtin default */ Glib::ustring ARDOUR_COMMAND_LINE::menus_file = "ardour.menus"; +bool ARDOUR_COMMAND_LINE::finder_invoked_ardour = false; using namespace ARDOUR_COMMAND_LINE; @@ -48,8 +51,9 @@ print_help (const char *execname) << _(" -v, --version Show version information\n") << _(" -h, --help Print this message\n") << _(" -b, --bindings Print all possible keyboard binding names\n") - << _(" -n, --show-splash Show splash screen\n") << _(" -c, --name name Use a specific jack client name, default is ardour\n") + << _(" -d, --disable-plugins Disable all plugins in an existing session\n") + << _(" -n, --show-splash Show splash screen\n") << _(" -m, --menus file Use \"file\" for Ardour menus\n") << _(" -N, --new session-name Create a new session from the command line\n") << _(" -O, --no-hw-optimizations Disable h/w specific optimizations\n") @@ -69,11 +73,12 @@ int ARDOUR_COMMAND_LINE::parse_opts (int argc, char *argv[]) { - const char *optstring = "U:hSbvVnOc:C:m:N:k:"; + const char *optstring = "U:hSbvVnOdc:C:m:N:k:p:"; const char *execname = strrchr (argv[0], '/'); if (getenv ("ARDOUR_SAE")) { menus_file = "ardour-sae.menus"; + keybindings_path = "ardour-sae"; } if (execname == 0) { @@ -122,6 +127,10 @@ ARDOUR_COMMAND_LINE::parse_opts (int argc, char *argv[]) case 'b': show_key_actions = true; break; + + case 'd': + ARDOUR::Session::set_disable_all_loaded_plugins (true); + break; case 'm': @@ -131,6 +140,11 @@ ARDOUR_COMMAND_LINE::parse_opts (int argc, char *argv[]) case 'n': no_splash = false; break; + + case 'p': + //undocumented OS X finder -psn_XXXXX argument + finder_invoked_ardour = true; + break; case 'S': // ; just pass this through to gtk it will figure it out @@ -144,11 +158,6 @@ ARDOUR_COMMAND_LINE::parse_opts (int argc, char *argv[]) case 'O': try_hw_optimization = false; break; - - - case 'p': - //undocumented OS X finder -psn_XXXXX argument - break; case 'V': #ifdef VST_SUPPORT diff --git a/gtk2_ardour/opts.h b/gtk2_ardour/opts.h index c1b3f062d4..08e38be88d 100644 --- a/gtk2_ardour/opts.h +++ b/gtk2_ardour/opts.h @@ -39,6 +39,7 @@ extern bool try_hw_optimization; extern bool use_gtk_theme; extern string keybindings_path; extern Glib::ustring menus_file; +extern bool finder_invoked_ardour; extern int32_t parse_opts (int argc, char *argv[]); diff --git a/gtk2_ardour/panner2d.cc b/gtk2_ardour/panner2d.cc index 34f367b25b..a1f99c40d4 100644 --- a/gtk2_ardour/panner2d.cc +++ b/gtk2_ardour/panner2d.cc @@ -534,7 +534,7 @@ Panner2d::on_button_release_event (GdkEventButton *ev) y = (int) floor (ev->y); state = (GdkModifierType) ev->state; - if (drag_is_puck && (Keyboard::modifier_state_contains (state, Keyboard::Shift))) { + if (drag_is_puck && (Keyboard::modifier_state_contains (state, Keyboard::TertiaryModifier))) { for (Targets::iterator i = pucks.begin(); i != pucks.end(); ++i) { Target* puck = i->second; diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index 0b96adf682..001ff370c8 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -65,20 +65,20 @@ PluginSelector::PluginSelector (PluginManager *mgr) manager = mgr; session = 0; - current_selection = ARDOUR::LADSPA; - - lmodel = Gtk::ListStore::create(lcols); - ladspa_display.set_model (lmodel); - ladspa_display.append_column (_("Available LADSPA Plugins"), lcols.name); - ladspa_display.append_column (_("Type"), lcols.type); - ladspa_display.append_column (_("# Inputs"),lcols.ins); - ladspa_display.append_column (_("# Outputs"), lcols.outs); - ladspa_display.set_headers_visible (true); - ladspa_display.set_headers_clickable (true); - ladspa_display.set_reorderable (false); - lscroller.set_border_width(10); - lscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - lscroller.add(ladspa_display); + plugin_model = Gtk::ListStore::create (plugin_columns); + plugin_display.set_model (plugin_model); + plugin_display.append_column (_("Available Plugins"), plugin_columns.name); + plugin_display.append_column (_("Type"), plugin_columns.type_name); + plugin_display.append_column (_("Category"), plugin_columns.category); + plugin_display.append_column (_("Creator"), plugin_columns.creator); + plugin_display.append_column (_("# Inputs"),plugin_columns.ins); + plugin_display.append_column (_("# Outputs"), plugin_columns.outs); + plugin_display.set_headers_visible (true); + plugin_display.set_headers_clickable (true); + plugin_display.set_reorderable (false); + scroller.set_border_width(10); + scroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + scroller.add(plugin_display); amodel = Gtk::ListStore::create(acols); added_list.set_model (amodel); @@ -87,48 +87,10 @@ PluginSelector::PluginSelector (PluginManager *mgr) added_list.set_reorderable (false); for (int i = 0; i <=3; i++) { - Gtk::TreeView::Column* column = ladspa_display.get_column(i); + Gtk::TreeView::Column* column = plugin_display.get_column(i); column->set_sort_column(i); } -#ifdef VST_SUPPORT - vmodel = ListStore::create(vcols); - vst_display.set_model (vmodel); - vst_display.append_column (_("Available plugins"), vcols.name); - vst_display.append_column (_("# Inputs"), vcols.ins); - vst_display.append_column (_("# Outputs"), vcols.outs); - vst_display.set_headers_visible (true); - vst_display.set_headers_clickable (true); - vst_display.set_reorderable (false); - vscroller.set_border_width(10); - vscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - vscroller.add(vst_display); - - for (int i = 0; i <=2; i++) { - Gtk::TreeView::Column* column = vst_display.get_column(i); - column->set_sort_column(i); - } -#endif - -#ifdef HAVE_AUDIOUNIT - aumodel = ListStore::create(aucols); - au_display.set_model (aumodel); - au_display.append_column (_("Available plugins"), aucols.name); - au_display.append_column (_("# Inputs"), aucols.ins); - au_display.append_column (_("# Outputs"), aucols.outs); - au_display.set_headers_visible (true); - au_display.set_headers_clickable (true); - au_display.set_reorderable (false); - auscroller.set_border_width(10); - auscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - auscroller.add(au_display); - - for (int i = 0; i <=2; i++) { - Gtk::TreeView::Column* column = au_display.get_column(i); - column->set_sort_column(i); - } -#endif - ascroller.set_border_width(10); ascroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); ascroller.add(added_list); @@ -146,7 +108,7 @@ PluginSelector::PluginSelector (PluginManager *mgr) Gtk::Table* table = manage(new Gtk::Table(7, 11)); table->set_size_request(750, 500); - table->attach(notebook, 0, 7, 0, 5); + table->attach(scroller, 0, 7, 0, 5); HBox* filter_box = manage (new HBox); @@ -176,98 +138,26 @@ PluginSelector::PluginSelector (PluginManager *mgr) table->attach(ascroller, 0, 7, 8, 10); add_button (Stock::CANCEL, RESPONSE_CANCEL); - add_button (Stock::CONNECT, RESPONSE_APPLY); + add_button (_("Insert Plugin(s)"), RESPONSE_APPLY); set_default_response (RESPONSE_APPLY); set_response_sensitive (RESPONSE_APPLY, false); get_vbox()->pack_start (*table); - - // Notebook tab order must be the same in here as in set_correct_focus() - using namespace Notebook_Helpers; - notebook.pages().push_back (TabElem (lscroller, _("LADSPA"))); - -#ifdef VST_SUPPORT - if (Config->get_use_vst()) { - notebook.pages().push_back (TabElem (vscroller, _("VST"))); - } -#endif - -#ifdef HAVE_AUDIOUNIT - notebook.pages().push_back (TabElem (auscroller, _("AudioUnit"))); -#endif - table->set_name("PluginSelectorTable"); - ladspa_display.set_name("PluginSelectorDisplay"); - //ladspa_display.set_name("PluginSelectorList"); + plugin_display.set_name("PluginSelectorDisplay"); + //plugin_display.set_name("PluginSelectorList"); added_list.set_name("PluginSelectorList"); - ladspa_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); - ladspa_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::ladspa_display_selection_changed)); - ladspa_display.grab_focus(); + plugin_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); + plugin_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::display_selection_changed)); + plugin_display.grab_focus(); -#ifdef VST_SUPPORT - if (Config->get_use_vst()) { - vst_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); - vst_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::vst_display_selection_changed)); - } -#endif - -#ifdef HAVE_AUDIOUNIT - au_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); - au_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::au_display_selection_changed)); -#endif - btn_update->signal_clicked().connect (mem_fun(*this, &PluginSelector::btn_update_clicked)); btn_add->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_add_clicked)); btn_remove->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_remove_clicked)); added_list.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::added_list_selection_changed)); - ladspa_refiller (); - -#ifdef VST_SUPPORT - vst_refiller (); -#endif - -#ifdef HAVE_AUDIOUNIT - au_refiller (); -#endif - - signal_show().connect (mem_fun (*this, &PluginSelector::set_correct_focus)); -} - -/** - * Makes sure keyboard focus is always in the plugin list - * of the selected notebook tab. - **/ -void -PluginSelector::set_correct_focus() -{ - int cp = notebook.get_current_page(); - - if (cp == 0) { - ladspa_display.grab_focus(); - return; - } - -#ifdef VST_SUPPORT - if (Config->get_use_vst()) { - cp--; - - if (cp == 0) { - vst_display.grab_focus(); - return; - } - } -#endif - -#ifdef HAVE_AUDIOUNIT - cp--; - - if (cp == 0) { - au_display.grab_focus(); - return; - } -#endif + refill (); } void @@ -290,7 +180,7 @@ PluginSelector::set_session (Session* s) } bool -PluginSelector::show_this_plugin (PluginInfoPtr& info, const std::string& filterstr) +PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& filterstr) { std::string compstr; std::string mode = filter_mode.get_active_text (); @@ -328,124 +218,83 @@ PluginSelector::setup_filter_string (string& filterstr) } void -PluginSelector::ladspa_refiller () +PluginSelector::refill () { - guint row; - PluginInfoList &plugs = manager->ladspa_plugin_info (); - PluginInfoList::iterator i; - char ibuf[16], obuf[16]; + std::string filterstr; - lmodel->clear(); + plugin_model->clear (); - std::string filterstr; setup_filter_string (filterstr); - - for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { - if (show_this_plugin (*i, filterstr)) { - snprintf (ibuf, sizeof(ibuf)-1, "%u", (*i)->n_inputs.n_total()); - snprintf (obuf, sizeof(obuf)-1, "%u", (*i)->n_outputs.n_total()); - - TreeModel::Row newrow = *(lmodel->append()); - newrow[lcols.name] = (*i)->name.c_str(); - newrow[lcols.type] = (*i)->category.c_str(); - newrow[lcols.ins] = ibuf; - newrow[lcols.outs] = obuf; - newrow[lcols.plugin] = *i; - } - } - lmodel->set_sort_column (0, SORT_ASCENDING); + ladspa_refiller (filterstr); + vst_refiller (filterstr); + au_refiller (filterstr); } -#ifdef VST_SUPPORT - void -PluginSelector::vst_refiller () +PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& filterstr, const char* type) { - guint row; - PluginInfoList &plugs = manager->vst_plugin_info (); - PluginInfoList::iterator i; - char ibuf[16], obuf[16]; - vmodel->clear(); - - std::string filterstr; - setup_filter_string (filterstr); - - for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { + char buf[16]; + + for (PluginInfoList::const_iterator i = plugs.begin(); i != plugs.end(); ++i) { if (show_this_plugin (*i, filterstr)) { - snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs); - snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs); - - TreeModel::Row newrow = *(vmodel->append()); - newrow[vcols.name] = (*i)->name.c_str(); - newrow[vcols.ins] = ibuf; - newrow[vcols.outs] = obuf; - newrow[vcols.plugin] = *i; - } - } - vmodel->set_sort_column (0, SORT_ASCENDING); -} -void -PluginSelector::vst_display_selection_changed() -{ - if (vst_display.get_selection()->count_selected_rows() != 0) { - btn_add->set_sensitive (true); - } else { - btn_add->set_sensitive (false); - } + TreeModel::Row newrow = *(plugin_model->append()); + newrow[plugin_columns.name] = (*i)->name; + newrow[plugin_columns.type_name] = type; + newrow[plugin_columns.category] = (*i)->category; - current_selection = ARDOUR::VST; -} -#endif //VST_SUPPORT + string creator = (*i)->creator; + string::size_type pos = 0; -#ifdef HAVE_AUDIOUNIT + /* stupid LADSPA creator strings */ -void -PluginSelector::au_refiller () -{ - guint row; - PluginInfoList plugs (AUPluginInfo::discover ()); - PluginInfoList::iterator i; - char ibuf[16], obuf[16]; - aumodel->clear(); - - std::string filterstr; - setup_filter_string (filterstr); - - for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { + while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos; + creator = creator.substr (0, pos); - if (show_this_plugin (*i, filterstr)) { + newrow[plugin_columns.creator] = creator; + + if ((*i)->n_inputs.n_total() < 0) { + newrow[plugin_columns.ins] = "various"; + } else { + snprintf (buf, sizeof(buf), "%d", (*i)->n_inputs.n_total()); + newrow[plugin_columns.ins] = buf; + } + if ((*i)->n_outputs.n_total() < 0) { + newrow[plugin_columns.outs] = "various"; + } else { + snprintf (buf, sizeof(buf), "%d", (*i)->n_outputs.n_total()); + newrow[plugin_columns.outs] = buf; + } - snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs); - snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs); - - TreeModel::Row newrow = *(aumodel->append()); - newrow[aucols.name] = (*i)->name.c_str(); - newrow[aucols.ins] = ibuf; - newrow[aucols.outs] = obuf; - newrow[aucols.plugin] = *i; + newrow[plugin_columns.plugin] = *i; } - } + } +} - aumodel->set_sort_column (0, SORT_ASCENDING); +void +PluginSelector::ladspa_refiller (const std::string& filterstr) +{ + refiller (manager->ladspa_plugin_info(), filterstr, "LADSPA"); } void -PluginSelector::au_display_selection_changed() +PluginSelector::vst_refiller (const std::string& filterstr) { - if (au_display.get_selection()->count_selected_rows() != 0) { - btn_add->set_sensitive (true); - } else { - btn_add->set_sensitive (false); - } - - current_selection = ARDOUR::AudioUnit; +#ifdef VST_SUPPORT + refiller (manager->vst_plugin_info(), filterstr, "VST"); +#endif } -#endif //HAVE_AUDIOUNIT +void +PluginSelector::au_refiller (const std::string& filterstr) +{ +#ifdef HAVE_AUDIOUNITS + refiller (manager->au_plugin_info(), filterstr, "AU"); +#endif +} void PluginSelector::use_plugin (PluginInfoPtr pi) @@ -467,33 +316,11 @@ PluginSelector::btn_add_clicked() std::string name; PluginInfoPtr pi; TreeModel::Row newrow = *(amodel->append()); - TreeModel::Row row; - switch (current_selection) { - case ARDOUR::LADSPA: - row = *(ladspa_display.get_selection()->get_selected()); - name = row[lcols.name]; - pi = row[lcols.plugin]; - break; - case ARDOUR::VST: -#ifdef VST_SUPPORT - row = *(vst_display.get_selection()->get_selected()); - name = row[vcols.name]; - pi = row[vcols.plugin]; -#endif - break; - case ARDOUR::AudioUnit: -#ifdef HAVE_AUDIOUNIT - row = *(au_display.get_selection()->get_selected()); - name = row[aucols.name]; - pi = row[aucols.plugin]; -#endif - break; - default: - error << "Programming error. Unknown plugin selected." << endmsg; - return; - } + row = *(plugin_display.get_selection()->get_selected()); + name = row[plugin_columns.name]; + pi = row[plugin_columns.plugin]; newrow[acols.text] = name; newrow[acols.plugin] = pi; @@ -522,27 +349,13 @@ PluginSelector::btn_update_clicked() } void -PluginSelector::refill() +PluginSelector::display_selection_changed() { - ladspa_refiller (); -#ifdef VST_SUPPORT - vst_refiller (); -#endif -#ifdef HAVE_AUDIOUNIT - au_refiller (); -#endif -} - -void -PluginSelector::ladspa_display_selection_changed() -{ - if (ladspa_display.get_selection()->count_selected_rows() != 0) { + if (plugin_display.get_selection()->count_selected_rows() != 0) { btn_add->set_sensitive (true); } else { btn_add->set_sensitive (false); } - - current_selection = ARDOUR::LADSPA; } void @@ -566,7 +379,8 @@ PluginSelector::run () switch (r) { case RESPONSE_APPLY: for (i = amodel->children().begin(); i != amodel->children().end(); ++i) { - use_plugin ((*i)[acols.plugin]); + PluginInfoPtr pp = (*i)[acols.plugin]; + use_plugin (pp); } break; diff --git a/gtk2_ardour/plugin_selector.h b/gtk2_ardour/plugin_selector.h index 5994e7b3ef..ac300638d7 100644 --- a/gtk2_ardour/plugin_selector.h +++ b/gtk2_ardour/plugin_selector.h @@ -44,10 +44,7 @@ class PluginSelector : public ArdourDialog private: ARDOUR::Session* session; - Gtk::Notebook notebook; - Gtk::ScrolledWindow lscroller; // ladspa - Gtk::ScrolledWindow vscroller; // vst - Gtk::ScrolledWindow auscroller; // AudioUnit + Gtk::ScrolledWindow scroller; // Available plugins Gtk::ScrolledWindow ascroller; // Added plugins Gtk::ComboBoxText filter_mode; @@ -58,27 +55,27 @@ class PluginSelector : public ArdourDialog void filter_entry_changed (); void filter_mode_changed (); - ARDOUR::PluginType current_selection; - - // page 1 - struct LadspaColumns : public Gtk::TreeModel::ColumnRecord { - LadspaColumns () { + struct PluginColumns : public Gtk::TreeModel::ColumnRecord { + PluginColumns () { add (name); - add (type); + add (type_name); + add (category); + add (creator); add (ins); add (outs); add (plugin); } - Gtk::TreeModelColumn<std::string> name; - Gtk::TreeModelColumn<std::string> type; + Gtk::TreeModelColumn<std::string> name; + Gtk::TreeModelColumn<std::string> type_name; + Gtk::TreeModelColumn<std::string> category; + Gtk::TreeModelColumn<std::string> creator; Gtk::TreeModelColumn<std::string> ins; Gtk::TreeModelColumn<std::string> outs; - Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin; + Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin; }; - LadspaColumns lcols; - Glib::RefPtr<Gtk::ListStore> lmodel; - Glib::RefPtr<Gtk::TreeSelection> lselection; - Gtk::TreeView ladspa_display; + PluginColumns plugin_columns; + Glib::RefPtr<Gtk::ListStore> plugin_model; + Gtk::TreeView plugin_display; Gtk::Button* btn_add; Gtk::Button* btn_remove; @@ -92,72 +89,27 @@ class PluginSelector : public ArdourDialog }; AddedColumns acols; Glib::RefPtr<Gtk::ListStore> amodel; - Glib::RefPtr<Gtk::TreeSelection> aselection; Gtk::TreeView added_list; -#ifdef VST_SUPPORT - // page 2 - struct VstColumns : public Gtk::TreeModel::ColumnRecord { - VstColumns () { - add (name); - add (ins); - add (outs); - add (plugin); - } - Gtk::TreeModelColumn<std::string> name; - Gtk::TreeModelColumn<std::string> ins; - Gtk::TreeModelColumn<std::string> outs; - Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin; - }; - VstColumns vcols; - Glib::RefPtr<Gtk::ListStore> vmodel; - Glib::RefPtr<Gtk::TreeSelection> vselection; - Gtk::TreeView vst_display; - void vst_refiller (); - void vst_display_selection_changed(); -#endif // VST_SUPPORT - -#ifdef HAVE_AUDIOUNIT - // page 3 - struct AUColumns : public Gtk::TreeModel::ColumnRecord { - AUColumns () { - add (name); - add (ins); - add (outs); - add (plugin); - } - Gtk::TreeModelColumn<std::string> name; - Gtk::TreeModelColumn<std::string> ins; - Gtk::TreeModelColumn<std::string> outs; - Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin; - }; - AUColumns aucols; - Glib::RefPtr<Gtk::ListStore> aumodel; - Glib::RefPtr<Gtk::TreeSelection> auselection; - Gtk::TreeView au_display; - void au_refiller (); - void au_display_selection_changed(); -#endif //HAVE_AUDIOUNIT + void refill (); + void refiller (const ARDOUR::PluginInfoList& plugs, const::std::string& filterstr, const char* type); + void ladspa_refiller (const std::string&); + void vst_refiller (const std::string&); + void au_refiller (const std::string&); ARDOUR::PluginManager *manager; - static void _ladspa_refiller (void *); - - void ladspa_refiller (); void row_clicked(GdkEventButton *); void btn_add_clicked(); void btn_remove_clicked(); void btn_update_clicked(); void added_list_selection_changed(); - void ladspa_display_selection_changed(); + void display_selection_changed(); void btn_apply_clicked(); void use_plugin (ARDOUR::PluginInfoPtr); void cleanup (); - void refill (); - bool show_this_plugin (ARDOUR::PluginInfoPtr&, const std::string&); + bool show_this_plugin (const ARDOUR::PluginInfoPtr&, const std::string&); void setup_filter_string (std::string&); - - void set_correct_focus(); }; #endif // __ardour_plugin_selector_h__ diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 935fc6000d..0f2eedb080 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -64,41 +64,42 @@ using namespace sigc; PluginUIWindow::PluginUIWindow (boost::shared_ptr<PluginInsert> insert, nframes64_t sr, nframes64_t period, bool scrollable) : ArdourDialog ("plugin ui") { - if (insert->plugin()->has_editor()) { - -#ifdef VST_SUPPORT + bool have_gui = false; + non_gtk_gui = false; - boost::shared_ptr<VSTPlugin> vp; - - if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (insert->plugin())) != 0) { - - - VSTPluginUI* vpu = new VSTPluginUI (insert, vp, session.frame_rate(), session.engine().frames_per_cycle()); - - _pluginui = vpu; - get_vbox()->add (*vpu); - vpu->package (*this); + if (insert->plugin()->has_editor()) { + switch (insert->type()) { + case ARDOUR::VST: + have_gui = create_vst_editor (insert); + break; + + case ARDOUR::AudioUnit: + have_gui = create_audiounit_editor (insert); + break; - } else { -#endif + case ARDOUR::LADSPA: + error << _("Eh? LADSPA plugins don't have editors!") << endmsg; + break; + + default: error << _("unknown type of editor-supplying plugin (note: no VST support in this version of ardour)") << endmsg; throw failed_constructor (); -#ifdef VST_SUPPORT } -#endif - } else { + } + + if (!have_gui) { - LadspaPluginUI* pu = new LadspaPluginUI (insert, sr, period, scrollable); + GenericPluginUI* pu = new GenericPluginUI (insert, scrollable); _pluginui = pu; get_vbox()->add (*pu); set_wmclass (X_("ardour_plugin_editor"), "Ardour"); - signal_map_event().connect (mem_fun (*pu, &LadspaPluginUI::start_updating)); - signal_unmap_event().connect (mem_fun (*pu, &LadspaPluginUI::stop_updating)); + signal_map_event().connect (mem_fun (*pu, &GenericPluginUI::start_updating)); + signal_unmap_event().connect (mem_fun (*pu, &GenericPluginUI::stop_updating)); } set_position (Gtk::WIN_POS_MOUSE); @@ -108,12 +109,19 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr<PluginInsert> insert, nframes6 signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this))); insert->GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away)); + gint h = _pluginui->get_preferred_height (); + gint w = _pluginui->get_preferred_width (); + if (scrollable) { - gint h = _pluginui->get_preferred_height (); if (h > 600) h = 600; - set_default_size (450, h); + if (w > 600) w = 600; + + if (w < 0) { + w = 450; + } } + set_default_size (w, h); } PluginUIWindow::~PluginUIWindow () @@ -121,8 +129,67 @@ PluginUIWindow::~PluginUIWindow () } bool +PluginUIWindow::create_vst_editor(boost::shared_ptr<PluginInsert> insert) +{ +#ifndef VST_SUPPORT + return false; +#else + + boost::shared_ptr<VSTPlugin> vp; + + if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (insert->plugin())) == 0) { + error << _("unknown type of editor-supplying plugin (note: no VST support in this version of ardour)") + << endmsg; + throw failed_constructor (); + } else { + VSTPluginUI* vpu = new VSTPluginUI (insert, vp); + + _pluginui = vpu; + get_vbox()->add (*vpu); + vpu->package (*this); + } + + non_gtk_gui = true; + return true; +#endif +} + +bool +PluginUIWindow::create_audiounit_editor (boost::shared_ptr<PluginInsert> insert) +{ +#if !defined(HAVE_AUDIOUNITS) || !defined(GTKOSX) + return false; +#else + VBox* box; + _pluginui = create_au_gui (insert, &box); + get_vbox()->add (*box); + non_gtk_gui = true; + + extern sigc::signal<void,bool> ApplicationActivationChanged; + ApplicationActivationChanged.connect (mem_fun (*this, &PluginUIWindow::app_activated)); + + return true; +#endif +} + +void +PluginUIWindow::app_activated (bool yn) +{ +#if defined (HAVE_AUDIOUNITS) && defined(GTKOSX) + if (yn) { + _pluginui->activate (); + } + cerr << "activated ? " << yn << endl; +#endif +} + +bool PluginUIWindow::on_key_press_event (GdkEventKey* event) { + if (non_gtk_gui) { + return false; + } + if (!key_press_focus_accelerator_handler (*this, event)) { return PublicEditor::instance().on_key_press_event(event); } else { @@ -145,12 +212,12 @@ PluginUIWindow::plugin_going_away () delete_when_idle (this); } -PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi, nframes64_t sr, nframes64_t period) +PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi) : insert (pi), plugin (insert->plugin()), save_button(_("Add")), bypass_button (_("Bypass")), - latency_gui (*pi, sr, period) + latency_gui (*pi, pi->session().frame_rate(), pi->session().get_block_size()) { //combo.set_use_arrows_always(true); set_popdown_strings (combo, plugin->get_presets()); diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index 5a712636f6..2ae7507d7c 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -68,12 +68,16 @@ namespace Gtkmm2ext { class PlugUIBase : public virtual sigc::trackable { public: - PlugUIBase (boost::shared_ptr<ARDOUR::PluginInsert>, nframes64_t sample_rate, nframes64_t period_size); + PlugUIBase (boost::shared_ptr<ARDOUR::PluginInsert>); virtual ~PlugUIBase() {} virtual gint get_preferred_height () = 0; + virtual gint get_preferred_width () = 0; virtual bool start_updating(GdkEventAny*) = 0; virtual bool stop_updating(GdkEventAny*) = 0; + + virtual void activate () {} + virtual void deactivate () {} protected: boost::shared_ptr<ARDOUR::PluginInsert> insert; @@ -88,14 +92,15 @@ class PlugUIBase : public virtual sigc::trackable void bypass_toggled(); }; -class LadspaPluginUI : public PlugUIBase, public Gtk::VBox +class GenericPluginUI : public PlugUIBase, public Gtk::VBox { public: - LadspaPluginUI (boost::shared_ptr<ARDOUR::PluginInsert> plug, nframes64_t sample_rate, nframes64_t period_size, bool scrollable = false); - ~LadspaPluginUI (); + GenericPluginUI (boost::shared_ptr<ARDOUR::PluginInsert> plug, bool scrollable=false); + ~GenericPluginUI (); gint get_preferred_height () { return prefheight; } - + gint get_preferred_width () { return -1; } + bool start_updating(GdkEventAny*); bool stop_updating(GdkEventAny*); @@ -210,7 +215,12 @@ class PluginUIWindow : public ArdourDialog private: PlugUIBase* _pluginui; + bool non_gtk_gui; + void app_activated (bool); void plugin_going_away (); + + bool create_vst_editor (boost::shared_ptr<ARDOUR::PluginInsert>); + bool create_audiounit_editor (boost::shared_ptr<ARDOUR::PluginInsert>); }; #ifdef VST_SUPPORT @@ -221,6 +231,7 @@ class VSTPluginUI : public PlugUIBase, public Gtk::VBox ~VSTPluginUI (); gint get_preferred_height (); + gint get_preferred_width (); bool start_updating(GdkEventAny*) {return false;} bool stop_updating(GdkEventAny*) {return false;} @@ -237,4 +248,9 @@ class VSTPluginUI : public PlugUIBase, public Gtk::VBox }; #endif // VST_SUPPORT +#ifdef HAVE_AUDIOUNITS +/* this function has to be in a .mm file */ +extern PlugUIBase* create_au_gui (boost::shared_ptr<ARDOUR::PluginInsert>, Gtk::VBox**); +#endif + #endif /* __ardour_plugin_ui_h__ */ diff --git a/gtk2_ardour/po/de_DE.po b/gtk2_ardour/po/de_DE.po index 200c296417..5df81e9209 100644 --- a/gtk2_ardour/po/de_DE.po +++ b/gtk2_ardour/po/de_DE.po @@ -7,16 +7,17 @@ msgid "" msgstr "" "Project-Id-Version: gtk-ardour 0.347.2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-11-24 00:48+0100\n" -"PO-Revision-Date: 2007-04-10 20:11+0100\n" +"POT-Creation-Date: 2008-01-07 12:21+0100\n" +"PO-Revision-Date: 2008-01-07 17:01+0100\n" "Last-Translator: Sebastian Arnold <mail@sebastian-arnold.net>\n" "Language-Team: Deutsch <de@li.org>\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: KBabel 0.9.6\n" "X-Poedit-Country: GERMANY\n" +"X-Poedit-Basepath: ../\n" #: gtk2_ardour/about.cc:120 msgid "Paul Davis" @@ -154,7 +155,11 @@ msgstr "John Anderson" msgid "Nedko Arnaudov" msgstr "Nedko Arnaudov" -#: gtk2_ardour/about.cc:158 +#: gtk2_ardour/about.cc:154 +msgid "Carl Hetherington" +msgstr "Carl Hetherington" + +#: gtk2_ardour/about.cc:159 msgid "" "French:\n" "\tAlain Fréhel <alain.frehel@free.fr>\n" @@ -164,17 +169,17 @@ msgstr "" "\tAlain Fréhel <alain.frehel@free.fr>\n" "\tChristophe Combelles <ccomb@free.fr>\n" -#: gtk2_ardour/about.cc:159 +#: gtk2_ardour/about.cc:160 msgid "" "German:\n" "\tKarsten Petersen <kapet@kapet.de>\n" "\tSebastian Arnold <mail@sebastian-arnold.net>\n" msgstr "" -"German:\n" +"Deutsch:\n" "\tKarsten Petersen <kapet@kapet.de>\n" "\tSebastian Arnold <mail@sebastian-arnold.net>\n" -#: gtk2_ardour/about.cc:160 +#: gtk2_ardour/about.cc:161 msgid "" "Italian:\n" "\tFilippo Pappalardo <filippo@email.it>\n" @@ -182,7 +187,7 @@ msgstr "" "Italian:\n" "\tFilippo Pappalardo <filippo@email.it>\n" -#: gtk2_ardour/about.cc:161 +#: gtk2_ardour/about.cc:162 msgid "" "Portuguese:\n" "\tRui Nuno Capela <rncbc@rncbc.org>\n" @@ -190,7 +195,7 @@ msgstr "" "Portuguese:\n" "\tRui Nuno Capela <rncbc@rncbc.org>\n" -#: gtk2_ardour/about.cc:162 +#: gtk2_ardour/about.cc:163 msgid "" "Brazilian Portuguese:\n" "\tAlexander da Franca Fernandes <alexander@nautae.eti.br>\n" @@ -200,7 +205,7 @@ msgstr "" "\tAlexander da Franca Fernandes <alexander@nautae.eti.br>\n" "\tChris Ross <chris@tebibyte.org>\n" -#: gtk2_ardour/about.cc:164 +#: gtk2_ardour/about.cc:165 msgid "" "Spanish:\n" "\t Alex Krohn <alexkrohn@fastmail.fm>\n" @@ -208,7 +213,7 @@ msgstr "" "Spanish:\n" "\t Alex Krohn <alexkrohn@fastmail.fm>\n" -#: gtk2_ardour/about.cc:165 +#: gtk2_ardour/about.cc:166 msgid "" "Russian:\n" "\t Igor Blinov <pitstop@nm.ru>\n" @@ -216,11 +221,19 @@ msgstr "" "Russian:\n" "\t Igor Blinov <pitstop@nm.ru>\n" -#: gtk2_ardour/about.cc:193 +#: gtk2_ardour/about.cc:167 +msgid "" +"Greek:\n" +"\t Klearchos Gourgourinis <muadib@in.gr>\n" +msgstr "" +"Greek:\n" +"\t Klearchos Gourgourinis <muadib@in.gr>\n" + +#: gtk2_ardour/about.cc:195 msgid "Copyright (C) 1999-2007 Paul Davis\n" msgstr "Copyright (C) 1999-2007 Paul Davis\n" -#: gtk2_ardour/about.cc:194 +#: gtk2_ardour/about.cc:196 msgid "" "Ardour comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome to redistribute it\n" @@ -230,11 +243,11 @@ msgstr "" "Dies ist freie Software und Sie dürfen sie gerne weiterverbreiten,\n" "solange Sie sich an die Bedingungen, die in der Datei COPYING aufgeführt sind halten.\n" -#: gtk2_ardour/about.cc:199 +#: gtk2_ardour/about.cc:201 msgid "visit http://www.ardour.org/" msgstr "besuchen Sie http://www.ardour.org" -#: gtk2_ardour/about.cc:200 +#: gtk2_ardour/about.cc:202 msgid "" "%1\n" "(built from revision %2)" @@ -242,98 +255,93 @@ msgstr "" "%1\n" "(built from revision %2)" -#: gtk2_ardour/actions.cc:76 +#: gtk2_ardour/actions.cc:78 msgid "badly formatted UI definition file" msgstr "die UI Definitionsdatei ist falsch formatiert" -#: gtk2_ardour/actions.cc:78 +#: gtk2_ardour/actions.cc:80 msgid "Ardour menu definition file not found" msgstr "Konnte die ardour Menü-Definition nicht finden" -#: gtk2_ardour/actions.cc:82 +#: gtk2_ardour/actions.cc:84 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:234 +#: gtk2_ardour/actions.cc:265 msgid "programmer error: %1 %2" msgstr "Programmierfehler: %1 %2" -#: gtk2_ardour/actions.cc:253 +#: gtk2_ardour/actions.cc:284 msgid "Unknown action name: %1" msgstr "Unbekannte Aktionsbezeichnung: %1" -#: gtk2_ardour/add_route_dialog.cc:40 -#: gtk2_ardour/add_route_dialog.cc:195 +#: gtk2_ardour/add_route_dialog.cc:41 +#: gtk2_ardour/add_route_dialog.cc:219 msgid "Mono" msgstr "Mono" -#: gtk2_ardour/add_route_dialog.cc:41 -#: gtk2_ardour/add_route_dialog.cc:197 +#: gtk2_ardour/add_route_dialog.cc:42 +#: gtk2_ardour/add_route_dialog.cc:221 msgid "Stereo" msgstr "Stereo" -#: gtk2_ardour/add_route_dialog.cc:42 +#: gtk2_ardour/add_route_dialog.cc:43 msgid "3 Channels" msgstr "3 Kanäle" -#: gtk2_ardour/add_route_dialog.cc:43 +#: gtk2_ardour/add_route_dialog.cc:44 msgid "4 Channels" msgstr "4 Kanäle" -#: gtk2_ardour/add_route_dialog.cc:44 +#: gtk2_ardour/add_route_dialog.cc:45 msgid "6 Channels" msgstr "6 Kanäle" -#: gtk2_ardour/add_route_dialog.cc:45 +#: gtk2_ardour/add_route_dialog.cc:46 msgid "8 Channels" msgstr "8 Kanäle" -#: gtk2_ardour/add_route_dialog.cc:46 +#: gtk2_ardour/add_route_dialog.cc:47 msgid "Manual Setup" msgstr "Manuell" -#: gtk2_ardour/add_route_dialog.cc:51 -#: gtk2_ardour/add_route_dialog.cc:176 -#: gtk2_ardour/editor.cc:128 -#: gtk2_ardour/editor.cc:3011 -#: gtk2_ardour/editor_actions.cc:288 -#: gtk2_ardour/time_axis_view.cc:589 +#: gtk2_ardour/add_route_dialog.cc:52 +#: gtk2_ardour/add_route_dialog.cc:200 +#: gtk2_ardour/time_axis_view.cc:592 msgid "Normal" msgstr "Normal" -#: gtk2_ardour/add_route_dialog.cc:52 -#: gtk2_ardour/add_route_dialog.cc:178 +#: gtk2_ardour/add_route_dialog.cc:53 +#: gtk2_ardour/add_route_dialog.cc:202 msgid "Tape" msgstr "Tape" -#: gtk2_ardour/add_route_dialog.cc:61 +#: gtk2_ardour/add_route_dialog.cc:62 msgid "ardour: add track/bus" msgstr "ardour: Füge Spur/Bus hinzu" -#: gtk2_ardour/add_route_dialog.cc:62 -#: gtk2_ardour/editor_route_list.cc:72 +#: gtk2_ardour/add_route_dialog.cc:63 msgid "Tracks" msgstr "Audiospuren" -#: gtk2_ardour/add_route_dialog.cc:63 -#: gtk2_ardour/editor_route_list.cc:69 +#: gtk2_ardour/add_route_dialog.cc:64 msgid "Busses" msgstr "Busse" -#: gtk2_ardour/add_route_dialog.cc:95 -#: gtk2_ardour/plugin_ui.cc:151 +#: gtk2_ardour/add_route_dialog.cc:113 +#: gtk2_ardour/plugin_ui.cc:220 msgid "Add" msgstr "Hinzufügen" -#: gtk2_ardour/add_route_dialog.cc:113 +#: gtk2_ardour/add_route_dialog.cc:131 msgid "Name (template)" msgstr "Name für Mixer-Vorlage" -#: gtk2_ardour/add_route_dialog.cc:119 +#: gtk2_ardour/add_route_dialog.cc:137 msgid "Channel Configuration" msgstr "Kanaleinstellungen" -#: gtk2_ardour/ardour_ui.cc:110 +#: gtk2_ardour/ardour_ui.cc:114 msgid "" "pre\n" "roll" @@ -341,7 +349,7 @@ msgstr "" "pre\n" "roll" -#: gtk2_ardour/ardour_ui.cc:111 +#: gtk2_ardour/ardour_ui.cc:115 msgid "" "post\n" "roll" @@ -349,42 +357,42 @@ msgstr "" "post\n" "roll" -#: gtk2_ardour/ardour_ui.cc:137 +#: gtk2_ardour/ardour_ui.cc:141 msgid "% " msgstr "" -#: gtk2_ardour/ardour_ui.cc:139 -#: gtk2_ardour/ardour_ui_ed.cc:294 +#: gtk2_ardour/ardour_ui.cc:143 +#: gtk2_ardour/ardour_ui_ed.cc:306 msgid "Punch In" msgstr "Punch In" -#: gtk2_ardour/ardour_ui.cc:140 -#: gtk2_ardour/ardour_ui_ed.cc:297 +#: gtk2_ardour/ardour_ui.cc:144 +#: gtk2_ardour/ardour_ui_ed.cc:309 msgid "Punch Out" msgstr "Punch Out" -#: gtk2_ardour/ardour_ui.cc:141 -#: gtk2_ardour/ardour_ui_ed.cc:309 +#: gtk2_ardour/ardour_ui.cc:145 +#: gtk2_ardour/ardour_ui_ed.cc:321 msgid "Auto Return" msgstr "Auto Return" -#: gtk2_ardour/ardour_ui.cc:142 -#: gtk2_ardour/ardour_ui_ed.cc:306 +#: gtk2_ardour/ardour_ui.cc:146 +#: gtk2_ardour/ardour_ui_ed.cc:318 msgid "Auto Play" msgstr "Auto Play" -#: gtk2_ardour/ardour_ui.cc:143 -#: gtk2_ardour/ardour_ui_ed.cc:303 +#: gtk2_ardour/ardour_ui.cc:147 +#: gtk2_ardour/ardour_ui_ed.cc:315 msgid "Auto Input" msgstr "Auto Input" -#: gtk2_ardour/ardour_ui.cc:144 -#: gtk2_ardour/ardour_ui_ed.cc:300 -#: gtk2_ardour/option_editor.cc:133 +#: gtk2_ardour/ardour_ui.cc:148 +#: gtk2_ardour/ardour_ui_ed.cc:312 +#: gtk2_ardour/option_editor.cc:147 msgid "Click" msgstr "Click" -#: gtk2_ardour/ardour_ui.cc:145 +#: gtk2_ardour/ardour_ui.cc:149 msgid "" "time\n" "master" @@ -392,15 +400,83 @@ msgstr "" "Time\n" "Master" -#: gtk2_ardour/ardour_ui.cc:147 +#: gtk2_ardour/ardour_ui.cc:151 msgid "AUDITION" msgstr "VORHÖREN" -#: gtk2_ardour/ardour_ui.cc:148 +#: gtk2_ardour/ardour_ui.cc:152 msgid "SOLO" msgstr "SOLO" -#: gtk2_ardour/ardour_ui.cc:475 +#: gtk2_ardour/ardour_ui.cc:154 +msgid "Errors" +msgstr "Fehlermeldungen" + +#: gtk2_ardour/ardour_ui.cc:237 +msgid "could not initialize Ardour." +msgstr "Konnte ardour nicht initialisieren." + +#: gtk2_ardour/ardour_ui.cc:548 +msgid "Ardour could not start JACK" +msgstr "Ardour konnte JACK nicht starten" + +#: gtk2_ardour/ardour_ui.cc:550 +msgid "Ardour could not connect to JACK." +msgstr "ardour konnte nicht zu JACK verbinden." + +#: gtk2_ardour/ardour_ui.cc:559 +msgid "" +"There are several possible reasons:\n" +"\n" +"1) You requested audio parameters that are not supported..\n" +"2) JACK is running as another user.\n" +"\n" +"Please consider the possibilities, and perhaps try different parameters." +msgstr "" +"Dafür kann es verschiedene Gründe geben:\n" +"\n" +"1) Sie haben nicht unterstützte Audioeinstellungen gewählt.\n" +"2) JACK wurde unter einem anderen Benutzer gestartet.\n" +"\n" +"Betrachten Sie bitte diese Möglichkeiten und verwenden sie ggf. andere Einstellungen." + +#: gtk2_ardour/ardour_ui.cc:566 +msgid "" +"There are several possible reasons:\n" +"\n" +"1) JACK is not running.\n" +"2) JACK is running as another user, perhaps root.\n" +"3) There is already another client called \"ardour\".\n" +"\n" +"Please consider the possibilities, and perhaps (re)start JACK." +msgstr "" +"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" +"Betrachten Sie bitte diese Möglichkeiten und starten Sie JACK neu, wenn dies notwendig sein sollte." + +#: gtk2_ardour/ardour_ui.cc:615 +msgid "Could not find command line session \"%1\"" +msgstr "Konnte das per Kommandozeile übergebene Projekt nicht laden: \"%1\"" + +#: gtk2_ardour/ardour_ui.cc:633 +msgid "" +"\n" +"\n" +"No session named \"%1\" exists.\n" +"To create it from the command line, start ardour as:\n" +" ardour --new %1" +msgstr "" +"\n" +"\n" +"Es existiert kein Projekt mit dem Namen \"%1\".\n" +"Um es von der Kommandozeile aus zu erstellen, starten Sie ardour mit:\n" +" ardour --new %1" + +#: gtk2_ardour/ardour_ui.cc:702 msgid "" "WARNING: Your system has a limit for maximum amount of locked memory. This might cause Ardour to run out of memory before your system runs out of memory. \n" "\n" @@ -410,15 +486,15 @@ msgstr "" "\n" "Sie können die Speicherbegrenzung mit 'ulimit -l' einsehen und normalerweise in /etc/security/limits.conf verändern." -#: gtk2_ardour/ardour_ui.cc:483 +#: gtk2_ardour/ardour_ui.cc:710 msgid "Do not show this window again" msgstr "Diese Meldung nicht wieder anzeigen" -#: gtk2_ardour/ardour_ui.cc:504 +#: gtk2_ardour/ardour_ui.cc:730 msgid "quit" msgstr "Beenden" -#: gtk2_ardour/ardour_ui.cc:513 +#: gtk2_ardour/ardour_ui.cc:739 msgid "" "Ardour was unable to save your session.\n" "\n" @@ -432,31 +508,31 @@ msgstr "" "\n" "\"Trotzdem beenden\"." -#: gtk2_ardour/ardour_ui.cc:537 +#: gtk2_ardour/ardour_ui.cc:763 msgid "ardour: save session?" msgstr "ardour: Projekt speichern?" -#: gtk2_ardour/ardour_ui.cc:544 +#: gtk2_ardour/ardour_ui.cc:770 msgid "Don't %1" -msgstr "Nicht %1" +msgstr "Abbrechen" -#: gtk2_ardour/ardour_ui.cc:546 +#: gtk2_ardour/ardour_ui.cc:772 msgid "Just %1" -msgstr "Nur %1" +msgstr "%1" -#: gtk2_ardour/ardour_ui.cc:548 +#: gtk2_ardour/ardour_ui.cc:774 msgid "Save and %1" msgstr "Speichern und %1" -#: gtk2_ardour/ardour_ui.cc:560 +#: gtk2_ardour/ardour_ui.cc:786 msgid "session" msgstr "Das Projekt" -#: gtk2_ardour/ardour_ui.cc:562 +#: gtk2_ardour/ardour_ui.cc:788 msgid "snapshot" msgstr "Der Schnappschuss" -#: gtk2_ardour/ardour_ui.cc:564 +#: gtk2_ardour/ardour_ui.cc:790 msgid "" "The %1\"%2\"\n" "has not been saved.\n" @@ -472,87 +548,95 @@ msgstr "" "\n" "Wie wollen Sie vorgehen?" -#: gtk2_ardour/ardour_ui.cc:578 +#: gtk2_ardour/ardour_ui.cc:804 msgid "Prompter" msgstr "Frage" -#: gtk2_ardour/ardour_ui.cc:638 +#: gtk2_ardour/ardour_ui.cc:866 #, c-format msgid "disconnected" msgstr "getrennt" -#: gtk2_ardour/ardour_ui.cc:645 +#: gtk2_ardour/ardour_ui.cc:873 #, c-format msgid "%.1f kHz / %4.1f ms" msgstr "%.1f kHz / %4.1f ms" -#: gtk2_ardour/ardour_ui.cc:649 +#: gtk2_ardour/ardour_ui.cc:877 #, c-format msgid "%u kHz / %4.1f ms" msgstr "%u kHz / %4.1f ms" -#: gtk2_ardour/ardour_ui.cc:662 +#: gtk2_ardour/ardour_ui.cc:890 #, c-format msgid "DSP: %5.1f%%" msgstr "DSP: %5.1f%%" -#: gtk2_ardour/ardour_ui.cc:672 +#: gtk2_ardour/ardour_ui.cc:900 #, c-format msgid "Buffers p:%<PRIu32>%% c:%<PRIu32>%%" msgstr "Buffer p:%<PRIu32>%% c:%<PRIu32>%%" -#: gtk2_ardour/ardour_ui.cc:700 +#: gtk2_ardour/ardour_ui.cc:928 msgid "Disk: 24hrs+" msgstr "HD: >24 Std." -#: gtk2_ardour/ardour_ui.cc:720 +#: gtk2_ardour/ardour_ui.cc:948 #, c-format msgid "Disk: %02dh:%02dm:%02ds" msgstr "HD: %02dh:%02dm:%02ds" -#: gtk2_ardour/ardour_ui.cc:833 -#: gtk2_ardour/new_session_dialog.cc:362 +#: gtk2_ardour/ardour_ui.cc:1061 +#: gtk2_ardour/new_session_dialog.cc:365 msgid "Recent Sessions" msgstr "Zuletzt verwendete Projekte" -#: gtk2_ardour/ardour_ui.cc:926 +#: gtk2_ardour/ardour_ui.cc:1150 +msgid "" +"Ardour is not connected to JACK\n" +"You cannot open or close sessions in this condition" +msgstr "" +"Ardour ist derzeit nicht mit JACK verbunden.\n" +"Es ist nicht möglich, neue Projekte zu erstellen." + +#: gtk2_ardour/ardour_ui.cc:1174 msgid "open session" msgstr "Projekt öffnen" -#: gtk2_ardour/ardour_ui.cc:932 +#: gtk2_ardour/ardour_ui.cc:1181 msgid "Ardour sessions" msgstr "ardour-Projekte" -#: gtk2_ardour/ardour_ui.cc:965 +#: gtk2_ardour/ardour_ui.cc:1214 msgid "Patience is a virtue.\n" msgstr "Geduld ist eine Tugend.\n" -#: gtk2_ardour/ardour_ui.cc:975 +#: gtk2_ardour/ardour_ui.cc:1224 msgid "You cannot add a track or bus without a session already loaded." msgstr "Sie können erst Spuren oder Busse hinzufügen, wenn ein Projekt geladen wurde." -#: gtk2_ardour/ardour_ui.cc:985 -#: gtk2_ardour/ardour_ui.cc:998 +#: gtk2_ardour/ardour_ui.cc:1234 +#: gtk2_ardour/ardour_ui.cc:1247 msgid "could not create a new audio track" msgstr "Konnte neue Spur nicht erstellen." -#: gtk2_ardour/ardour_ui.cc:987 +#: gtk2_ardour/ardour_ui.cc:1236 msgid "could only create %1 of %2 new audio %3" msgstr "Konnte nur %1 von %2 neuen %3 erstellen" -#: gtk2_ardour/ardour_ui.cc:988 +#: gtk2_ardour/ardour_ui.cc:1237 msgid "tracks" msgstr "Spuren" -#: gtk2_ardour/ardour_ui.cc:988 +#: gtk2_ardour/ardour_ui.cc:1237 msgid "busses" msgstr "Audio-Bussen" -#: gtk2_ardour/ardour_ui.cc:1000 +#: gtk2_ardour/ardour_ui.cc:1249 msgid "could not create %1 new audio tracks" msgstr "Konnte %1 neue Spuren nicht erstellen." -#: gtk2_ardour/ardour_ui.cc:1021 +#: gtk2_ardour/ardour_ui.cc:1270 msgid "" "There are insufficient JACK ports available\n" "to create a new track or bus.\n" @@ -565,7 +649,7 @@ msgstr "" "ardour sowie JACK mit einer größeren\n" "Anzahl Ports erneut." -#: gtk2_ardour/ardour_ui.cc:1141 +#: gtk2_ardour/ardour_ui.cc:1390 msgid "" "Please create 1 or more track\n" "before trying to record.\n" @@ -575,7 +659,7 @@ msgstr "" "bevor Sie aufnehmen.\n" "Weitere Einstellungen finden Sie im Projektmenü." -#: gtk2_ardour/ardour_ui.cc:1386 +#: gtk2_ardour/ardour_ui.cc:1645 msgid "" "JACK has either been shutdown or it\n" "disconnected Ardour because Ardour\n" @@ -587,39 +671,61 @@ msgstr "" "schnell genug war. Sie sollten versuchen,\n" "das Projekt zu speichern und erneut mit JACK zu verbinden." -#: gtk2_ardour/ardour_ui.cc:1403 +#: gtk2_ardour/ardour_ui.cc:1662 msgid "Unable to start the session running" msgstr "Konnte das aktuelle Projekt nicht starten" -#: gtk2_ardour/ardour_ui.cc:1503 -#: gtk2_ardour/ardour_ui.cc:1522 -#: gtk2_ardour/audio_clock.cc:461 +#: gtk2_ardour/ardour_ui.cc:1753 +#: gtk2_ardour/ardour_ui.cc:1772 +#: gtk2_ardour/audio_clock.cc:508 msgid "none" msgstr "keine" -#: gtk2_ardour/ardour_ui.cc:1512 -#: gtk2_ardour/ardour_ui.cc:1531 +#: gtk2_ardour/ardour_ui.cc:1762 +#: gtk2_ardour/ardour_ui.cc:1781 msgid "off" msgstr "aus" -#: gtk2_ardour/ardour_ui.cc:1557 +#: gtk2_ardour/ardour_ui.cc:1807 msgid "Name of New Snapshot" msgstr "Name für neuen Schnappschuss" -#: gtk2_ardour/ardour_ui.cc:1697 +#: gtk2_ardour/ardour_ui.cc:1959 msgid "Name for mix template:" msgstr "Name für Mixer-Vorlage" -#: gtk2_ardour/ardour_ui.cc:1698 +#: gtk2_ardour/ardour_ui.cc:1960 msgid "-template" msgstr "Vorlage" -#: gtk2_ardour/ardour_ui.cc:1722 -#: gtk2_ardour/ardour_ui.cc:1739 -msgid "Ardour is not connected to JACK at this time. Creating new sessions is not possible." -msgstr "Ardour ist derzeit nicht mit JACK verbunden. Es ist nicht möglich, neue Projekte zu erstellen." +#: gtk2_ardour/ardour_ui.cc:1989 +msgid "" +"Welcome to Ardour.\n" +"\n" +"The program will take a bit longer to start up\n" +"while the system fonts are checked.\n" +"\n" +"This will only be done once, and you will\n" +"not see this message again\n" +msgstr "" +"Willkommen bei Ardour.\n" +"\n" +"Der Programmstart wird etwas länger dauern,\n" +"da die Systemschriften geprüft werden.\n" +"\n" +"Diese Meldung wird nur dieses eine Mal\n" +"auftauchen.\n" + +#: gtk2_ardour/ardour_ui.cc:2039 +msgid "Ardour cannot understand \"%1\" as a session name" +msgstr "Ardour kann \"%1\" nicht als Projektnamen benutzen" -#: gtk2_ardour/ardour_ui.cc:1832 +#: gtk2_ardour/ardour_ui.cc:2074 +#: gtk2_ardour/ardour_ui.cc:2131 +msgid "Starting audio engine" +msgstr "Starte Audio Engine" + +#: gtk2_ardour/ardour_ui.cc:2249 msgid "" "This session\n" "%1\n" @@ -629,7 +735,7 @@ msgstr "" "%1\n" "existiert bereits. Wollen Sie sie öffnen?" -#: gtk2_ardour/ardour_ui.cc:1955 +#: gtk2_ardour/ardour_ui.cc:2430 msgid "" "You do not have write access to this session.\n" "This prevents the session from being loaded." @@ -637,19 +743,32 @@ msgstr "" "Sie haben keinen Schreibzugriff auf dieses Projekt.\n" "Dadurch kann das Projekt nicht geladen werden." -#: gtk2_ardour/ardour_ui.cc:1967 +#: gtk2_ardour/ardour_ui.cc:2437 +msgid "Please wait while Ardour loads your session" +msgstr "Bitte warten Sie, während Ardour das Projekt lädt" + +#: gtk2_ardour/ardour_ui.cc:2448 msgid "Session \"%1 (snapshot %2)\" did not load successfully" msgstr "Projekt \"%1 (Schnappschuss %2)\" konnte nicht geladen werden." -#: gtk2_ardour/ardour_ui.cc:2017 +#: gtk2_ardour/ardour_ui.cc:2453 +#, fuzzy +msgid "Loading Error" +msgstr "Programmierfehler:" + +#: gtk2_ardour/ardour_ui.cc:2454 +msgid "Click the OK button to try again." +msgstr "Klicken Sie auf OK, um es erneut zu versuchen." + +#: gtk2_ardour/ardour_ui.cc:2527 msgid "Could not create session in \"%1\"" msgstr "Konnte kein Projekt in \"%1\" anlegen" -#: gtk2_ardour/ardour_ui.cc:2077 +#: gtk2_ardour/ardour_ui.cc:2587 msgid "No audio files were ready for cleanup" msgstr "Keine Audiodateien zum Aufräumen vorhanden" -#: gtk2_ardour/ardour_ui.cc:2081 +#: gtk2_ardour/ardour_ui.cc:2591 msgid "" "If this seems suprising, \n" "check for any existing snapshots.\n" @@ -661,25 +780,25 @@ msgstr "" "sind sie wahrscheinlich noch in einem\n" "älteren Schnappschuss als Region eingebunden." -#: gtk2_ardour/ardour_ui.cc:2090 +#: gtk2_ardour/ardour_ui.cc:2600 msgid "ardour: cleanup" msgstr "ardour: Aufräumen" -#: gtk2_ardour/ardour_ui.cc:2126 -#: gtk2_ardour/ardour_ui.cc:2132 +#: gtk2_ardour/ardour_ui.cc:2636 +#: gtk2_ardour/ardour_ui.cc:2642 msgid "files were" msgstr "folgenden Dateien wurden" -#: gtk2_ardour/ardour_ui.cc:2128 -#: gtk2_ardour/ardour_ui.cc:2134 +#: gtk2_ardour/ardour_ui.cc:2638 +#: gtk2_ardour/ardour_ui.cc:2644 msgid "file was" msgstr "folgende Datei wurde" -#: gtk2_ardour/ardour_ui.cc:2175 +#: gtk2_ardour/ardour_ui.cc:2685 msgid "Are you sure you want to cleanup?" msgstr "Sind Sie sicher, dass Sie aufräumen wollen?" -#: gtk2_ardour/ardour_ui.cc:2180 +#: gtk2_ardour/ardour_ui.cc:2690 msgid "" "Cleanup is a destructive operation.\n" "ALL undo/redo information will be lost if you cleanup.\n" @@ -689,19 +808,19 @@ msgstr "" "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." -#: gtk2_ardour/ardour_ui.cc:2186 +#: gtk2_ardour/ardour_ui.cc:2696 msgid "Clean Up" msgstr "Aufräumen" -#: gtk2_ardour/ardour_ui.cc:2189 +#: gtk2_ardour/ardour_ui.cc:2699 msgid "CleanupDialog" msgstr "" -#: gtk2_ardour/ardour_ui.cc:2217 +#: gtk2_ardour/ardour_ui.cc:2727 msgid "cleaned files" msgstr "aufgeräumte Dateien" -#: gtk2_ardour/ardour_ui.cc:2218 +#: gtk2_ardour/ardour_ui.cc:2728 msgid "" "The following %1 %2 not in use and \n" "have been moved to:\n" @@ -718,11 +837,11 @@ msgstr "" "Wenn Sie den Müll leeren werden weitere\n" "%4 %5byte Speicherplatz frei.\n" -#: gtk2_ardour/ardour_ui.cc:2246 +#: gtk2_ardour/ardour_ui.cc:2756 msgid "deleted file" msgstr "gelöschte Datei" -#: gtk2_ardour/ardour_ui.cc:2247 +#: gtk2_ardour/ardour_ui.cc:2757 msgid "" "The following %1 %2 deleted from\n" "%3,\n" @@ -732,11 +851,11 @@ msgstr "" "%3,\n" "und machten %4 %5byte Speicherplatz frei" -#: gtk2_ardour/ardour_ui.cc:2365 +#: gtk2_ardour/ardour_ui.cc:2875 msgid "Recording was stopped because your system could not keep up." msgstr "Die Aufnahme wurde gestoppt, da Ihr System nicht schnell genug folgen konnte." -#: gtk2_ardour/ardour_ui.cc:2376 +#: gtk2_ardour/ardour_ui.cc:2886 msgid "" "The disk system on your computer\n" "was not able to keep up with Ardour.\n" @@ -750,7 +869,7 @@ msgstr "" "Die Daten konnten nicht schnell genug geschrieben\n" "werden, um die Aufnahme fortzuführen.\n" -#: gtk2_ardour/ardour_ui.cc:2395 +#: gtk2_ardour/ardour_ui.cc:2905 msgid "" "The disk system on your computer\n" "was not able to keep up with Ardour.\n" @@ -764,7 +883,7 @@ msgstr "" "Die Daten konnten nicht schnell genug gelesen\n" "werden, um die Wiedergabe aufrechtzuerhalten.\n" -#: gtk2_ardour/ardour_ui.cc:2416 +#: gtk2_ardour/ardour_ui.cc:2926 msgid "" "This session appears to have been in\n" "middle of recording when ardour or\n" @@ -782,19 +901,19 @@ msgstr "" "für Sie wiederherstellen oder sie verwerfen.\n" "Bitte entscheiden Sie, wie Sie vorgehen möchten.\n" -#: gtk2_ardour/ardour_ui.cc:2426 +#: gtk2_ardour/ardour_ui.cc:2936 msgid "Recover from crash" msgstr "Daten wiederherstellen" -#: gtk2_ardour/ardour_ui.cc:2427 +#: gtk2_ardour/ardour_ui.cc:2937 msgid "Ignore crash data" msgstr "Daten verwerfen" -#: gtk2_ardour/ardour_ui.cc:2445 +#: gtk2_ardour/ardour_ui.cc:2955 msgid "Could not disconnect from JACK" msgstr "Konnte Verbindung mit JACK nicht trennen" -#: gtk2_ardour/ardour_ui.cc:2458 +#: gtk2_ardour/ardour_ui.cc:2968 msgid "Could not reconnect to JACK" msgstr "Konnte nicht erneut zu JACK verbinden" @@ -806,84 +925,96 @@ msgstr "Der Editor konnte nicht initialisiert werden." msgid "UI: cannot setup mixer" msgstr "Der Mixer konnte nicht initialisiert werden." -#: gtk2_ardour/ardour_ui2.cc:243 +#: gtk2_ardour/ardour_ui2.cc:110 +msgid "[ERROR]: " +msgstr "[FEHLER]:" + +#: gtk2_ardour/ardour_ui2.cc:112 +msgid "[WARNING]: " +msgstr "[WARNUNG]:" + +#: gtk2_ardour/ardour_ui2.cc:114 +msgid "[INFO]: " +msgstr "[INFO]: " + +#: gtk2_ardour/ardour_ui2.cc:282 msgid "Play from playhead" msgstr "Wiedergabe ab Positionszeiger" -#: gtk2_ardour/ardour_ui2.cc:244 +#: gtk2_ardour/ardour_ui2.cc:283 msgid "Stop playback" msgstr "Wiedergabe anhalten" -#: gtk2_ardour/ardour_ui2.cc:245 +#: gtk2_ardour/ardour_ui2.cc:284 msgid "Play range/selection" msgstr "Bereich/Auswahl wiedergeben" -#: gtk2_ardour/ardour_ui2.cc:246 +#: gtk2_ardour/ardour_ui2.cc:285 msgid "Go to start of session" msgstr "Zum Anfang des Projekts springen" -#: gtk2_ardour/ardour_ui2.cc:247 +#: gtk2_ardour/ardour_ui2.cc:286 msgid "Go to end of session" msgstr "Zum Ende des Projekts springen" -#: gtk2_ardour/ardour_ui2.cc:248 +#: gtk2_ardour/ardour_ui2.cc:287 msgid "Play loop range" msgstr "Schleife wiedergeben" -#: gtk2_ardour/ardour_ui2.cc:250 +#: gtk2_ardour/ardour_ui2.cc:289 msgid "Return to last playback start when stopped" msgstr "Bei Stop zum letzten Wiedergabeanfang springen" -#: gtk2_ardour/ardour_ui2.cc:251 +#: gtk2_ardour/ardour_ui2.cc:290 msgid "Start playback after any locate" msgstr "Startet die Wiedergabe nach setzen des Positionszeigers" -#: gtk2_ardour/ardour_ui2.cc:252 +#: gtk2_ardour/ardour_ui2.cc:291 msgid "Be sensible about input monitoring" msgstr "Automatisches Input Monitoring aktivieren" -#: gtk2_ardour/ardour_ui2.cc:253 +#: gtk2_ardour/ardour_ui2.cc:292 msgid "Start recording at auto-punch start" msgstr "Beginnt die Aufnahme bei Auto-Punch Start" -#: gtk2_ardour/ardour_ui2.cc:254 +#: gtk2_ardour/ardour_ui2.cc:293 msgid "Stop recording at auto-punch end" msgstr "Beginnt die Aufnahme bei Auto-Punch Ende" -#: gtk2_ardour/ardour_ui2.cc:255 +#: gtk2_ardour/ardour_ui2.cc:294 msgid "Enable/Disable audio click" msgstr "Aktiviert/Deaktiviert Audio Click" -#: gtk2_ardour/ardour_ui2.cc:256 +#: gtk2_ardour/ardour_ui2.cc:295 msgid "Positional sync source" msgstr "Positionsbezogene Sync-quelle" -#: gtk2_ardour/ardour_ui2.cc:257 +#: gtk2_ardour/ardour_ui2.cc:296 msgid "Does Ardour control the time?" msgstr "Bestimmt ardour die Time?" -#: gtk2_ardour/ardour_ui2.cc:258 +#: gtk2_ardour/ardour_ui2.cc:297 msgid "Shuttle speed control" msgstr "Shuttle-Geschwindigkeit" -#: gtk2_ardour/ardour_ui2.cc:259 +#: gtk2_ardour/ardour_ui2.cc:298 #, c-format msgid "Select semitones or %%-age for speed display" msgstr "Geschwindigkeitsanzeige als Prozent oder Halbtöne einstellen" -#: gtk2_ardour/ardour_ui2.cc:260 +#: gtk2_ardour/ardour_ui2.cc:299 msgid "Current transport speed" msgstr "Geschwindigkeitsanzeige" -#: gtk2_ardour/ardour_ui2.cc:280 +#: gtk2_ardour/ardour_ui2.cc:320 msgid "Primary clock" -msgstr "Primärer Zeitgeber" +msgstr "Primäre Zeitanzeige" -#: gtk2_ardour/ardour_ui2.cc:281 +#: gtk2_ardour/ardour_ui2.cc:321 msgid "secondary clock" -msgstr "Sekundärer Zeitgeber" +msgstr "Sekundäre Zeitanzeige" -#: gtk2_ardour/ardour_ui2.cc:307 +#: gtk2_ardour/ardour_ui2.cc:347 msgid "" "When active, something is soloed.\n" "Click to de-solo everything" @@ -891,7 +1022,7 @@ msgstr "" "Wird aktiv, wenn eine Spur Solo läuft.\n" "Schaltet bei Klick Solo aus." -#: gtk2_ardour/ardour_ui2.cc:308 +#: gtk2_ardour/ardour_ui2.cc:348 msgid "" "When active, auditioning is taking place\n" "Click to stop the audition" @@ -899,972 +1030,1057 @@ msgstr "" "Wird beim Vorhören aktiv.\n" "Klicken stoppt das Vorhören." -#: gtk2_ardour/ardour_ui2.cc:336 -#: gtk2_ardour/ardour_ui2.cc:775 -#: gtk2_ardour/ardour_ui2.cc:831 -#: gtk2_ardour/ardour_ui_options.cc:910 +#: gtk2_ardour/ardour_ui2.cc:376 +#: gtk2_ardour/ardour_ui2.cc:826 +#: gtk2_ardour/ardour_ui2.cc:882 +#: gtk2_ardour/ardour_ui_options.cc:1064 msgid "sprung" msgstr "Feder" -#: gtk2_ardour/ardour_ui2.cc:337 -#: gtk2_ardour/ardour_ui2.cc:777 -#: gtk2_ardour/ardour_ui_options.cc:921 +#: gtk2_ardour/ardour_ui2.cc:377 +#: gtk2_ardour/ardour_ui2.cc:828 +#: gtk2_ardour/ardour_ui_options.cc:1075 msgid "wheel" msgstr "Drehrad" -#: gtk2_ardour/ardour_ui2.cc:545 +#: gtk2_ardour/ardour_ui2.cc:596 msgid "Maximum speed" msgstr "Max. Geschwindigkeit" -#: gtk2_ardour/ardour_ui2.cc:787 -#: gtk2_ardour/ardour_ui2.cc:810 +#: gtk2_ardour/ardour_ui2.cc:838 +#: gtk2_ardour/ardour_ui2.cc:861 msgid "stop" msgstr "Stop" -#: gtk2_ardour/ardour_ui2.cc:829 +#: gtk2_ardour/ardour_ui2.cc:880 msgid "-0.55" msgstr "-0.55" -#: gtk2_ardour/ardour_ui_dependents.cc:84 +#: gtk2_ardour/ardour_ui_dependents.cc:85 msgid "Ardour key bindings file not found at \"%1\" or contains errors." msgstr "Konnte die Datei mit den Tastaturzuweisungen nicht an der Stelle \"%1\" finden, oder sie ist fehlerhaft." -#: gtk2_ardour/ardour_ui_dialogs.cc:165 +#: gtk2_ardour/ardour_ui_dialogs.cc:170 #: gtk2_ardour/playlist_selector.cc:73 msgid "close" msgstr "Schließen" -#: gtk2_ardour/ardour_ui_ed.cc:81 +#: gtk2_ardour/ardour_ui_ed.cc:84 msgid "Session" msgstr "Projekt" -#: gtk2_ardour/ardour_ui_ed.cc:82 -#: gtk2_ardour/ardour_ui_ed.cc:143 -#: gtk2_ardour/editor.cc:1625 -#: gtk2_ardour/export_dialog.cc:125 -#: gtk2_ardour/export_dialog.cc:352 -#: gtk2_ardour/export_dialog.cc:1061 -#: gtk2_ardour/export_dialog.cc:1065 -msgid "Export" -msgstr "Exportieren" +#: gtk2_ardour/ardour_ui_ed.cc:85 +msgid "Import/Export" +msgstr "Import/Export" + +#: gtk2_ardour/ardour_ui_ed.cc:86 +#: gtk2_ardour/editor.cc:576 +#: gtk2_ardour/editor.cc:647 +msgid "Regions" +msgstr "Regionen" -#: gtk2_ardour/ardour_ui_ed.cc:83 +#: gtk2_ardour/ardour_ui_ed.cc:87 msgid "Cleanup" msgstr "Aufräumen" -#: gtk2_ardour/ardour_ui_ed.cc:84 -#: gtk2_ardour/option_editor.cc:130 +#: gtk2_ardour/ardour_ui_ed.cc:88 +#: gtk2_ardour/option_editor.cc:144 msgid "Sync" msgstr "Sync" -#: gtk2_ardour/ardour_ui_ed.cc:85 -#: gtk2_ardour/ardour_ui_ed.cc:86 +#: gtk2_ardour/ardour_ui_ed.cc:89 +#: gtk2_ardour/ardour_ui_ed.cc:90 +#: gtk2_ardour/engine_dialog.cc:343 msgid "Options" msgstr "Optionen" -#: gtk2_ardour/ardour_ui_ed.cc:87 +#: gtk2_ardour/ardour_ui_ed.cc:91 msgid "Help" msgstr "Hilfe" -#: gtk2_ardour/ardour_ui_ed.cc:88 +#: gtk2_ardour/ardour_ui_ed.cc:92 msgid "KeyMouse Actions" msgstr "Tastatur/Maus-Befehle" -#: gtk2_ardour/ardour_ui_ed.cc:89 +#: gtk2_ardour/ardour_ui_ed.cc:93 msgid "Audio File Format" msgstr "Audio-Dateiformat" -#: gtk2_ardour/ardour_ui_ed.cc:90 +#: gtk2_ardour/ardour_ui_ed.cc:94 msgid "Header" msgstr "Header" -#: gtk2_ardour/ardour_ui_ed.cc:91 +#: gtk2_ardour/ardour_ui_ed.cc:95 msgid "Data" msgstr "Datenformat" -#: gtk2_ardour/ardour_ui_ed.cc:92 +#: gtk2_ardour/ardour_ui_ed.cc:96 msgid "Control Surfaces" msgstr "Eingabegeräte / Controller" -#: gtk2_ardour/ardour_ui_ed.cc:93 +#: gtk2_ardour/ardour_ui_ed.cc:97 msgid "Metering" msgstr "Pegelanzeige" -#: gtk2_ardour/ardour_ui_ed.cc:94 +#: gtk2_ardour/ardour_ui_ed.cc:98 msgid "Fall off rate" msgstr "Abfall der Pegelanzeige" -#: gtk2_ardour/ardour_ui_ed.cc:95 +#: gtk2_ardour/ardour_ui_ed.cc:99 msgid "Hold Time" msgstr "Pegelanzeige halten" -#: gtk2_ardour/ardour_ui_ed.cc:99 -#: gtk2_ardour/route_time_axis.cc:1308 -#: gtk2_ardour/new_session_dialog.cc:619 +#: gtk2_ardour/ardour_ui_ed.cc:100 +msgid "Denormal Handling" +msgstr "Umgang mit Denormals" + +#: gtk2_ardour/ardour_ui_ed.cc:104 +#: gtk2_ardour/route_time_axis.cc:1343 msgid "New" msgstr "Neu" -#: gtk2_ardour/ardour_ui_ed.cc:101 -#: gtk2_ardour/new_session_dialog.cc:606 +#: gtk2_ardour/ardour_ui_ed.cc:106 msgid "Open" msgstr "Öffnen" -#: gtk2_ardour/ardour_ui_ed.cc:102 +#: gtk2_ardour/ardour_ui_ed.cc:107 msgid "Recent" msgstr "Zuletzt verwendet..." -#: gtk2_ardour/ardour_ui_ed.cc:103 +#: gtk2_ardour/ardour_ui_ed.cc:108 #: gtk2_ardour/io_selector.cc:59 #: gtk2_ardour/io_selector.cc:747 #: gtk2_ardour/connection_editor.cc:58 msgid "Close" msgstr "Schließen" -#: gtk2_ardour/ardour_ui_ed.cc:106 +#: gtk2_ardour/ardour_ui_ed.cc:111 #: gtk2_ardour/route_params_ui.cc:513 msgid "Add Track/Bus" msgstr "Spur/Bus hinzufügen..." -#: gtk2_ardour/ardour_ui_ed.cc:118 +#: gtk2_ardour/ardour_ui_ed.cc:123 msgid "Connect" msgstr "Verbinden" -#: gtk2_ardour/ardour_ui_ed.cc:126 +#: gtk2_ardour/ardour_ui_ed.cc:131 msgid "Snapshot" msgstr "Schnappschuss..." -#: gtk2_ardour/ardour_ui_ed.cc:129 +#: gtk2_ardour/ardour_ui_ed.cc:134 msgid "Save Template..." msgstr "Als Vorlage Speichern..." -#: gtk2_ardour/ardour_ui_ed.cc:132 +#: gtk2_ardour/ardour_ui_ed.cc:137 msgid "Export session to audiofile..." msgstr "Exportiere Projekt als Audio-Datei..." -#: gtk2_ardour/ardour_ui_ed.cc:135 +#: gtk2_ardour/ardour_ui_ed.cc:140 msgid "Export selection to audiofile..." -msgstr "Exportiere Auswahl als Audio-Datei..." +msgstr "Exportiere Auswahlbereich als Audio-Datei..." -#: gtk2_ardour/ardour_ui_ed.cc:139 +#: gtk2_ardour/ardour_ui_ed.cc:144 msgid "Export range markers to audiofile..." -msgstr "Exportiere Bereich als Audio-Datei..." +msgstr "Exportiere Bereiche als Audio-Datei..." -#: gtk2_ardour/ardour_ui_ed.cc:146 +#: gtk2_ardour/ardour_ui_ed.cc:148 +#: gtk2_ardour/editor.cc:1724 +#: gtk2_ardour/export_dialog.cc:125 +#: gtk2_ardour/export_dialog.cc:374 +#: gtk2_ardour/export_dialog.cc:1122 +#: gtk2_ardour/export_dialog.cc:1126 +msgid "Export" +msgstr "Exportieren" + +#: gtk2_ardour/ardour_ui_ed.cc:151 msgid "Cleanup unused sources" msgstr "Nicht benutzte Dateien entfernen" -#: gtk2_ardour/ardour_ui_ed.cc:148 +#: gtk2_ardour/ardour_ui_ed.cc:153 msgid "Flush wastebasket" msgstr "Müll leeren" -#: gtk2_ardour/ardour_ui_ed.cc:154 +#: gtk2_ardour/ardour_ui_ed.cc:159 msgid "JACK" msgstr "JACK" -#: gtk2_ardour/ardour_ui_ed.cc:155 +#: gtk2_ardour/ardour_ui_ed.cc:160 msgid "Latency" msgstr "Latenz" -#: gtk2_ardour/ardour_ui_ed.cc:157 +#: gtk2_ardour/ardour_ui_ed.cc:162 msgid "Reconnect" msgstr "Neu Verbinden" -#: gtk2_ardour/ardour_ui_ed.cc:160 -#: gtk2_ardour/mixer_strip.cc:510 -#: gtk2_ardour/mixer_strip.cc:572 +#: gtk2_ardour/ardour_ui_ed.cc:165 +#: gtk2_ardour/mixer_strip.cc:504 +#: gtk2_ardour/mixer_strip.cc:566 msgid "Disconnect" msgstr "Trennen" -#: gtk2_ardour/ardour_ui_ed.cc:187 +#: gtk2_ardour/ardour_ui_ed.cc:192 msgid "Windows" msgstr "Fenster" -#: gtk2_ardour/ardour_ui_ed.cc:188 +#: gtk2_ardour/ardour_ui_ed.cc:193 msgid "Quit" msgstr "Beenden" -#: gtk2_ardour/ardour_ui_ed.cc:192 +#: gtk2_ardour/ardour_ui_ed.cc:197 msgid "Maximise Editor Space" msgstr "Editor Maximieren" -#: gtk2_ardour/ardour_ui_ed.cc:194 +#: gtk2_ardour/ardour_ui_ed.cc:199 msgid "Show Editor" msgstr "Editor anzeigen" -#: gtk2_ardour/ardour_ui_ed.cc:195 +#: gtk2_ardour/ardour_ui_ed.cc:200 msgid "Show Mixer" msgstr "Mixer anzeigen" -#: gtk2_ardour/ardour_ui_ed.cc:196 -#: gtk2_ardour/option_editor.cc:103 -msgid "Options Editor" +#: gtk2_ardour/ardour_ui_ed.cc:201 +#: gtk2_ardour/option_editor.cc:117 +msgid "Preferences" msgstr "Einstellungen" -#: gtk2_ardour/ardour_ui_ed.cc:197 +#: gtk2_ardour/ardour_ui_ed.cc:202 #: gtk2_ardour/route_params_ui.cc:143 #: gtk2_ardour/route_params_ui.cc:659 msgid "Track/Bus Inspector" msgstr "Verbindungen" -#: gtk2_ardour/ardour_ui_ed.cc:199 +#: gtk2_ardour/ardour_ui_ed.cc:204 #: gtk2_ardour/connection_editor.cc:146 #: gtk2_ardour/connection_editor.cc:147 msgid "Connections" msgstr "Verbindungen" -#: gtk2_ardour/ardour_ui_ed.cc:201 -#: gtk2_ardour/location_ui.cc:577 +#: gtk2_ardour/ardour_ui_ed.cc:206 +#: gtk2_ardour/location_ui.cc:611 msgid "Locations" msgstr "Positionen" -#: gtk2_ardour/ardour_ui_ed.cc:203 +#: gtk2_ardour/ardour_ui_ed.cc:208 msgid "Big Clock" msgstr "Große Zeitanzeige" -#: gtk2_ardour/ardour_ui_ed.cc:205 +#: gtk2_ardour/ardour_ui_ed.cc:210 msgid "About" msgstr "Ãœber ardour..." -#: gtk2_ardour/ardour_ui_ed.cc:206 -msgid "Colors" -msgstr "Farben" +#: gtk2_ardour/ardour_ui_ed.cc:211 +msgid "Theme Manager" +msgstr "Thema" -#: gtk2_ardour/ardour_ui_ed.cc:208 +#: gtk2_ardour/ardour_ui_ed.cc:212 +msgid "Keybindings" +msgstr "Tastaturbefehle" + +#: gtk2_ardour/ardour_ui_ed.cc:214 msgid "Add Audio Track" msgstr "Audiospur hinzufügen" -#: gtk2_ardour/ardour_ui_ed.cc:210 +#: gtk2_ardour/ardour_ui_ed.cc:216 msgid "Add Audio Bus" msgstr "Audio-Bus hinzufügen" -#: gtk2_ardour/ardour_ui_ed.cc:212 +#: gtk2_ardour/ardour_ui_ed.cc:218 msgid "Save" msgstr "Speichern" -#: gtk2_ardour/ardour_ui_ed.cc:214 -#: gtk2_ardour/editor_actions.cc:258 +#: gtk2_ardour/ardour_ui_ed.cc:220 +#: gtk2_ardour/editor_actions.cc:377 msgid "Remove Last Capture" msgstr "Letzte Aufnahme entfernen" -#: gtk2_ardour/ardour_ui_ed.cc:221 +#: gtk2_ardour/ardour_ui_ed.cc:227 msgid "Transport" msgstr "Transport" -#: gtk2_ardour/ardour_ui_ed.cc:227 -#: gtk2_ardour/sfdb_ui.cc:62 +#: gtk2_ardour/ardour_ui_ed.cc:233 +#: gtk2_ardour/engine_dialog.cc:56 +#: gtk2_ardour/sfdb_ui.cc:178 msgid "Stop" msgstr "Stop" -#: gtk2_ardour/ardour_ui_ed.cc:230 +#: gtk2_ardour/ardour_ui_ed.cc:236 msgid "Roll" msgstr "Wiedergabe" -#: gtk2_ardour/ardour_ui_ed.cc:234 +#: gtk2_ardour/ardour_ui_ed.cc:240 msgid "Start/Stop" msgstr "Start/Stop" -#: gtk2_ardour/ardour_ui_ed.cc:237 +#: gtk2_ardour/ardour_ui_ed.cc:243 msgid "Stop + Forget Capture" msgstr "Stop + Aufnahme verwerfen" -#: gtk2_ardour/ardour_ui_ed.cc:247 +#: gtk2_ardour/ardour_ui_ed.cc:253 msgid "Transition To Roll" -msgstr "Ãœbergang zu Roll" +msgstr "Vorwärts wiedergeben" -#: gtk2_ardour/ardour_ui_ed.cc:251 +#: gtk2_ardour/ardour_ui_ed.cc:257 msgid "Transition To Reverse" -msgstr "Ãœbergang zu Rückwärts" +msgstr "Rückwärts wiedergeben" -#: gtk2_ardour/ardour_ui_ed.cc:256 +#: gtk2_ardour/ardour_ui_ed.cc:262 msgid "Play Loop Range" msgstr "Schleife wiedergeben" -#: gtk2_ardour/ardour_ui_ed.cc:259 +#: gtk2_ardour/ardour_ui_ed.cc:265 msgid "Play Selection" -msgstr "Auswahl wiedergeben" +msgstr "Ausgewählten Bereich wiedergeben" -#: gtk2_ardour/ardour_ui_ed.cc:263 +#: gtk2_ardour/ardour_ui_ed.cc:269 msgid "Enable Record" msgstr "Aufnahme aktivieren" -#: gtk2_ardour/ardour_ui_ed.cc:266 +#: gtk2_ardour/ardour_ui_ed.cc:271 +msgid "Start Recording" +msgstr "Aufnahme beginnen" + +#: gtk2_ardour/ardour_ui_ed.cc:274 msgid "Rewind" msgstr "Rückwärts" -#: gtk2_ardour/ardour_ui_ed.cc:269 +#: gtk2_ardour/ardour_ui_ed.cc:277 msgid "Rewind (Slow)" msgstr "Rückwärts (langsam)" -#: gtk2_ardour/ardour_ui_ed.cc:272 +#: gtk2_ardour/ardour_ui_ed.cc:280 msgid "Rewind (Fast)" msgstr "Rückwärts (schnell)" -#: gtk2_ardour/ardour_ui_ed.cc:275 +#: gtk2_ardour/ardour_ui_ed.cc:283 msgid "Forward" msgstr "Vorwärts" -#: gtk2_ardour/ardour_ui_ed.cc:278 +#: gtk2_ardour/ardour_ui_ed.cc:286 msgid "Forward (Slow)" msgstr "Vorwärts (langsam)" -#: gtk2_ardour/ardour_ui_ed.cc:281 +#: gtk2_ardour/ardour_ui_ed.cc:289 msgid "Forward (Fast)" msgstr "Vorwärts (schnell)" -#: gtk2_ardour/ardour_ui_ed.cc:284 +#: gtk2_ardour/ardour_ui_ed.cc:292 msgid "Goto Zero" msgstr "Zum Nullpunkt springen" -#: gtk2_ardour/ardour_ui_ed.cc:287 +#: gtk2_ardour/ardour_ui_ed.cc:295 msgid "Goto Start" msgstr "Zum Anfang springen" -#: gtk2_ardour/ardour_ui_ed.cc:290 +#: gtk2_ardour/ardour_ui_ed.cc:298 msgid "Goto End" msgstr "Zum Ende Springen" -#: gtk2_ardour/ardour_ui_ed.cc:313 +#: gtk2_ardour/ardour_ui_ed.cc:302 +msgid "Focus On Clock" +msgstr "Fokus auf Zeitanzeige setzen" + +#: gtk2_ardour/ardour_ui_ed.cc:325 msgid "Sync startup to video" msgstr "Mit Video synchronisieren" -#: gtk2_ardour/ardour_ui_ed.cc:314 +#: gtk2_ardour/ardour_ui_ed.cc:326 msgid "Time master" msgstr "Time Master" -#: gtk2_ardour/ardour_ui_ed.cc:317 +#: gtk2_ardour/ardour_ui_ed.cc:329 msgid "Toggle Record Enable Track1" msgstr "Aufnahme aktivieren für Spur 1" -#: gtk2_ardour/ardour_ui_ed.cc:319 +#: gtk2_ardour/ardour_ui_ed.cc:331 msgid "Toggle Record Enable Track2" msgstr "Aufnahme aktivieren für Spur 2" -#: gtk2_ardour/ardour_ui_ed.cc:321 +#: gtk2_ardour/ardour_ui_ed.cc:333 msgid "Toggle Record Enable Track3" msgstr "Aufnahme aktivieren für Spur 3" -#: gtk2_ardour/ardour_ui_ed.cc:323 +#: gtk2_ardour/ardour_ui_ed.cc:335 msgid "Toggle Record Enable Track4" msgstr "Aufnahme aktivieren für Spur 4" -#: gtk2_ardour/ardour_ui_ed.cc:325 +#: gtk2_ardour/ardour_ui_ed.cc:337 msgid "Toggle Record Enable Track5" msgstr "Aufnahme aktivieren für Spur 5" -#: gtk2_ardour/ardour_ui_ed.cc:327 +#: gtk2_ardour/ardour_ui_ed.cc:339 msgid "Toggle Record Enable Track6" msgstr "Aufnahme aktivieren für Spur 6" -#: gtk2_ardour/ardour_ui_ed.cc:329 +#: gtk2_ardour/ardour_ui_ed.cc:341 msgid "Toggle Record Enable Track7" msgstr "Aufnahme aktivieren für Spur 7" -#: gtk2_ardour/ardour_ui_ed.cc:331 +#: gtk2_ardour/ardour_ui_ed.cc:343 msgid "Toggle Record Enable Track8" msgstr "Aufnahme aktivieren für Spur 8" -#: gtk2_ardour/ardour_ui_ed.cc:333 +#: gtk2_ardour/ardour_ui_ed.cc:345 msgid "Toggle Record Enable Track9" msgstr "Aufnahme aktivieren für Spur 9" -#: gtk2_ardour/ardour_ui_ed.cc:335 +#: gtk2_ardour/ardour_ui_ed.cc:347 msgid "Toggle Record Enable Track10" msgstr "Aufnahme aktivieren für Spur 10" -#: gtk2_ardour/ardour_ui_ed.cc:337 +#: gtk2_ardour/ardour_ui_ed.cc:349 msgid "Toggle Record Enable Track11" msgstr "Aufnahme aktivieren für Spur 11" -#: gtk2_ardour/ardour_ui_ed.cc:339 +#: gtk2_ardour/ardour_ui_ed.cc:351 msgid "Toggle Record Enable Track12" msgstr "Aufnahme aktivieren für Spur 12" -#: gtk2_ardour/ardour_ui_ed.cc:341 +#: gtk2_ardour/ardour_ui_ed.cc:353 msgid "Toggle Record Enable Track13" msgstr "Aufnahme aktivieren für Spur 13" -#: gtk2_ardour/ardour_ui_ed.cc:343 +#: gtk2_ardour/ardour_ui_ed.cc:355 msgid "Toggle Record Enable Track14" msgstr "Aufnahme aktivieren für Spur 14" -#: gtk2_ardour/ardour_ui_ed.cc:345 +#: gtk2_ardour/ardour_ui_ed.cc:357 msgid "Toggle Record Enable Track15" msgstr "Aufnahme aktivieren für Spur 15" -#: gtk2_ardour/ardour_ui_ed.cc:347 +#: gtk2_ardour/ardour_ui_ed.cc:359 msgid "Toggle Record Enable Track16" msgstr "Aufnahme aktivieren für Spur 16" -#: gtk2_ardour/ardour_ui_ed.cc:349 +#: gtk2_ardour/ardour_ui_ed.cc:361 msgid "Toggle Record Enable Track17" msgstr "Aufnahme aktivieren für Spur 17" -#: gtk2_ardour/ardour_ui_ed.cc:351 +#: gtk2_ardour/ardour_ui_ed.cc:363 msgid "Toggle Record Enable Track18" msgstr "Aufnahme aktivieren für Spur 18" -#: gtk2_ardour/ardour_ui_ed.cc:353 +#: gtk2_ardour/ardour_ui_ed.cc:365 msgid "Toggle Record Enable Track19" msgstr "Aufnahme aktivieren für Spur 19" -#: gtk2_ardour/ardour_ui_ed.cc:355 +#: gtk2_ardour/ardour_ui_ed.cc:367 msgid "Toggle Record Enable Track20" msgstr "Aufnahme aktivieren für Spur 20" -#: gtk2_ardour/ardour_ui_ed.cc:357 +#: gtk2_ardour/ardour_ui_ed.cc:369 msgid "Toggle Record Enable Track21" msgstr "Aufnahme aktivieren für Spur 21" -#: gtk2_ardour/ardour_ui_ed.cc:359 +#: gtk2_ardour/ardour_ui_ed.cc:371 msgid "Toggle Record Enable Track22" msgstr "Aufnahme aktivieren für Spur 22" -#: gtk2_ardour/ardour_ui_ed.cc:361 +#: gtk2_ardour/ardour_ui_ed.cc:373 msgid "Toggle Record Enable Track23" msgstr "Aufnahme aktivieren für Spur 23" -#: gtk2_ardour/ardour_ui_ed.cc:363 +#: gtk2_ardour/ardour_ui_ed.cc:375 msgid "Toggle Record Enable Track24" msgstr "Aufnahme aktivieren für Spur 24" -#: gtk2_ardour/ardour_ui_ed.cc:365 +#: gtk2_ardour/ardour_ui_ed.cc:377 msgid "Toggle Record Enable Track25" msgstr "Aufnahme aktivieren für Spur 25" -#: gtk2_ardour/ardour_ui_ed.cc:367 +#: gtk2_ardour/ardour_ui_ed.cc:379 msgid "Toggle Record Enable Track26" msgstr "Aufnahme aktivieren für Spur 26" -#: gtk2_ardour/ardour_ui_ed.cc:369 +#: gtk2_ardour/ardour_ui_ed.cc:381 msgid "Toggle Record Enable Track27" msgstr "Aufnahme aktivieren für Spur 27" -#: gtk2_ardour/ardour_ui_ed.cc:371 +#: gtk2_ardour/ardour_ui_ed.cc:383 msgid "Toggle Record Enable Track28" msgstr "Aufnahme aktivieren für Spur 28" -#: gtk2_ardour/ardour_ui_ed.cc:373 +#: gtk2_ardour/ardour_ui_ed.cc:385 msgid "Toggle Record Enable Track29" msgstr "Aufnahme aktivieren für Spur 29" -#: gtk2_ardour/ardour_ui_ed.cc:375 +#: gtk2_ardour/ardour_ui_ed.cc:387 msgid "Toggle Record Enable Track30" msgstr "Aufnahme aktivieren für Spur 30" -#: gtk2_ardour/ardour_ui_ed.cc:377 +#: gtk2_ardour/ardour_ui_ed.cc:389 msgid "Toggle Record Enable Track31" msgstr "Aufnahme aktivieren für Spur 31" -#: gtk2_ardour/ardour_ui_ed.cc:379 +#: gtk2_ardour/ardour_ui_ed.cc:391 msgid "Toggle Record Enable Track32" msgstr "Aufnahme aktivieren für Spur 32" -#: gtk2_ardour/ardour_ui_ed.cc:384 +#: gtk2_ardour/ardour_ui_ed.cc:396 msgid "Percentage" msgstr "Prozent" -#: gtk2_ardour/ardour_ui_ed.cc:385 +#: gtk2_ardour/ardour_ui_ed.cc:397 msgid "Semitones" msgstr "Halbtöne" -#: gtk2_ardour/ardour_ui_ed.cc:389 +#: gtk2_ardour/ardour_ui_ed.cc:401 msgid "Send MTC" msgstr "MTC senden" -#: gtk2_ardour/ardour_ui_ed.cc:391 +#: gtk2_ardour/ardour_ui_ed.cc:403 msgid "Send MMC" msgstr "MMC senden" -#: gtk2_ardour/ardour_ui_ed.cc:393 +#: gtk2_ardour/ardour_ui_ed.cc:405 msgid "Use MMC" msgstr "Benutze MMC" -#: gtk2_ardour/ardour_ui_ed.cc:395 +#: gtk2_ardour/ardour_ui_ed.cc:407 msgid "Send MIDI feedback" msgstr "MIDI Feedback senden" -#: gtk2_ardour/ardour_ui_ed.cc:398 +#: gtk2_ardour/ardour_ui_ed.cc:410 msgid "Use OSC" msgstr "Aktiviere OSC" -#: gtk2_ardour/ardour_ui_ed.cc:403 +#: gtk2_ardour/ardour_ui_ed.cc:415 +msgid "Sync Editor and Mixer track order" +msgstr "Einheitliche Reihenfolge der Spuren im Editor und Mixer" + +#: gtk2_ardour/ardour_ui_ed.cc:416 msgid "Stop plugins with transport" msgstr "Plugins mit Transport stoppen" -#: gtk2_ardour/ardour_ui_ed.cc:404 +#: gtk2_ardour/ardour_ui_ed.cc:417 msgid "Verify remove last capture" msgstr "Verwerfen der letzten Aufnahme bestätigen" -#: gtk2_ardour/ardour_ui_ed.cc:405 +#: gtk2_ardour/ardour_ui_ed.cc:418 +msgid "Make periodic safety backups" +msgstr "Erstelle regelmäßig Sicherungskopien" + +#: gtk2_ardour/ardour_ui_ed.cc:419 msgid "Stop recording on xrun" msgstr "Aufnahme bei XRUN stoppen" -#: gtk2_ardour/ardour_ui_ed.cc:406 +#: gtk2_ardour/ardour_ui_ed.cc:420 msgid "Stop transport at session end" msgstr "Transport am Ende des Projekts stoppen" -#: gtk2_ardour/ardour_ui_ed.cc:407 +#: gtk2_ardour/ardour_ui_ed.cc:421 msgid "-12dB gain reduce ffwd/rewind" msgstr "Beim Spulen Pegel um -12dB absenken" -#: gtk2_ardour/ardour_ui_ed.cc:408 +#: gtk2_ardour/ardour_ui_ed.cc:422 msgid "Rec-enable stays engaged at stop" msgstr "Aufnahmestatus bleibt nach Stop erhalten" -#: gtk2_ardour/ardour_ui_ed.cc:409 +#: gtk2_ardour/ardour_ui_ed.cc:423 msgid "Region equivalents overlap" msgstr "Region entspricht Ãœberdeckung" -#: gtk2_ardour/ardour_ui_ed.cc:411 +#: gtk2_ardour/ardour_ui_ed.cc:424 +msgid "Primary Clock delta to edit point" +msgstr "Primäre Zeitanzeige zeigt Abstand zum Arbeitspunkt" + +#: gtk2_ardour/ardour_ui_ed.cc:425 +msgid "Secondary Clock delta to edit point" +msgstr "Sekundäre Zeitanzeige zeigt Abstand zum Arbeitspunkt" + +#: gtk2_ardour/ardour_ui_ed.cc:426 +msgid "Enable Editor Meters" +msgstr "Aktiviere Pegelanzeigen im Editor" + +#: gtk2_ardour/ardour_ui_ed.cc:427 +msgid "Always copy imported files" +msgstr "Importierte Dateien immer kopieren" + +#: gtk2_ardour/ardour_ui_ed.cc:431 +msgid "Use DC bias" +msgstr "DC bias aktivieren" + +#: gtk2_ardour/ardour_ui_ed.cc:433 +msgid "No processor handling" +msgstr "Keine Korrekturen" + +#: gtk2_ardour/ardour_ui_ed.cc:442 +#: gtk2_ardour/ardour_ui_ed.cc:453 +msgid "Use FlushToZero" +msgstr "Benutze FlushToZero" + +#: gtk2_ardour/ardour_ui_ed.cc:444 +#: gtk2_ardour/ardour_ui_ed.cc:458 +msgid "Use DenormalsAreZero" +msgstr "Benutze DenormalsAreZero" + +#: gtk2_ardour/ardour_ui_ed.cc:446 +#: gtk2_ardour/ardour_ui_ed.cc:463 +msgid "Use FlushToZero & DenormalsAreZero" +msgstr "Benutze FlushToZero & DenormalsAreZero" + +#: gtk2_ardour/ardour_ui_ed.cc:469 msgid "Do not run plugins while recording" msgstr "Plugins während der Aufnahme daktivieren" -#: gtk2_ardour/ardour_ui_ed.cc:414 +#: gtk2_ardour/ardour_ui_ed.cc:471 msgid "Latched solo" msgstr "Latch Solo" -#: gtk2_ardour/ardour_ui_ed.cc:416 +#: gtk2_ardour/ardour_ui_ed.cc:473 msgid "Show solo muting" msgstr "Solo als Mute anzeigen" -#: gtk2_ardour/ardour_ui_ed.cc:424 -#: gtk2_ardour/ardour_ui_ed.cc:432 -#: gtk2_ardour/audio_clock.cc:1805 +#: gtk2_ardour/ardour_ui_ed.cc:481 +#: gtk2_ardour/ardour_ui_ed.cc:489 +#: gtk2_ardour/audio_clock.cc:1889 msgid "Off" msgstr "Aus" -#: gtk2_ardour/ardour_ui_ed.cc:425 -#: gtk2_ardour/editor.cc:1246 -#: gtk2_ardour/editor.cc:1263 +#: gtk2_ardour/ardour_ui_ed.cc:482 +#: gtk2_ardour/editor.cc:1335 +#: gtk2_ardour/editor.cc:1338 +#: gtk2_ardour/editor.cc:1357 +#: gtk2_ardour/editor.cc:1360 msgid "Slowest" msgstr "Sehr langsam" -#: gtk2_ardour/ardour_ui_ed.cc:426 -#: gtk2_ardour/editor.cc:1247 -#: gtk2_ardour/editor.cc:1264 +#: gtk2_ardour/ardour_ui_ed.cc:483 +#: gtk2_ardour/editor.cc:1339 +#: gtk2_ardour/editor.cc:1361 msgid "Slow" msgstr "Langsam" -#: gtk2_ardour/ardour_ui_ed.cc:427 -#: gtk2_ardour/ardour_ui_ed.cc:434 +#: gtk2_ardour/ardour_ui_ed.cc:484 +#: gtk2_ardour/ardour_ui_ed.cc:491 msgid "Medium" msgstr "Mittel" -#: gtk2_ardour/ardour_ui_ed.cc:428 -#: gtk2_ardour/editor.cc:1248 -#: gtk2_ardour/editor.cc:1265 +#: gtk2_ardour/ardour_ui_ed.cc:485 +#: gtk2_ardour/editor.cc:1340 +#: gtk2_ardour/editor.cc:1362 +#: gtk2_ardour/sfdb_ui.cc:1070 +#: gtk2_ardour/sfdb_ui.cc:1151 msgid "Fast" msgstr "Schnell" -#: gtk2_ardour/ardour_ui_ed.cc:429 +#: gtk2_ardour/ardour_ui_ed.cc:486 msgid "Faster" msgstr "Schneller" -#: gtk2_ardour/ardour_ui_ed.cc:430 -#: gtk2_ardour/editor.cc:1249 -#: gtk2_ardour/editor.cc:1266 +#: gtk2_ardour/ardour_ui_ed.cc:487 +#: gtk2_ardour/editor.cc:1341 +#: gtk2_ardour/editor.cc:1363 +#: gtk2_ardour/sfdb_ui.cc:1071 msgid "Fastest" msgstr "Schnellstmöglich" -#: gtk2_ardour/ardour_ui_ed.cc:433 -#: gtk2_ardour/editor_actions.cc:58 +#: gtk2_ardour/ardour_ui_ed.cc:490 +#: gtk2_ardour/editor_actions.cc:79 msgid "Short" msgstr "Kurz" -#: gtk2_ardour/ardour_ui_ed.cc:435 +#: gtk2_ardour/ardour_ui_ed.cc:492 msgid "Long" msgstr "Lange" -#: gtk2_ardour/ardour_ui_ed.cc:453 +#: gtk2_ardour/ardour_ui_ed.cc:511 msgid "Hardware monitoring" msgstr "Hardware Monitoring" -#: gtk2_ardour/ardour_ui_ed.cc:454 +#: gtk2_ardour/ardour_ui_ed.cc:512 msgid "Software monitoring" msgstr "Software Monitoring" -#: gtk2_ardour/ardour_ui_ed.cc:455 +#: gtk2_ardour/ardour_ui_ed.cc:513 msgid "External monitoring" msgstr "Externes Monitoring" -#: gtk2_ardour/ardour_ui_ed.cc:459 +#: gtk2_ardour/ardour_ui_ed.cc:517 msgid "Solo in-place" msgstr "Solo-In-Place" -#: gtk2_ardour/ardour_ui_ed.cc:461 +#: gtk2_ardour/ardour_ui_ed.cc:519 msgid "Solo via bus" msgstr "Solo über Bus" -#: gtk2_ardour/ardour_ui_ed.cc:466 +#: gtk2_ardour/ardour_ui_ed.cc:524 msgid "Auto-connect inputs to physical inputs" -msgstr "Eingänge automatisch mit Soundkarteneingängen verbinden" +msgstr "Eingänge automatisch mit Audioeingängen verbinden" -#: gtk2_ardour/ardour_ui_ed.cc:468 +#: gtk2_ardour/ardour_ui_ed.cc:526 msgid "Manually connect inputs" msgstr "Eingänge manuell verbinden" -#: gtk2_ardour/ardour_ui_ed.cc:473 +#: gtk2_ardour/ardour_ui_ed.cc:531 msgid "Auto-connect outputs to physical outs" -msgstr "Ausgänge automatisch mit Soundkartenausgängen verbinden" +msgstr "Ausgänge automatisch mit Audioausgängen verbinden" -#: gtk2_ardour/ardour_ui_ed.cc:475 +#: gtk2_ardour/ardour_ui_ed.cc:533 msgid "Auto-connect outputs to master bus" msgstr "Ausgänge automatisch mit Master-Bus verbinden" -#: gtk2_ardour/ardour_ui_ed.cc:477 +#: gtk2_ardour/ardour_ui_ed.cc:535 msgid "Manually connect outputs" msgstr "Ausgänge manuell verbinden" -#: gtk2_ardour/ardour_ui_ed.cc:482 +#: gtk2_ardour/ardour_ui_ed.cc:540 msgid "Remote ID assigned by User" msgstr "Fernsteuerungs-ID vom Benutzer festgelegt" -#: gtk2_ardour/ardour_ui_ed.cc:484 +#: gtk2_ardour/ardour_ui_ed.cc:542 msgid "Remote ID follows order of Mixer" msgstr "Fernsteuerungs-ID aus Reihenfolge im Mixer" -#: gtk2_ardour/ardour_ui_ed.cc:486 +#: gtk2_ardour/ardour_ui_ed.cc:544 msgid "Remote ID follows order of Editor" msgstr "Fernsteuerungs-ID aus Reihenfolge im Editor" -#: gtk2_ardour/ardour_ui_ed.cc:635 -#: gtk2_ardour/ladspa_pluginui.cc:168 +#: gtk2_ardour/ardour_ui_ed.cc:693 +#: gtk2_ardour/generic_pluginui.cc:168 msgid "Controls" msgstr "Steuerelemente" -#: gtk2_ardour/ardour_ui_ed.cc:639 +#: gtk2_ardour/ardour_ui_ed.cc:697 msgid "Feedback" msgstr "Feedback" -#: gtk2_ardour/ardour_ui_ed.cc:723 +#: gtk2_ardour/ardour_ui_ed.cc:803 msgid "Clock" -msgstr "Clock" - -#: gtk2_ardour/ardour_ui_options.cc:106 -#: gtk2_ardour/ardour_ui_options.cc:133 -#: gtk2_ardour/editor_actions.cc:725 -#: gtk2_ardour/editor_actions.cc:953 -#: gtk2_ardour/editor_actions.cc:966 -#: gtk2_ardour/editor_actions.cc:1030 -#: gtk2_ardour/sfdb_ui.cc:536 -#: gtk2_ardour/audio_streamview.cc:173 +msgstr "Zeitanzeige" + +#: gtk2_ardour/ardour_ui_options.cc:119 +#: gtk2_ardour/ardour_ui_options.cc:149 +#: gtk2_ardour/editor_actions.cc:874 +#: gtk2_ardour/editor_actions.cc:1233 +#: gtk2_ardour/editor_actions.cc:1246 +#: gtk2_ardour/editor_actions.cc:1310 +#: gtk2_ardour/engine_dialog.cc:887 +#: gtk2_ardour/audio_streamview.cc:172 msgid "programming error: %1" msgstr "Programmierfehler: %1" -#: gtk2_ardour/ardour_ui_options.cc:212 +#: gtk2_ardour/ardour_ui_options.cc:228 msgid "programming error: unknown solo model in ARDOUR_UI::set_solo_model: %1" msgstr "Programmierfehler: unbekannte Solo-Einstellung in ARDOUR_UI::set_solo_model: %1" -#: gtk2_ardour/ardour_ui_options.cc:245 +#: gtk2_ardour/ardour_ui_options.cc:261 msgid "programming error: unknown remote model in ARDOUR_UI::set_remote_model: %1" msgstr "Programmierfehler: unbekanntes Fernsteuerungsmodell in ARDOUR_UI::set_remote_model: %1" -#: gtk2_ardour/ardour_ui_options.cc:279 +#: gtk2_ardour/ardour_ui_options.cc:295 msgid "programming error: unknown monitor model in ARDOUR_UI::set_monitor_model: %1" msgstr "Programmierfehler: unbekannte Monitoring-Einstellung in ARDOUR_UI::set_monitor_model: %1" -#: gtk2_ardour/ardour_ui_options.cc:571 +#: gtk2_ardour/ardour_ui_options.cc:334 +msgid "programming error: unknown denormal model in ARDOUR_UI::set_denormal_model: %1" +msgstr "Programmierfehler: unknown denormal model in ARDOUR_UI::set_denormal_model: %1" + +#: gtk2_ardour/ardour_ui_options.cc:699 msgid "programming error: unknown file header format passed to ARDOUR_UI::map_file_data_format: %1" msgstr "Programmierfehler: unbekanntes Dateiheaderformat übergeben an ARDOUR_UI::map_file_data_format: %1" -#: gtk2_ardour/ardour_ui_options.cc:603 +#: gtk2_ardour/ardour_ui_options.cc:735 msgid "programming error: unknown file data format passed to ARDOUR_UI::map_file_data_format: %1" msgstr "Programmierfehler: unbekanntes Dateiformat übergeben an ARDOUR_UI::map_file_data_format: %1" -#: gtk2_ardour/ardour_ui_options.cc:932 +#: gtk2_ardour/ardour_ui_options.cc:1086 msgid "ST" msgstr "HT" -#: gtk2_ardour/audio_clock.cc:1801 -#: gtk2_ardour/editor.cc:181 +#: gtk2_ardour/audio_clock.cc:1885 +#: gtk2_ardour/editor.cc:179 +#: gtk2_ardour/editor_rulers.cc:410 msgid "Timecode" msgstr "Timecode" -#: gtk2_ardour/audio_clock.cc:1802 -#: gtk2_ardour/editor.cc:180 -#: gtk2_ardour/editor_rulers.cc:395 +#: gtk2_ardour/audio_clock.cc:1886 +#: gtk2_ardour/editor.cc:178 +#: gtk2_ardour/editor_rulers.cc:422 msgid "Bars:Beats" msgstr "Takte:Schläge" -#: gtk2_ardour/audio_clock.cc:1803 +#: gtk2_ardour/audio_clock.cc:1887 msgid "Minutes:Seconds" msgstr "Minuten:Sekunden" -#: gtk2_ardour/audio_clock.cc:1804 -msgid "Audio Frames" -msgstr "Audio Frames" - -#: gtk2_ardour/audio_clock.cc:1807 -msgid "Mode" -msgstr "Modus" +#: gtk2_ardour/audio_clock.cc:1888 +#: gtk2_ardour/editor.cc:180 +#: gtk2_ardour/editor_rulers.cc:416 +msgid "Samples" +msgstr "Samples" -#: gtk2_ardour/route_time_axis.cc:87 +#: gtk2_ardour/route_time_axis.cc:88 msgid "m" msgstr "m" -#: gtk2_ardour/route_time_axis.cc:87 +#: gtk2_ardour/route_time_axis.cc:88 msgid "s" msgstr "s" -#: gtk2_ardour/route_time_axis.cc:87 +#: gtk2_ardour/route_time_axis.cc:88 msgid "r" msgstr "r" -#: gtk2_ardour/route_time_axis.cc:91 +#: gtk2_ardour/route_time_axis.cc:92 msgid "g" msgstr "g" -#: gtk2_ardour/route_time_axis.cc:92 +#: gtk2_ardour/route_time_axis.cc:93 msgid "p" msgstr "w" -#: gtk2_ardour/route_time_axis.cc:93 -#: gtk2_ardour/automation_time_axis.cc:36 +#: gtk2_ardour/route_time_axis.cc:94 +#: gtk2_ardour/automation_time_axis.cc:55 #: gtk2_ardour/visual_time_axis.cc:73 msgid "h" msgstr "h" -#: gtk2_ardour/route_time_axis.cc:94 +#: gtk2_ardour/route_time_axis.cc:95 msgid "a" msgstr "a" -#: gtk2_ardour/route_time_axis.cc:95 +#: gtk2_ardour/route_time_axis.cc:96 #: gtk2_ardour/visual_time_axis.cc:72 msgid "v" msgstr "v" -#: gtk2_ardour/route_time_axis.cc:148 -#: gtk2_ardour/mixer_strip.cc:86 +#: gtk2_ardour/route_time_axis.cc:154 +#: gtk2_ardour/mixer_strip.cc:88 msgid "Record" msgstr "Aufnahme" -#: gtk2_ardour/route_time_axis.cc:156 -#: gtk2_ardour/editor_actions.cc:38 -#: gtk2_ardour/mixer_strip.cc:86 -#: gtk2_ardour/mixer_strip.cc:426 +#: gtk2_ardour/route_time_axis.cc:168 +#: gtk2_ardour/editor_actions.cc:58 +#: gtk2_ardour/mixer_strip.cc:88 +#: gtk2_ardour/mixer_strip.cc:422 msgid "Solo" msgstr "Solo" -#: gtk2_ardour/route_time_axis.cc:157 -#: gtk2_ardour/editor.cc:1549 -#: gtk2_ardour/editor.cc:1644 -#: gtk2_ardour/mixer_strip.cc:86 -#: gtk2_ardour/mixer_strip.cc:425 +#: gtk2_ardour/route_time_axis.cc:169 +#: gtk2_ardour/editor.cc:1647 +#: gtk2_ardour/editor.cc:1743 +#: gtk2_ardour/mixer_strip.cc:88 +#: gtk2_ardour/mixer_strip.cc:421 #: gtk2_ardour/panner_ui.cc:404 msgid "Mute" msgstr "Mute" -#: gtk2_ardour/route_time_axis.cc:158 +#: gtk2_ardour/route_time_axis.cc:170 msgid "Edit Group" msgstr "Bearbeitungsgruppe" -#: gtk2_ardour/route_time_axis.cc:159 +#: gtk2_ardour/route_time_axis.cc:171 #: gtk2_ardour/visual_time_axis.cc:91 msgid "Display Height" msgstr "Anzeigehöhe" -#: gtk2_ardour/route_time_axis.cc:160 +#: gtk2_ardour/route_time_axis.cc:172 msgid "Playlist" msgstr "Wiedergabeliste" -#: gtk2_ardour/route_time_axis.cc:161 -#: gtk2_ardour/route_time_axis.cc:414 +#: gtk2_ardour/route_time_axis.cc:173 +#: gtk2_ardour/route_time_axis.cc:431 msgid "Automation" msgstr "Automationen" -#: gtk2_ardour/route_time_axis.cc:162 +#: gtk2_ardour/route_time_axis.cc:174 #: gtk2_ardour/visual_time_axis.cc:92 msgid "Visual options" msgstr "Visuelle optionen" -#: gtk2_ardour/route_time_axis.cc:163 +#: gtk2_ardour/route_time_axis.cc:175 #: gtk2_ardour/visual_time_axis.cc:93 msgid "Hide this track" msgstr "Diese Spur verbergen" -#: gtk2_ardour/route_time_axis.cc:265 -#: gtk2_ardour/mixer_strip.cc:910 +#: gtk2_ardour/route_time_axis.cc:282 +#: gtk2_ardour/mixer_strip.cc:907 msgid "No group" msgstr "keine Gruppe" -#: gtk2_ardour/route_time_axis.cc:375 +#: gtk2_ardour/route_time_axis.cc:391 msgid "Show all automation" msgstr "Alle Automationen zeigen" -#: gtk2_ardour/route_time_axis.cc:378 +#: gtk2_ardour/route_time_axis.cc:394 msgid "Show existing automation" msgstr "Verfügbare Automationen zeigen" -#: gtk2_ardour/route_time_axis.cc:381 +#: gtk2_ardour/route_time_axis.cc:397 msgid "Hide all automation" msgstr "Automationen verbergen" -#: gtk2_ardour/route_time_axis.cc:384 +#: gtk2_ardour/route_time_axis.cc:400 msgid "Plugins" msgstr "Plugins" -#: gtk2_ardour/route_time_axis.cc:405 -#: gtk2_ardour/automation_time_axis.cc:431 +#: gtk2_ardour/route_time_axis.cc:421 +#: gtk2_ardour/automation_time_axis.cc:450 #: gtk2_ardour/imageframe_time_axis.cc:254 #: gtk2_ardour/marker_time_axis.cc:210 msgid "Height" msgstr "Höhe" -#: gtk2_ardour/route_time_axis.cc:406 -#: gtk2_ardour/color_manager.cc:41 +#: gtk2_ardour/route_time_axis.cc:422 #: gtk2_ardour/imageframe_time_axis.cc:255 #: gtk2_ardour/marker_time_axis.cc:211 +#: gtk2_ardour/theme_manager.cc:52 msgid "Color" msgstr "Farbe" -#: gtk2_ardour/route_time_axis.cc:411 +#: gtk2_ardour/route_time_axis.cc:430 #: gtk2_ardour/mixer_strip.cc:995 msgid "Remote Control ID" msgstr "ID für Fernsteuerung" -#: gtk2_ardour/route_time_axis.cc:429 +#: gtk2_ardour/route_time_axis.cc:447 msgid "Align with existing material" msgstr "An vorhandenem Material ausrichten" -#: gtk2_ardour/route_time_axis.cc:435 +#: gtk2_ardour/route_time_axis.cc:453 msgid "Align with capture time" msgstr "An Aufnahmezeit ausrichten" -#: gtk2_ardour/route_time_axis.cc:441 +#: gtk2_ardour/route_time_axis.cc:460 msgid "Alignment" msgstr "Ausrichtung" -#: gtk2_ardour/route_time_axis.cc:447 +#: gtk2_ardour/route_time_axis.cc:464 msgid "Normal mode" msgstr "Normaler Modus" -#: gtk2_ardour/route_time_axis.cc:450 +#: gtk2_ardour/route_time_axis.cc:467 msgid "Tape mode" msgstr "Tape-Modus" -#: gtk2_ardour/route_time_axis.cc:466 -#: gtk2_ardour/editor.cc:487 -#: gtk2_ardour/editor_actions.cc:61 -#: gtk2_ardour/mixer_strip.cc:984 -#: gtk2_ardour/mixer_ui.cc:108 +#: gtk2_ardour/route_time_axis.cc:484 +#: gtk2_ardour/editor.cc:502 +#: gtk2_ardour/editor_actions.cc:82 +#: gtk2_ardour/mixer_strip.cc:980 +#: gtk2_ardour/mixer_ui.cc:116 msgid "Active" msgstr "Aktiv" -#: gtk2_ardour/route_time_axis.cc:471 -#: gtk2_ardour/editor.cc:1746 -#: gtk2_ardour/editor.cc:3456 -#: gtk2_ardour/editor_actions.cc:328 -#: gtk2_ardour/editor_markers.cc:529 +#: gtk2_ardour/route_time_axis.cc:489 +#: gtk2_ardour/editor.cc:1852 +#: gtk2_ardour/editor.cc:3730 +#: gtk2_ardour/editor_actions.cc:463 +#: gtk2_ardour/editor_markers.cc:596 +#: gtk2_ardour/editor_markers.cc:652 #: gtk2_ardour/imageframe_time_axis.cc:258 #: gtk2_ardour/location_ui.cc:58 #: gtk2_ardour/marker_time_axis.cc:214 -#: gtk2_ardour/mixer_strip.cc:998 +#: gtk2_ardour/mixer_strip.cc:999 msgid "Remove" msgstr "Löschen" -#: gtk2_ardour/route_time_axis.cc:496 -#: gtk2_ardour/route_time_axis.cc:551 -#: gtk2_ardour/route_time_axis.cc:816 -#: gtk2_ardour/editor_actions.cc:1017 +#: gtk2_ardour/route_time_axis.cc:514 +#: gtk2_ardour/route_time_axis.cc:569 +#: gtk2_ardour/route_time_axis.cc:838 +#: gtk2_ardour/editor_actions.cc:1297 msgid "programming error: %1 %2" msgstr "Programmierfehler: %1 %2" -#: gtk2_ardour/route_time_axis.cc:840 +#: gtk2_ardour/route_time_axis.cc:862 msgid "Name for playlist" msgstr "Name für Wiedergabeliste" -#: gtk2_ardour/route_time_axis.cc:842 -#: gtk2_ardour/route_time_axis.cc:1305 -#: gtk2_ardour/editor.cc:3461 -#: gtk2_ardour/editor_markers.cc:875 -#: gtk2_ardour/editor_mouse.cc:4752 +#: gtk2_ardour/route_time_axis.cc:864 +#: gtk2_ardour/route_time_axis.cc:1340 +#: gtk2_ardour/editor.cc:1714 +#: gtk2_ardour/editor.cc:3735 +#: gtk2_ardour/editor_markers.cc:590 +#: gtk2_ardour/editor_markers.cc:1022 +#: gtk2_ardour/editor_mouse.cc:5097 #: gtk2_ardour/imageframe_time_axis.cc:247 #: gtk2_ardour/marker_time_axis.cc:207 -#: gtk2_ardour/mixer_strip.cc:982 -#: gtk2_ardour/redirect_box.cc:825 -#: gtk2_ardour/redirect_box.cc:1165 -#: gtk2_ardour/route_ui.cc:807 +#: gtk2_ardour/mixer_strip.cc:978 +#: gtk2_ardour/redirect_box.cc:860 +#: gtk2_ardour/redirect_box.cc:1192 +#: gtk2_ardour/route_ui.cc:814 #: gtk2_ardour/visual_time_axis.cc:330 msgid "Rename" msgstr "Umbenennen" -#: gtk2_ardour/route_time_axis.cc:884 -#: gtk2_ardour/route_time_axis.cc:930 +#: gtk2_ardour/route_time_axis.cc:906 +#: gtk2_ardour/route_time_axis.cc:952 msgid "Name for Playlist" msgstr "Name für Wiedergabeliste" -#: gtk2_ardour/route_time_axis.cc:1133 +#: gtk2_ardour/route_time_axis.cc:1155 #: gtk2_ardour/visual_time_axis.cc:340 #: gtk2_ardour/visual_time_axis.cc:387 msgid "A track already exists with that name" msgstr "Es existiert bereits eine Spur mit diesem Namen" -#: gtk2_ardour/route_time_axis.cc:1309 +#: gtk2_ardour/route_time_axis.cc:1344 msgid "New Copy" msgstr "Neue Kopie" -#: gtk2_ardour/route_time_axis.cc:1311 +#: gtk2_ardour/route_time_axis.cc:1346 msgid "Clear Current" msgstr "Ausgewählte zurücksetzen" -#: gtk2_ardour/route_time_axis.cc:1314 +#: gtk2_ardour/route_time_axis.cc:1349 msgid "Select from all ..." msgstr "Aus allen auswählen..." -#: gtk2_ardour/route_time_axis.cc:1520 -#: gtk2_ardour/editor.cc:1271 -#: gtk2_ardour/selection.cc:661 -#: gtk2_ardour/selection.cc:700 +#: gtk2_ardour/route_time_axis.cc:1554 +#: gtk2_ardour/editor.cc:1368 +#: gtk2_ardour/selection.cc:694 +#: gtk2_ardour/selection.cc:733 msgid "programming error: " msgstr "Programmierfehler:" -#: gtk2_ardour/audio_time_axis.cc:213 +#: gtk2_ardour/audio_time_axis.cc:214 msgid "Fader" msgstr "Fader" -#: gtk2_ardour/audio_time_axis.cc:218 +#: gtk2_ardour/audio_time_axis.cc:219 msgid "Pan" msgstr "Pan" -#: gtk2_ardour/audio_time_axis.cc:233 +#: gtk2_ardour/audio_time_axis.cc:235 msgid "Hide all crossfades" msgstr "Alle Crossfades verbergen" -#: gtk2_ardour/audio_time_axis.cc:234 +#: gtk2_ardour/audio_time_axis.cc:236 msgid "Show all crossfades" msgstr "Alle Crossfades zeigen" -#: gtk2_ardour/audio_time_axis.cc:241 +#: gtk2_ardour/audio_time_axis.cc:244 msgid "Show waveforms" msgstr "Wellenformen zeigen" -#: gtk2_ardour/audio_time_axis.cc:251 +#: gtk2_ardour/audio_time_axis.cc:254 msgid "Traditional" msgstr "Traditionell" -#: gtk2_ardour/audio_time_axis.cc:254 +#: gtk2_ardour/audio_time_axis.cc:258 msgid "Rectified" msgstr "Gleichgerichtet" -#: gtk2_ardour/audio_time_axis.cc:261 -#: gtk2_ardour/editor.cc:1245 -#: gtk2_ardour/editor.cc:1262 +#: gtk2_ardour/audio_time_axis.cc:268 +#: gtk2_ardour/editor.cc:1334 +#: gtk2_ardour/editor.cc:1337 +#: gtk2_ardour/editor.cc:1356 +#: gtk2_ardour/editor.cc:1359 msgid "Linear" msgstr "Linear" -#: gtk2_ardour/audio_time_axis.cc:264 +#: gtk2_ardour/audio_time_axis.cc:271 msgid "Logarithmic" msgstr "Logarithmisch" -#: gtk2_ardour/audio_time_axis.cc:281 +#: gtk2_ardour/audio_time_axis.cc:290 msgid "Waveform" msgstr "Wellenform" -#: gtk2_ardour/audio_time_axis.cc:353 +#: gtk2_ardour/audio_time_axis.cc:362 msgid "gain" msgstr "Gain" -#: gtk2_ardour/audio_time_axis.cc:393 +#: gtk2_ardour/audio_time_axis.cc:402 msgid "pan" msgstr "Pan" @@ -1877,96 +2093,96 @@ msgid "automation range drag" msgstr "Automationsbereich bewegen" #: gtk2_ardour/automation_line.cc:1021 -#: gtk2_ardour/region_gain_line.cc:64 +#: gtk2_ardour/region_gain_line.cc:83 msgid "remove control point" msgstr "Automationspunkt entfernen" -#: gtk2_ardour/automation_time_axis.cc:37 -#: gtk2_ardour/editor_ops.cc:2641 +#: gtk2_ardour/automation_time_axis.cc:56 +#: gtk2_ardour/editor_ops.cc:3404 msgid "clear" msgstr "Leeren" -#: gtk2_ardour/automation_time_axis.cc:78 +#: gtk2_ardour/automation_time_axis.cc:97 msgid "track height" msgstr "Anzeigehöhe" -#: gtk2_ardour/automation_time_axis.cc:79 +#: gtk2_ardour/automation_time_axis.cc:98 msgid "automation state" msgstr "Automationsmodus" -#: gtk2_ardour/automation_time_axis.cc:80 +#: gtk2_ardour/automation_time_axis.cc:99 msgid "clear track" msgstr "Spur zurücksetzen" -#: gtk2_ardour/automation_time_axis.cc:81 +#: gtk2_ardour/automation_time_axis.cc:100 msgid "hide track" msgstr "Diese Spur verbergen" -#: gtk2_ardour/automation_time_axis.cc:188 -#: gtk2_ardour/automation_time_axis.cc:217 -#: gtk2_ardour/automation_time_axis.cc:442 -#: gtk2_ardour/gain_meter.cc:159 -#: gtk2_ardour/ladspa_pluginui.cc:332 -#: gtk2_ardour/ladspa_pluginui.cc:576 +#: gtk2_ardour/automation_time_axis.cc:207 +#: gtk2_ardour/automation_time_axis.cc:236 +#: gtk2_ardour/automation_time_axis.cc:461 +#: gtk2_ardour/gain_meter.cc:160 +#: gtk2_ardour/generic_pluginui.cc:332 +#: gtk2_ardour/generic_pluginui.cc:579 #: gtk2_ardour/panner_ui.cc:88 msgid "Manual" msgstr "Manuell" -#: gtk2_ardour/automation_time_axis.cc:190 -#: gtk2_ardour/automation_time_axis.cc:228 -#: gtk2_ardour/automation_time_axis.cc:446 -#: gtk2_ardour/editor.cc:1824 -#: gtk2_ardour/editor.cc:1905 -#: gtk2_ardour/gain_meter.cc:161 -#: gtk2_ardour/ladspa_pluginui.cc:335 -#: gtk2_ardour/ladspa_pluginui.cc:578 +#: gtk2_ardour/automation_time_axis.cc:209 +#: gtk2_ardour/automation_time_axis.cc:247 +#: gtk2_ardour/automation_time_axis.cc:465 +#: gtk2_ardour/editor.cc:1931 +#: gtk2_ardour/editor.cc:2014 +#: gtk2_ardour/gain_meter.cc:162 +#: gtk2_ardour/generic_pluginui.cc:335 +#: gtk2_ardour/generic_pluginui.cc:581 #: gtk2_ardour/panner_ui.cc:90 -#: gtk2_ardour/sfdb_ui.cc:61 msgid "Play" -msgstr "Play" +msgstr "Wiedergabe" -#: gtk2_ardour/automation_time_axis.cc:192 -#: gtk2_ardour/automation_time_axis.cc:239 -#: gtk2_ardour/automation_time_axis.cc:450 -#: gtk2_ardour/gain_meter.cc:163 -#: gtk2_ardour/ladspa_pluginui.cc:338 -#: gtk2_ardour/ladspa_pluginui.cc:580 +#: gtk2_ardour/automation_time_axis.cc:211 +#: gtk2_ardour/automation_time_axis.cc:258 +#: gtk2_ardour/automation_time_axis.cc:469 +#: gtk2_ardour/gain_meter.cc:164 +#: gtk2_ardour/generic_pluginui.cc:338 +#: gtk2_ardour/generic_pluginui.cc:583 #: gtk2_ardour/panner_ui.cc:92 msgid "Write" msgstr "Write" -#: gtk2_ardour/automation_time_axis.cc:194 -#: gtk2_ardour/automation_time_axis.cc:250 -#: gtk2_ardour/automation_time_axis.cc:454 -#: gtk2_ardour/gain_meter.cc:165 -#: gtk2_ardour/ladspa_pluginui.cc:341 -#: gtk2_ardour/ladspa_pluginui.cc:582 +#: gtk2_ardour/automation_time_axis.cc:213 +#: gtk2_ardour/automation_time_axis.cc:269 +#: gtk2_ardour/automation_time_axis.cc:473 +#: gtk2_ardour/gain_meter.cc:166 +#: gtk2_ardour/generic_pluginui.cc:341 +#: gtk2_ardour/generic_pluginui.cc:585 #: gtk2_ardour/panner_ui.cc:94 msgid "Touch" msgstr "Touch" -#: gtk2_ardour/automation_time_axis.cc:261 -#: gtk2_ardour/ladspa_pluginui.cc:344 +#: gtk2_ardour/automation_time_axis.cc:280 +#: gtk2_ardour/generic_pluginui.cc:344 msgid "???" msgstr "???" -#: gtk2_ardour/automation_time_axis.cc:275 +#: gtk2_ardour/automation_time_axis.cc:294 msgid "clear automation" msgstr "Automation zurücksetzen" -#: gtk2_ardour/automation_time_axis.cc:433 -#: gtk2_ardour/editor_actions.cc:326 +#: gtk2_ardour/automation_time_axis.cc:452 +#: gtk2_ardour/editor_actions.cc:461 +#: gtk2_ardour/editor_markers.cc:588 msgid "Hide" msgstr "Verbergen" -#: gtk2_ardour/automation_time_axis.cc:435 -#: gtk2_ardour/crossfade_edit.cc:78 -#: gtk2_ardour/redirect_box.cc:1157 +#: gtk2_ardour/automation_time_axis.cc:454 +#: gtk2_ardour/crossfade_edit.cc:77 +#: gtk2_ardour/redirect_box.cc:1180 #: gtk2_ardour/connection_editor.cc:56 msgid "Clear" msgstr "Leeren" -#: gtk2_ardour/automation_time_axis.cc:458 +#: gtk2_ardour/automation_time_axis.cc:477 msgid "State" msgstr "Automationssmodus" @@ -2116,765 +2332,840 @@ msgstr "" msgid "color of fill" msgstr "" -#: gtk2_ardour/color_manager.cc:40 -msgid "Object" -msgstr "" - -#: gtk2_ardour/color_manager.cc:78 -msgid "cannot open color definition file %1: %2" -msgstr "Konnte die Datei mit den Farbdefinitonen %1 nicht laden: %2" - -#: gtk2_ardour/crossfade_edit.cc:75 +#: gtk2_ardour/crossfade_edit.cc:74 msgid "ardour: x-fade edit" msgstr "ardour: Crossfade Editor" -#: gtk2_ardour/crossfade_edit.cc:79 +#: gtk2_ardour/crossfade_edit.cc:78 #: gtk2_ardour/panner_ui.cc:420 msgid "Reset" msgstr "Zurücksetzen" -#: gtk2_ardour/crossfade_edit.cc:80 +#: gtk2_ardour/crossfade_edit.cc:79 msgid "Fade" msgstr "Fade" -#: gtk2_ardour/crossfade_edit.cc:81 +#: gtk2_ardour/crossfade_edit.cc:80 msgid "Out (dry)" msgstr "Out (dry)" -#: gtk2_ardour/crossfade_edit.cc:82 +#: gtk2_ardour/crossfade_edit.cc:81 msgid "Out" msgstr "Out" -#: gtk2_ardour/crossfade_edit.cc:83 +#: gtk2_ardour/crossfade_edit.cc:82 msgid "In (dry)" msgstr "In (dry)" -#: gtk2_ardour/crossfade_edit.cc:84 +#: gtk2_ardour/crossfade_edit.cc:83 msgid "In" msgstr "In" -#: gtk2_ardour/crossfade_edit.cc:86 +#: gtk2_ardour/crossfade_edit.cc:85 msgid "With Pre-roll" msgstr "mit Pre-Roll" -#: gtk2_ardour/crossfade_edit.cc:87 +#: gtk2_ardour/crossfade_edit.cc:86 msgid "With Post-roll" msgstr "mit Post-Roll" -#: gtk2_ardour/crossfade_edit.cc:95 +#: gtk2_ardour/crossfade_edit.cc:94 msgid "Fade In" msgstr "Fade In" -#: gtk2_ardour/crossfade_edit.cc:96 +#: gtk2_ardour/crossfade_edit.cc:95 msgid "Fade Out" msgstr "Fade Out" -#: gtk2_ardour/crossfade_edit.cc:172 -#: gtk2_ardour/editor.cc:1624 -#: gtk2_ardour/editor_actions.cc:324 -#: gtk2_ardour/option_editor.cc:134 +#: gtk2_ardour/crossfade_edit.cc:171 +#: gtk2_ardour/editor.cc:1723 +#: gtk2_ardour/editor_actions.cc:459 +#: gtk2_ardour/option_editor.cc:148 msgid "Audition" msgstr "Vorhören" -#: gtk2_ardour/editor.cc:104 -#: gtk2_ardour/editor.cc:2995 -#: gtk2_ardour/editor_actions.cc:402 -#: gtk2_ardour/export_dialog.cc:78 -#: gtk2_ardour/export_dialog.cc:92 -#: gtk2_ardour/export_dialog.cc:895 -#: gtk2_ardour/export_dialog.cc:1227 -#: gtk2_ardour/route_ui.cc:506 -msgid "None" -msgstr "Kein" - -#: gtk2_ardour/editor.cc:105 -#: gtk2_ardour/editor.cc:2983 +#: gtk2_ardour/editor.cc:109 +#: gtk2_ardour/editor.cc:3214 msgid "CD Frames" msgstr "CD-Frames" -#: gtk2_ardour/editor.cc:106 -#: gtk2_ardour/editor.cc:2985 +#: gtk2_ardour/editor.cc:110 +#: gtk2_ardour/editor.cc:3216 msgid "SMPTE Frames" msgstr "SMPTE-Frames" -#: gtk2_ardour/editor.cc:107 -#: gtk2_ardour/editor.cc:2987 +#: gtk2_ardour/editor.cc:111 +#: gtk2_ardour/editor.cc:2748 +#: gtk2_ardour/editor.cc:3218 msgid "SMPTE Seconds" msgstr "SMPTE-Sekunden" -#: gtk2_ardour/editor.cc:108 -#: gtk2_ardour/editor.cc:2989 +#: gtk2_ardour/editor.cc:112 +#: gtk2_ardour/editor.cc:3220 msgid "SMPTE Minutes" msgstr "SMPTE-Minuten" -#: gtk2_ardour/editor.cc:109 -#: gtk2_ardour/editor.cc:2991 +#: gtk2_ardour/editor.cc:113 +#: gtk2_ardour/editor.cc:3222 msgid "Seconds" msgstr "Sekunden" -#: gtk2_ardour/editor.cc:110 -#: gtk2_ardour/editor.cc:2993 +#: gtk2_ardour/editor.cc:114 +#: gtk2_ardour/editor.cc:3224 msgid "Minutes" msgstr "Minuten" -#: gtk2_ardour/editor.cc:111 -#: gtk2_ardour/editor.cc:2965 +#: gtk2_ardour/editor.cc:115 +#: gtk2_ardour/editor.cc:3198 msgid "Beats/32" msgstr "Schläge / 32" -#: gtk2_ardour/editor.cc:112 -#: gtk2_ardour/editor.cc:2963 +#: gtk2_ardour/editor.cc:116 +#: gtk2_ardour/editor.cc:3196 msgid "Beats/16" msgstr "Schläge / 16" -#: gtk2_ardour/editor.cc:113 -#: gtk2_ardour/editor.cc:2961 +#: gtk2_ardour/editor.cc:117 +#: gtk2_ardour/editor.cc:3194 msgid "Beats/8" msgstr "Schläge / 8" -#: gtk2_ardour/editor.cc:114 -#: gtk2_ardour/editor.cc:2959 +#: gtk2_ardour/editor.cc:118 +#: gtk2_ardour/editor.cc:3192 msgid "Beats/4" msgstr "Schläge / 4" -#: gtk2_ardour/editor.cc:115 -#: gtk2_ardour/editor.cc:2957 +#: gtk2_ardour/editor.cc:119 +#: gtk2_ardour/editor.cc:3190 msgid "Beats/3" msgstr "Schläge / 3" -#: gtk2_ardour/editor.cc:116 -#: gtk2_ardour/editor.cc:2967 +#: gtk2_ardour/editor.cc:120 +#: gtk2_ardour/editor.cc:3200 msgid "Beats" msgstr "Schläge" -#: gtk2_ardour/editor.cc:117 -#: gtk2_ardour/editor.cc:2969 +#: gtk2_ardour/editor.cc:121 +#: gtk2_ardour/editor.cc:3202 msgid "Bars" msgstr "Takte" -#: gtk2_ardour/editor.cc:118 -#: gtk2_ardour/editor.cc:2971 +#: gtk2_ardour/editor.cc:122 +#: gtk2_ardour/editor.cc:3204 msgid "Marks" msgstr "Marker" -#: gtk2_ardour/editor.cc:119 -#: gtk2_ardour/editor.cc:138 -#: gtk2_ardour/editor.cc:2973 -#: gtk2_ardour/editor.cc:3038 -msgid "Edit Cursor" -msgstr "Editierzeiger" - -#: gtk2_ardour/editor.cc:120 -#: gtk2_ardour/editor.cc:2975 +#: gtk2_ardour/editor.cc:123 +#: gtk2_ardour/editor.cc:3206 msgid "Region starts" msgstr "Regionen-Anfang" -#: gtk2_ardour/editor.cc:121 -#: gtk2_ardour/editor.cc:2977 +#: gtk2_ardour/editor.cc:124 +#: gtk2_ardour/editor.cc:3208 msgid "Region ends" msgstr "Regionen-Ende" -#: gtk2_ardour/editor.cc:122 -#: gtk2_ardour/editor.cc:2981 +#: gtk2_ardour/editor.cc:125 +#: gtk2_ardour/editor.cc:3212 msgid "Region syncs" msgstr "Regionen-Sync" -#: gtk2_ardour/editor.cc:123 -#: gtk2_ardour/editor.cc:2979 +#: gtk2_ardour/editor.cc:126 +#: gtk2_ardour/editor.cc:3210 msgid "Region bounds" msgstr "Regionen-Grenzen" -#: gtk2_ardour/editor.cc:129 -#: gtk2_ardour/editor.cc:3013 -#: gtk2_ardour/editor_actions.cc:289 +#: gtk2_ardour/editor.cc:131 +#: gtk2_ardour/editor.cc:3240 +#: gtk2_ardour/editor_actions.cc:421 +msgid "No Grid" +msgstr "Raster aus" + +#: gtk2_ardour/editor.cc:132 +#: gtk2_ardour/editor.cc:3242 +#: gtk2_ardour/editor_actions.cc:422 +msgid "Grid" +msgstr "Einrasten" + +#: gtk2_ardour/editor.cc:133 +#: gtk2_ardour/editor.cc:3244 +#: gtk2_ardour/editor_actions.cc:423 msgid "Magnetic" msgstr "Magnetisch" -#: gtk2_ardour/editor.cc:134 -#: gtk2_ardour/editor.cc:3030 +#: gtk2_ardour/editor.cc:138 +#: gtk2_ardour/editor.cc:148 +#: gtk2_ardour/editor.cc:2734 +#: gtk2_ardour/editor.cc:2760 +#: gtk2_ardour/editor.cc:3283 +#: gtk2_ardour/editor.cc:3308 +#: gtk2_ardour/editor_actions.cc:406 +msgid "Playhead" +msgstr "Positionszeiger" + +#: gtk2_ardour/editor.cc:139 +#: gtk2_ardour/editor.cc:3281 +#: gtk2_ardour/editor_actions.cc:408 +#: gtk2_ardour/marker_time_axis.cc:255 +msgid "Marker" +msgstr "Marker" + +#: gtk2_ardour/editor.cc:140 +#: gtk2_ardour/editor.cc:149 +#: gtk2_ardour/editor.cc:3310 +#: gtk2_ardour/editor_actions.cc:407 +msgid "Mouse" +msgstr "Maus" + +#: gtk2_ardour/editor.cc:145 +#: gtk2_ardour/editor.cc:3302 #: gtk2_ardour/export_dialog.cc:142 #: gtk2_ardour/export_dialog.cc:158 -#: gtk2_ardour/export_dialog.cc:1070 -#: gtk2_ardour/export_dialog.cc:1074 +#: gtk2_ardour/export_dialog.cc:1131 +#: gtk2_ardour/export_dialog.cc:1135 msgid "Left" msgstr "Links" -#: gtk2_ardour/editor.cc:135 -#: gtk2_ardour/editor.cc:3032 +#: gtk2_ardour/editor.cc:146 +#: gtk2_ardour/editor.cc:3304 #: gtk2_ardour/export_dialog.cc:143 #: gtk2_ardour/export_dialog.cc:159 msgid "Right" msgstr "Rechts" -#: gtk2_ardour/editor.cc:136 -#: gtk2_ardour/editor.cc:3034 +#: gtk2_ardour/editor.cc:147 +#: gtk2_ardour/editor.cc:3306 msgid "Center" msgstr "Mitte" -#: gtk2_ardour/editor.cc:137 -#: gtk2_ardour/editor.cc:3036 -msgid "Playhead" -msgstr "Positionszeiger" +#: gtk2_ardour/editor.cc:150 +#: gtk2_ardour/editor.cc:3312 +msgid "Edit Point" +msgstr "Arbeitspunkt" -#: gtk2_ardour/editor.cc:179 +#: gtk2_ardour/editor.cc:177 msgid "Mins:Secs" msgstr "Min:Sek" -#: gtk2_ardour/editor.cc:182 -#: gtk2_ardour/editor_rulers.cc:389 -msgid "Frames" -msgstr "Frames" - -#: gtk2_ardour/editor.cc:183 -#: gtk2_ardour/editor_rulers.cc:409 +#: gtk2_ardour/editor.cc:181 +#: gtk2_ardour/editor_rulers.cc:436 msgid "Tempo" msgstr "Tempo" -#: gtk2_ardour/editor.cc:184 -#: gtk2_ardour/editor_rulers.cc:403 +#: gtk2_ardour/editor.cc:182 +#: gtk2_ardour/editor_rulers.cc:430 msgid "Meter" msgstr "Taktart" -#: gtk2_ardour/editor.cc:185 -#: gtk2_ardour/editor_rulers.cc:415 +#: gtk2_ardour/editor.cc:183 +#: gtk2_ardour/editor_rulers.cc:442 msgid "Location Markers" msgstr "Positionsmarker" -#: gtk2_ardour/editor.cc:186 -#: gtk2_ardour/editor_rulers.cc:421 +#: gtk2_ardour/editor.cc:184 +#: gtk2_ardour/editor_rulers.cc:449 msgid "Range Markers" msgstr "Bereiche" -#: gtk2_ardour/editor.cc:187 -#: gtk2_ardour/editor_rulers.cc:427 +#: gtk2_ardour/editor.cc:185 +#: gtk2_ardour/editor_rulers.cc:462 msgid "Loop/Punch Ranges" msgstr "Schleifen/Punch-Bereiche" -#: gtk2_ardour/editor.cc:205 +#: gtk2_ardour/editor.cc:186 +#: gtk2_ardour/editor_rulers.cc:456 +msgid "CD Markers" +msgstr "CD-Marker" + +#: gtk2_ardour/editor.cc:204 msgid "mode" msgstr "Modus" -#: gtk2_ardour/editor.cc:206 +#: gtk2_ardour/editor.cc:205 msgid "automation" msgstr "Automation" -#: gtk2_ardour/editor.cc:462 -#: gtk2_ardour/editor.cc:488 -#: gtk2_ardour/editor_actions.cc:63 -#: gtk2_ardour/mixer_ui.cc:83 -#: gtk2_ardour/mixer_ui.cc:109 +#: gtk2_ardour/editor.cc:476 +#: gtk2_ardour/editor.cc:503 +#: gtk2_ardour/editor_actions.cc:84 +#: gtk2_ardour/mixer_ui.cc:90 +#: gtk2_ardour/mixer_ui.cc:117 #: gtk2_ardour/analysis_window.cc:63 msgid "Show" msgstr "Anzeigen" -#: gtk2_ardour/editor.cc:463 -#: gtk2_ardour/editor.cc:486 +#: gtk2_ardour/editor.cc:477 +#: gtk2_ardour/editor.cc:501 msgid "Name" msgstr "Name" -#: gtk2_ardour/editor.cc:561 -#: gtk2_ardour/editor.cc:628 -msgid "Regions" -msgstr "Regionen" - -#: gtk2_ardour/editor.cc:600 -#: gtk2_ardour/editor.cc:640 +#: gtk2_ardour/editor.cc:619 +#: gtk2_ardour/editor.cc:661 msgid "Chunks" msgstr "Teile" -#: gtk2_ardour/editor.cc:631 +#: gtk2_ardour/editor.cc:650 msgid "Tracks/Busses" msgstr "Spuren/Busse" -#: gtk2_ardour/editor.cc:634 +#: gtk2_ardour/editor.cc:653 msgid "Snapshots" -msgstr "Schnapschüsse" +msgstr "Schnappschüsse" -#: gtk2_ardour/editor.cc:637 +#: gtk2_ardour/editor.cc:656 msgid "Edit Groups" msgstr "Bearbeitungsgruppen" -#: gtk2_ardour/editor.cc:688 +#: gtk2_ardour/editor.cc:720 msgid "Nudge Region/Selection Forwards" msgstr "Region/Auswahl schrittweise nach vorne" -#: gtk2_ardour/editor.cc:689 +#: gtk2_ardour/editor.cc:721 msgid "Nudge Region/Selection Backwards" msgstr "Region/Auswahl schrittweise nach hinten" -#: gtk2_ardour/editor.cc:719 -#: gtk2_ardour/editor_mixer.cc:352 +#: gtk2_ardour/editor.cc:751 +#: gtk2_ardour/editor_mixer.cc:358 msgid "Editor" msgstr "Editor" -#: gtk2_ardour/editor.cc:1095 -#: gtk2_ardour/editor.cc:1103 -#: gtk2_ardour/editor_markers.cc:919 +#: gtk2_ardour/editor.cc:1169 +#: gtk2_ardour/editor.cc:1177 +#: gtk2_ardour/editor.cc:4181 +#: gtk2_ardour/editor.cc:4209 msgid "Loop" msgstr "Schleife" -#: gtk2_ardour/editor.cc:1108 -#: gtk2_ardour/editor.cc:1116 -#: gtk2_ardour/editor_markers.cc:947 +#: gtk2_ardour/editor.cc:1182 +#: gtk2_ardour/editor.cc:1190 msgid "Punch" msgstr "Punch" -#: gtk2_ardour/editor.cc:1226 -#: gtk2_ardour/editor_mouse.cc:1691 +#: gtk2_ardour/editor.cc:1314 +#: gtk2_ardour/editor_mouse.cc:1823 msgid "programming error: fade in canvas item has no regionview data pointer!" msgstr "Programmierfehler: fade in canvas item has no regionview data pointer!" -#: gtk2_ardour/editor.cc:1238 -#: gtk2_ardour/editor.cc:1255 -#: gtk2_ardour/redirect_box.cc:1173 +#: gtk2_ardour/editor.cc:1326 +#: gtk2_ardour/editor.cc:1348 +#: gtk2_ardour/redirect_box.cc:1200 msgid "Deactivate" msgstr "Deaktivieren" -#: gtk2_ardour/editor.cc:1240 -#: gtk2_ardour/editor.cc:1257 -#: gtk2_ardour/redirect_box.cc:1171 +#: gtk2_ardour/editor.cc:1328 +#: gtk2_ardour/editor.cc:1350 +#: gtk2_ardour/redirect_box.cc:1198 msgid "Activate" msgstr "Aktivieren" -#: gtk2_ardour/editor.cc:1378 -#: gtk2_ardour/editor.cc:1386 -#: gtk2_ardour/editor_ops.cc:2534 +#: gtk2_ardour/editor.cc:1475 +#: gtk2_ardour/editor.cc:1483 +#: gtk2_ardour/editor_ops.cc:3297 msgid "Freeze" msgstr "Einfrieren" -#: gtk2_ardour/editor.cc:1382 +#: gtk2_ardour/editor.cc:1479 msgid "Unfreeze" msgstr "Auftauen" -#: gtk2_ardour/editor.cc:1551 +#: gtk2_ardour/editor.cc:1649 msgid "Unmute" msgstr "Unmute" -#: gtk2_ardour/editor.cc:1555 -#: gtk2_ardour/editor.cc:1869 -#: gtk2_ardour/editor_actions.cc:28 -#: gtk2_ardour/editor_markers.cc:528 -#: gtk2_ardour/mixer_strip.cc:508 -#: gtk2_ardour/mixer_strip.cc:570 -#: gtk2_ardour/redirect_box.cc:1179 +#: gtk2_ardour/editor.cc:1653 +#: gtk2_ardour/editor.cc:1978 +#: gtk2_ardour/editor_actions.cc:47 +#: gtk2_ardour/editor_markers.cc:651 +#: gtk2_ardour/mixer_strip.cc:502 +#: gtk2_ardour/mixer_strip.cc:564 +#: gtk2_ardour/redirect_box.cc:1206 msgid "Edit" msgstr "Bearbeiten" -#: gtk2_ardour/editor.cc:1560 +#: gtk2_ardour/editor.cc:1658 msgid "Convert to short" msgstr "In kurzen Crossfade umwandeln" -#: gtk2_ardour/editor.cc:1562 +#: gtk2_ardour/editor.cc:1660 msgid "Convert to full" msgstr "In langen Crossfade umwandeln" -#: gtk2_ardour/editor.cc:1573 +#: gtk2_ardour/editor.cc:1671 msgid "Crossfade" msgstr "Crossfade" -#: gtk2_ardour/editor.cc:1616 +#: gtk2_ardour/editor.cc:1715 msgid "Popup region editor" msgstr "Regioneneditor öffnen" -#: gtk2_ardour/editor.cc:1617 +#: gtk2_ardour/editor.cc:1716 msgid "Raise to top layer" msgstr "Region ganz nach oben" -#: gtk2_ardour/editor.cc:1618 +#: gtk2_ardour/editor.cc:1717 msgid "Lower to bottom layer" msgstr "Region ganz nach unten" -#: gtk2_ardour/editor.cc:1620 +#: gtk2_ardour/editor.cc:1719 msgid "Define sync point" -msgstr "Synchronisationspunkt definieren" +msgstr "Einrastpunkt definieren" -#: gtk2_ardour/editor.cc:1621 +#: gtk2_ardour/editor.cc:1720 msgid "Remove sync point" -msgstr "Synchronisationspunkt entfernen" +msgstr "Einrastpunkt entfernen" -#: gtk2_ardour/editor.cc:1626 +#: gtk2_ardour/editor.cc:1725 msgid "Bounce" msgstr "Bounce" -#: gtk2_ardour/editor.cc:1629 +#: gtk2_ardour/editor.cc:1728 msgid "Analyze region" msgstr "Analysiere Region" -#: gtk2_ardour/editor.cc:1636 +#: gtk2_ardour/editor.cc:1735 +#: gtk2_ardour/editor_markers.cc:591 msgid "Lock" msgstr "Sperren" -#: gtk2_ardour/editor.cc:1653 +#: gtk2_ardour/editor.cc:1753 msgid "Opaque" msgstr "Deckend" -#: gtk2_ardour/editor.cc:1662 +#: gtk2_ardour/editor.cc:1763 msgid "Original position" msgstr "Ursprungsposition" -#: gtk2_ardour/editor.cc:1674 +#: gtk2_ardour/editor.cc:1776 msgid "Reset Envelope" msgstr "Lautstärkekurve zurücksetzen" -#: gtk2_ardour/editor.cc:1676 +#: gtk2_ardour/editor.cc:1778 msgid "Envelope Visible" msgstr "Lautstärkekurve sichtbar" -#: gtk2_ardour/editor.cc:1685 +#: gtk2_ardour/editor.cc:1787 msgid "Envelope Active" msgstr "Lautstärkekurve aktiv" -#: gtk2_ardour/editor.cc:1698 +#: gtk2_ardour/editor.cc:1801 msgid "DeNormalize" -msgstr "Ardour: Region " +msgstr "DeNormalisieren" -#: gtk2_ardour/editor.cc:1700 +#: gtk2_ardour/editor.cc:1803 msgid "Normalize" msgstr "Normalisieren" -#: gtk2_ardour/editor.cc:1703 +#: gtk2_ardour/editor.cc:1807 msgid "Reverse" msgstr "Rückwärts" -#: gtk2_ardour/editor.cc:1709 -#: gtk2_ardour/editor.cc:1791 +#: gtk2_ardour/editor.cc:1812 +#: gtk2_ardour/editor.cc:1903 msgid "Add Range Markers" msgstr "Bereichsmarker einfügen" -#: gtk2_ardour/editor.cc:1710 +#: gtk2_ardour/editor.cc:1813 msgid "Set Range Selection" msgstr "Bereich auswählen" -#: gtk2_ardour/editor.cc:1719 +#: gtk2_ardour/editor.cc:1822 msgid "Nudge fwd" msgstr "Schritt nach vorne" -#: gtk2_ardour/editor.cc:1720 +#: gtk2_ardour/editor.cc:1823 msgid "Nudge bwd" msgstr "Schritt nach hinten" -#: gtk2_ardour/editor.cc:1721 +#: gtk2_ardour/editor.cc:1824 msgid "Nudge fwd by capture offset" msgstr "Schritt nach vorne um Aufnahme-Offset" -#: gtk2_ardour/editor.cc:1722 +#: gtk2_ardour/editor.cc:1825 msgid "Nudge bwd by capture offset" msgstr "Schritt nach hinten um Aufnahme-Offset" -#: gtk2_ardour/editor.cc:1724 -#: gtk2_ardour/editor.cc:1889 -#: gtk2_ardour/editor.cc:1945 +#: gtk2_ardour/editor.cc:1827 +#: gtk2_ardour/editor.cc:1998 +#: gtk2_ardour/editor.cc:2054 msgid "Nudge" msgstr "Verschieben" -#: gtk2_ardour/editor.cc:1731 -msgid "Start to edit cursor" -msgstr "Von Anfang bis Editierzeiger" +#: gtk2_ardour/editor.cc:1834 +#: gtk2_ardour/editor_actions.cc:253 +msgid "Start to edit point" +msgstr "Von Anfang bis Arbeitspunkt" + +#: gtk2_ardour/editor.cc:1835 +#: gtk2_ardour/editor_actions.cc:255 +msgid "Edit point to end" +msgstr "Von Arbeitspunkt bis Ende" -#: gtk2_ardour/editor.cc:1732 -msgid "Edit cursor to end" -msgstr "Von Editierzeiger bis Ende" +#: gtk2_ardour/editor.cc:1836 +#: gtk2_ardour/editor_actions.cc:257 +msgid "Trim To Loop" +msgstr "Auf Schleife kürzen" -#: gtk2_ardour/editor.cc:1734 -#: gtk2_ardour/gain_meter.cc:168 -#: gtk2_ardour/gain_meter.cc:880 +#: gtk2_ardour/editor.cc:1837 +#: gtk2_ardour/editor_actions.cc:259 +msgid "Trim To Punch" +msgstr "Punch-Bereich schneiden" + +#: gtk2_ardour/editor.cc:1839 +#: gtk2_ardour/gain_meter.cc:169 +#: gtk2_ardour/gain_meter.cc:903 #: gtk2_ardour/panner_ui.cc:97 #: gtk2_ardour/panner_ui.cc:780 msgid "Trim" msgstr "Abschneiden" -#: gtk2_ardour/editor.cc:1737 +#: gtk2_ardour/editor.cc:1842 msgid "Split" msgstr "Teilen" -#: gtk2_ardour/editor.cc:1740 +#: gtk2_ardour/editor.cc:1845 msgid "Make mono regions" msgstr "Zu Mono-Regionen umwandeln" -#: gtk2_ardour/editor.cc:1743 +#: gtk2_ardour/editor.cc:1848 msgid "Duplicate" msgstr "Duplizieren" -#: gtk2_ardour/editor.cc:1744 +#: gtk2_ardour/editor.cc:1849 +msgid "Multi-Duplicate" +msgstr "Mehrfach duplizieren" + +#: gtk2_ardour/editor.cc:1850 msgid "Fill Track" msgstr "Spur auffüllen" -#: gtk2_ardour/editor.cc:1776 +#: gtk2_ardour/editor.cc:1879 msgid "Play range" msgstr "Bereich abspielen" -#: gtk2_ardour/editor.cc:1777 +#: gtk2_ardour/editor.cc:1880 msgid "Loop range" msgstr "Bereich in Schleife abspielen" -#: gtk2_ardour/editor.cc:1781 +#: gtk2_ardour/editor.cc:1884 msgid "Analyze range" msgstr "Bereich analysieren" -#: gtk2_ardour/editor.cc:1785 -msgid "Separate range to track" -msgstr "Bereich als Spur" +#: gtk2_ardour/editor.cc:1888 +#: gtk2_ardour/editor_actions.cc:370 +msgid "Extend Range to End of Region" +msgstr "Bereich vergrößern bis zum Ende der Region " + +#: gtk2_ardour/editor.cc:1889 +#: gtk2_ardour/editor_actions.cc:372 +msgid "Extend Range to Start of Region" +msgstr "Bereich vergrößern bis zum Anfang der Region " + +#: gtk2_ardour/editor.cc:1892 +msgid "Convert to region in-place" +msgstr "Am Rastpunkt der Regionen einrasten" -#: gtk2_ardour/editor.cc:1786 -msgid "Separate range to region list" +#: gtk2_ardour/editor.cc:1893 +#, fuzzy +msgid "Convert to region in region list" msgstr "Bereich zur Regionenliste hinzufügen" -#: gtk2_ardour/editor.cc:1789 +#: gtk2_ardour/editor.cc:1896 msgid "Select all in range" msgstr "Alles im Bereich auswählen" -#: gtk2_ardour/editor.cc:1792 -#: gtk2_ardour/editor.cc:1837 -msgid "Set range to loop range" -msgstr "Ausgewählten Bereich als Schleife" +#: gtk2_ardour/editor.cc:1899 +msgid "Set loop from selection" +msgstr "Schleife aus Auswahl erstellen" -#: gtk2_ardour/editor.cc:1793 -#: gtk2_ardour/editor.cc:1838 -msgid "Set range to punch range" -msgstr "Ausgewählten Bereich als Punch-Bereich" +#: gtk2_ardour/editor.cc:1900 +msgid "Set punch from selection" +msgstr "Punch-Bereich aus Auswahl erstellen" -#: gtk2_ardour/editor.cc:1795 +#: gtk2_ardour/editor.cc:1905 msgid "Crop region to range" msgstr "Regionen-Editor öffnen" -#: gtk2_ardour/editor.cc:1796 +#: gtk2_ardour/editor.cc:1906 msgid "Fill range with region" msgstr "Bereich mit Region ausfüllen" -#: gtk2_ardour/editor.cc:1797 +#: gtk2_ardour/editor.cc:1907 msgid "Duplicate range" msgstr "Bereich Duplizieren" -#: gtk2_ardour/editor.cc:1798 +#: gtk2_ardour/editor.cc:1908 msgid "Create chunk from range" msgstr "Abschnitt aus Bereich erstellen..." -#: gtk2_ardour/editor.cc:1800 +#: gtk2_ardour/editor.cc:1910 msgid "Bounce range" msgstr "Bereich Bouncen" -#: gtk2_ardour/editor.cc:1801 +#: gtk2_ardour/editor.cc:1911 msgid "Export range" -msgstr "Bereiche exportieren..." - -#: gtk2_ardour/editor.cc:1803 -msgid "Range" -msgstr "Bereich" +msgstr "Bereich exportieren" -#: gtk2_ardour/editor.cc:1818 -#: gtk2_ardour/editor.cc:1903 -msgid "Play from edit cursor" -msgstr "Wiedergabe ab Editierzeiger" +#: gtk2_ardour/editor.cc:1925 +#: gtk2_ardour/editor.cc:2012 +msgid "Play from edit point" +msgstr "Wiedergabe ab Arbeitspunkt" -#: gtk2_ardour/editor.cc:1819 -#: gtk2_ardour/editor.cc:1904 +#: gtk2_ardour/editor.cc:1926 +#: gtk2_ardour/editor.cc:2013 msgid "Play from start" msgstr "Wiedergabe ab Anfang" -#: gtk2_ardour/editor.cc:1820 +#: gtk2_ardour/editor.cc:1927 msgid "Play region" msgstr "Region wiedergeben" -#: gtk2_ardour/editor.cc:1822 +#: gtk2_ardour/editor.cc:1929 +#: gtk2_ardour/editor_actions.cc:266 msgid "Loop Region" msgstr "Region in Schleife wiedergeben" -#: gtk2_ardour/editor.cc:1832 -#: gtk2_ardour/editor.cc:1913 +#: gtk2_ardour/editor.cc:1939 +#: gtk2_ardour/editor.cc:2022 msgid "Select All in track" msgstr "Alles in Spur auswählen" -#: gtk2_ardour/editor.cc:1833 -#: gtk2_ardour/editor.cc:1914 -#: gtk2_ardour/redirect_box.cc:1167 +#: gtk2_ardour/editor.cc:1940 +#: gtk2_ardour/editor.cc:2023 +#: gtk2_ardour/editor_actions.cc:137 +#: gtk2_ardour/redirect_box.cc:1194 msgid "Select All" msgstr "Alles Auswählen" -#: gtk2_ardour/editor.cc:1834 -#: gtk2_ardour/editor.cc:1915 +#: gtk2_ardour/editor.cc:1941 +#: gtk2_ardour/editor.cc:2024 msgid "Invert selection in track" msgstr "Auswahl in Spur umkehren" -#: gtk2_ardour/editor.cc:1835 -#: gtk2_ardour/editor.cc:1916 +#: gtk2_ardour/editor.cc:1942 +#: gtk2_ardour/editor.cc:2025 msgid "Invert selection" msgstr "Auswahl umkehren" -#: gtk2_ardour/editor.cc:1840 -#: gtk2_ardour/editor.cc:1918 -msgid "Select all after edit cursor" -msgstr "Alles nach Editierzeiger auswählen" +#: gtk2_ardour/editor.cc:1944 +msgid "Set range to loop range" +msgstr "Ausgewählten Bereich als Schleife" -#: gtk2_ardour/editor.cc:1841 -#: gtk2_ardour/editor.cc:1919 -msgid "Select all before edit cursor" -msgstr "Alles vor Editierzeiger auswählen" +#: gtk2_ardour/editor.cc:1945 +msgid "Set range to punch range" +msgstr "Ausgewählten Bereich als Punch-Bereich" -#: gtk2_ardour/editor.cc:1842 -#: gtk2_ardour/editor.cc:1920 -msgid "Select all after playhead" -msgstr "Alles nach Positionszeiger auswählen" +#: gtk2_ardour/editor.cc:1947 +#: gtk2_ardour/editor_actions.cc:143 +msgid "Select All After Edit Point" +msgstr "Alle Regionen nach dem Arbeitspunkt auswählen" -#: gtk2_ardour/editor.cc:1843 -#: gtk2_ardour/editor.cc:1921 -msgid "Select all before playhead" -msgstr "Alles vor Positionszeiger auswählen" +#: gtk2_ardour/editor.cc:1948 +#: gtk2_ardour/editor_actions.cc:145 +msgid "Select All Before Edit Point" +msgstr "Alle Regionen vor dem Arbeitspunkt auswählen" + +#: gtk2_ardour/editor.cc:1949 +#: gtk2_ardour/editor_actions.cc:148 +msgid "Select All After Playhead" +msgstr "Alle Regionen nach dem Positionszeiger auswählen" + +#: gtk2_ardour/editor.cc:1950 +#: gtk2_ardour/editor_actions.cc:150 +msgid "Select All Before Playhead" +msgstr "Alle Regionen vor dem Positionszeiger auswählen" -#: gtk2_ardour/editor.cc:1844 -msgid "Select all between cursors" -msgstr "Alles zwischen Zeigern auswählen" +#: gtk2_ardour/editor.cc:1951 +#: gtk2_ardour/editor_actions.cc:152 +msgid "Select All Between Playhead & Edit Point" +msgstr "Alle Regionen zwischen Positionszeiger und Arbeitspunkt auswählen" + +#: gtk2_ardour/editor.cc:1952 +#: gtk2_ardour/editor_actions.cc:154 +msgid "Select All Within Playhead & Edit Point" +msgstr "Alle Regionen innerhalb Positionszeiger und Arbeitspunkt auswählen" + +#: gtk2_ardour/editor.cc:1953 +#: gtk2_ardour/editor_actions.cc:157 +msgid "Select Range Between Playhead & Edit Point" +msgstr "Wähle Bereich zwischen Positionszeiger und Arbeitspunkt aus" -#: gtk2_ardour/editor.cc:1847 -#: gtk2_ardour/editor.cc:1923 +#: gtk2_ardour/editor.cc:1957 +#: gtk2_ardour/editor.cc:2032 +#: gtk2_ardour/editor_actions.cc:48 msgid "Select" msgstr "Auswahl" -#: gtk2_ardour/editor.cc:1855 -#: gtk2_ardour/editor.cc:1931 -#: gtk2_ardour/editor_actions.cc:217 -#: gtk2_ardour/redirect_box.cc:1160 +#: gtk2_ardour/editor.cc:1965 +#: gtk2_ardour/editor.cc:2040 +#: gtk2_ardour/editor_actions.cc:334 +#: gtk2_ardour/redirect_box.cc:1183 msgid "Cut" msgstr "Ausschneiden" -#: gtk2_ardour/editor.cc:1856 -#: gtk2_ardour/editor.cc:1932 -#: gtk2_ardour/editor_actions.cc:222 -#: gtk2_ardour/redirect_box.cc:1162 +#: gtk2_ardour/editor.cc:1966 +#: gtk2_ardour/editor.cc:2041 +#: gtk2_ardour/editor_actions.cc:339 +#: gtk2_ardour/redirect_box.cc:1185 msgid "Copy" msgstr "Kopieren" -#: gtk2_ardour/editor.cc:1857 -msgid "Paste at edit cursor" -msgstr "Am Editierzeiger einfügen" - -#: gtk2_ardour/editor.cc:1858 -msgid "Paste at mouse" -msgstr "An Mausposition einfügen" +#: gtk2_ardour/editor.cc:1967 +#: gtk2_ardour/editor.cc:2042 +#: gtk2_ardour/editor_actions.cc:341 +#: gtk2_ardour/redirect_box.cc:1191 +msgid "Paste" +msgstr "Einfügen" -#: gtk2_ardour/editor.cc:1862 +#: gtk2_ardour/editor.cc:1971 msgid "Align" msgstr "Ausrichten" -#: gtk2_ardour/editor.cc:1863 +#: gtk2_ardour/editor.cc:1972 msgid "Align Relative" msgstr "Relativ ausrichten" -#: gtk2_ardour/editor.cc:1867 +#: gtk2_ardour/editor.cc:1976 msgid "Insert chunk" msgstr "Abschnitt einfügen" -#: gtk2_ardour/editor.cc:1874 +#: gtk2_ardour/editor.cc:1983 msgid "Insert Selected Region" msgstr "Ausgewählte Region einfügen" -#: gtk2_ardour/editor.cc:1875 +#: gtk2_ardour/editor.cc:1984 msgid "Insert Existing Audio" msgstr "Audio importieren..." -#: gtk2_ardour/editor.cc:1884 -#: gtk2_ardour/editor.cc:1940 +#: gtk2_ardour/editor.cc:1993 +#: gtk2_ardour/editor.cc:2049 msgid "Nudge entire track fwd" msgstr "Gesamte Spur schrittweise nach vorne" -#: gtk2_ardour/editor.cc:1885 -#: gtk2_ardour/editor.cc:1941 -msgid "Nudge track after edit cursor fwd" -msgstr "Spur nach Editierzeiger schrittweise nach vorne" +#: gtk2_ardour/editor.cc:1994 +#: gtk2_ardour/editor.cc:2050 +msgid "Nudge track after edit point fwd" +msgstr "Spur nach Arbeitspunkt schrittweise nach vorne" -#: gtk2_ardour/editor.cc:1886 -#: gtk2_ardour/editor.cc:1942 +#: gtk2_ardour/editor.cc:1995 +#: gtk2_ardour/editor.cc:2051 msgid "Nudge entire track bwd" msgstr "Gesamte Spur schrittweise nach hinten" -#: gtk2_ardour/editor.cc:1887 -#: gtk2_ardour/editor.cc:1943 -msgid "Nudge track after edit cursor bwd" -msgstr "Spur nach Editierzeiger schrittweise nach hinten" +#: gtk2_ardour/editor.cc:1996 +#: gtk2_ardour/editor.cc:2052 +msgid "Nudge track after edit point bwd" +msgstr "Spur nach Arbeitspunkt schrittweise nach hinten" -#: gtk2_ardour/editor.cc:1933 -#: gtk2_ardour/editor_actions.cc:224 -#: gtk2_ardour/redirect_box.cc:1164 -msgid "Paste" -msgstr "Einfügen" +#: gtk2_ardour/editor.cc:2027 +msgid "Select all after edit point" +msgstr "Alles nach Arbeitspunkt auswählen" + +#: gtk2_ardour/editor.cc:2028 +msgid "Select all before edit point" +msgstr "Alles vor Arbeitspunkt auswählen" + +#: gtk2_ardour/editor.cc:2029 +msgid "Select all after playhead" +msgstr "Alles nach Positionszeiger auswählen" -#: gtk2_ardour/editor.cc:2518 +#: gtk2_ardour/editor.cc:2030 +msgid "Select all before playhead" +msgstr "Alles vor Positionszeiger auswählen" + +#: gtk2_ardour/editor.cc:2684 msgid "Select/Move Objects" msgstr "Objekte auswählen/verschieben" -#: gtk2_ardour/editor.cc:2519 +#: gtk2_ardour/editor.cc:2685 msgid "Select/Move Ranges" -msgstr "Bereiche auswählen/verschieben" +msgstr "Editierbereich auswählen/verschieben" -#: gtk2_ardour/editor.cc:2520 +#: gtk2_ardour/editor.cc:2686 msgid "Draw Gain Automation" msgstr "Lautstärkekurve zeichnen" -#: gtk2_ardour/editor.cc:2521 +#: gtk2_ardour/editor.cc:2687 msgid "Select Zoom Range" msgstr "Zoombereich auswählen" -#: gtk2_ardour/editor.cc:2522 +#: gtk2_ardour/editor.cc:2688 msgid "Stretch/Shrink Regions" msgstr "Regionen vergrößern/verkleinern (Time-Stretch)" -#: gtk2_ardour/editor.cc:2523 +#: gtk2_ardour/editor.cc:2689 msgid "Listen to Specific Regions" msgstr "Ausgewählte Regionen vorhören" -#: gtk2_ardour/editor.cc:2553 -#: gtk2_ardour/editor_actions.cc:143 +#: gtk2_ardour/editor.cc:2719 +#: gtk2_ardour/editor_actions.cc:209 msgid "Zoom In" msgstr "Vergrößern" -#: gtk2_ardour/editor.cc:2559 -#: gtk2_ardour/editor_actions.cc:141 +#: gtk2_ardour/editor.cc:2725 +#: gtk2_ardour/editor_actions.cc:207 msgid "Zoom Out" msgstr "Verkleinern" -#: gtk2_ardour/editor.cc:2565 -#: gtk2_ardour/editor_actions.cc:145 +#: gtk2_ardour/editor.cc:2731 +#: gtk2_ardour/editor_actions.cc:211 msgid "Zoom to Session" msgstr "Auf ganzes Projekt zoomen" -#: gtk2_ardour/editor.cc:2571 +#: gtk2_ardour/editor.cc:2737 msgid "Zoom focus" msgstr "Zoom-Mittelpunkt" -#: gtk2_ardour/editor.cc:2587 -msgid "Unit to snap cursors and ranges to" -msgstr "Rastereinheit für Zeiger und Bereiche" +#: gtk2_ardour/editor.cc:2751 +msgid "Snap/Grid Units" +msgstr "Einrast-Einheiten" -#: gtk2_ardour/editor.cc:2835 -#: gtk2_ardour/editor_actions.cc:207 +#: gtk2_ardour/editor.cc:2754 +msgid "Magnetic Snap" +msgstr "Magnetisch einrasten" + +#: gtk2_ardour/editor.cc:2757 +msgid "Snap/Grid Mode" +msgstr "Einrastmodus" + +#: gtk2_ardour/editor.cc:2763 +msgid "Edit point" +msgstr "Arbeitspunkt" + +#: gtk2_ardour/editor.cc:2913 +msgid "malformed URL passed to drag-n-drop code" +msgstr "" + +#: gtk2_ardour/editor.cc:3032 +#: gtk2_ardour/editor_actions.cc:320 msgid "Undo" msgstr "Rückgängig" -#: gtk2_ardour/editor.cc:2837 +#: gtk2_ardour/editor.cc:3034 msgid "Undo (%1)" msgstr "Rückgängig (%1)" -#: gtk2_ardour/editor.cc:2844 -#: gtk2_ardour/editor_actions.cc:209 +#: gtk2_ardour/editor.cc:3041 +#: gtk2_ardour/editor_actions.cc:322 msgid "Redo" msgstr "Wiederherstellen" -#: gtk2_ardour/editor.cc:2846 +#: gtk2_ardour/editor.cc:3043 msgid "Redo (%1)" msgstr "Wiederherstellen (%1)" -#: gtk2_ardour/editor.cc:2860 +#: gtk2_ardour/editor.cc:3073 msgid "Duplicate how many times?" msgstr "Wie häufig duplizieren?" -#: gtk2_ardour/editor.cc:2942 +#: gtk2_ardour/editor.cc:3175 msgid "Splice Edit" msgstr "Kleben" -#: gtk2_ardour/editor.cc:2944 +#: gtk2_ardour/editor.cc:3177 msgid "Slide Edit" msgstr "Slide Edit" -#: gtk2_ardour/editor.cc:3298 +#: gtk2_ardour/editor.cc:3572 msgid "" "Playlist %1 is currently unused.\n" "If left alone, no audio files used by it will be cleaned.\n" @@ -2884,35 +3175,34 @@ msgstr "" "Es können keine Audiodateien aufgeräumt werden, die von ihr verwendet werden.\n" "Falls sie gelöscht wird, werden die ausschließlich von ihr verwendeten Audiodateien gelöscht." -#: gtk2_ardour/editor.cc:3308 +#: gtk2_ardour/editor.cc:3582 msgid "Delete playlist" msgstr "Wiedergabeliste löschen" -#: gtk2_ardour/editor.cc:3309 +#: gtk2_ardour/editor.cc:3583 msgid "Keep playlist" msgstr "Wiedergabeliste beibehalten" -#: gtk2_ardour/editor.cc:3310 -#: gtk2_ardour/editor_audio_import.cc:366 -#: gtk2_ardour/editor_ops.cc:1747 -#: gtk2_ardour/editor_timefx.cc:77 -#: gtk2_ardour/export_dialog.cc:973 +#: gtk2_ardour/editor.cc:3584 +#: gtk2_ardour/editor_audio_import.cc:515 +#: gtk2_ardour/editor_timefx.cc:78 +#: gtk2_ardour/export_dialog.cc:1034 #: gtk2_ardour/io_selector.cc:60 #: gtk2_ardour/io_selector.cc:748 -#: gtk2_ardour/redirect_box.cc:987 -#: gtk2_ardour/tempo_dialog.cc:22 -#: gtk2_ardour/tempo_dialog.cc:41 -#: gtk2_ardour/tempo_dialog.cc:158 -#: gtk2_ardour/tempo_dialog.cc:176 +#: gtk2_ardour/redirect_box.cc:1022 +#: gtk2_ardour/tempo_dialog.cc:42 +#: gtk2_ardour/tempo_dialog.cc:61 +#: gtk2_ardour/tempo_dialog.cc:256 +#: gtk2_ardour/tempo_dialog.cc:274 #: gtk2_ardour/connection_editor.cc:59 msgid "Cancel" msgstr "Abbrechen" -#: gtk2_ardour/editor.cc:3478 +#: gtk2_ardour/editor.cc:3752 msgid "New name of snapshot" msgstr "Name für neuen Schnappschuss" -#: gtk2_ardour/editor.cc:3496 +#: gtk2_ardour/editor.cc:3770 msgid "" "Do you really want to remove snapshot \"%1\" ?\n" "(cannot be undone)" @@ -2920,793 +3210,920 @@ msgstr "" "Wollen Sie den Schnappschuss \"%1\" wirklich löschen?\n" "(Dies kann nicht rückgängig gemacht werden!)" -#: gtk2_ardour/editor.cc:3498 -#: gtk2_ardour/editor_ops.cc:181 -#: gtk2_ardour/editor_ops.cc:3153 -#: gtk2_ardour/route_ui.cc:783 +#: gtk2_ardour/editor.cc:3772 +#: gtk2_ardour/editor_ops.cc:206 +#: gtk2_ardour/editor_ops.cc:3954 +#: gtk2_ardour/route_ui.cc:790 #: gtk2_ardour/visual_time_axis.cc:282 msgid "No, do nothing." msgstr "Nein, nichts machen." -#: gtk2_ardour/editor.cc:3499 -#: gtk2_ardour/route_ui.cc:784 +#: gtk2_ardour/editor.cc:3773 +#: gtk2_ardour/route_ui.cc:791 #: gtk2_ardour/visual_time_axis.cc:283 msgid "Yes, remove it." msgstr "Ja, entfernen." -#: gtk2_ardour/editor.cc:3603 +#: gtk2_ardour/editor.cc:3883 msgid "new playlists" msgstr "Neue Wiedergabelisten" -#: gtk2_ardour/editor.cc:3611 +#: gtk2_ardour/editor.cc:3898 msgid "copy playlists" msgstr "Wiedergabelisten kopieren" -#: gtk2_ardour/editor.cc:3619 +#: gtk2_ardour/editor.cc:3913 msgid "clear playlists" msgstr "Wiedergabelisten zurücksetzen" -#: gtk2_ardour/editor_actions.cc:29 -msgid "Select regions" -msgstr "Region(en) auswählen" +#: gtk2_ardour/editor_actions.cc:49 +msgid "Select Regions" +msgstr "Region auswählen" -#: gtk2_ardour/editor_actions.cc:30 -msgid "Select range operations" -msgstr "Bereich" +#: gtk2_ardour/editor_actions.cc:50 +msgid "Select Range Operations" +msgstr "Bereichs" -#: gtk2_ardour/editor_actions.cc:31 -msgid "Move edit cursor" -msgstr "Editierzeiger bewegen" +#: gtk2_ardour/editor_actions.cc:51 +msgid "Move Selected Marker" +msgstr "Ausgewählten Positionsmarker verschieben" -#: gtk2_ardour/editor_actions.cc:32 +#: gtk2_ardour/editor_actions.cc:52 msgid "Region operations" msgstr "Region(en)" -#: gtk2_ardour/editor_actions.cc:33 +#: gtk2_ardour/editor_actions.cc:53 msgid "Tools" msgstr "Werkzeuge" -#: gtk2_ardour/editor_actions.cc:34 +#: gtk2_ardour/editor_actions.cc:54 msgid "View" msgstr "Ansicht" -#: gtk2_ardour/editor_actions.cc:35 +#: gtk2_ardour/editor_actions.cc:55 msgid "ZoomFocus" msgstr "Zoom-Mittelpunkt" -#: gtk2_ardour/editor_actions.cc:36 +#: gtk2_ardour/editor_actions.cc:56 msgid "Meter hold" msgstr "Pegelanzeige halten" -#: gtk2_ardour/editor_actions.cc:37 +#: gtk2_ardour/editor_actions.cc:57 msgid "Meter falloff" msgstr "Abfall der Pegelanzeigen" -#: gtk2_ardour/editor_actions.cc:39 +#: gtk2_ardour/editor_actions.cc:59 msgid "Crossfades" msgstr "Crossfades" -#: gtk2_ardour/editor_actions.cc:40 +#: gtk2_ardour/editor_actions.cc:60 msgid "Monitoring" msgstr "Monitoring" -#: gtk2_ardour/editor_actions.cc:41 +#: gtk2_ardour/editor_actions.cc:61 msgid "Autoconnect" msgstr "Automatisch verbinden" -#: gtk2_ardour/editor_actions.cc:42 +#: gtk2_ardour/editor_actions.cc:62 msgid "Layering" msgstr "Layering" -#: gtk2_ardour/editor_actions.cc:43 +#: gtk2_ardour/editor_actions.cc:63 msgid "Timecode fps" msgstr "Timecode FPS" -#: gtk2_ardour/editor_actions.cc:44 +#: gtk2_ardour/editor_actions.cc:64 msgid "Pullup / Pulldown" msgstr "Pull-Up / Pull-Down" -#: gtk2_ardour/editor_actions.cc:45 +#: gtk2_ardour/editor_actions.cc:65 msgid "Subframes" msgstr "Subframes" -#: gtk2_ardour/editor_actions.cc:46 -msgid "Add Existing Audio" -msgstr "Audio importieren" +#: gtk2_ardour/editor_actions.cc:66 +#, fuzzy +msgid "Locate To Markers" +msgstr "Positionsmarker" -#: gtk2_ardour/editor_actions.cc:51 +#: gtk2_ardour/editor_actions.cc:70 +msgid "Link Region/Track Selection" +msgstr "Spurauswahl folgt Auswahl der Region" + +#: gtk2_ardour/editor_actions.cc:72 msgid "Show Editor Mixer" msgstr "Mixer-Panel zeigen" -#: gtk2_ardour/editor_actions.cc:56 +#: gtk2_ardour/editor_actions.cc:77 msgid "Span Entire Overlap" msgstr "Gesamte Ãœberlappung" -#: gtk2_ardour/editor_actions.cc:65 +#: gtk2_ardour/editor_actions.cc:86 msgid "Created Automatically" msgstr "Automatisch erzeugen" -#: gtk2_ardour/editor_actions.cc:68 +#: gtk2_ardour/editor_actions.cc:89 +msgid "Playhead to Next Region Boundary" +msgstr "Positionszeiger zur nächsten Regiongrenze" + +#: gtk2_ardour/editor_actions.cc:91 +msgid "Playhead to Previous Region Boundary" +msgstr "Positionszeiger zur vorherigen Regiongrenze" + +#: gtk2_ardour/editor_actions.cc:94 msgid "Playhead to Next Region Start" msgstr "Positionszeiger zum Anfang der nächsten Region" -#: gtk2_ardour/editor_actions.cc:70 +#: gtk2_ardour/editor_actions.cc:96 msgid "Playhead to Next Region End" msgstr "Positionszeiger zum Ende der nächsten Region" -#: gtk2_ardour/editor_actions.cc:72 +#: gtk2_ardour/editor_actions.cc:98 msgid "Playhead to Next Region Sync" -msgstr "Positionszeiger zum Sync der nächsten Region" +msgstr "Positionszeiger zum Einrastpunkt der nächsten Region" -#: gtk2_ardour/editor_actions.cc:75 +#: gtk2_ardour/editor_actions.cc:101 msgid "Playhead to Previous Region Start" msgstr "Positionszeiger zum Anfang der vorherigen Region" -#: gtk2_ardour/editor_actions.cc:77 +#: gtk2_ardour/editor_actions.cc:103 msgid "Playhead to Previous Region End" msgstr "Positionszeiger zum Ende der vorherigen Region" -#: gtk2_ardour/editor_actions.cc:79 +#: gtk2_ardour/editor_actions.cc:105 msgid "Playhead to Previous Region Sync" -msgstr "Positionszeiger zum Sync der vorherigen Region" - -#: gtk2_ardour/editor_actions.cc:82 -msgid "Edit Cursor to Next Region Start" -msgstr "Editierzeiger zum Anfang der nächsten Region" - -#: gtk2_ardour/editor_actions.cc:84 -msgid "Edit Cursor to Next Region End" -msgstr "Editierzeiger zum Ende der nächsten Region" +msgstr "Positionszeiger zum Einrastpunkt der vorherigen Region" -#: gtk2_ardour/editor_actions.cc:86 -msgid "Edit Cursor to Next Region Sync" -msgstr "Editierzeiger zum Sync der nächsten Region" +#: gtk2_ardour/editor_actions.cc:108 +msgid "to Next Region Boundary" +msgstr "zur nächsten Regiongrenze" -#: gtk2_ardour/editor_actions.cc:89 -msgid "Edit Cursor to Previous Region Start" -msgstr "Editierzeiger zum Anfang der vorherigen Region" +#: gtk2_ardour/editor_actions.cc:110 +msgid "to Previous Region Boundary" +msgstr "zur vorherigen Regiongrenze" -#: gtk2_ardour/editor_actions.cc:91 -msgid "Edit Cursor to Previous Region End" -msgstr "Editierzeiger zum Ende der vorherigen Region" +#: gtk2_ardour/editor_actions.cc:113 +msgid "to Next Region Start" +msgstr "zum Anfang der nächsten Region" -#: gtk2_ardour/editor_actions.cc:93 -msgid "Edit Cursor to Previous Region Sync" -msgstr "Editierzeiger zum Sync der vorherigen Region" +#: gtk2_ardour/editor_actions.cc:115 +msgid "to Next Region End" +msgstr "zum Ende der nächsten Region" -#: gtk2_ardour/editor_actions.cc:96 -msgid "Playhead to Range Start" -msgstr "Positionszeiger zum Anfang der Auswahl" +#: gtk2_ardour/editor_actions.cc:117 +msgid "to Next Region Sync" +msgstr "zum Einrastpunkt der nächsten Region" -#: gtk2_ardour/editor_actions.cc:98 -msgid "Playhead to Range End" -msgstr "Positionszeiger zum Ende der Auswahl" +#: gtk2_ardour/editor_actions.cc:120 +msgid "to Previous Region Start" +msgstr "zum Anfang der vorherigen Region" -#: gtk2_ardour/editor_actions.cc:101 -msgid "Edit Cursor to Range Start" -msgstr "Editierzeiger zum Anfang der Auswahl" +#: gtk2_ardour/editor_actions.cc:122 +msgid "to Previous Region End" +msgstr "zum Ende der vorherigen Region" -#: gtk2_ardour/editor_actions.cc:103 -msgid "Edit Cursor to Range End" -msgstr "Editierzeiger zum Ende der Auswahl" +#: gtk2_ardour/editor_actions.cc:124 +msgid "to Previous Region Sync" +msgstr "zum Einrastpunkt der vorherigen Region" -#: gtk2_ardour/editor_actions.cc:106 -#: gtk2_ardour/editor_selection.cc:726 -msgid "select all" -msgstr "Alle Regionen auswählen" +#: gtk2_ardour/editor_actions.cc:127 +msgid "to Range Start" +msgstr "zum Anfang des Auswahlbereichs" -#: gtk2_ardour/editor_actions.cc:108 -msgid "Select All After Edit Cursor" -msgstr "Alle Regionen nach dem Editierzeiger auswählen" +#: gtk2_ardour/editor_actions.cc:129 +msgid "to Range End" +msgstr "zum Ende des Auswahlbereichs" -#: gtk2_ardour/editor_actions.cc:110 -msgid "Select All Before Edit Cursor" -msgstr "Alle Regionen vor dem Editierzeiger auswählen" +#: gtk2_ardour/editor_actions.cc:132 +msgid "Playhead to Range Start" +msgstr "Positionszeiger zum Anfang des Auswahlbereichs" -#: gtk2_ardour/editor_actions.cc:113 -msgid "Select All After Playhead" -msgstr "Alle Regionen nach dem Positionszeiger auswählen" +#: gtk2_ardour/editor_actions.cc:134 +msgid "Playhead to Range End" +msgstr "Positionszeiger zum Ende des Auswahlbereichs" -#: gtk2_ardour/editor_actions.cc:115 -msgid "Select All Before Playhead" -msgstr "Alle Regionen vor dem Positionszeiger auswählen" +#: gtk2_ardour/editor_actions.cc:139 +#: gtk2_ardour/redirect_box.cc:1195 +msgid "Deselect All" +msgstr "Nichts auswählen" -#: gtk2_ardour/editor_actions.cc:117 -msgid "Select All Between Cursors" -msgstr "Alle Regionen zwischen den Zeigern auswählen" +#: gtk2_ardour/editor_actions.cc:141 +msgid "Invert Selection" +msgstr "Auswahl umkehren" -#: gtk2_ardour/editor_actions.cc:120 +#: gtk2_ardour/editor_actions.cc:160 msgid "Select All in Punch Range" msgstr "Alle Regionen im Punch-Bereich auswählen" -#: gtk2_ardour/editor_actions.cc:122 +#: gtk2_ardour/editor_actions.cc:162 msgid "Select All in Loop Range" msgstr "Alle Regionen innerhalb der Schleife auswählen" -#: gtk2_ardour/editor_actions.cc:125 +#: gtk2_ardour/editor_actions.cc:165 +msgid "Select Next Track/Bus" +msgstr "Nächste Spur/Bus auswählen" + +#: gtk2_ardour/editor_actions.cc:167 +msgid "Select Previous Track/Bus" +msgstr "Vorherige Spur/Bus auswählen" + +#: gtk2_ardour/editor_actions.cc:171 +#, fuzzy +msgid "Locate to Mark 1" +msgstr "Zu Marker 1 " + +#: gtk2_ardour/editor_actions.cc:173 +#, fuzzy +msgid "Locate to Mark 2" +msgstr "Positionszeiger zu Marker setzen" + +#: gtk2_ardour/editor_actions.cc:175 +#, fuzzy +msgid "Locate to Mark 3" +msgstr "Positionszeiger zu Marker setzen" + +#: gtk2_ardour/editor_actions.cc:177 +#, fuzzy +msgid "Locate to Mark 4" +msgstr "Positionszeiger zu Marker setzen" + +#: gtk2_ardour/editor_actions.cc:179 +#, fuzzy +msgid "Locate to Mark 5" +msgstr "Positionszeiger zu Marker setzen" + +#: gtk2_ardour/editor_actions.cc:181 +#, fuzzy +msgid "Locate to Mark 6" +msgstr "Positionszeiger zu Marker setzen" + +#: gtk2_ardour/editor_actions.cc:183 +#, fuzzy +msgid "Locate to Mark 7" +msgstr "Positionszeiger zu Marker setzen" + +#: gtk2_ardour/editor_actions.cc:185 +#, fuzzy +msgid "Locate to Mark 8" +msgstr "Positionszeiger zu Marker setzen" + +#: gtk2_ardour/editor_actions.cc:187 +#, fuzzy +msgid "Locate to Mark 9" +msgstr "Positionszeiger zu Marker setzen" + +#: gtk2_ardour/editor_actions.cc:190 msgid "Jump Forward to Mark" msgstr "Zum nächsten Marker springen" -#: gtk2_ardour/editor_actions.cc:127 +#: gtk2_ardour/editor_actions.cc:192 msgid "Jump Backward to Mark" msgstr "Zum vorherigen Marker springen" -#: gtk2_ardour/editor_actions.cc:129 +#: gtk2_ardour/editor_actions.cc:194 msgid "Add Mark from Playhead" msgstr "Marker am Positionszeiger setzen" -#: gtk2_ardour/editor_actions.cc:132 +#: gtk2_ardour/editor_actions.cc:197 msgid "Nudge Forward" msgstr "Schritt nach vorne" -#: gtk2_ardour/editor_actions.cc:134 +#: gtk2_ardour/editor_actions.cc:199 msgid "Nudge Next Forward" -msgstr "nächste Region Schritt vorwärts" +msgstr "Nächste Region Schritt vorwärts" -#: gtk2_ardour/editor_actions.cc:136 +#: gtk2_ardour/editor_actions.cc:201 msgid "Nudge Backward" msgstr "Schritt nach Hinten" -#: gtk2_ardour/editor_actions.cc:138 +#: gtk2_ardour/editor_actions.cc:203 msgid "Nudge Next Backward" -msgstr "Nächste Region Schritt nach vorne" +msgstr "Nächste Region Schritt rückwärts" -#: gtk2_ardour/editor_actions.cc:148 +#: gtk2_ardour/editor_actions.cc:213 +msgid "Zoom to Region" +msgstr "Auf Region zoomen" + +#: gtk2_ardour/editor_actions.cc:215 +msgid "Toggle Zoom State" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:218 msgid "Scroll Tracks Up" msgstr "Spuren nach oben scrollen" -#: gtk2_ardour/editor_actions.cc:150 +#: gtk2_ardour/editor_actions.cc:220 msgid "Scroll Tracks Down" msgstr "Spuren nach unten scrollen" -#: gtk2_ardour/editor_actions.cc:152 +#: gtk2_ardour/editor_actions.cc:222 msgid "Step Tracks Up" msgstr "Spuren langsam nach oben scrollen" -#: gtk2_ardour/editor_actions.cc:154 +#: gtk2_ardour/editor_actions.cc:224 msgid "Step Tracks Down" msgstr "Spuren langsam nach unten scrollen" -#: gtk2_ardour/editor_actions.cc:157 +#: gtk2_ardour/editor_actions.cc:227 msgid "Scroll Backward" msgstr "Vorwärts scrollen" -#: gtk2_ardour/editor_actions.cc:159 +#: gtk2_ardour/editor_actions.cc:229 msgid "Scroll Forward" msgstr "Rückwärts scrollen" -#: gtk2_ardour/editor_actions.cc:161 +#: gtk2_ardour/editor_actions.cc:231 msgid "goto" msgstr "Gehe zu" -#: gtk2_ardour/editor_actions.cc:163 -msgid "Center Playhead" -msgstr "Ansicht am Positionszeiger zentrieren" +#: gtk2_ardour/editor_actions.cc:233 +#: gtk2_ardour/editor_actions.cc:235 +msgid "to Center" +msgstr "zur Mitte" -#: gtk2_ardour/editor_actions.cc:165 -msgid "Center Edit Cursor" -msgstr "Editierzeiger zentrieren" - -#: gtk2_ardour/editor_actions.cc:168 +#: gtk2_ardour/editor_actions.cc:238 msgid "Playhead forward" msgstr "Positionszeiger vorwärts" -#: gtk2_ardour/editor_actions.cc:170 +#: gtk2_ardour/editor_actions.cc:240 msgid "Playhead Backward" msgstr "Positionszeiger rückwärts" -#: gtk2_ardour/editor_actions.cc:173 -msgid "Playhead to Edit" -msgstr "Positionszeiger zum Editierzeiger setzen" +#: gtk2_ardour/editor_actions.cc:243 +msgid "to Edit" +msgstr "Positionszeiger zum Arbeitspunkt" -#: gtk2_ardour/editor_actions.cc:175 -msgid "Edit to Playhead" -msgstr "Editierzeiger zum Positionszeiger setzen" +#: gtk2_ardour/editor_actions.cc:245 +msgid "to Playhead" +msgstr "zum Positionszeiger" + +#: gtk2_ardour/editor_actions.cc:248 +msgid "Trim start at edit point" +msgstr "Schneide Regionanfang am Arbeitspunkt" + +#: gtk2_ardour/editor_actions.cc:250 +msgid "Trim end at edit point" +msgstr "Schneide Regionende am Arbeitspunkt" + +#: gtk2_ardour/editor_actions.cc:262 +msgid "Set Loop From Edit Range" +msgstr "Schleife aus Editierbereich erstellen" + +#: gtk2_ardour/editor_actions.cc:264 +msgid "Set Loop From Region" +msgstr "Schleife aus Region erstellen" + +#: gtk2_ardour/editor_actions.cc:268 +msgid "Set Punch From Edit Range" +msgstr "Punch-Bereich aus Editierbereich erstellen" -#: gtk2_ardour/editor_actions.cc:178 +#: gtk2_ardour/editor_actions.cc:272 +msgid "Transpose" +msgstr "Transponieren" + +#: gtk2_ardour/editor_actions.cc:275 +msgid "Set Fade In Length" +msgstr "Ändere Fade-In Länge" + +#: gtk2_ardour/editor_actions.cc:277 +msgid "Toggle Fade In Active" +msgstr "Fade-In aktivieren" + +#: gtk2_ardour/editor_actions.cc:279 +msgid "Set Fade Out Length" +msgstr "Fade-Out verändern" + +#: gtk2_ardour/editor_actions.cc:281 +msgid "Toggle Fade Out Active" +msgstr "Fade-Out aktivieren" + +#: gtk2_ardour/editor_actions.cc:284 msgid "Align Regions Start" msgstr "Anfang der Regionen ausrichten" -#: gtk2_ardour/editor_actions.cc:180 +#: gtk2_ardour/editor_actions.cc:286 msgid "Align Regions Start Relative" msgstr "Anfang der Regionen relativ ausrichten" -#: gtk2_ardour/editor_actions.cc:182 +#: gtk2_ardour/editor_actions.cc:288 msgid "Align Regions End" -msgstr "ardour: Region" +msgstr "Regionenenden ausrichten" -#: gtk2_ardour/editor_actions.cc:184 +#: gtk2_ardour/editor_actions.cc:290 msgid "Align Regions End Relative" msgstr "Regionenenden relativ ausrichten" -#: gtk2_ardour/editor_actions.cc:187 +#: gtk2_ardour/editor_actions.cc:293 msgid "Align Regions Sync" -msgstr "ardour: Region" +msgstr "Regionen-Einrastpunkt ausrichten" -#: gtk2_ardour/editor_actions.cc:189 +#: gtk2_ardour/editor_actions.cc:295 msgid "Align Regions Sync Relative" -msgstr "Regionen-Sync relativ ausrichten" +msgstr "Regionen-Einrastpunkt relativ ausrichten" -#: gtk2_ardour/editor_actions.cc:192 -msgid "Audition at Mouse" -msgstr "An Mauszeigerposition vorhören" +#: gtk2_ardour/editor_actions.cc:298 +msgid "Play From Edit Point" +msgstr "Wiedergabe ab Arbeitspunkt" -#: gtk2_ardour/editor_actions.cc:194 +#: gtk2_ardour/editor_actions.cc:300 +msgid "Play from Edit Point & Return" +msgstr "Wiedergabe ab Arbeitspunkt & Return" + +#: gtk2_ardour/editor_actions.cc:303 +msgid "Play Edit Range" +msgstr "Editierbereich wiedergeben" + +#: gtk2_ardour/editor_actions.cc:304 +msgid "Play Selected Region(s)" +msgstr "Ausgewählte Regionen wiedergeben" + +#: gtk2_ardour/editor_actions.cc:306 msgid "Brush at Mouse" msgstr "Pinsel an Mausposition (Brush)" -#: gtk2_ardour/editor_actions.cc:196 -msgid "Set Edit Cursor" -msgstr "Editierzeiger setzen" - -#: gtk2_ardour/editor_actions.cc:198 +#: gtk2_ardour/editor_actions.cc:308 msgid "Mute/Unmute Region" msgstr "Region Mute/Unmute" -#: gtk2_ardour/editor_actions.cc:200 +#: gtk2_ardour/editor_actions.cc:311 msgid "Set Playhead" msgstr "Positionszeiger setzen" -#: gtk2_ardour/editor_actions.cc:202 +#: gtk2_ardour/editor_actions.cc:313 +msgid "Set Edit Point" +msgstr "Arbeitspunkt setzen" + +#: gtk2_ardour/editor_actions.cc:315 msgid "Split Region" msgstr "Region teilen (Split)" -#: gtk2_ardour/editor_actions.cc:204 +#: gtk2_ardour/editor_actions.cc:317 msgid "Set Region Sync Position" -msgstr "Sync-Position der Region setzen" +msgstr "Einrastpunkt der Region setzen" -#: gtk2_ardour/editor_actions.cc:212 +#: gtk2_ardour/editor_actions.cc:325 msgid "Export Session" -msgstr "Projekt exportieren" +msgstr "Projekt exportieren..." -#: gtk2_ardour/editor_actions.cc:214 +#: gtk2_ardour/editor_actions.cc:327 msgid "Export Range" -msgstr "Bereich exportieren" +msgstr "Bereiche exportieren..." -#: gtk2_ardour/editor_actions.cc:220 +#: gtk2_ardour/editor_actions.cc:330 +msgid "Separate" +msgstr "Teilen" + +#: gtk2_ardour/editor_actions.cc:332 +#: gtk2_ardour/editor_actions.cc:355 +#, fuzzy +msgid "Crop" +msgstr "Kopieren" + +#: gtk2_ardour/editor_actions.cc:337 +#: gtk2_ardour/redirect_box.cc:1188 #: gtk2_ardour/connection_editor.cc:55 msgid "Delete" msgstr "Löschen" -#: gtk2_ardour/editor_actions.cc:226 +#: gtk2_ardour/editor_actions.cc:343 msgid "Duplicate Region" msgstr "Duplizieren" -#: gtk2_ardour/editor_actions.cc:228 +#: gtk2_ardour/editor_actions.cc:345 +msgid "Multi-Duplicate Region" +msgstr "Region mehrfach Duplizieren" + +#: gtk2_ardour/editor_actions.cc:347 msgid "Duplicate Range" msgstr "Bereich duplizieren" -#: gtk2_ardour/editor_actions.cc:230 +#: gtk2_ardour/editor_actions.cc:349 msgid "Insert Region" msgstr "Einfügen" -#: gtk2_ardour/editor_actions.cc:232 +#: gtk2_ardour/editor_actions.cc:351 msgid "Reverse Region" msgstr "Rückwärts" -#: gtk2_ardour/editor_actions.cc:234 +#: gtk2_ardour/editor_actions.cc:353 msgid "Normalize Region" msgstr "Normalisieren" -#: gtk2_ardour/editor_actions.cc:236 -msgid "crop" -msgstr "Abschneiden" - -#: gtk2_ardour/editor_actions.cc:238 +#: gtk2_ardour/editor_actions.cc:357 msgid "Insert Chunk" msgstr "Abschnitt einfügen" -#: gtk2_ardour/editor_actions.cc:241 -msgid "Split at edit cursor" -msgstr "Am Editierzeiger trennen" +#: gtk2_ardour/editor_actions.cc:360 +msgid "Split At Edit Point" +msgstr "Am Arbeitspunkt trennen" -#: gtk2_ardour/editor_actions.cc:244 +#: gtk2_ardour/editor_actions.cc:363 msgid "Start Range" -msgstr "Bereich anfangen" +msgstr "Bereich beginnen" -#: gtk2_ardour/editor_actions.cc:246 +#: gtk2_ardour/editor_actions.cc:365 msgid "Finish Range" msgstr "Bereich beenden" -#: gtk2_ardour/editor_actions.cc:248 +#: gtk2_ardour/editor_actions.cc:367 msgid "Finish add Range" msgstr "Bereich hinzufügen beenden" -#: gtk2_ardour/editor_actions.cc:251 -msgid "Extend Range to End of Region" -msgstr "Bereich vergrößern bis zum Ende der Region " - -#: gtk2_ardour/editor_actions.cc:253 -msgid "Extend Range to Start of Region" -msgstr "Bereich vergrößern bis zum Anfang der Region " - -#: gtk2_ardour/editor_actions.cc:256 +#: gtk2_ardour/editor_actions.cc:375 msgid "Follow Playhead" msgstr "Positionszeiger folgen" -#: gtk2_ardour/editor_actions.cc:264 +#: gtk2_ardour/editor_actions.cc:383 msgid "Zoom Focus Left" msgstr "Am linken Rand ausrichten" -#: gtk2_ardour/editor_actions.cc:266 +#: gtk2_ardour/editor_actions.cc:385 msgid "Zoom Focus Right" msgstr "Am rechten Rand ausrichten" -#: gtk2_ardour/editor_actions.cc:268 +#: gtk2_ardour/editor_actions.cc:387 msgid "Zoom Focus Center" msgstr "Zentriert ausrichten" -#: gtk2_ardour/editor_actions.cc:270 +#: gtk2_ardour/editor_actions.cc:389 msgid "Zoom Focus Playhead" msgstr "Am Positionszeiger ausrichten" -#: gtk2_ardour/editor_actions.cc:272 +#: gtk2_ardour/editor_actions.cc:391 +msgid "Zoom Focus Mouse" +msgstr "Zoom Fokus zur Maus" + +#: gtk2_ardour/editor_actions.cc:393 msgid "Zoom Focus Edit" msgstr "Am Editierzeiger ausrichten" -#: gtk2_ardour/editor_actions.cc:278 +#: gtk2_ardour/editor_actions.cc:399 msgid "Object Tool" msgstr "Objektwerkzeug" -#: gtk2_ardour/editor_actions.cc:279 +#: gtk2_ardour/editor_actions.cc:400 msgid "Range Tool" msgstr "Bereich-Werkzeug (Range)" -#: gtk2_ardour/editor_actions.cc:280 +#: gtk2_ardour/editor_actions.cc:401 msgid "Gain Tool" msgstr "Lautstärkewerkzeug (Gain)" -#: gtk2_ardour/editor_actions.cc:281 +#: gtk2_ardour/editor_actions.cc:402 msgid "Zoom Tool" msgstr "Zoom-Werkzeug" -#: gtk2_ardour/editor_actions.cc:282 +#: gtk2_ardour/editor_actions.cc:403 msgid "Timefx Tool" msgstr "Zeit-Werkzeug (Time)" -#: gtk2_ardour/editor_actions.cc:284 +#: gtk2_ardour/editor_actions.cc:410 +msgid "Change edit point" +msgstr "Arbeitspunkt ändern" + +#: gtk2_ardour/editor_actions.cc:411 +msgid "Change edit point (w/Marker)" +msgstr "Setze Arbeitspunkt (über Positionsmarker)" + +#: gtk2_ardour/editor_actions.cc:413 +#, fuzzy +msgid "Splice" +msgstr "Teilen" + +#: gtk2_ardour/editor_actions.cc:414 +#, fuzzy +msgid "Slide" +msgstr "Verbergen" + +#: gtk2_ardour/editor_actions.cc:415 +msgid "Toggle Edit Mode" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:417 msgid "Snap To" msgstr "Raster" -#: gtk2_ardour/editor_actions.cc:285 +#: gtk2_ardour/editor_actions.cc:418 msgid "Snap Mode" msgstr "Einrastmodus" -#: gtk2_ardour/editor_actions.cc:294 -msgid "Snap to frame" -msgstr "An Frames einrasten" +#: gtk2_ardour/editor_actions.cc:425 +msgid "Next Snap Mode" +msgstr "Nächster Einrastmodus" -#: gtk2_ardour/editor_actions.cc:295 +#: gtk2_ardour/editor_actions.cc:426 +msgid "Next Snap Choice" +msgstr "" + +#: gtk2_ardour/editor_actions.cc:431 msgid "Snap to cd frame" msgstr "An CD-Frames einrasten" -#: gtk2_ardour/editor_actions.cc:296 +#: gtk2_ardour/editor_actions.cc:432 msgid "Snap to SMPTE frame" msgstr "An SMPTE-Frames einrasten" -#: gtk2_ardour/editor_actions.cc:297 +#: gtk2_ardour/editor_actions.cc:433 msgid "Snap to SMPTE seconds" msgstr "An SMPTE-Sekunden einrasten" -#: gtk2_ardour/editor_actions.cc:298 +#: gtk2_ardour/editor_actions.cc:434 msgid "Snap to SMPTE minutes" msgstr "An SMPTE-Minuten einrasten" -#: gtk2_ardour/editor_actions.cc:299 +#: gtk2_ardour/editor_actions.cc:435 msgid "Snap to seconds" msgstr "An Sekunden einrasten" -#: gtk2_ardour/editor_actions.cc:300 +#: gtk2_ardour/editor_actions.cc:436 msgid "Snap to minutes" msgstr "An Minuten einrasten" -#: gtk2_ardour/editor_actions.cc:301 +#: gtk2_ardour/editor_actions.cc:437 msgid "Snap to thirtyseconds" msgstr "An halben Minuten einrasten" -#: gtk2_ardour/editor_actions.cc:302 +#: gtk2_ardour/editor_actions.cc:438 msgid "Snap to asixteenthbeat" msgstr "An Sechzehnteln einrasten" -#: gtk2_ardour/editor_actions.cc:303 +#: gtk2_ardour/editor_actions.cc:439 msgid "Snap to eighths" msgstr "An Achteln einrasten" -#: gtk2_ardour/editor_actions.cc:304 +#: gtk2_ardour/editor_actions.cc:440 msgid "Snap to quarters" msgstr "An Vierteln einrasten" -#: gtk2_ardour/editor_actions.cc:305 +#: gtk2_ardour/editor_actions.cc:441 msgid "Snap to thirds" msgstr "An Triolen einrasten" -#: gtk2_ardour/editor_actions.cc:306 +#: gtk2_ardour/editor_actions.cc:442 msgid "Snap to beat" msgstr "An Schlägen einrasten" -#: gtk2_ardour/editor_actions.cc:307 +#: gtk2_ardour/editor_actions.cc:443 msgid "Snap to bar" msgstr "An Takten einrasten" -#: gtk2_ardour/editor_actions.cc:308 +#: gtk2_ardour/editor_actions.cc:444 msgid "Snap to mark" msgstr "An Markern einrasten" -#: gtk2_ardour/editor_actions.cc:309 -msgid "Snap to edit cursor" -msgstr "Am Editierzeiger einrasten" - -#: gtk2_ardour/editor_actions.cc:310 +#: gtk2_ardour/editor_actions.cc:445 msgid "Snap to region start" msgstr "Am Anfang der Regionen einrasten" -#: gtk2_ardour/editor_actions.cc:311 +#: gtk2_ardour/editor_actions.cc:446 msgid "Snap to region end" msgstr "Am Ende der Regionen einrasten" -#: gtk2_ardour/editor_actions.cc:312 +#: gtk2_ardour/editor_actions.cc:447 msgid "Snap to region sync" -msgstr "Am Sync der Regionen einrasten" +msgstr "Am Einrastpunkt der Regionen einrasten" -#: gtk2_ardour/editor_actions.cc:313 +#: gtk2_ardour/editor_actions.cc:448 msgid "Snap to region boundary" msgstr "An Grenzen der Regionen einrasten" -#: gtk2_ardour/editor_actions.cc:322 +#: gtk2_ardour/editor_actions.cc:457 msgid "Sort" msgstr "Sortieren" -#: gtk2_ardour/editor_actions.cc:330 +#: gtk2_ardour/editor_actions.cc:465 msgid "Show all" msgstr "Alle zeigen" -#: gtk2_ardour/editor_actions.cc:331 +#: gtk2_ardour/editor_actions.cc:466 msgid "Show automatic regions" msgstr "Automatische Regionen zeigen" -#: gtk2_ardour/editor_actions.cc:333 +#: gtk2_ardour/editor_actions.cc:468 msgid "Ascending" msgstr "aufsteigend" -#: gtk2_ardour/editor_actions.cc:335 +#: gtk2_ardour/editor_actions.cc:470 msgid "Descending" msgstr "absteigend" -#: gtk2_ardour/editor_actions.cc:338 +#: gtk2_ardour/editor_actions.cc:473 msgid "By Region Name" msgstr "nach Name der Region" -#: gtk2_ardour/editor_actions.cc:340 +#: gtk2_ardour/editor_actions.cc:475 msgid "By Region Length" msgstr "nach Länge der Region" -#: gtk2_ardour/editor_actions.cc:342 +#: gtk2_ardour/editor_actions.cc:477 msgid "By Region Position" msgstr "nach Position der Region" -#: gtk2_ardour/editor_actions.cc:344 +#: gtk2_ardour/editor_actions.cc:479 msgid "By Region Timestamp" msgstr "nach Zeitstempel der Region" -#: gtk2_ardour/editor_actions.cc:346 +#: gtk2_ardour/editor_actions.cc:481 msgid "By Region Start in File" msgstr "nach Anfang der Region in der Datei" -#: gtk2_ardour/editor_actions.cc:348 +#: gtk2_ardour/editor_actions.cc:483 msgid "By Region End in File" msgstr "nach Ende der Region in der Datei" -#: gtk2_ardour/editor_actions.cc:350 +#: gtk2_ardour/editor_actions.cc:485 msgid "By Source File Name" msgstr "nach Namen der Quelldatei" -#: gtk2_ardour/editor_actions.cc:352 +#: gtk2_ardour/editor_actions.cc:487 msgid "By Source File Length" msgstr "nach Länge der Quelldatei" -#: gtk2_ardour/editor_actions.cc:354 +#: gtk2_ardour/editor_actions.cc:489 msgid "By Source File Creation Date" msgstr "nach Erstellungsdatum der Quelldatei" -#: gtk2_ardour/editor_actions.cc:356 +#: gtk2_ardour/editor_actions.cc:491 msgid "By Source Filesystem" msgstr "nach Dateisystem der Quelle" -#: gtk2_ardour/editor_actions.cc:362 +#: gtk2_ardour/editor_actions.cc:497 +msgid "Add Existing Audio" +msgstr "Audio importieren" + +#: gtk2_ardour/editor_actions.cc:499 msgid "Add External Audio" msgstr "Audio importieren..." -#: gtk2_ardour/editor_actions.cc:364 -msgid "as Region(s)" -msgstr "als Region(en)..." - -#: gtk2_ardour/editor_actions.cc:366 -msgid "as Tracks" -msgstr "als neue Spur(en)..." - -#: gtk2_ardour/editor_actions.cc:368 -msgid "as Tape Tracks" -msgstr "als neue Tape-Spur(en)..." - -#: gtk2_ardour/editor_actions.cc:370 -msgid "to Tracks" -msgstr "in vorhandene Spuren..." - -#: gtk2_ardour/editor_actions.cc:373 +#: gtk2_ardour/editor_actions.cc:502 msgid "Show Waveforms" msgstr "Wellenformen zeigen" -#: gtk2_ardour/editor_actions.cc:374 +#: gtk2_ardour/editor_actions.cc:503 msgid "Show Waveforms While Recording" msgstr "Wellenformen beim Aufnehmen zeigen" -#: gtk2_ardour/editor_actions.cc:375 +#: gtk2_ardour/editor_actions.cc:504 msgid "Show Measures" msgstr "Takte zeigen" -#: gtk2_ardour/editor_actions.cc:379 +#: gtk2_ardour/editor_actions.cc:508 +msgid "Show Logo" +msgstr "Zeige Logo" + +#: gtk2_ardour/editor_actions.cc:514 msgid "Later is Higher" msgstr "Neuste nach oben" -#: gtk2_ardour/editor_actions.cc:380 +#: gtk2_ardour/editor_actions.cc:515 msgid "Most Recently Moved/Added is Higher" msgstr "Zuletzt bewegte/hinzugefügte nach oben" -#: gtk2_ardour/editor_actions.cc:381 +#: gtk2_ardour/editor_actions.cc:516 msgid "Most Recently Added is Higher" msgstr "Zuletzt hinzugefügte nach oben" -#: gtk2_ardour/editor_actions.cc:385 +#: gtk2_ardour/editor_actions.cc:520 msgid "23.976" -msgstr "" +msgstr "23,976" -#: gtk2_ardour/editor_actions.cc:386 +#: gtk2_ardour/editor_actions.cc:521 msgid "24" -msgstr "" +msgstr "24" -#: gtk2_ardour/editor_actions.cc:387 +#: gtk2_ardour/editor_actions.cc:522 msgid "24.976" -msgstr "" +msgstr "24,976" -#: gtk2_ardour/editor_actions.cc:388 +#: gtk2_ardour/editor_actions.cc:523 msgid "25" -msgstr "" +msgstr "25" -#: gtk2_ardour/editor_actions.cc:389 +#: gtk2_ardour/editor_actions.cc:524 msgid "29.97" -msgstr "" +msgstr "29,97" -#: gtk2_ardour/editor_actions.cc:390 +#: gtk2_ardour/editor_actions.cc:525 msgid "29.97 drop" -msgstr "" +msgstr "29,97 (drop)" -#: gtk2_ardour/editor_actions.cc:391 +#: gtk2_ardour/editor_actions.cc:526 msgid "30" -msgstr "" +msgstr "30" -#: gtk2_ardour/editor_actions.cc:392 +#: gtk2_ardour/editor_actions.cc:527 msgid "30 drop" -msgstr "" +msgstr "30 (drop)" -#: gtk2_ardour/editor_actions.cc:393 +#: gtk2_ardour/editor_actions.cc:528 msgid "59.94" -msgstr "" +msgstr "59,94" -#: gtk2_ardour/editor_actions.cc:394 +#: gtk2_ardour/editor_actions.cc:529 msgid "60" -msgstr "" +msgstr "60" -#: gtk2_ardour/editor_actions.cc:398 +#: gtk2_ardour/editor_actions.cc:533 msgid "+4.1667% + 0.1%" -msgstr "" +msgstr "+4,1667% + 0,1%" -#: gtk2_ardour/editor_actions.cc:399 +#: gtk2_ardour/editor_actions.cc:534 msgid "+4.1667%" -msgstr "" +msgstr "+4,1667%" -#: gtk2_ardour/editor_actions.cc:400 +#: gtk2_ardour/editor_actions.cc:535 msgid "+4.1667% - 0.1%" -msgstr "" +msgstr "+4,1667% - 0,1%" -#: gtk2_ardour/editor_actions.cc:401 +#: gtk2_ardour/editor_actions.cc:536 msgid "+ 0.1%" -msgstr "" +msgstr "+ 0,1%" -#: gtk2_ardour/editor_actions.cc:403 +#: gtk2_ardour/editor_actions.cc:537 +#: gtk2_ardour/engine_dialog.cc:98 +#: gtk2_ardour/engine_dialog.cc:103 +#: gtk2_ardour/engine_dialog.cc:479 +#: gtk2_ardour/export_dialog.cc:78 +#: gtk2_ardour/export_dialog.cc:92 +#: gtk2_ardour/export_dialog.cc:956 +#: gtk2_ardour/export_dialog.cc:1294 +#: gtk2_ardour/route_ui.cc:513 +msgid "None" +msgstr "Kein" + +#: gtk2_ardour/editor_actions.cc:538 msgid "- 0.1%" -msgstr "" +msgstr "- 0,1%" -#: gtk2_ardour/editor_actions.cc:404 +#: gtk2_ardour/editor_actions.cc:539 msgid "-4.1667% + 0.1%" -msgstr "" +msgstr "-4,1667% + 0,1%" -#: gtk2_ardour/editor_actions.cc:405 +#: gtk2_ardour/editor_actions.cc:540 msgid "-4.1667%" -msgstr "" +msgstr "-4,1667%" -#: gtk2_ardour/editor_actions.cc:406 +#: gtk2_ardour/editor_actions.cc:541 msgid "-4.1667% - 0.1%" -msgstr "" +msgstr "-4,1667% - 0,1%" -#: gtk2_ardour/editor_actions.cc:410 +#: gtk2_ardour/editor_actions.cc:545 msgid "80 per frame" msgstr "80 pro Frame" -#: gtk2_ardour/editor_actions.cc:411 +#: gtk2_ardour/editor_actions.cc:547 msgid "100 per frame" msgstr "100 pro Frame" -#: gtk2_ardour/editor_actions.cc:714 -#: gtk2_ardour/editor_actions.cc:759 -#: gtk2_ardour/editor_actions.cc:770 -#: gtk2_ardour/editor_actions.cc:814 -#: gtk2_ardour/editor_actions.cc:824 +#: gtk2_ardour/editor_actions.cc:863 +#: gtk2_ardour/editor_actions.cc:972 +#: gtk2_ardour/editor_actions.cc:983 +#: gtk2_ardour/editor_actions.cc:1036 +#: gtk2_ardour/editor_actions.cc:1047 +#: gtk2_ardour/editor_actions.cc:1094 +#: gtk2_ardour/editor_actions.cc:1104 msgid "programming error: %1: %2" msgstr "Programmierfehler: %1: %2" -#: gtk2_ardour/editor_actions.cc:985 +#: gtk2_ardour/editor_actions.cc:1265 msgid "Configuraton is using unhandled subframes per frame value: %1" msgstr "Diese Konfiguration benutzt einen unzulässigen Wert für Subframes pro Frame: %1" -#: gtk2_ardour/editor_audio_import.cc:84 +#: gtk2_ardour/editor_audio_import.cc:71 +#: gtk2_ardour/editor_audio_import.cc:92 msgid "You can't import or embed an audiofile until you have a session loaded." msgstr "Sie können keine Audiodatei importieren, solange kein Projekt geladen ist." -#: gtk2_ardour/editor_audio_import.cc:89 -msgid "Add existing audio to session" +#: gtk2_ardour/editor_audio_import.cc:77 +#: gtk2_ardour/editor_audio_import.cc:110 +msgid "Add existing audio" msgstr "Audio importieren" -#: gtk2_ardour/editor_audio_import.cc:176 -msgid "Import as a %1 region" -msgstr "Importiere als eine %1 Region" - -#: gtk2_ardour/editor_audio_import.cc:177 -msgid "multichannel" -msgstr "Mehrkanal" - -#: gtk2_ardour/editor_audio_import.cc:177 -#: gtk2_ardour/export_dialog.cc:86 -msgid "stereo" -msgstr "Stereo" - -#: gtk2_ardour/editor_audio_import.cc:178 -msgid "Import as multiple regions" -msgstr "In mehrere Regionen aufteilen" - -#: gtk2_ardour/editor_audio_import.cc:180 -msgid "" -"Paired files detected (%1, %2 ...).\n" -"Do you want to:" -msgstr "" -"Zusammenhängende Dateien gefunden (%1, %2 ...).\n" -"Wollen Sie:" - -#: gtk2_ardour/editor_audio_import.cc:226 +#: gtk2_ardour/editor_audio_import.cc:370 msgid "importing %1" msgstr "importiere %1" -#: gtk2_ardour/editor_audio_import.cc:232 +#: gtk2_ardour/editor_audio_import.cc:376 msgid "Cancel Import" msgstr "Importieren Abbrechen" -#: gtk2_ardour/editor_audio_import.cc:332 +#: gtk2_ardour/editor_audio_import.cc:479 msgid "Editor: cannot open file \"%1\", (%2)" msgstr "Editor: kann die Datei \"%1\" nicht öffnen (%2)" -#: gtk2_ardour/editor_audio_import.cc:340 +#: gtk2_ardour/editor_audio_import.cc:487 msgid "Cancel entire import" msgstr "Importieren Abbrechen" -#: gtk2_ardour/editor_audio_import.cc:341 +#: gtk2_ardour/editor_audio_import.cc:488 msgid "Don't embed it" msgstr "Nicht einbetten" -#: gtk2_ardour/editor_audio_import.cc:342 +#: gtk2_ardour/editor_audio_import.cc:489 msgid "Embed all without questions" msgstr "Alle Importieren ohne nachzufragen" -#: gtk2_ardour/editor_audio_import.cc:345 -#: gtk2_ardour/editor_audio_import.cc:370 +#: gtk2_ardour/editor_audio_import.cc:492 +#: gtk2_ardour/editor_audio_import.cc:519 msgid "" "%1\n" "This audiofile's sample rate doesn't match the session sample rate!" @@ -3714,52 +4131,44 @@ msgstr "" "%1\n" "Die Samplerate dieser Audiodatei unterscheidet sich von der Samplerate dieses Projekts." -#: gtk2_ardour/editor_audio_import.cc:367 +#: gtk2_ardour/editor_audio_import.cc:516 msgid "Embed it anyway" msgstr "Trotzdem importieren" -#: gtk2_ardour/editor_audio_import.cc:417 +#: gtk2_ardour/editor_audio_import.cc:561 msgid "could not open %1" msgstr "Konnte \"%s\" nicht öffnen." -#: gtk2_ardour/editor_audio_import.cc:464 +#: gtk2_ardour/editor_audio_import.cc:691 msgid "insert sndfile" msgstr "Audiodatei einfügen" -#: gtk2_ardour/editor_canvas.cc:118 +#: gtk2_ardour/editor_canvas.cc:129 msgid "VerboseCanvasCursor" msgstr "" -#: gtk2_ardour/editor_canvas.cc:267 -msgid "edit cursor color not defined, check your ardour.colors file!" -msgstr "Die Farbe für den Editierzeiger ist nicht definiert, bitte in ardour.colors prüfen!" - -#: gtk2_ardour/editor_canvas.cc:272 -msgid "playhead color not defined, check your ardour.colors file!" -msgstr "Die Farbe für den Wiedergabezeiger ist nicht definiert, bitte in ardour.colors prüfen!" - #: gtk2_ardour/editor_edit_groups.cc:52 -#: gtk2_ardour/mixer_ui.cc:765 +#: gtk2_ardour/mixer_ui.cc:848 msgid "Activate All" msgstr "Alle aktivieren" #: gtk2_ardour/editor_edit_groups.cc:53 -#: gtk2_ardour/mixer_ui.cc:766 +#: gtk2_ardour/mixer_ui.cc:849 msgid "Disable All" msgstr "Alle deaktivieren" #: gtk2_ardour/editor_edit_groups.cc:55 -#: gtk2_ardour/mixer_ui.cc:768 +#: gtk2_ardour/mixer_ui.cc:851 msgid "Add group" msgstr "Gruppe hinzufügen" #: gtk2_ardour/editor_edit_groups.cc:228 -#: gtk2_ardour/mixer_ui.cc:1009 +#: gtk2_ardour/mixer_ui.cc:1092 msgid "unnamed" msgstr "unbenannt" #: gtk2_ardour/editor_edit_groups.cc:257 -#: gtk2_ardour/mixer_ui.cc:863 +#: gtk2_ardour/mixer_ui.cc:946 msgid "-all-" msgstr "-alle-" @@ -3769,11 +4178,11 @@ msgid "" "\n" "Select a selection using the range mouse mode" msgstr "" -"Es wurde keine Auswahl zum Exportieren getroffen.\n" +"Es wurde keine Auswahlbereich zum Exportieren erstellt.\n" "\n" "Erstellen Sie eine Auswahl mit dem Bereichswerkzeug" -#: gtk2_ardour/editor_export_audio.cc:111 +#: gtk2_ardour/editor_export_audio.cc:109 msgid "" "There are no ranges to export.\n" "\n" @@ -3793,305 +4202,293 @@ msgstr "Programmierfehler: kein ImageFrameView ausgewählt" msgid "programming error: no MarkerView selected" msgstr "Programmierfehler: kein MarkerView ausgewählt" -#: gtk2_ardour/editor_keyboard.cc:104 +#: gtk2_ardour/editor_keyboard.cc:82 msgid "mute region" msgstr "Region stummschalten" -#: gtk2_ardour/editor_keys.cc:45 -msgid "keyboard selection" -msgstr "Tastaturauswahl" - -#: gtk2_ardour/editor_markers.cc:296 -#: gtk2_ardour/editor_ops.cc:1241 -#: gtk2_ardour/editor_ops.cc:1258 -#: gtk2_ardour/editor_ops.cc:1277 -#: gtk2_ardour/location_ui.cc:782 +#: gtk2_ardour/editor_markers.cc:399 +#: gtk2_ardour/editor_ops.cc:1794 +#: gtk2_ardour/editor_ops.cc:1811 +#: gtk2_ardour/editor_ops.cc:1836 +#: gtk2_ardour/location_ui.cc:821 msgid "add marker" msgstr "Marker hinzufügen" -#: gtk2_ardour/editor_markers.cc:312 -#: gtk2_ardour/editor_markers.cc:376 -#: gtk2_ardour/editor_markers.cc:553 -#: gtk2_ardour/editor_markers.cc:571 -#: gtk2_ardour/editor_markers.cc:589 -#: gtk2_ardour/editor_markers.cc:608 -#: gtk2_ardour/editor_markers.cc:627 -#: gtk2_ardour/editor_markers.cc:657 -#: gtk2_ardour/editor_markers.cc:685 -#: gtk2_ardour/editor_markers.cc:713 -#: gtk2_ardour/editor_markers.cc:752 -#: gtk2_ardour/editor_markers.cc:777 -#: gtk2_ardour/editor_markers.cc:804 -#: gtk2_ardour/editor_markers.cc:827 -#: gtk2_ardour/editor_markers.cc:846 -#: gtk2_ardour/editor_mouse.cc:2015 -#: gtk2_ardour/editor_mouse.cc:4351 +#: gtk2_ardour/editor_markers.cc:423 +#: gtk2_ardour/editor_markers.cc:491 +#: gtk2_ardour/editor_markers.cc:676 +#: gtk2_ardour/editor_markers.cc:694 +#: gtk2_ardour/editor_markers.cc:712 +#: gtk2_ardour/editor_markers.cc:731 +#: gtk2_ardour/editor_markers.cc:750 +#: gtk2_ardour/editor_markers.cc:780 +#: gtk2_ardour/editor_markers.cc:808 +#: gtk2_ardour/editor_markers.cc:836 +#: gtk2_ardour/editor_markers.cc:874 +#: gtk2_ardour/editor_markers.cc:899 +#: gtk2_ardour/editor_markers.cc:926 +#: gtk2_ardour/editor_markers.cc:949 +#: gtk2_ardour/editor_markers.cc:969 +#: gtk2_ardour/editor_markers.cc:993 +#: gtk2_ardour/editor_mouse.cc:2139 +#: gtk2_ardour/editor_mouse.cc:4686 msgid "programming error: marker canvas item has no marker object pointer!" msgstr "Programmierfehler: marker canvas item has no marker object pointer!" -#: gtk2_ardour/editor_markers.cc:326 -#: gtk2_ardour/location_ui.cc:660 +#: gtk2_ardour/editor_markers.cc:441 +#: gtk2_ardour/location_ui.cc:699 msgid "remove marker" msgstr "Marker entfernen" -#: gtk2_ardour/editor_markers.cc:467 -msgid "Locate to Mark" -msgstr "Positionszeiger zu Marker setzen" - -#: gtk2_ardour/editor_markers.cc:468 -msgid "Play from Mark" -msgstr "Wiedergabe ab Marker" +#: gtk2_ardour/editor_markers.cc:582 +msgid "Locate to here" +msgstr "Positionszeiger hierhin setzen" -#: gtk2_ardour/editor_markers.cc:469 -msgid "Set Mark from Playhead" -msgstr "Marker am Positionszeiger setzen" +#: gtk2_ardour/editor_markers.cc:583 +msgid "Play from here" +msgstr "Wiedergabe ab hier" -#: gtk2_ardour/editor_markers.cc:473 -msgid "Hide Mark" -msgstr "Marker verbergen" +#: gtk2_ardour/editor_markers.cc:584 +msgid "Move Mark to Playhead" +msgstr "Marker zum Positionszeiger verschieben" -#: gtk2_ardour/editor_markers.cc:475 -#: gtk2_ardour/editor_markers.cc:864 -msgid "Rename Mark" -msgstr "Marker umbenennen" +#: gtk2_ardour/editor_markers.cc:592 +msgid "Unlock" +msgstr "Entsperren" -#: gtk2_ardour/editor_markers.cc:476 -msgid "Remove Mark" -msgstr "Marker entfernen" +#: gtk2_ardour/editor_markers.cc:614 +msgid "Play Range" +msgstr "Bereich wiedergeben" -#: gtk2_ardour/editor_markers.cc:494 +#: gtk2_ardour/editor_markers.cc:615 msgid "Locate to Range Mark" msgstr "Positionszeiger zu Bereichsmarker" -#: gtk2_ardour/editor_markers.cc:495 +#: gtk2_ardour/editor_markers.cc:616 msgid "Play from Range Mark" msgstr "Wiedergabe ab Bereichsmarker" -#: gtk2_ardour/editor_markers.cc:497 -msgid "Play Range" -msgstr "Bereich wiedergeben" - -#: gtk2_ardour/editor_markers.cc:498 +#: gtk2_ardour/editor_markers.cc:618 msgid "Loop Range" msgstr "Bereich in Schleife wiedergeben" -#: gtk2_ardour/editor_markers.cc:500 +#: gtk2_ardour/editor_markers.cc:620 msgid "Set Range Mark from Playhead" msgstr "Bereichsmarker zum Positionszeiger verschieben" -#: gtk2_ardour/editor_markers.cc:501 +#: gtk2_ardour/editor_markers.cc:622 msgid "Set Range from Range Selection" msgstr "Bereichsmarker zum Auswahlbereich verschieben" -#: gtk2_ardour/editor_markers.cc:505 +#: gtk2_ardour/editor_markers.cc:628 msgid "Hide Range" msgstr "Bereich verbergen" -#: gtk2_ardour/editor_markers.cc:507 -#: gtk2_ardour/editor_markers.cc:866 +#: gtk2_ardour/editor_markers.cc:629 +#: gtk2_ardour/editor_markers.cc:1013 msgid "Rename Range" msgstr "Bereich umbenennen" -#: gtk2_ardour/editor_markers.cc:508 +#: gtk2_ardour/editor_markers.cc:630 msgid "Remove Range" msgstr "Bereich entfernen" -#: gtk2_ardour/editor_markers.cc:513 +#: gtk2_ardour/editor_markers.cc:635 msgid "Separate Regions in Range" msgstr "Regionen an Bereichsgrenzen teilen" -#: gtk2_ardour/editor_markers.cc:514 +#: gtk2_ardour/editor_markers.cc:636 msgid "Select All in Range" msgstr "Alles im Bereich auswählen" -#: gtk2_ardour/editor_markers.cc:515 +#: gtk2_ardour/editor_markers.cc:638 msgid "Select Range" msgstr "Bereich auswählen" -#: gtk2_ardour/editor_markers.cc:541 +#: gtk2_ardour/editor_markers.cc:664 msgid "Set Loop Range" msgstr "Schleife erstellen" -#: gtk2_ardour/editor_markers.cc:542 +#: gtk2_ardour/editor_markers.cc:665 msgid "Set Punch Range" msgstr "Punch-Bereich erstellen" -#: gtk2_ardour/editor_markers.cc:860 +#: gtk2_ardour/editor_markers.cc:1007 msgid "New Name:" msgstr "Neuer Name: " -#: gtk2_ardour/editor_markers.cc:888 +#: gtk2_ardour/editor_markers.cc:1011 +msgid "Rename Mark" +msgstr "Marker umbenennen" + +#: gtk2_ardour/editor_markers.cc:1035 msgid "rename marker" msgstr "Marker umbenennen" -#: gtk2_ardour/editor_markers.cc:914 +#: gtk2_ardour/editor_markers.cc:1059 msgid "set loop range" msgstr "Loop-Bereich festlegen" -#: gtk2_ardour/editor_markers.cc:942 +#: gtk2_ardour/editor_markers.cc:1065 msgid "set punch range" msgstr "Punch-Bereich festlegen" -#: gtk2_ardour/editor_mouse.cc:105 +#: gtk2_ardour/editor_mouse.cc:144 msgid "Editor::event_frame() used on unhandled event type %1" msgstr "" -#: gtk2_ardour/editor_mouse.cc:1539 +#: gtk2_ardour/editor_mouse.cc:1696 msgid "programming error: start_grab called without drag item" msgstr "Programmierfehler: start_grab called without drag item" -#: gtk2_ardour/editor_mouse.cc:1766 +#: gtk2_ardour/editor_mouse.cc:1898 msgid "change fade in length" msgstr "Ändere Fade-In Länge" -#: gtk2_ardour/editor_mouse.cc:1798 +#: gtk2_ardour/editor_mouse.cc:1930 msgid "programming error: fade out canvas item has no regionview data pointer!" msgstr "Programmierfehler: fade out canvas item has no regionview data pointer!" -#: gtk2_ardour/editor_mouse.cc:1883 +#: gtk2_ardour/editor_mouse.cc:2014 msgid "change fade out length" msgstr "Fade-Out verändern" -#: gtk2_ardour/editor_mouse.cc:1915 +#: gtk2_ardour/editor_mouse.cc:2046 msgid "programming error: cursor canvas item has no cursor data pointer!" msgstr "Programmierfehler: cursor canvas item has no cursor data pointer!" -#: gtk2_ardour/editor_mouse.cc:2150 +#: gtk2_ardour/editor_mouse.cc:2301 msgid "move marker" msgstr "Marker bewegen" -#: gtk2_ardour/editor_mouse.cc:2178 -#: gtk2_ardour/editor_mouse.cc:2209 -#: gtk2_ardour/editor_tempodisplay.cc:500 +#: gtk2_ardour/editor_mouse.cc:2334 +#: gtk2_ardour/editor_mouse.cc:2366 +#: gtk2_ardour/editor_tempodisplay.cc:505 msgid "programming error: meter marker canvas item has no marker object pointer!" msgstr "pProgrammierfehler: meter marker canvas item has no marker object pointer!" -#: gtk2_ardour/editor_mouse.cc:2277 +#: gtk2_ardour/editor_mouse.cc:2434 msgid "copy meter mark" msgstr "Taktmarker kopieren" -#: gtk2_ardour/editor_mouse.cc:2288 +#: gtk2_ardour/editor_mouse.cc:2445 msgid "move meter mark" msgstr "Taktwechsel bewegen" -#: gtk2_ardour/editor_mouse.cc:2304 -#: gtk2_ardour/editor_mouse.cc:2337 -#: gtk2_ardour/editor_tempodisplay.cc:369 -#: gtk2_ardour/editor_tempodisplay.cc:449 -#: gtk2_ardour/editor_tempodisplay.cc:468 +#: gtk2_ardour/editor_mouse.cc:2461 +#: gtk2_ardour/editor_mouse.cc:2495 +#: gtk2_ardour/editor_tempodisplay.cc:373 +#: gtk2_ardour/editor_tempodisplay.cc:454 +#: gtk2_ardour/editor_tempodisplay.cc:473 msgid "programming error: tempo marker canvas item has no marker object pointer!" msgstr "Programmierfehler: tempo marker canvas item has no marker object pointer!" -#: gtk2_ardour/editor_mouse.cc:2309 -#: gtk2_ardour/editor_mouse.cc:2342 -#: gtk2_ardour/editor_tempodisplay.cc:374 -#: gtk2_ardour/editor_tempodisplay.cc:454 +#: gtk2_ardour/editor_mouse.cc:2466 +#: gtk2_ardour/editor_mouse.cc:2500 +#: gtk2_ardour/editor_tempodisplay.cc:378 +#: gtk2_ardour/editor_tempodisplay.cc:459 msgid "programming error: marker for tempo is not a tempo marker!" msgstr "Programmierfehler: marker for tempo is not a tempo marker!" -#: gtk2_ardour/editor_mouse.cc:2409 +#: gtk2_ardour/editor_mouse.cc:2567 msgid "copy tempo mark" msgstr "Tempomarker kopieren" -#: gtk2_ardour/editor_mouse.cc:2420 +#: gtk2_ardour/editor_mouse.cc:2578 msgid "move tempo mark" msgstr "Tempowechsel bewegen" -#: gtk2_ardour/editor_mouse.cc:2435 -#: gtk2_ardour/editor_mouse.cc:2454 -#: gtk2_ardour/editor_mouse.cc:2467 +#: gtk2_ardour/editor_mouse.cc:2593 +#: gtk2_ardour/editor_mouse.cc:2612 +#: gtk2_ardour/editor_mouse.cc:2625 msgid "programming error: control point canvas item has no control point object pointer!" msgstr "Programmierfehler: control point canvas item has no control point object pointer!" -#: gtk2_ardour/editor_mouse.cc:2573 +#: gtk2_ardour/editor_mouse.cc:2761 msgid "programming error: line canvas item has no line pointer!" msgstr "Programmierfehler: line canvas item has no line pointer!" -#: gtk2_ardour/editor_mouse.cc:2682 +#: gtk2_ardour/editor_mouse.cc:2900 msgid "move region(s)" msgstr "Region(en) bewegen" -#: gtk2_ardour/editor_mouse.cc:2746 +#: gtk2_ardour/editor_mouse.cc:2964 msgid "Drag region brush" msgstr "Region Brush ziehen" -#: gtk2_ardour/editor_mouse.cc:3274 +#: gtk2_ardour/editor_mouse.cc:3595 msgid "fixed time region copy" msgstr "Region zeitgleich kopieren" -#: gtk2_ardour/editor_mouse.cc:3276 +#: gtk2_ardour/editor_mouse.cc:3597 msgid "region copy" msgstr "Region kopieren" -#: gtk2_ardour/editor_mouse.cc:3280 +#: gtk2_ardour/editor_mouse.cc:3601 msgid "fixed time region drag" msgstr "Region zeitgleich verschieben" -#: gtk2_ardour/editor_mouse.cc:3282 +#: gtk2_ardour/editor_mouse.cc:3603 msgid "region drag" msgstr "Region verschieben" -#: gtk2_ardour/editor_mouse.cc:3670 +#: gtk2_ardour/editor_mouse.cc:4007 msgid "selection grab" msgstr "Auswählen" -#: gtk2_ardour/editor_mouse.cc:3712 -msgid "cancel selection" -msgstr "Auswahl abbrechen" - -#: gtk2_ardour/editor_mouse.cc:3822 +#: gtk2_ardour/editor_mouse.cc:4157 msgid "range selection" -msgstr "Bereichsauswahl" +msgstr "Auswahlbereich" -#: gtk2_ardour/editor_mouse.cc:3838 +#: gtk2_ardour/editor_mouse.cc:4173 msgid "trim selection start" msgstr "Anfangspunkt der Auswahl abschneiden" -#: gtk2_ardour/editor_mouse.cc:3854 +#: gtk2_ardour/editor_mouse.cc:4189 msgid "trim selection end" msgstr "Endpunkt der Auswahl abschneiden" -#: gtk2_ardour/editor_mouse.cc:3871 +#: gtk2_ardour/editor_mouse.cc:4206 msgid "move selection" msgstr "Auswahl bewegen" -#: gtk2_ardour/editor_mouse.cc:4260 +#: gtk2_ardour/editor_mouse.cc:4595 msgid "Start point trim" msgstr "Anfangspunkt verändern" -#: gtk2_ardour/editor_mouse.cc:4292 +#: gtk2_ardour/editor_mouse.cc:4627 msgid "End point trim" msgstr "Endpunkt verändern" -#: gtk2_ardour/editor_mouse.cc:4335 +#: gtk2_ardour/editor_mouse.cc:4670 msgid "trimmed region" msgstr "Abgeschnittene Region" -#: gtk2_ardour/editor_mouse.cc:4478 +#: gtk2_ardour/editor_mouse.cc:4817 msgid "new range marker" msgstr "Neuer Bereich" -#: gtk2_ardour/editor_mouse.cc:4720 +#: gtk2_ardour/editor_mouse.cc:5065 msgid "rubberband selection" msgstr "Bereichsauswahl" -#: gtk2_ardour/editor_mouse.cc:4750 +#: gtk2_ardour/editor_mouse.cc:5095 msgid "Name for region:" msgstr "Name für Region:" -#: gtk2_ardour/editor_mouse.cc:4814 +#: gtk2_ardour/editor_mouse.cc:5168 msgid "timestretch" msgstr "Time-Stretch" -#: gtk2_ardour/editor_ops.cc:116 +#: gtk2_ardour/editor_ops.cc:114 msgid "split" msgstr "Teile" -#: gtk2_ardour/editor_ops.cc:155 +#: gtk2_ardour/editor_ops.cc:180 msgid "remove region" msgstr "Region(en) löschen" -#: gtk2_ardour/editor_ops.cc:175 +#: gtk2_ardour/editor_ops.cc:200 msgid "" " This is destructive, will possibly delete audio files\n" "It cannot be undone\n" @@ -4101,177 +4498,188 @@ msgstr "" "Dies kann nicht rückgängig gemacht werden\n" "Wollen Sie %1 wirklich löschen ?" -#: gtk2_ardour/editor_ops.cc:179 +#: gtk2_ardour/editor_ops.cc:204 msgid "these regions" msgstr "diese Region" -#: gtk2_ardour/editor_ops.cc:179 +#: gtk2_ardour/editor_ops.cc:204 msgid "this region" msgstr "diese Region" -#: gtk2_ardour/editor_ops.cc:184 +#: gtk2_ardour/editor_ops.cc:209 msgid "Yes, destroy them." msgstr "Ja, entfernen." -#: gtk2_ardour/editor_ops.cc:186 -#: gtk2_ardour/editor_ops.cc:3154 +#: gtk2_ardour/editor_ops.cc:211 +#: gtk2_ardour/editor_ops.cc:3955 msgid "Yes, destroy it." msgstr "Ja, entfernen." -#: gtk2_ardour/editor_ops.cc:272 -#: gtk2_ardour/editor_ops.cc:300 +#: gtk2_ardour/editor_ops.cc:297 +#: gtk2_ardour/editor_ops.cc:325 msgid "extend selection" msgstr "Auswahl erweitern" -#: gtk2_ardour/editor_ops.cc:316 -#: gtk2_ardour/editor_ops.cc:351 -#: gtk2_ardour/editor_ops.cc:396 -#: gtk2_ardour/editor_ops.cc:423 +#: gtk2_ardour/editor_ops.cc:341 +msgid "nudge regions forward" +msgstr "Regionen Schritt vorwärts" + +#: gtk2_ardour/editor_ops.cc:368 +#: gtk2_ardour/editor_ops.cc:445 +msgid "nudge location forward" +msgstr "Position Schritt vorwärts" + +#: gtk2_ardour/editor_ops.cc:414 +msgid "nudge regions backward" +msgstr "Regionen Schritt nach hinten" + +#: gtk2_ardour/editor_ops.cc:497 +#: gtk2_ardour/editor_ops.cc:524 msgid "nudge forward" msgstr "Schritt vorwärts" -#: gtk2_ardour/editor_ops.cc:488 +#: gtk2_ardour/editor_ops.cc:591 msgid "build_region_boundary_cache called with snap_type = %1" msgstr "" -#: gtk2_ardour/editor_ops.cc:1398 +#: gtk2_ardour/editor_ops.cc:1634 +#: gtk2_ardour/editor_ops.cc:4709 +msgid "cannot set loop: no region selected" +msgstr "Kann keine Schleife erstellen: keine Region ausgewählt" + +#: gtk2_ardour/editor_ops.cc:1957 msgid "clear markers" msgstr "Marker zurücksetzen" -#: gtk2_ardour/editor_ops.cc:1411 +#: gtk2_ardour/editor_ops.cc:1970 msgid "clear ranges" msgstr "Bereiche zurücksetzen" -#: gtk2_ardour/editor_ops.cc:1431 +#: gtk2_ardour/editor_ops.cc:1990 msgid "clear locations" msgstr "Positionen zurücksetzen" -#: gtk2_ardour/editor_ops.cc:1504 +#: gtk2_ardour/editor_ops.cc:2063 msgid "insert dragged region" msgstr "Region ziehen" -#: gtk2_ardour/editor_ops.cc:1547 +#: gtk2_ardour/editor_ops.cc:2110 msgid "insert region" msgstr "Region einfügen" -#: gtk2_ardour/editor_ops.cc:1746 -#: gtk2_ardour/io_selector.cc:59 -#: gtk2_ardour/io_selector.cc:747 -#: gtk2_ardour/connection_editor.cc:85 -msgid "OK" -msgstr "OK" - -#: gtk2_ardour/editor_ops.cc:1754 +#: gtk2_ardour/editor_ops.cc:2321 msgid "Rename Region" msgstr "Region umbenennen" -#: gtk2_ardour/editor_ops.cc:1996 -#: gtk2_ardour/editor_ops.cc:2055 +#: gtk2_ardour/editor_ops.cc:2325 +msgid "New name:" +msgstr "Neuer Name: " + +#: gtk2_ardour/editor_ops.cc:2624 msgid "separate" msgstr "Teilen" -#: gtk2_ardour/editor_ops.cc:2119 +#: gtk2_ardour/editor_ops.cc:2759 msgid "trim to selection" msgstr "Auf Auswahl kürzen" -#: gtk2_ardour/editor_ops.cc:2164 +#: gtk2_ardour/editor_ops.cc:2804 msgid "region fill" msgstr "Region füllen" -#: gtk2_ardour/editor_ops.cc:2228 +#: gtk2_ardour/editor_ops.cc:2868 msgid "fill selection" msgstr "Auswahl füllen" -#: gtk2_ardour/editor_ops.cc:2249 -msgid "Programming error. that region doesn't cover that position" -msgstr "Programmierfehler: that region doesn't cover that position" - -#: gtk2_ardour/editor_ops.cc:2252 -msgid "set region sync position" -msgstr "Sync-Position setzen" - -#: gtk2_ardour/editor_ops.cc:2268 -msgid "Place the edit cursor at the desired sync point" -msgstr "Positionieren sie den Arbeits-Cursor am gewünschten Synchronisationspunkt" - -#: gtk2_ardour/editor_ops.cc:2273 -msgid "set sync from edit cursor" -msgstr "Sync-Position an Editierzeiger setzen" +#: gtk2_ardour/editor_ops.cc:2906 +msgid "set sync point" +msgstr "Einrastpunkt definieren" -#: gtk2_ardour/editor_ops.cc:2286 +#: gtk2_ardour/editor_ops.cc:2926 msgid "remove sync" -msgstr "Synchronisationspunkt entfernen" +msgstr "Einrastpunkt entfernen" -#: gtk2_ardour/editor_ops.cc:2301 +#: gtk2_ardour/editor_ops.cc:2941 msgid "naturalize" msgstr "zur Ursprungsposition setzen" -#: gtk2_ardour/editor_ops.cc:2366 +#: gtk2_ardour/editor_ops.cc:3026 msgid "align selection (relative)" msgstr "Auswahl relativ ausrichten" -#: gtk2_ardour/editor_ops.cc:2395 +#: gtk2_ardour/editor_ops.cc:3055 msgid "align selection" msgstr "Auswahl ausrichten" -#: gtk2_ardour/editor_ops.cc:2407 +#: gtk2_ardour/editor_ops.cc:3067 msgid "align region" msgstr "Region ausrichten" -#: gtk2_ardour/editor_ops.cc:2455 -#: gtk2_ardour/editor_ops.cc:2481 -msgid "trim to edit" -msgstr "Am Editierzeiger abschneiden" +#: gtk2_ardour/editor_ops.cc:3104 +msgid "trim to loop" +msgstr "Auf Schleife kürzen" + +#: gtk2_ardour/editor_ops.cc:3114 +msgid "trim to punch" +msgstr "Auf Punch-Bereich kürzen" + +#: gtk2_ardour/editor_ops.cc:3174 +msgid "trim region start to edit point" +msgstr "Regionanfang bis Arbeitspunkt abschneiden" -#: gtk2_ardour/editor_ops.cc:2540 +#: gtk2_ardour/editor_ops.cc:3216 +msgid "trim region end to edit point" +msgstr "Regionende bis Arbeitspunkt abschneiden" + +#: gtk2_ardour/editor_ops.cc:3303 msgid "Cancel Freeze" msgstr "Einfrieren abbrechen" -#: gtk2_ardour/editor_ops.cc:2583 +#: gtk2_ardour/editor_ops.cc:3346 msgid "bounce range" msgstr "Bereich Bouncen" -#: gtk2_ardour/editor_ops.cc:2635 +#: gtk2_ardour/editor_ops.cc:3398 msgid "cut" msgstr "Ausschneiden" -#: gtk2_ardour/editor_ops.cc:2638 +#: gtk2_ardour/editor_ops.cc:3401 msgid "copy" msgstr "Kopieren" -#: gtk2_ardour/editor_ops.cc:2651 +#: gtk2_ardour/editor_ops.cc:3429 msgid " objects" msgstr "Objekte" -#: gtk2_ardour/editor_ops.cc:2677 +#: gtk2_ardour/editor_ops.cc:3469 msgid " range" msgstr "Bereich" -#: gtk2_ardour/editor_ops.cc:2906 +#: gtk2_ardour/editor_ops.cc:3698 msgid "paste" msgstr "Einfügen" -#: gtk2_ardour/editor_ops.cc:2948 +#: gtk2_ardour/editor_ops.cc:3747 msgid "paste chunk" msgstr "Abschnitt einfügen" -#: gtk2_ardour/editor_ops.cc:2991 +#: gtk2_ardour/editor_ops.cc:3791 msgid "duplicate region" msgstr "Region duplizieren" -#: gtk2_ardour/editor_ops.cc:3036 +#: gtk2_ardour/editor_ops.cc:3839 msgid "duplicate selection" msgstr "Auswahl duplizieren" -#: gtk2_ardour/editor_ops.cc:3092 +#: gtk2_ardour/editor_ops.cc:3893 msgid "clear playlist" msgstr "Wiedergabeliste zurücksetzen" -#: gtk2_ardour/editor_ops.cc:3122 +#: gtk2_ardour/editor_ops.cc:3923 msgid "nudge track" msgstr "Spur verschieben" -#: gtk2_ardour/editor_ops.cc:3150 +#: gtk2_ardour/editor_ops.cc:3951 msgid "" "Do you really want to destroy the last capture?\n" "(This is destructive and cannot be undone)" @@ -4279,161 +4687,228 @@ msgstr "" "Wollen Sie wirklich die letzte Aufnahme rückgängig machen?\n" "(Dies kann nicht rückgängig gemacht werden!)" -#: gtk2_ardour/editor_ops.cc:3178 +#: gtk2_ardour/editor_ops.cc:3979 msgid "normalize" msgstr "Normalisieren" -#: gtk2_ardour/editor_ops.cc:3231 +#: gtk2_ardour/editor_ops.cc:4032 msgid "reverse regions" msgstr "Regionen umkehren" -#: gtk2_ardour/editor_ops.cc:3344 +#: gtk2_ardour/editor_ops.cc:4145 msgid "reset region gain" msgstr "Lautstärkekurve zurücksetzen" -#: gtk2_ardour/editor_ops.cc:3433 +#: gtk2_ardour/editor_ops.cc:4258 +msgid "set fade in length" +msgstr "Ändere Fade-In Länge" + +#: gtk2_ardour/editor_ops.cc:4265 +msgid "set fade out length" +msgstr "Ändere Fade-Out Länge" + +#: gtk2_ardour/editor_ops.cc:4305 +msgid "toggle fade in active" +msgstr "Fade-In aktivieren" + +#: gtk2_ardour/editor_ops.cc:4305 +msgid "toggle fade out active" +msgstr "Fade-Out aktivieren" + +#: gtk2_ardour/editor_ops.cc:4343 msgid "set fade in shape" msgstr "Fade-In Kurve bearbeiten" -#: gtk2_ardour/editor_ops.cc:3457 +#: gtk2_ardour/editor_ops.cc:4367 msgid "set fade out shape" msgstr "Fade-Out Kurve ändern" -#: gtk2_ardour/editor_ops.cc:3481 +#: gtk2_ardour/editor_ops.cc:4391 msgid "set fade in active" msgstr "Fade-In aktivieren" -#: gtk2_ardour/editor_ops.cc:3505 +#: gtk2_ardour/editor_ops.cc:4415 msgid "set fade out active" msgstr "Fade-Out aktivieren" -#: gtk2_ardour/editor_region_list.cc:108 -#: gtk2_ardour/editor_region_list.cc:114 -#: gtk2_ardour/editor_region_list.cc:117 +#: gtk2_ardour/editor_ops.cc:4589 +msgid "trim front" +msgstr "vorne abschneiden" + +#: gtk2_ardour/editor_ops.cc:4589 +msgid "trim back" +msgstr "hinten Abschneiden" + +#: gtk2_ardour/editor_ops.cc:4670 +msgid "set loop range from selection" +msgstr "Schleife aus Auswahl erstellen" + +#: gtk2_ardour/editor_ops.cc:4692 +msgid "set loop range from edit range" +msgstr "Schleife aus Editierbereich erstellen" + +#: gtk2_ardour/editor_ops.cc:4722 +msgid "set loop range from region" +msgstr "Schleife aus Region erstellen" + +#: gtk2_ardour/editor_ops.cc:4740 +msgid "set punch range from selection" +msgstr "Punch-Bereich aus Auswahl erstellen" + +#: gtk2_ardour/editor_ops.cc:4757 +msgid "set punch range from edit range" +msgstr "Punch-Bereich aus Editierbereich erstellen" + +#: gtk2_ardour/editor_region_list.cc:109 +#: gtk2_ardour/editor_region_list.cc:113 +#: gtk2_ardour/editor_region_list.cc:116 #: gtk2_ardour/location_ui.cc:57 msgid "Hidden" msgstr "Versteckt" -#: gtk2_ardour/editor_region_list.cc:172 +#: gtk2_ardour/editor_region_list.cc:159 msgid " (MISSING)" msgstr "(FEHLT)" -#: gtk2_ardour/editor_route_list.cc:101 -#: gtk2_ardour/editor_route_list.cc:102 -#: gtk2_ardour/editor_route_list.cc:252 +#: gtk2_ardour/editor_route_list.cc:77 +#: gtk2_ardour/editor_route_list.cc:78 +#: gtk2_ardour/editor_route_list.cc:264 msgid "editor" msgstr "Editor" -#: gtk2_ardour/editor_route_list.cc:320 -#: gtk2_ardour/mixer_ui.cc:728 +#: gtk2_ardour/editor_route_list.cc:338 +#: gtk2_ardour/mixer_ui.cc:811 msgid "Show All" msgstr "Alles zeigen" -#: gtk2_ardour/editor_route_list.cc:321 -#: gtk2_ardour/mixer_ui.cc:729 +#: gtk2_ardour/editor_route_list.cc:339 +#: gtk2_ardour/mixer_ui.cc:812 msgid "Hide All" msgstr "Alle verbergen" -#: gtk2_ardour/editor_route_list.cc:322 -#: gtk2_ardour/mixer_ui.cc:730 +#: gtk2_ardour/editor_route_list.cc:340 +#: gtk2_ardour/mixer_ui.cc:813 msgid "Show All Audio Tracks" msgstr "Zeige alle Audio-Spuren" -#: gtk2_ardour/editor_route_list.cc:323 -#: gtk2_ardour/mixer_ui.cc:731 +#: gtk2_ardour/editor_route_list.cc:341 +#: gtk2_ardour/mixer_ui.cc:814 msgid "Hide All Audio Tracks" msgstr "Verberge alle Audio-Spuren" -#: gtk2_ardour/editor_route_list.cc:324 -#: gtk2_ardour/mixer_ui.cc:732 +#: gtk2_ardour/editor_route_list.cc:342 +#: gtk2_ardour/mixer_ui.cc:815 msgid "Show All Audio Busses" msgstr "Zeige alle Audio-Busse" -#: gtk2_ardour/editor_route_list.cc:325 -#: gtk2_ardour/mixer_ui.cc:733 +#: gtk2_ardour/editor_route_list.cc:343 +#: gtk2_ardour/mixer_ui.cc:816 msgid "Hide All Audio Busses" msgstr "Verberge alle Audio-Busse" -#: gtk2_ardour/editor_rulers.cc:345 +#: gtk2_ardour/editor_rulers.cc:366 msgid "New location marker" msgstr "Neuer Positionsmarker" -#: gtk2_ardour/editor_rulers.cc:346 +#: gtk2_ardour/editor_rulers.cc:367 msgid "Clear all locations" msgstr "Alle Positionsmarker entfernen" -#: gtk2_ardour/editor_rulers.cc:347 +#: gtk2_ardour/editor_rulers.cc:368 msgid "Unhide locations" msgstr "Positionen anzeigen" -#: gtk2_ardour/editor_rulers.cc:352 +#: gtk2_ardour/editor_rulers.cc:373 msgid "Clear all ranges" msgstr "Alle Bereiche entfernen" -#: gtk2_ardour/editor_rulers.cc:353 +#: gtk2_ardour/editor_rulers.cc:374 msgid "Unhide ranges" msgstr "Bereiche anzeigen" -#: gtk2_ardour/editor_rulers.cc:362 +#: gtk2_ardour/editor_rulers.cc:384 +msgid "New CD track marker" +msgstr "Neuer CD-Track Marker" + +#: gtk2_ardour/editor_rulers.cc:389 msgid "New Tempo" msgstr "Tempowechsel einfügen..." -#: gtk2_ardour/editor_rulers.cc:363 +#: gtk2_ardour/editor_rulers.cc:390 msgid "Clear tempo" msgstr "Tempo zurücksetzen" -#: gtk2_ardour/editor_rulers.cc:368 +#: gtk2_ardour/editor_rulers.cc:395 msgid "New Meter" msgstr "Taktwechsel einfügen..." -#: gtk2_ardour/editor_rulers.cc:369 +#: gtk2_ardour/editor_rulers.cc:396 msgid "Clear meter" msgstr "Taktart zurücksetzen" -#: gtk2_ardour/editor_rulers.cc:377 +#: gtk2_ardour/editor_rulers.cc:404 msgid "Min:Secs" msgstr "Min:Sek" -#: gtk2_ardour/editor_selection.cc:564 -#: gtk2_ardour/editor_selection.cc:613 +#: gtk2_ardour/editor_selection.cc:740 msgid "set selected regions" msgstr "Regionen auswählen" -#: gtk2_ardour/editor_selection.cc:810 +#: gtk2_ardour/editor_selection.cc:850 +msgid "select all" +msgstr "Alle Regionen auswählen" + +#: gtk2_ardour/editor_selection.cc:939 msgid "select all within" msgstr "Alle im Bereich auswählen" -#: gtk2_ardour/editor_selection.cc:840 +#: gtk2_ardour/editor_selection.cc:970 msgid "set selection from region" -msgstr "Auswahl von Region wählen" +msgstr "Auswahlbereich von Region erstellen" -#: gtk2_ardour/editor_selection.cc:873 +#: gtk2_ardour/editor_selection.cc:1003 msgid "set selection from range" -msgstr "Auswahl von Bereich wählen" +msgstr "Auswahlbereich von Bereich erstellen" -#: gtk2_ardour/editor_selection.cc:903 +#: gtk2_ardour/editor_selection.cc:1033 msgid "select all from range" msgstr "Alle im Bereich auswählen" -#: gtk2_ardour/editor_selection.cc:925 +#: gtk2_ardour/editor_selection.cc:1055 msgid "select all from punch" msgstr "Alle im Punch-Bereich auswählen" -#: gtk2_ardour/editor_selection.cc:947 +#: gtk2_ardour/editor_selection.cc:1077 msgid "select all from loop" msgstr "Alle im Loop-Bereich auswählen" -#: gtk2_ardour/editor_selection.cc:961 +#: gtk2_ardour/editor_selection.cc:1091 msgid "select all after cursor" msgstr "Alle nach Positionszeiger auswählen" -#: gtk2_ardour/editor_selection.cc:966 +#: gtk2_ardour/editor_selection.cc:1096 msgid "select all before cursor" msgstr "Alle vor Positionszeiger auswählen" -#: gtk2_ardour/editor_selection.cc:996 -msgid "select all between cursors" -msgstr "Alle zwischen den Zeigern auswählen" +#: gtk2_ardour/editor_selection.cc:1122 +msgid "select all after edit" +msgstr "Alles nach Arbeitspunkt auswählen" + +#: gtk2_ardour/editor_selection.cc:1127 +msgid "select all before edit" +msgstr "Alles vor Arbeitspunkt auswählen" + +#: gtk2_ardour/editor_selection.cc:1237 +msgid "No edit range defined" +msgstr "Kein Editierbereich definiert" + +#: gtk2_ardour/editor_selection.cc:1243 +msgid "" +"the edit point is Selected Marker\n" +"but there is no selected marker." +msgstr "" +"der Arbeitspunkt ist der gewählte Positionsmarker,\n" +"es ist aber kein Positionsmarker ausgewählt." #: gtk2_ardour/editor_selection_list.cc:180 msgid "Name for Chunk:" @@ -4451,157 +4926,399 @@ msgstr "Abbrechen" msgid "No selectable material found in the currently selected time range" msgstr "Konnte im ausgewählten Bereich kein auswählbares Material finden" -#: gtk2_ardour/editor_tempodisplay.cc:290 -#: gtk2_ardour/editor_tempodisplay.cc:331 +#: gtk2_ardour/editor_tempodisplay.cc:293 +#: gtk2_ardour/editor_tempodisplay.cc:335 msgid "add" msgstr "Hinzufügen" -#: gtk2_ardour/editor_tempodisplay.cc:312 +#: gtk2_ardour/editor_tempodisplay.cc:316 msgid "add tempo mark" msgstr "Tempowechsel einfügen" -#: gtk2_ardour/editor_tempodisplay.cc:353 +#: gtk2_ardour/editor_tempodisplay.cc:357 msgid "add meter mark" msgstr "Taktwechsel einfügen" -#: gtk2_ardour/editor_tempodisplay.cc:386 -#: gtk2_ardour/editor_tempodisplay.cc:415 +#: gtk2_ardour/editor_tempodisplay.cc:390 +#: gtk2_ardour/editor_tempodisplay.cc:419 msgid "done" msgstr "Fertig" -#: gtk2_ardour/editor_tempodisplay.cc:404 -#: gtk2_ardour/editor_tempodisplay.cc:433 +#: gtk2_ardour/editor_tempodisplay.cc:408 +#: gtk2_ardour/editor_tempodisplay.cc:438 msgid "replace tempo mark" msgstr "Tempowechsel ersetzen" -#: gtk2_ardour/editor_tempodisplay.cc:473 -#: gtk2_ardour/editor_tempodisplay.cc:505 +#: gtk2_ardour/editor_tempodisplay.cc:478 +#: gtk2_ardour/editor_tempodisplay.cc:510 msgid "programming error: marker for meter is not a meter marker!" msgstr "Programmierfehler: marker for meter is not a meter marker!" -#: gtk2_ardour/editor_tempodisplay.cc:483 -#: gtk2_ardour/editor_tempodisplay.cc:517 +#: gtk2_ardour/editor_tempodisplay.cc:488 +#: gtk2_ardour/editor_tempodisplay.cc:522 msgid "remove tempo mark" msgstr "Tempowechsel entfernen" -#: gtk2_ardour/editor_timefx.cc:54 +#: gtk2_ardour/editor_timefx.cc:63 msgid "Quick but Ugly" msgstr "Quick but Ugly" -#: gtk2_ardour/editor_timefx.cc:55 +#: gtk2_ardour/editor_timefx.cc:64 msgid "Skip Anti-aliasing" msgstr "Ãœberspringe Anti-Aliasing" -#: gtk2_ardour/editor_timefx.cc:59 -msgid "TimeStretchDialog" +#: gtk2_ardour/editor_timefx.cc:68 +msgid "TimeFXDialog" msgstr "" -#: gtk2_ardour/editor_timefx.cc:62 -msgid "Timestretch" +#: gtk2_ardour/editor_timefx.cc:72 +msgid "Pitch Shift" +msgstr "Pitch-Shift" + +#: gtk2_ardour/editor_timefx.cc:74 +msgid "Time Stretch" msgstr "Time-Stretch" -#: gtk2_ardour/editor_timefx.cc:76 -msgid "Stretch/Shrink it" -msgstr "Time-Stretch ausführen" +#: gtk2_ardour/editor_timefx.cc:92 +msgid "Octaves" +msgstr "Oktaven" -#: gtk2_ardour/editor_timefx.cc:79 -#: gtk2_ardour/editor_timefx.cc:80 -msgid "TimeStretchButton" +#: gtk2_ardour/editor_timefx.cc:96 +msgid "Semitones (12TET)" +msgstr "Halbtöne" + +#: gtk2_ardour/editor_timefx.cc:100 +msgid "Cents" +msgstr "Cents" + +#: gtk2_ardour/editor_timefx.cc:106 +msgid "Shift" +msgstr "Shift" + +#: gtk2_ardour/editor_timefx.cc:116 +msgid "Stretch/Shrink" +msgstr "Stretch/Shrink" + +#: gtk2_ardour/editor_timefx.cc:119 +#: gtk2_ardour/editor_timefx.cc:120 +msgid "TimeFXButton" msgstr "" -#: gtk2_ardour/editor_timefx.cc:81 -msgid "TimeStretchProgress" +#: gtk2_ardour/editor_timefx.cc:121 +msgid "TimeFXProgress" msgstr "" -#: gtk2_ardour/editor_timefx.cc:145 -msgid "timestretch cannot be started - thread creation error" +#: gtk2_ardour/editor_timefx.cc:234 +#, fuzzy +msgid "timefx cannot be started - thread creation error" msgstr "Time-Stretch konnte nicht gestartet werden - Fehler beim erstellen des Threads" +#: gtk2_ardour/editor_timefx.cc:315 +msgid "pitch shift" +msgstr "pitch-shift" + +#: gtk2_ardour/editor_timefx.cc:315 +msgid "time stretch" +msgstr "Time-Stretch" + +#: gtk2_ardour/engine_dialog.cc:46 +msgid "Realtime" +msgstr "Realtime" + +#: gtk2_ardour/engine_dialog.cc:47 +msgid "Do not lock memory" +msgstr "Speicherzugriff nicht sperren" + +#: gtk2_ardour/engine_dialog.cc:48 +msgid "Unlock memory" +msgstr "Speicherzugriff öffnen" + +#: gtk2_ardour/engine_dialog.cc:49 +msgid "No zombies" +msgstr "Keine Zombies (Soft Mode)" + +#: gtk2_ardour/engine_dialog.cc:50 +msgid "Provide monitor ports" +msgstr "Monitor-Ports erstellen" + +#: gtk2_ardour/engine_dialog.cc:51 +msgid "Force 16 bit" +msgstr "Erzwinge 16 Bit" + +#: gtk2_ardour/engine_dialog.cc:52 +msgid "H/W monitoring" +msgstr "Hardware Monitoring" + +#: gtk2_ardour/engine_dialog.cc:53 +msgid "H/W metering" +msgstr "Hardware-Pegelanzeige" + +#: gtk2_ardour/engine_dialog.cc:54 +msgid "Verbose output" +msgstr "Ausführliche Statusmeldungen" + +#: gtk2_ardour/engine_dialog.cc:55 +msgid "Start" +msgstr "Start" + +#: gtk2_ardour/engine_dialog.cc:74 +msgid "8000Hz" +msgstr "8000 Hz" + +#: gtk2_ardour/engine_dialog.cc:75 +msgid "22050Hz" +msgstr "22050 Hz" + +#: gtk2_ardour/engine_dialog.cc:76 +msgid "44100Hz" +msgstr "44100 Hz" + +#: gtk2_ardour/engine_dialog.cc:77 +msgid "48000Hz" +msgstr "48000 Hz" + +#: gtk2_ardour/engine_dialog.cc:78 +msgid "88200Hz" +msgstr "88200 Hz" + +#: gtk2_ardour/engine_dialog.cc:79 +msgid "96000Hz" +msgstr "96000 Hz" + +#: gtk2_ardour/engine_dialog.cc:80 +msgid "192000Hz" +msgstr "192000 Hz" + +#: gtk2_ardour/engine_dialog.cc:99 +#: gtk2_ardour/engine_dialog.cc:480 +#: gtk2_ardour/export_dialog.cc:81 +#: gtk2_ardour/export_dialog.cc:1298 +msgid "Triangular" +msgstr "dreieckig" + +#: gtk2_ardour/engine_dialog.cc:100 +#: gtk2_ardour/engine_dialog.cc:482 +#: gtk2_ardour/export_dialog.cc:79 +#: gtk2_ardour/export_dialog.cc:1296 +msgid "Rectangular" +msgstr "rechteckig" + +#: gtk2_ardour/engine_dialog.cc:101 +#: gtk2_ardour/engine_dialog.cc:484 +msgid "Shaped" +msgstr "shaped" + +#: gtk2_ardour/engine_dialog.cc:129 +#: gtk2_ardour/engine_dialog.cc:435 +#: gtk2_ardour/engine_dialog.cc:803 +msgid "Playback/Recording on 1 Device" +msgstr "Wiedergabe/Aufnahme mit einem Gerät" + +#: gtk2_ardour/engine_dialog.cc:130 +#: gtk2_ardour/engine_dialog.cc:439 +#: gtk2_ardour/engine_dialog.cc:464 +#: gtk2_ardour/engine_dialog.cc:806 +msgid "Playback/Recording on 2 Devices" +msgstr "Wiedergabe/Aufnahme mit zwei Geräten" + +#: gtk2_ardour/engine_dialog.cc:131 +#: gtk2_ardour/engine_dialog.cc:446 +#: gtk2_ardour/engine_dialog.cc:809 +msgid "Playback only" +msgstr "Nur Wiedergabe" + +#: gtk2_ardour/engine_dialog.cc:132 +#: gtk2_ardour/engine_dialog.cc:448 +#: gtk2_ardour/engine_dialog.cc:811 +msgid "Recording only" +msgstr "Nur Aufnahme" + +#: gtk2_ardour/engine_dialog.cc:141 +msgid "Driver" +msgstr "Treiber" + +#: gtk2_ardour/engine_dialog.cc:146 +msgid "Interface" +msgstr "Gerät / Interface" + +#: gtk2_ardour/engine_dialog.cc:151 +#: gtk2_ardour/export_dialog.cc:108 +msgid "Sample Rate" +msgstr "Samplerate" + +#: gtk2_ardour/engine_dialog.cc:156 +msgid "Buffer size" +msgstr "Größe Buffer" + +#: gtk2_ardour/engine_dialog.cc:162 +msgid "Number of buffers" +msgstr "Anzahl Buffer" + +#: gtk2_ardour/engine_dialog.cc:169 +msgid "Approximate latency" +msgstr "Latenz (ca.)" + +#: gtk2_ardour/engine_dialog.cc:183 +msgid "Audio Mode" +msgstr "Audio-Modus" + +#: gtk2_ardour/engine_dialog.cc:222 +msgid "Realtime Priority" +msgstr "Realtime Priorität" + +#: gtk2_ardour/engine_dialog.cc:251 +#: gtk2_ardour/engine_dialog.cc:374 +msgid "Ignore" +msgstr "ignorieren" + +#: gtk2_ardour/engine_dialog.cc:259 +msgid "Client timeout" +msgstr "Client Timeout" + +#: gtk2_ardour/engine_dialog.cc:265 +msgid "Number of ports" +msgstr "Anzahl Ports" + +#: gtk2_ardour/engine_dialog.cc:272 +msgid "Dither" +msgstr "Dithering" + +#: gtk2_ardour/engine_dialog.cc:282 +msgid "No JACK server found anywhere on this system. Please install JACK and restart" +msgstr "Es wurde kein JACK Server auf diesem System gefunden. Bitte installieren Sie JACK und starten Sie ardour neu." + +#: gtk2_ardour/engine_dialog.cc:290 +#, fuzzy +msgid "Server:" +msgstr "Stereo" + +#: gtk2_ardour/engine_dialog.cc:303 +msgid "Input device" +msgstr "Eingangsgerät" + +#: gtk2_ardour/engine_dialog.cc:308 +msgid "Output device" +msgstr "Ausgabegerät" + +#: gtk2_ardour/engine_dialog.cc:314 +msgid "Input channels" +msgstr "Eingangskanäle" + +#: gtk2_ardour/engine_dialog.cc:319 +msgid "Output channels" +msgstr "Ausgangskanäle" + +#: gtk2_ardour/engine_dialog.cc:324 +msgid "Hardware input latency (samples)" +msgstr "Hardware Eingangslatenz (Samples)" + +#: gtk2_ardour/engine_dialog.cc:329 +msgid "Hardware output latency (samples)" +msgstr "Hardware Ausgangslatenz (Samples)" + +#: gtk2_ardour/engine_dialog.cc:342 +msgid "Device" +msgstr "Gerät" + +#: gtk2_ardour/engine_dialog.cc:344 +msgid "Advanced" +msgstr "Erweitert" + +#: gtk2_ardour/engine_dialog.cc:537 +msgid "cannot open JACK rc file %1 to store parameters" +msgstr "kann die JACK rc-Datei %1 nicht öffnen, um die Parameter zu sichern" + +#: gtk2_ardour/engine_dialog.cc:842 +msgid "JACK appears to be missing from the Ardour bundle" +msgstr "" + +#: gtk2_ardour/engine_dialog.cc:1026 +msgid "AudioSetup value for %1 is missing data" +msgstr "" + +#: gtk2_ardour/engine_dialog.cc:1106 +msgid "configuration files contain a JACK server path that doesn't exist (%1)" +msgstr "die Konfiguration enthält einen JACK-Serverpfad, der nicht existiert (%1)" + #: gtk2_ardour/export_dialog.cc:59 -#: gtk2_ardour/export_dialog.cc:401 -#: gtk2_ardour/export_dialog.cc:1029 -#: gtk2_ardour/export_dialog.cc:1197 +#: gtk2_ardour/export_dialog.cc:423 +#: gtk2_ardour/export_dialog.cc:1090 +#: gtk2_ardour/export_dialog.cc:1260 msgid "22.05kHz" -msgstr "" +msgstr "22,05 kHz" #: gtk2_ardour/export_dialog.cc:60 -#: gtk2_ardour/export_dialog.cc:404 -#: gtk2_ardour/export_dialog.cc:419 -#: gtk2_ardour/export_dialog.cc:1031 -#: gtk2_ardour/export_dialog.cc:1199 +#: gtk2_ardour/export_dialog.cc:426 +#: gtk2_ardour/export_dialog.cc:441 +#: gtk2_ardour/export_dialog.cc:1092 +#: gtk2_ardour/export_dialog.cc:1262 msgid "44.1kHz" -msgstr "" +msgstr "44,1 kHz" #: gtk2_ardour/export_dialog.cc:61 -#: gtk2_ardour/export_dialog.cc:407 -#: gtk2_ardour/export_dialog.cc:1033 -#: gtk2_ardour/export_dialog.cc:1201 +#: gtk2_ardour/export_dialog.cc:429 +#: gtk2_ardour/export_dialog.cc:1094 +#: gtk2_ardour/export_dialog.cc:1264 msgid "48kHz" msgstr "4" #: gtk2_ardour/export_dialog.cc:62 -#: gtk2_ardour/export_dialog.cc:410 -#: gtk2_ardour/export_dialog.cc:1035 -#: gtk2_ardour/export_dialog.cc:1203 +#: gtk2_ardour/export_dialog.cc:432 +#: gtk2_ardour/export_dialog.cc:1096 +#: gtk2_ardour/export_dialog.cc:1266 msgid "88.2kHz" -msgstr "" +msgstr "88,2 kHz" #: gtk2_ardour/export_dialog.cc:63 -#: gtk2_ardour/export_dialog.cc:413 -#: gtk2_ardour/export_dialog.cc:1037 -#: gtk2_ardour/export_dialog.cc:1205 +#: gtk2_ardour/export_dialog.cc:435 +#: gtk2_ardour/export_dialog.cc:1098 +#: gtk2_ardour/export_dialog.cc:1268 msgid "96kHz" -msgstr "" +msgstr "96 kHz" #: gtk2_ardour/export_dialog.cc:64 -#: gtk2_ardour/export_dialog.cc:416 -#: gtk2_ardour/export_dialog.cc:1039 -#: gtk2_ardour/export_dialog.cc:1207 +#: gtk2_ardour/export_dialog.cc:438 +#: gtk2_ardour/export_dialog.cc:1100 +#: gtk2_ardour/export_dialog.cc:1270 msgid "192kHz" -msgstr "" +msgstr "192 kHz" #: gtk2_ardour/export_dialog.cc:69 msgid "best" msgstr "bestmöglich" #: gtk2_ardour/export_dialog.cc:70 -#: gtk2_ardour/export_dialog.cc:1214 +#: gtk2_ardour/export_dialog.cc:1280 msgid "fastest" msgstr "schnellstmöglich" #: gtk2_ardour/export_dialog.cc:71 -#: gtk2_ardour/export_dialog.cc:1216 +#: gtk2_ardour/export_dialog.cc:1282 msgid "linear" msgstr "Linear" #: gtk2_ardour/export_dialog.cc:72 -#: gtk2_ardour/export_dialog.cc:1218 +#: gtk2_ardour/export_dialog.cc:1284 msgid "better" msgstr "besser" #: gtk2_ardour/export_dialog.cc:73 -#: gtk2_ardour/export_dialog.cc:1220 +#: gtk2_ardour/export_dialog.cc:1286 msgid "intermediate" msgstr "mittelmäßig" -#: gtk2_ardour/export_dialog.cc:79 -#: gtk2_ardour/export_dialog.cc:1229 -msgid "Rectangular" -msgstr "rechteckig" - #: gtk2_ardour/export_dialog.cc:80 msgid "Shaped Noise" msgstr "Shaped Noise" -#: gtk2_ardour/export_dialog.cc:81 -#: gtk2_ardour/export_dialog.cc:1231 -msgid "Triangular" -msgstr "dreieckig" +#: gtk2_ardour/export_dialog.cc:86 +msgid "stereo" +msgstr "Stereo" #: gtk2_ardour/export_dialog.cc:87 -#: gtk2_ardour/export_dialog.cc:488 -#: gtk2_ardour/export_dialog.cc:1057 -#: gtk2_ardour/export_dialog.cc:1179 +#: gtk2_ardour/export_dialog.cc:510 +#: gtk2_ardour/export_dialog.cc:1118 +#: gtk2_ardour/export_dialog.cc:1240 msgid "mono" msgstr "Mono" @@ -4610,6 +5327,7 @@ msgid "CUE" msgstr "CUE" #: gtk2_ardour/export_dialog.cc:94 +#: gtk2_ardour/export_dialog.cc:926 msgid "TOC" msgstr "TOC" @@ -4637,10 +5355,6 @@ msgstr "Sampleformat" msgid "Sample Endianness" msgstr "Bytefolge" -#: gtk2_ardour/export_dialog.cc:108 -msgid "Sample Rate" -msgstr "Samplerate" - #: gtk2_ardour/export_dialog.cc:109 msgid "Conversion Quality" msgstr "Qualität" @@ -4654,8 +5368,8 @@ msgid "Export CD Marker File Only" msgstr "Nur CD-Marker exportieren" #: gtk2_ardour/export_dialog.cc:112 -#: gtk2_ardour/option_editor.cc:84 -#: gtk2_ardour/option_editor.cc:85 +#: gtk2_ardour/option_editor.cc:98 +#: gtk2_ardour/option_editor.cc:99 msgid "Browse" msgstr "Durchsuchen" @@ -4665,40 +5379,49 @@ msgstr "Alle Spuren..." #: gtk2_ardour/export_dialog.cc:141 #: gtk2_ardour/export_dialog.cc:157 -#: gtk2_ardour/mixer_strip.cc:124 -#: gtk2_ardour/mixer_strip.cc:739 +#: gtk2_ardour/mixer_strip.cc:127 +#: gtk2_ardour/mixer_strip.cc:733 msgid "Output" msgstr "Ausgang" -#: gtk2_ardour/export_dialog.cc:635 +#: gtk2_ardour/export_dialog.cc:656 msgid "Editor: cannot open \"%1\" as export file for CD toc file" msgstr "Editor: Kann \"%1\" nicht nicht zum Export für CD-Inhaltsverzeichnis (TOC) öffnen." -#: gtk2_ardour/export_dialog.cc:761 +#: gtk2_ardour/export_dialog.cc:790 msgid "Editor: cannot open \"%1\" as export file for CD cue file" msgstr "Editor: Kann \"%1\" nicht zum Export für CD CUE-Datei öffnen." -#: gtk2_ardour/export_dialog.cc:780 +#: gtk2_ardour/export_dialog.cc:809 msgid "WAV" msgstr "WAV" -#: gtk2_ardour/export_dialog.cc:914 +#: gtk2_ardour/export_dialog.cc:941 +#, fuzzy +msgid "Not connected to audioengine" +msgstr "Nicht mit JACK verbunden - konnte die Aufnahme nicht starten" + +#: gtk2_ardour/export_dialog.cc:945 +msgid "Ardour cannot export audio when disconnected" +msgstr "Ardour kann nicht exportieren, wenn keine Verbindung zu JACK besteht." + +#: gtk2_ardour/export_dialog.cc:975 msgid "Stop Export" msgstr "Export Abbrechen" -#: gtk2_ardour/export_dialog.cc:1133 +#: gtk2_ardour/export_dialog.cc:1194 msgid "Please enter a valid filename." msgstr "Bitte geben Sie einen gültigen Dateinamen ein." -#: gtk2_ardour/export_dialog.cc:1143 +#: gtk2_ardour/export_dialog.cc:1204 msgid "Please specify a complete filename for the audio file." msgstr "Bitte geben Sie einen kompletten Dateinamen für die Audiodatei ein." -#: gtk2_ardour/export_dialog.cc:1149 +#: gtk2_ardour/export_dialog.cc:1210 msgid "File already exists, do you want to overwrite it?" msgstr "Datei existiert bereits, wollen Sie sie überschreiben?" -#: gtk2_ardour/export_dialog.cc:1161 +#: gtk2_ardour/export_dialog.cc:1222 #: gtk2_ardour/export_range_markers_dialog.cc:160 msgid "Cannot write file in: " msgstr "Konnte Datei nicht in Verzeichnis schreiben:" @@ -4734,58 +5457,75 @@ msgstr "" msgid "add gain automation event" msgstr "Punkt in die Lautstärkekurve einfügen" -#: gtk2_ardour/gain_meter.cc:112 -#: gtk2_ardour/gain_meter.cc:330 -#: gtk2_ardour/gain_meter.cc:519 -#: gtk2_ardour/gain_meter.cc:590 +#: gtk2_ardour/gain_meter.cc:114 +#: gtk2_ardour/gain_meter.cc:345 +#: gtk2_ardour/gain_meter.cc:541 +#: gtk2_ardour/gain_meter.cc:612 msgid "-inf" msgstr "-inf" -#: gtk2_ardour/gain_meter.cc:123 +#: gtk2_ardour/gain_meter.cc:125 msgid "Fader automation mode" msgstr "Fader Automationsmodus" -#: gtk2_ardour/gain_meter.cc:124 +#: gtk2_ardour/gain_meter.cc:126 msgid "Fader automation type" msgstr "Fader-Automationstyp" -#: gtk2_ardour/gain_meter.cc:169 -#: gtk2_ardour/gain_meter.cc:884 +#: gtk2_ardour/gain_meter.cc:170 +#: gtk2_ardour/gain_meter.cc:907 #: gtk2_ardour/panner_ui.cc:98 #: gtk2_ardour/panner_ui.cc:784 msgid "Abs" msgstr "Abs" -#: gtk2_ardour/gain_meter.cc:497 +#: gtk2_ardour/gain_meter.cc:519 msgid "-Inf" msgstr "-Inf" -#: gtk2_ardour/gain_meter.cc:700 -#: gtk2_ardour/gain_meter.cc:715 +#: gtk2_ardour/gain_meter.cc:723 +#: gtk2_ardour/gain_meter.cc:738 msgid "meter point change" msgstr "Taktwechsel ändern" -#: gtk2_ardour/gain_meter.cc:848 -#: gtk2_ardour/mixer_strip.cc:449 +#: gtk2_ardour/gain_meter.cc:871 +#: gtk2_ardour/mixer_strip.cc:443 #: gtk2_ardour/panner_ui.cc:748 msgid "M" msgstr "M" -#: gtk2_ardour/gain_meter.cc:851 +#: gtk2_ardour/gain_meter.cc:874 #: gtk2_ardour/panner_ui.cc:751 msgid "P" msgstr "P" -#: gtk2_ardour/gain_meter.cc:854 +#: gtk2_ardour/gain_meter.cc:877 #: gtk2_ardour/panner_ui.cc:754 msgid "T" msgstr "T" -#: gtk2_ardour/gain_meter.cc:857 +#: gtk2_ardour/gain_meter.cc:880 #: gtk2_ardour/panner_ui.cc:757 msgid "W" msgstr "W" +#: gtk2_ardour/generic_pluginui.cc:77 +msgid "<span size=\"large\">Presets</span>" +msgstr "<span size=\"large\">Voreinstellungen</span>" + +#: gtk2_ardour/generic_pluginui.cc:205 +msgid "Plugin Editor: could not build control element for port %1" +msgstr "Plugin Editor: konnte kein Steuerelement für Port %1 erzeugen" + +#: gtk2_ardour/generic_pluginui.cc:295 +msgid "Automation control" +msgstr "Automation" + +#: gtk2_ardour/generic_pluginui.cc:302 +#, fuzzy +msgid "Mgnual" +msgstr "Manuell" + #: gtk2_ardour/gtk-custom-ruler.c:126 msgid "Lower" msgstr "Untergrenze" @@ -4877,6 +5617,12 @@ msgstr "" msgid "Rename Track" msgstr "Spur umbenennen" +#: gtk2_ardour/io_selector.cc:59 +#: gtk2_ardour/io_selector.cc:747 +#: gtk2_ardour/connection_editor.cc:85 +msgid "OK" +msgstr "OK" + #: gtk2_ardour/io_selector.cc:61 #: gtk2_ardour/io_selector.cc:749 #: gtk2_ardour/connection_editor.cc:60 @@ -4935,22 +5681,29 @@ msgstr "Es sind keine weiteren JACK Ports verfügbar." msgid "ardour: " msgstr "ardour: " -#: gtk2_ardour/ladspa_pluginui.cc:77 -msgid "<span size=\"large\">Presets</span>" -msgstr "<span size=\"large\">Voreinstellungen</span>" +#: gtk2_ardour/keyeditor.cc:25 +msgid "Keybinding Editor" +msgstr "" -#: gtk2_ardour/ladspa_pluginui.cc:205 -msgid "Plugin Editor: could not build control element for port %1" -msgstr "Plugin Editor: konnte kein Steuerelement für Port %1 erzeugen" +#: gtk2_ardour/keyeditor.cc:33 +msgid "Action" +msgstr "Aktion" -#: gtk2_ardour/ladspa_pluginui.cc:295 -msgid "Automation control" -msgstr "Automation" +#: gtk2_ardour/keyeditor.cc:34 +msgid "Binding" +msgstr "Zugewiesene Taste" -#: gtk2_ardour/ladspa_pluginui.cc:302 -#, fuzzy -msgid "Mgnual" -msgstr "Manuell" +#: gtk2_ardour/keyeditor.cc:188 +msgid "Command-" +msgstr "Befehl-" + +#: gtk2_ardour/keyeditor.cc:189 +msgid "Option-" +msgstr "Option-" + +#: gtk2_ardour/keyeditor.cc:190 +msgid "Shift-" +msgstr "" #: gtk2_ardour/location_ui.cc:49 #: gtk2_ardour/location_ui.cc:52 @@ -4974,77 +5727,43 @@ msgstr "SCMS" msgid "Pre-Emphasis" msgstr "Präemphase" -#: gtk2_ardour/location_ui.cc:571 +#: gtk2_ardour/location_ui.cc:430 +msgid "You cannot put a CD marker at the start of the session" +msgstr "Sie können keinen CD-Marker am Anfang des Projekts erstellen" + +#: gtk2_ardour/location_ui.cc:605 msgid "Add New Location" msgstr "Neue Position hinzufügen" -#: gtk2_ardour/location_ui.cc:572 +#: gtk2_ardour/location_ui.cc:606 msgid "Add New Range" msgstr "Neuen Bereich hinzufügen" -#: gtk2_ardour/location_ui.cc:608 +#: gtk2_ardour/location_ui.cc:642 msgid "Location (CD Index) Markers" msgstr "Positionsmarker (CD Index)" -#: gtk2_ardour/location_ui.cc:628 +#: gtk2_ardour/location_ui.cc:662 msgid "Range (CD Track) Markers" msgstr "Bereiche (CD Tracks)" -#: gtk2_ardour/location_ui.cc:801 +#: gtk2_ardour/location_ui.cc:840 msgid "add range marker" msgstr "Bereich hinzufügen" -#: gtk2_ardour/main.cc:75 -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" - -#: gtk2_ardour/main.cc:96 -msgid "Ardour could not connect to JACK." -msgstr "ardour konnte nicht zu JACK verbinden." +#: gtk2_ardour/main.cc:153 +msgid "cannot open pango.rc file %1" +msgstr "kann die Datei pango.rc nicht öffnen %1" -#: gtk2_ardour/main.cc:100 -msgid "" -"There are several possible reasons:\n" -"\n" -"1) JACK is not running.\n" -"2) JACK is running as another user, perhaps root.\n" -"3) There is already another client called \"ardour\".\n" -"\n" -"Please consider the possibilities, and perhaps (re)start JACK." +#: gtk2_ardour/main.cc:230 +msgid "Key bindings file \"%1\" not found. Default bindings used instead" msgstr "" -"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" -"Betrachten Sie bitte diese Möglichkeiten und starten Sie JACK neu, wenn dies notwendig sein sollte." - -#: gtk2_ardour/main.cc:144 -msgid "could not load command line session \"%1\"" -msgstr "Konnte das per Kommandozeile übergebene Projekt nicht laden: \"%1\"" -#: gtk2_ardour/main.cc:152 -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 kein Projekt mit dem Namen \"%1\".\n" -"Um sie von der Kommandozeile aus zu erstellen, starten Sie ardour mit \"ardour --new %1" - -#: gtk2_ardour/main.cc:225 +#: gtk2_ardour/main.cc:292 msgid "Ardour/GTK " msgstr "Ardour/GTK " -#: gtk2_ardour/main.cc:227 +#: gtk2_ardour/main.cc:294 msgid "" "\n" " (built using " @@ -5052,47 +5771,39 @@ msgstr "" "\n" " (kompiliert mit Version " -#: gtk2_ardour/main.cc:230 +#: gtk2_ardour/main.cc:297 msgid " and GCC version " msgstr " und GCC Version" -#: gtk2_ardour/main.cc:240 +#: gtk2_ardour/main.cc:307 msgid "Copyright (C) 1999-2007 Paul Davis" msgstr "Copyright (C) 1999-2007 Paul Davis" -#: gtk2_ardour/main.cc:241 +#: gtk2_ardour/main.cc:308 msgid "Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker" msgstr "Einige Teile Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker" -#: gtk2_ardour/main.cc:243 +#: gtk2_ardour/main.cc:310 msgid "Ardour comes with ABSOLUTELY NO WARRANTY" msgstr "Ardour wird Ihnen ohne jegliche Gewährleistung und ausdrücklich ohne die Zusicherung" -#: gtk2_ardour/main.cc:244 +#: gtk2_ardour/main.cc:311 msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." msgstr "für allgemeine oder spezielle Gebrauchstauglichkeit zur Verfügung gestellt." -#: gtk2_ardour/main.cc:245 +#: gtk2_ardour/main.cc:312 msgid "This is free software, and you are welcome to redistribute it " msgstr "Dies ist freie Software und Sie dürfen sie gerne weiterverbreiten," -#: gtk2_ardour/main.cc:246 +#: gtk2_ardour/main.cc:313 msgid "under certain conditions; see the source for copying conditions." msgstr "solange Sie sich an die Bedingungen, die in der Datei COPYING aufgeführt sind halten." -#: gtk2_ardour/main.cc:257 +#: gtk2_ardour/main.cc:324 msgid "could not create ARDOUR GUI" msgstr "konnte das grafische Ardour User Interface nicht erstellen" -#: gtk2_ardour/main.cc:282 -msgid "Could not connect to JACK server as \"%1\"" -msgstr "Konnte nicht zu JACK Server als \"%1\" verbinden" - -#: gtk2_ardour/main.cc:289 -msgid "could not initialize Ardour." -msgstr "Konnte ardour nicht initialisieren." - -#: gtk2_ardour/marker.cc:243 +#: gtk2_ardour/marker.cc:244 msgid "MarkerText" msgstr "" @@ -5100,295 +5811,330 @@ msgstr "" msgid "Remove Marker" msgstr "Marker entfernen" -#: gtk2_ardour/marker_time_axis.cc:255 -msgid "Marker" -msgstr "Marker" +#: gtk2_ardour/midi_port_dialog.cc:22 +msgid "Port name" +msgstr "Port Name" -#: gtk2_ardour/mixer_strip.cc:95 -#: gtk2_ardour/mixer_strip.cc:140 -#: gtk2_ardour/mixer_strip.cc:1211 +#: gtk2_ardour/mixer_strip.cc:97 +#: gtk2_ardour/mixer_strip.cc:143 +#: gtk2_ardour/mixer_strip.cc:1217 msgid "pre" msgstr "Pre" -#: gtk2_ardour/mixer_strip.cc:96 -#: gtk2_ardour/mixer_strip.cc:789 +#: gtk2_ardour/mixer_strip.cc:98 +#: gtk2_ardour/mixer_strip.cc:786 msgid "Comments" msgstr "Kommentare" -#: gtk2_ardour/mixer_strip.cc:119 +#: gtk2_ardour/mixer_strip.cc:122 msgid "Input" msgstr "Eingang" -#: gtk2_ardour/mixer_strip.cc:136 -#: gtk2_ardour/mixer_strip.cc:1207 +#: gtk2_ardour/mixer_strip.cc:139 +#: gtk2_ardour/mixer_strip.cc:1213 +#: gtk2_ardour/option_editor.cc:707 msgid "input" msgstr "Input" -#: gtk2_ardour/mixer_strip.cc:144 -#: gtk2_ardour/mixer_strip.cc:1215 +#: gtk2_ardour/mixer_strip.cc:147 +#: gtk2_ardour/mixer_strip.cc:1221 msgid "post" msgstr "Post" -#: gtk2_ardour/mixer_strip.cc:151 +#: gtk2_ardour/mixer_strip.cc:154 msgid "tupni" msgstr "" -#: gtk2_ardour/mixer_strip.cc:199 +#: gtk2_ardour/mixer_strip.cc:202 msgid "Varispeed" msgstr "Varispeed" -#: gtk2_ardour/mixer_strip.cc:225 -#: gtk2_ardour/mixer_strip.cc:805 +#: gtk2_ardour/mixer_strip.cc:228 +#: gtk2_ardour/mixer_strip.cc:802 msgid "Click to Add/Edit Comments" msgstr "Kommentare hinzufügen/ändern" -#: gtk2_ardour/mixer_strip.cc:380 -msgid "unknown strip width \"%1\" in XML GUI information" -msgstr "Unbekannte Mixerkanalbreite \"%1\" in der XML GUI Information" - -#: gtk2_ardour/mixer_strip.cc:423 +#: gtk2_ardour/mixer_strip.cc:419 msgid "record" msgstr "Aufnahme" -#: gtk2_ardour/mixer_strip.cc:430 +#: gtk2_ardour/mixer_strip.cc:426 msgid "comments" msgstr "Kommentare" -#: gtk2_ardour/mixer_strip.cc:433 +#: gtk2_ardour/mixer_strip.cc:429 msgid "*comments*" msgstr "*Kommentare*" -#: gtk2_ardour/mixer_strip.cc:447 +#: gtk2_ardour/mixer_strip.cc:441 msgid "Rec" msgstr "Rec" -#: gtk2_ardour/mixer_strip.cc:450 +#: gtk2_ardour/mixer_strip.cc:444 msgid "S" msgstr "S" -#: gtk2_ardour/mixer_strip.cc:454 -#: gtk2_ardour/mixer_strip.cc:799 +#: gtk2_ardour/mixer_strip.cc:448 +#: gtk2_ardour/mixer_strip.cc:796 msgid "Cmt" msgstr "Kmt" -#: gtk2_ardour/mixer_strip.cc:457 -#: gtk2_ardour/mixer_strip.cc:796 +#: gtk2_ardour/mixer_strip.cc:451 +#: gtk2_ardour/mixer_strip.cc:793 msgid "*Cmt*" msgstr "*Kmt*" -#: gtk2_ardour/mixer_strip.cc:496 -#: gtk2_ardour/mixer_strip.cc:562 -#: gtk2_ardour/redirect_box.cc:1102 +#: gtk2_ardour/mixer_strip.cc:490 +#: gtk2_ardour/mixer_strip.cc:556 +#: gtk2_ardour/redirect_box.cc:1124 msgid "Not connected to JACK - no I/O changes are possible" msgstr "Nicht mit Jack verbunden - es sind keine Änderungen an Ein-/Ausgängen möglich" -#: gtk2_ardour/mixer_strip.cc:596 -#: gtk2_ardour/mixer_strip.cc:612 +#: gtk2_ardour/mixer_strip.cc:590 +#: gtk2_ardour/mixer_strip.cc:606 msgid "could not register new ports required for that connection" msgstr "Konnte die Ports, die diese Verbindung benötigt nicht registrieren" -#: gtk2_ardour/mixer_strip.cc:719 +#: gtk2_ardour/mixer_strip.cc:713 msgid " Input" msgstr "Eingang" -#: gtk2_ardour/mixer_strip.cc:722 +#: gtk2_ardour/mixer_strip.cc:716 msgid "I" msgstr "I" -#: gtk2_ardour/mixer_strip.cc:742 +#: gtk2_ardour/mixer_strip.cc:736 msgid "O" msgstr "O" -#: gtk2_ardour/mixer_strip.cc:786 +#: gtk2_ardour/mixer_strip.cc:783 msgid "*Comments*" msgstr "*Kommentare*" -#: gtk2_ardour/mixer_strip.cc:841 +#: gtk2_ardour/mixer_strip.cc:838 msgid ": comment editor" msgstr "Kommentare bearbeiten" -#: gtk2_ardour/mixer_strip.cc:936 +#: gtk2_ardour/mixer_strip.cc:933 msgid "Grp" msgstr "Grp" -#: gtk2_ardour/mixer_strip.cc:939 +#: gtk2_ardour/mixer_strip.cc:936 msgid "~G" msgstr "~G" -#: gtk2_ardour/mixer_strip.cc:988 +#: gtk2_ardour/mixer_strip.cc:984 msgid "Invert Polarity" msgstr "Polarität umkehren" -#: gtk2_ardour/mixer_ui.cc:82 +#: gtk2_ardour/mixer_strip.cc:987 +msgid "Protect against denormals" +msgstr "Schutz vor Denormals" + +#: gtk2_ardour/mixer_ui.cc:89 msgid "Strips" msgstr "Spur" -#: gtk2_ardour/mixer_ui.cc:107 +#: gtk2_ardour/mixer_ui.cc:115 msgid "Group" msgstr "Gruppe" -#: gtk2_ardour/mixer_ui.cc:207 -#: gtk2_ardour/mixer_ui.cc:362 -#: gtk2_ardour/mixer_ui.cc:394 +#: gtk2_ardour/mixer_ui.cc:215 +#: gtk2_ardour/mixer_ui.cc:425 +#: gtk2_ardour/mixer_ui.cc:457 msgid "Mixer" msgstr "Mixer" -#: gtk2_ardour/mixer_ui.cc:601 -msgid "signal" -msgstr "Signal" - -#: gtk2_ardour/mixer_ui.cc:752 +#: gtk2_ardour/mixer_ui.cc:835 msgid "track display list item for renamed strip not found!" msgstr "Konnte Bezeichnung für umbenannten Mixerkanal nicht in der Spurliste finden!" -#: gtk2_ardour/new_session_dialog.cc:44 +#: gtk2_ardour/new_session_dialog.cc:46 msgid "Name :" msgstr "Name :" -#: gtk2_ardour/new_session_dialog.cc:48 -#: gtk2_ardour/new_session_dialog.cc:49 #: gtk2_ardour/new_session_dialog.cc:50 #: gtk2_ardour/new_session_dialog.cc:51 +#: gtk2_ardour/new_session_dialog.cc:52 +#: gtk2_ardour/new_session_dialog.cc:53 msgid "channels" msgstr "Kanäle" -#: gtk2_ardour/new_session_dialog.cc:69 +#: gtk2_ardour/new_session_dialog.cc:71 msgid "<b>Busses</b>" msgstr "<b>Busse</b>" -#: gtk2_ardour/new_session_dialog.cc:70 +#: gtk2_ardour/new_session_dialog.cc:72 msgid "<b>Inputs</b>" msgstr "<b>Eingänge</b>" -#: gtk2_ardour/new_session_dialog.cc:71 +#: gtk2_ardour/new_session_dialog.cc:73 msgid "<b>Outputs</b>" msgstr "<b>Ausgänge</b>" -#: gtk2_ardour/new_session_dialog.cc:73 +#: gtk2_ardour/new_session_dialog.cc:75 msgid "Create Folder In :" msgstr "Verzeichnis erstellen in:" -#: gtk2_ardour/new_session_dialog.cc:75 +#: gtk2_ardour/new_session_dialog.cc:77 msgid "Template :" msgstr "Vorlage :" -#: gtk2_ardour/new_session_dialog.cc:77 +#: gtk2_ardour/new_session_dialog.cc:79 msgid "Create Monitor Bus" msgstr "Monitor Bus erstellen" -#: gtk2_ardour/new_session_dialog.cc:84 +#: gtk2_ardour/new_session_dialog.cc:86 msgid "Create Master Bus" msgstr "Master Bus erstellen" -#: gtk2_ardour/new_session_dialog.cc:86 +#: gtk2_ardour/new_session_dialog.cc:88 msgid "Automatically Connect to Physical Inputs" -msgstr "Eingänge automatisch mit Soundkarteneingängen verbinden" +msgstr "Eingänge automatisch mit Audioeingängen verbinden" -#: gtk2_ardour/new_session_dialog.cc:87 -#: gtk2_ardour/new_session_dialog.cc:100 +#: gtk2_ardour/new_session_dialog.cc:89 +#: gtk2_ardour/new_session_dialog.cc:102 msgid "Use only" msgstr "Benutze nur" -#: gtk2_ardour/new_session_dialog.cc:99 +#: gtk2_ardour/new_session_dialog.cc:101 msgid "Automatically Connect Outputs" msgstr "Ausgänge automatisch verbinden" -#: gtk2_ardour/new_session_dialog.cc:108 +#: gtk2_ardour/new_session_dialog.cc:110 msgid "... to Master Bus" msgstr "... mit Master Bus" -#: gtk2_ardour/new_session_dialog.cc:109 +#: gtk2_ardour/new_session_dialog.cc:111 msgid "... to Physical Outputs" -msgstr "... mit Soundkartenausgängen" +msgstr "... mit Audioausgängen" -#: gtk2_ardour/new_session_dialog.cc:115 +#: gtk2_ardour/new_session_dialog.cc:117 msgid "Advanced Options" msgstr "Erweiterte Einstellungen" -#: gtk2_ardour/new_session_dialog.cc:123 +#: gtk2_ardour/new_session_dialog.cc:125 msgid "Recent:" msgstr "Zuletzt verwendet:" -#: gtk2_ardour/new_session_dialog.cc:160 +#: gtk2_ardour/new_session_dialog.cc:162 msgid "Browse:" msgstr "Durchsuchen:" -#: gtk2_ardour/new_session_dialog.cc:338 -msgid "New Session" -msgstr "Neues Projekt" - -#: gtk2_ardour/new_session_dialog.cc:340 -msgid "Open Session" -msgstr "Projekt öffnen" - -#: gtk2_ardour/new_session_dialog.cc:347 +#: gtk2_ardour/new_session_dialog.cc:350 msgid "Session Control" msgstr "Projektübersicht" -#: gtk2_ardour/new_session_dialog.cc:390 +#: gtk2_ardour/new_session_dialog.cc:393 msgid "select template" msgstr "Vorlage auswählen" -#: gtk2_ardour/new_session_dialog.cc:396 +#: gtk2_ardour/new_session_dialog.cc:399 msgid "select session file" msgstr "Projektdatei auswählen" -#: gtk2_ardour/new_session_dialog.cc:405 +#: gtk2_ardour/new_session_dialog.cc:408 msgid "select directory" msgstr "Verzeichnis auswählen" -#: gtk2_ardour/option_editor.cc:74 +#: gtk2_ardour/new_session_dialog.cc:468 +msgid "Audio Setup" +msgstr "Audio-Einstellungen" + +#: gtk2_ardour/new_session_dialog.cc:492 +msgid "New Session" +msgstr "Neues Projekt" + +#: gtk2_ardour/new_session_dialog.cc:497 +msgid "Open Session" +msgstr "Projekt öffnen" + +#: gtk2_ardour/option_editor.cc:77 +msgid "Limit undo history" +msgstr "Begrenze Aktionsliste" + +#: gtk2_ardour/option_editor.cc:78 +msgid "Save undo history" +msgstr "Aktionsliste speichern" + +#: gtk2_ardour/option_editor.cc:83 msgid "SMPTE offset is negative" msgstr "Negatives SMPTE-Offset" -#: gtk2_ardour/option_editor.cc:131 +#: gtk2_ardour/option_editor.cc:84 +msgid "Timecode source is sample-clock synced" +msgstr "" + +#: gtk2_ardour/option_editor.cc:93 +msgid "Add new MIDI port" +msgstr "Neuen MIDI-Port hinzufügen" + +#: gtk2_ardour/option_editor.cc:145 msgid "Paths/Files" msgstr "Pfade" -#: gtk2_ardour/option_editor.cc:132 +#: gtk2_ardour/option_editor.cc:146 msgid "Kbd/Mouse" msgstr "Tastatur/Maus" -#: gtk2_ardour/option_editor.cc:135 -msgid "Layers & Fades" -msgstr "Layer & Fades" +#: gtk2_ardour/option_editor.cc:149 +msgid "Misc" +msgstr "Sonstiges" -#: gtk2_ardour/option_editor.cc:139 +#: gtk2_ardour/option_editor.cc:152 msgid "MIDI" msgstr "MIDI" -#: gtk2_ardour/option_editor.cc:227 +#: gtk2_ardour/option_editor.cc:222 msgid "session RAID path" msgstr "Projektverzeichnis (RAID)" -#: gtk2_ardour/option_editor.cc:243 -#: gtk2_ardour/option_editor.cc:249 -#: gtk2_ardour/option_editor.cc:671 -#: gtk2_ardour/option_editor.cc:691 +#: gtk2_ardour/option_editor.cc:238 +#: gtk2_ardour/option_editor.cc:244 +#: gtk2_ardour/option_editor.cc:933 +#: gtk2_ardour/option_editor.cc:953 msgid "internal" msgstr "intern" -#: gtk2_ardour/option_editor.cc:262 +#: gtk2_ardour/option_editor.cc:257 msgid "Short crossfade length (msecs)" msgstr "Länge für kurze Crossfades (ms)" -#: gtk2_ardour/option_editor.cc:274 +#: gtk2_ardour/option_editor.cc:269 msgid "Destructive crossfade length (msecs)" msgstr "Länge für destruktive Crossfades (ms)" -#: gtk2_ardour/option_editor.cc:334 +#: gtk2_ardour/option_editor.cc:288 +msgid "History depth (commands)" +msgstr "Anzahl der Befehle, die rückgängig gemacht werden können" + +#: gtk2_ardour/option_editor.cc:309 +msgid "Saved history depth (commands)" +msgstr "Anzahl der Befehle, die im Verlauf gespeichert werden" + +#: gtk2_ardour/option_editor.cc:407 msgid "SMPTE Offset" msgstr "SMPTE Offset" -#: gtk2_ardour/option_editor.cc:382 +#: gtk2_ardour/option_editor.cc:480 +#, fuzzy +msgid "Inbound MMC Device ID" +msgstr "MMC Gerät ID" + +#: gtk2_ardour/option_editor.cc:490 +#, fuzzy +msgid "Outbound MMC Device ID" +msgstr "MMC Gerät ID" + +#: gtk2_ardour/option_editor.cc:522 msgid "Port" msgstr "Port" -#: gtk2_ardour/option_editor.cc:383 +#: gtk2_ardour/option_editor.cc:526 msgid "Offline" msgstr "Offline" -#: gtk2_ardour/option_editor.cc:384 +#: gtk2_ardour/option_editor.cc:530 msgid "" "Trace\n" "Input" @@ -5396,7 +6142,7 @@ msgstr "" "Verfolge\n" "Eingang" -#: gtk2_ardour/option_editor.cc:385 +#: gtk2_ardour/option_editor.cc:534 msgid "" "Trace\n" "Output" @@ -5404,15 +6150,15 @@ msgstr "" "Verfolge\n" "Ausgang" -#: gtk2_ardour/option_editor.cc:386 +#: gtk2_ardour/option_editor.cc:538 msgid "MTC" msgstr "MTC" -#: gtk2_ardour/option_editor.cc:387 +#: gtk2_ardour/option_editor.cc:542 msgid "MMC" msgstr "MMC" -#: gtk2_ardour/option_editor.cc:388 +#: gtk2_ardour/option_editor.cc:546 msgid "" "MIDI Parameter\n" "Control" @@ -5420,40 +6166,40 @@ msgstr "" "MIDI Parameter\n" "Steuerung" -#: gtk2_ardour/option_editor.cc:394 -msgid "MMC Device ID" -msgstr "MMC Gerät ID" - -#: gtk2_ardour/option_editor.cc:406 -#: gtk2_ardour/option_editor.cc:413 -#: gtk2_ardour/option_editor.cc:416 -#: gtk2_ardour/option_editor.cc:561 +#: gtk2_ardour/option_editor.cc:585 +#: gtk2_ardour/option_editor.cc:592 +#: gtk2_ardour/option_editor.cc:595 +#: gtk2_ardour/option_editor.cc:808 msgid "online" msgstr "Online" -#: gtk2_ardour/option_editor.cc:413 -#: gtk2_ardour/option_editor.cc:414 -#: gtk2_ardour/option_editor.cc:558 +#: gtk2_ardour/option_editor.cc:592 +#: gtk2_ardour/option_editor.cc:593 +#: gtk2_ardour/option_editor.cc:805 msgid "offline" msgstr "Offline" -#: gtk2_ardour/option_editor.cc:624 +#: gtk2_ardour/option_editor.cc:709 +msgid "output" +msgstr "Ausgang" + +#: gtk2_ardour/option_editor.cc:880 msgid "Choose Click" msgstr "Click auswählen" -#: gtk2_ardour/option_editor.cc:643 +#: gtk2_ardour/option_editor.cc:902 msgid "Choose Click Emphasis" msgstr "Click-Betonung auswählen" -#: gtk2_ardour/option_editor.cc:743 +#: gtk2_ardour/option_editor.cc:1005 msgid "Click audio file" msgstr "Audiodatei für Click" -#: gtk2_ardour/option_editor.cc:749 +#: gtk2_ardour/option_editor.cc:1011 msgid "Click emphasis audiofile" -msgstr "Audiodatei für betonten Click " +msgstr "Audiodatei für Click-Betonung" -#: gtk2_ardour/option_editor.cc:786 +#: gtk2_ardour/option_editor.cc:1048 msgid "" "The auditioner is a dedicated mixer strip used\n" "for listening to specific regions outside the context\n" @@ -5466,72 +6212,80 @@ msgstr "" "Dieser Bus lässt sich wie jeder andere Mixer-Kanal\n" "verbinden." -#: gtk2_ardour/option_editor.cc:859 +#: gtk2_ardour/option_editor.cc:1139 msgid "Edit using" msgstr "Bearbeiten mit" -#: gtk2_ardour/option_editor.cc:866 -#: gtk2_ardour/option_editor.cc:893 +#: gtk2_ardour/option_editor.cc:1146 +#: gtk2_ardour/option_editor.cc:1173 msgid "+ button" msgstr "und Maustaste" -#: gtk2_ardour/option_editor.cc:886 +#: gtk2_ardour/option_editor.cc:1166 msgid "Delete using" msgstr "Entfernen mit" -#: gtk2_ardour/option_editor.cc:913 +#: gtk2_ardour/option_editor.cc:1193 msgid "Ignore snap using" msgstr "Einrasten übergehen mit" -#: gtk2_ardour/opts.cc:46 +#: gtk2_ardour/opts.cc:49 msgid "Usage: " msgstr "Aufruf:" -#: gtk2_ardour/opts.cc:47 +#: gtk2_ardour/opts.cc:50 msgid " -v, --version Show version information\n" msgstr " -v, --version Versionsinformation ausgeben\n" -#: gtk2_ardour/opts.cc:48 +#: gtk2_ardour/opts.cc:51 msgid " -h, --help Print this message\n" msgstr " -h, --help Diese Hinweise\n" -#: gtk2_ardour/opts.cc:49 +#: gtk2_ardour/opts.cc:52 msgid " -b, --bindings Print all possible keyboard binding names\n" msgstr " -b, --bindings Alle möglichen Tastenzuweisungsnamen ausgeben\n" -#: gtk2_ardour/opts.cc:50 +#: gtk2_ardour/opts.cc:53 +msgid " -c, --name name Use a specific jack client name, default is ardour\n" +msgstr " -c, --name name Benutze spezielle JACK-Clientkennung, Standard: ardour\n" + +#: gtk2_ardour/opts.cc:54 +msgid " -d, --disable-plugins Disable all plugins in an existing session\n" +msgstr "" + +#: gtk2_ardour/opts.cc:55 msgid " -n, --show-splash Show splash screen\n" msgstr " -n, --show-splash Zeige Splashscreen\n" -#: gtk2_ardour/opts.cc:51 -msgid " -c, --name name Use a specific jack client name, default is ardour\n" -msgstr " -c, --name name Benutze spezielle JACK-Clientkennung, Standard: ardour\n" +#: gtk2_ardour/opts.cc:56 +msgid " -m, --menus file Use \"file\" for Ardour menus\n" +msgstr " -m, --menus file Benutze \"file\" für Ardour-Menüs\n" -#: gtk2_ardour/opts.cc:52 +#: gtk2_ardour/opts.cc:57 msgid " -N, --new session-name Create a new session from the command line\n" msgstr " -N, --new session-name Erstelle neues Projekt aus der Kommandozeile\n" -#: gtk2_ardour/opts.cc:53 +#: gtk2_ardour/opts.cc:58 msgid " -O, --no-hw-optimizations Disable h/w specific optimizations\n" msgstr " -O, --no-hw-optimizations Hardwarespezifische Optimierungen deaktivieren\n" -#: gtk2_ardour/opts.cc:54 -msgid " -S, --sync\t Draw the gui synchronously \n" -msgstr " -S, --sync\t Zeichne die GUI synchron \n" +#: gtk2_ardour/opts.cc:59 +msgid " -S, --sync\t Draw the gui synchronously \n" +msgstr " -S, --sync\t Zeichne die GUI synchron \n" -#: gtk2_ardour/opts.cc:56 +#: gtk2_ardour/opts.cc:61 msgid " -V, --novst Do not use VST support\n" msgstr " -V, --novst VST-Unterstützung ausschalten\n" -#: gtk2_ardour/opts.cc:58 +#: gtk2_ardour/opts.cc:63 msgid " [session-name] Name of session to load\n" msgstr " [session-name] Name des zu ladenden Projekts\n" -#: gtk2_ardour/opts.cc:59 +#: gtk2_ardour/opts.cc:64 msgid " -C, --curvetest filename Curve algorithm debugger\n" msgstr " -C, --curvetest filename Kurvenalgorithmus debuggen\n" -#: gtk2_ardour/opts.cc:60 +#: gtk2_ardour/opts.cc:65 msgid " -k, --keybindings filename Name of key bindings to load (default is ~/.ardour2/ardour.bindings)\n" msgstr " -k, --keybindings filename Dateiname für die Tastaturbelegungen (Standard: ~/.ardour2/ardour.bindings)\n" @@ -5545,14 +6299,14 @@ msgstr "Pan-Automationspunkt einfügen" #: gtk2_ardour/panner2d.cc:588 #: gtk2_ardour/panner_ui.cc:412 -#: gtk2_ardour/plugin_ui.cc:152 +#: gtk2_ardour/plugin_ui.cc:221 msgid "Bypass" msgstr "Bypass" #: gtk2_ardour/panner_ui.cc:58 #: gtk2_ardour/panner_ui.cc:217 msgid "link" -msgstr "verb" +msgstr "link" #: gtk2_ardour/panner_ui.cc:69 msgid "Pan automation mode" @@ -5603,72 +6357,88 @@ msgstr "Andere Spuren" msgid "unassigned" msgstr "nicht zugewiesen" -#: gtk2_ardour/plugin_selector.cc:43 +#: gtk2_ardour/plugin_selector.cc:50 +#: gtk2_ardour/plugin_selector.cc:190 +msgid "Name contains" +msgstr "Name enthält" + +#: gtk2_ardour/plugin_selector.cc:51 +#: gtk2_ardour/plugin_selector.cc:192 +msgid "Type contains" +msgstr "" + +#: gtk2_ardour/plugin_selector.cc:52 +#: gtk2_ardour/plugin_selector.cc:194 +msgid "Author contains" +msgstr "Autor enthält" + +#: gtk2_ardour/plugin_selector.cc:53 +#: gtk2_ardour/plugin_selector.cc:196 +msgid "Library contains" +msgstr "" + +#: gtk2_ardour/plugin_selector.cc:58 msgid "ardour: plugins" msgstr "ardour: Plugins" -#: gtk2_ardour/plugin_selector.cc:56 -msgid "Available LADSPA Plugins" -msgstr "Verfügbare LADSPA Plugins" +#: gtk2_ardour/plugin_selector.cc:70 +msgid "Available Plugins" +msgstr "Verfügbare Plugins" -#: gtk2_ardour/plugin_selector.cc:57 +#: gtk2_ardour/plugin_selector.cc:71 msgid "Type" msgstr "Typ" -#: gtk2_ardour/plugin_selector.cc:58 -#: gtk2_ardour/plugin_selector.cc:81 -#: gtk2_ardour/plugin_selector.cc:99 +#: gtk2_ardour/plugin_selector.cc:72 +msgid "Category" +msgstr "" + +#: gtk2_ardour/plugin_selector.cc:73 +msgid "Creator" +msgstr "Ersteller" + +#: gtk2_ardour/plugin_selector.cc:74 msgid "# Inputs" msgstr "Eingänge" -#: gtk2_ardour/plugin_selector.cc:59 -#: gtk2_ardour/plugin_selector.cc:82 -#: gtk2_ardour/plugin_selector.cc:100 +#: gtk2_ardour/plugin_selector.cc:75 msgid "# Outputs" msgstr "Ausgänge" -#: gtk2_ardour/plugin_selector.cc:68 -msgid "Plugins to be Connected to Insert" -msgstr "Plugins, die als Insert verbunden werden" +#: gtk2_ardour/plugin_selector.cc:85 +msgid "Plugins to be connected" +msgstr "Plugins, die verbunden werden" -#: gtk2_ardour/plugin_selector.cc:80 #: gtk2_ardour/plugin_selector.cc:98 -msgid "Available plugins" -msgstr "Verfügbare VST-Plugins" - -#: gtk2_ardour/plugin_selector.cc:117 msgid "Add a plugin to the effect list" msgstr "Plugin zur Effektliste hinzufügen" -#: gtk2_ardour/plugin_selector.cc:121 +#: gtk2_ardour/plugin_selector.cc:102 msgid "Remove a plugin from the effect list" msgstr "Plugin aus der Effektliste entfernen" -#: gtk2_ardour/plugin_selector.cc:123 +#: gtk2_ardour/plugin_selector.cc:104 msgid "Update available plugins" msgstr "Verfügbare Plugins auffrischen" -#: gtk2_ardour/plugin_selector.cc:146 -msgid "LADSPA" -msgstr "LADSPA" +#: gtk2_ardour/plugin_selector.cc:141 +msgid "Insert Plugin(s)" +msgstr "Plugin(s) einfügen" -#: gtk2_ardour/plugin_selector.cc:150 -msgid "VST" -msgstr "VST" - -#: gtk2_ardour/plugin_selector.cc:155 -msgid "AudioUnit" +#: gtk2_ardour/plugin_ui.cc:81 +msgid "Eh? LADSPA plugins don't have editors!" msgstr "" -#: gtk2_ardour/plugin_ui.cc:84 +#: gtk2_ardour/plugin_ui.cc:85 +#: gtk2_ardour/plugin_ui.cc:141 msgid "unknown type of editor-supplying plugin (note: no VST support in this version of ardour)" msgstr "Unbekannter Plugintyp (Hinweis: diese ardour-Version unterstützt keine VST-Plugins)" -#: gtk2_ardour/plugin_ui.cc:172 +#: gtk2_ardour/plugin_ui.cc:241 msgid "Plugin preset %1 not found" msgstr "Plugin Preset %1 nicht gefunden" -#: gtk2_ardour/plugin_ui.cc:182 +#: gtk2_ardour/plugin_ui.cc:251 msgid "Name of New Preset:" msgstr "Name für neue Voreinstellung:" @@ -5688,12 +6458,12 @@ msgstr "Neuer Send" msgid "Show send controls" msgstr "Zeige Send-Steuerung" -#: gtk2_ardour/redirect_box.cc:412 -#: gtk2_ardour/redirect_box.cc:707 +#: gtk2_ardour/redirect_box.cc:413 +#: gtk2_ardour/redirect_box.cc:708 msgid "ardour: weird plugin dialog" -msgstr "ardour: Plugins" +msgstr "ardour: Merkwürdiger Plugin-Dialog" -#: gtk2_ardour/redirect_box.cc:419 +#: gtk2_ardour/redirect_box.cc:420 msgid "" "You attempted to add a plugin (%1).\n" "The plugin has %2 inputs\n" @@ -5711,7 +6481,7 @@ msgstr "" "Das ist nicht möglich - es würden Teile\n" "des Signals fehlen." -#: gtk2_ardour/redirect_box.cc:431 +#: gtk2_ardour/redirect_box.cc:432 msgid "" "You attempted to add a plugin (%1).\n" "The plugin has %2 inputs\n" @@ -5731,7 +6501,7 @@ msgstr "" "Side-Chain-Eingänge unterstützt. Dies wird in einer\n" "der nächsten Versionen von ardour möglich sein." -#: gtk2_ardour/redirect_box.cc:444 +#: gtk2_ardour/redirect_box.cc:445 msgid "" "You attempted to add a plugin (%1).\n" "\n" @@ -5753,15 +6523,15 @@ msgstr "" "\n" "Ardour kann mit dieser Situation nicht umgehen.\n" -#: gtk2_ardour/redirect_box.cc:541 +#: gtk2_ardour/redirect_box.cc:542 msgid "Pre-fader inserts, sends & plugins:" msgstr "Pre-Fader Inserts, Sends & Plugins:" -#: gtk2_ardour/redirect_box.cc:544 +#: gtk2_ardour/redirect_box.cc:545 msgid "Post-fader inserts, sends & plugins:" msgstr "Post-Fader Inserts, Sends & Plugins:" -#: gtk2_ardour/redirect_box.cc:710 +#: gtk2_ardour/redirect_box.cc:711 msgid "" "You cannot reorder this set of redirects\n" "in that way because the inputs and\n" @@ -5771,12 +6541,12 @@ msgstr "" "nicht auf diese Weise verändern, denn\n" "die Ein-/Ausgänge arbeiten ncht korrekt." -#: gtk2_ardour/redirect_box.cc:823 +#: gtk2_ardour/redirect_box.cc:858 msgid "rename redirect" msgstr "Redirect umbenennen" -#: gtk2_ardour/redirect_box.cc:899 -#: gtk2_ardour/redirect_box.cc:948 +#: gtk2_ardour/redirect_box.cc:934 +#: gtk2_ardour/redirect_box.cc:983 msgid "" "Copying the set of redirects on the clipboard failed,\n" "probably because the I/O configuration of the plugins\n" @@ -5786,7 +6556,7 @@ msgstr "" "Zwischenablage kopieren. Wahrscheinlich passt die\n" "Ein-/Ausgangskonfiguration des Plugins nicht zu dieser Spur." -#: gtk2_ardour/redirect_box.cc:971 +#: gtk2_ardour/redirect_box.cc:1006 msgid "" "Do you really want to remove all pre-fader redirects from this track?\n" "(this cannot be undone)" @@ -5794,7 +6564,7 @@ msgstr "" "Wollen Sie wirklich alle Pre-Fader-Redirects von dieser Spur entfernen?\n" "(Dies kann nicht rückgängig gemacht werden)" -#: gtk2_ardour/redirect_box.cc:974 +#: gtk2_ardour/redirect_box.cc:1009 msgid "" "Do you really want to remove all post-fader redirects from this track?\n" "(this cannot be undone)" @@ -5802,7 +6572,7 @@ msgstr "" "Wollen Sie wirklich alle Post-Fader-Redirects von dieser Spur entfernen?\n" "(Dies kann nicht rückgängig gemacht werden)" -#: gtk2_ardour/redirect_box.cc:979 +#: gtk2_ardour/redirect_box.cc:1014 msgid "" "Do you really want to remove all pre-fader redirects from this bus?\n" "(this cannot be undone)" @@ -5810,7 +6580,7 @@ msgstr "" "Wollen Sie wirklich alle Pre-Fader-Redirects von diesem Bus entfernen?\n" "(Dies kann nicht rückgängig gemacht werden)" -#: gtk2_ardour/redirect_box.cc:982 +#: gtk2_ardour/redirect_box.cc:1017 msgid "" "Do you really want to remove all post-fader redirects from this bus?\n" "(this cannot be undone)" @@ -5818,38 +6588,33 @@ msgstr "" "Wollen Sie wirklich alle Post-Fader-Redirects von diesem Bus entfernen?\n" "(Dies kann nicht rückgängig gemacht werden)" -#: gtk2_ardour/redirect_box.cc:988 +#: gtk2_ardour/redirect_box.cc:1023 msgid "Yes, remove them all" msgstr "Ja, alle löschen" -#: gtk2_ardour/redirect_box.cc:1150 +#: gtk2_ardour/redirect_box.cc:1173 msgid "New Plugin ..." msgstr "Plugin einfügen..." -#: gtk2_ardour/redirect_box.cc:1152 +#: gtk2_ardour/redirect_box.cc:1175 msgid "New Insert" msgstr "Insert einfügen" -#: gtk2_ardour/redirect_box.cc:1154 +#: gtk2_ardour/redirect_box.cc:1177 msgid "New Send ..." msgstr "Send einfügen..." -#: gtk2_ardour/redirect_box.cc:1168 -msgid "Deselect All" -msgstr "Nichts auswählen" - -#: gtk2_ardour/redirect_box.cc:1175 +#: gtk2_ardour/redirect_box.cc:1202 msgid "Activate all" msgstr "Alle aktivieren" -#: gtk2_ardour/redirect_box.cc:1176 +#: gtk2_ardour/redirect_box.cc:1203 msgid "Deactivate all" msgstr "Alle deaktivieren" -#: gtk2_ardour/redirect_box.cc:1359 -#, fuzzy +#: gtk2_ardour/redirect_box.cc:1396 msgid "%1: %2 (by %3)" -msgstr "ardour: %1: %2 (by %3)" +msgstr "%1: %2 (by %3)" #: gtk2_ardour/audio_region_editor.cc:48 msgid "NAME:" @@ -5891,7 +6656,7 @@ msgstr "Endposition der Region ändern" msgid "change region length" msgstr "Länge der Region verändern" -#: gtk2_ardour/audio_region_view.cc:911 +#: gtk2_ardour/audio_region_view.cc:922 msgid "add gain control point" msgstr "Lautstärkekurve bearbeiten" @@ -5920,62 +6685,61 @@ msgstr "KEINE SPUR" msgid "No Route Selected" msgstr "Keine Route ausgewählt" -#: gtk2_ardour/route_ui.cc:154 +#: gtk2_ardour/route_ui.cc:156 msgid "mute change" msgstr "Mute ändern" -#: gtk2_ardour/route_ui.cc:232 -#: gtk2_ardour/route_ui.cc:243 +#: gtk2_ardour/route_ui.cc:234 +#: gtk2_ardour/route_ui.cc:245 msgid "solo change" msgstr "Solo ändern" -#: gtk2_ardour/route_ui.cc:301 +#: gtk2_ardour/route_ui.cc:303 msgid "Not connected to JACK - cannot engage record" msgstr "Nicht mit JACK verbunden - konnte die Aufnahme nicht starten" -#: gtk2_ardour/route_ui.cc:314 +#: gtk2_ardour/route_ui.cc:317 msgid "rec-enable change" msgstr "Aufnahmestatus ändern" -#: gtk2_ardour/route_ui.cc:548 -#, fuzzy +#: gtk2_ardour/route_ui.cc:555 msgid "Solo-safe" -msgstr "solo" +msgstr "Solo-Safe" -#: gtk2_ardour/route_ui.cc:570 +#: gtk2_ardour/route_ui.cc:577 msgid "Pre Fader" msgstr "Pre Fader" -#: gtk2_ardour/route_ui.cc:577 +#: gtk2_ardour/route_ui.cc:584 msgid "Post Fader" msgstr "Post Fader" -#: gtk2_ardour/route_ui.cc:584 +#: gtk2_ardour/route_ui.cc:591 msgid "Control Outs" msgstr "Vorhörausgang" -#: gtk2_ardour/route_ui.cc:591 +#: gtk2_ardour/route_ui.cc:598 msgid "Main Outs" msgstr "Main Ausgänge" -#: gtk2_ardour/route_ui.cc:628 +#: gtk2_ardour/route_ui.cc:635 msgid "mix group solo change" msgstr "Mixergruppe Solo-Status ändern" -#: gtk2_ardour/route_ui.cc:667 +#: gtk2_ardour/route_ui.cc:674 msgid "mix group mute change" msgstr "Mixergruppe Mute-Status ändern" -#: gtk2_ardour/route_ui.cc:684 +#: gtk2_ardour/route_ui.cc:691 msgid "mix group rec-enable change" msgstr "Mixergruppe Aufnahmestatus ändern" -#: gtk2_ardour/route_ui.cc:702 +#: gtk2_ardour/route_ui.cc:709 #: gtk2_ardour/visual_time_axis.cc:241 msgid "ardour: color selection" msgstr "ardour: Farbe auswählen" -#: gtk2_ardour/route_ui.cc:778 +#: gtk2_ardour/route_ui.cc:785 msgid "" "Do you really want to remove track \"%1\" ?\n" "\n" @@ -5987,7 +6751,7 @@ msgstr "" "Sie werden auch die Wiedergabeliste, die diese Spur benutzt verlieren.\n" "(Dies kann nicht rückgängig gemacht werden!)" -#: gtk2_ardour/route_ui.cc:780 +#: gtk2_ardour/route_ui.cc:787 msgid "" "Do you really want to remove bus \"%1\" ?\n" "(cannot be undone)" @@ -5995,247 +6759,371 @@ msgstr "" "Wollen Sie den Bus \"%1\" wirklich löschen?\n" "(Dies kann nicht rückgängig gemacht werden!)" -#: gtk2_ardour/route_ui.cc:805 +#: gtk2_ardour/route_ui.cc:812 msgid "New Name: " msgstr "Neuer Name: " -#: gtk2_ardour/sfdb_ui.cc:63 -msgid "Apply" -msgstr "Ãœbernehmen" +#: gtk2_ardour/sfdb_ui.cc:81 +#, fuzzy +msgid "programming error: unknown import mode string %1" +msgstr "Programmierfehler: unbekanntes Fernsteuerungsmodell in ARDOUR_UI::set_remote_model: %1" + +#: gtk2_ardour/sfdb_ui.cc:91 +#: gtk2_ardour/sfdb_ui.cc:100 +msgid "as new tracks" +msgstr "als neue Spuren" -#: gtk2_ardour/sfdb_ui.cc:69 -msgid "Soundfile Info" -msgstr "Eigenschaften der Audiodatei" +#: gtk2_ardour/sfdb_ui.cc:93 +msgid "to selected tracks" +msgstr "zu ausgewählten Spuren" -#: gtk2_ardour/sfdb_ui.cc:72 -msgid "comma seperated tags" -msgstr "Stichworte (durch Komma getrennt)" +#: gtk2_ardour/sfdb_ui.cc:95 +msgid "to region list" +msgstr "zur Liste der Regionen" + +#: gtk2_ardour/sfdb_ui.cc:97 +msgid "as new tape tracks" +msgstr "als neue Tape-Spuren" + +#: gtk2_ardour/sfdb_ui.cc:109 +msgid "Auto-play" +msgstr "Auto-Play" + +#: gtk2_ardour/sfdb_ui.cc:118 +#: gtk2_ardour/sfdb_ui.cc:228 +msgid "<b>Soundfile Info</b>" +msgstr "<b>Eigenschaften der Audiodatei</b>" + +#: gtk2_ardour/sfdb_ui.cc:129 +msgid "Length:" +msgstr "Länge:" #: gtk2_ardour/sfdb_ui.cc:130 -msgid "Length: n/a" -msgstr "Länge: n/a" +msgid "Timestamp:" +msgstr "Zeitstempel:" #: gtk2_ardour/sfdb_ui.cc:131 -msgid "Format: n/a" -msgstr "Format: n/a" +msgid "Format:" +msgstr "Format:" #: gtk2_ardour/sfdb_ui.cc:132 -msgid "Channels: n/a" -msgstr "Channels: n/a" +msgid "Channels:" +msgstr "Kanäle:" #: gtk2_ardour/sfdb_ui.cc:133 -msgid "Samplerate: n/a" -msgstr "Samplerate: n/a" - -#: gtk2_ardour/sfdb_ui.cc:134 -msgid "Timecode: n/a" -msgstr "Timecode: n/a" +#: gtk2_ardour/sfdb_ui.cc:248 +#: gtk2_ardour/sfdb_ui.cc:253 +msgid "Sample rate:" +msgstr "Samplerate:" -#: gtk2_ardour/sfdb_ui.cc:144 -msgid "Length: %1" -msgstr "Länge: %1" +#: gtk2_ardour/sfdb_ui.cc:165 +msgid "Tags:" +msgstr "Stichworte:" -#: gtk2_ardour/sfdb_ui.cc:146 -msgid "Channels: %1" -msgstr "Kanäle: %1" +#: gtk2_ardour/sfdb_ui.cc:175 +msgid "Play (double click)" +msgstr "Wiedergabe (Doppelklick)" -#: gtk2_ardour/sfdb_ui.cc:147 -msgid "Samplerate: %1" -msgstr "Samplerate: %1" - -#: gtk2_ardour/sfdb_ui.cc:148 -msgid "Timecode: %1" -msgstr "Timecode: %1" +#: gtk2_ardour/sfdb_ui.cc:229 +#: gtk2_ardour/sfdb_ui.cc:230 +#: gtk2_ardour/sfdb_ui.cc:231 +msgid "n/a" +msgstr "" -#: gtk2_ardour/sfdb_ui.cc:188 +#: gtk2_ardour/sfdb_ui.cc:306 msgid "Could not read file: %1 (%2)." msgstr "Konnte Datei nicht lesen: %1 (%2)." -#: gtk2_ardour/sfdb_ui.cc:206 +#: gtk2_ardour/sfdb_ui.cc:326 msgid "Could not access soundfile: " msgstr "Konnte auf Audiodatei nicht zugreifen: " -#: gtk2_ardour/sfdb_ui.cc:255 +#: gtk2_ardour/sfdb_ui.cc:372 msgid "SoundFileBox: Could not tokenize string: " msgstr "" -#: gtk2_ardour/sfdb_ui.cc:275 -msgid "Add to Region list" -msgstr "Zur Liste der Regionen hinzufügen" - -#: gtk2_ardour/sfdb_ui.cc:276 -msgid "Add to selected Track(s)" -msgstr "Zu ausgewählten Spuren hinzufügen" - -#: gtk2_ardour/sfdb_ui.cc:277 -msgid "Add as new Track(s)" -msgstr "Als neue Spur(en) hinzufügen" - -#: gtk2_ardour/sfdb_ui.cc:278 -msgid "Add as new Tape Track(s)" -msgstr "Als neue Tape-Spuren hinzufügen" - -#: gtk2_ardour/sfdb_ui.cc:287 +#: gtk2_ardour/sfdb_ui.cc:392 msgid "Search" msgstr "Suchen" -#: gtk2_ardour/sfdb_ui.cc:302 +#: gtk2_ardour/sfdb_ui.cc:421 msgid "Paths" msgstr "Pfade" -#: gtk2_ardour/sfdb_ui.cc:304 -msgid "Files" -msgstr "Dateien" +#: gtk2_ardour/sfdb_ui.cc:425 +msgid "Browse Files" +msgstr "Durchsuchen" + +#: gtk2_ardour/sfdb_ui.cc:426 +msgid "Search Tags" +msgstr "Stichwortsuche" -#: gtk2_ardour/sfdb_ui.cc:305 -msgid "Tags" -msgstr "Stichworte" +#: gtk2_ardour/sfdb_ui.cc:434 +msgid "Audio files" +msgstr "Audiodateien" + +#: gtk2_ardour/sfdb_ui.cc:437 +msgid "All files" +msgstr "Alle Dateien" -#: gtk2_ardour/sfdb_ui.cc:374 +#: gtk2_ardour/sfdb_ui.cc:598 msgid "SoundFileBrowser: Could not tokenize string: " msgstr "" -#: gtk2_ardour/sfdb_ui.cc:432 -msgid "Split Channels" -msgstr "Kanäle aufteilen" +#: gtk2_ardour/sfdb_ui.cc:766 +#: gtk2_ardour/sfdb_ui.cc:1049 +#: gtk2_ardour/sfdb_ui.cc:1091 +msgid "one track per file" +msgstr "eine Spur pro Datei" -#: gtk2_ardour/sfdb_ui.cc:435 -msgid "Create a region for each channel" -msgstr "Erstellt aus jedem Kanal eine eigene Region" +#: gtk2_ardour/sfdb_ui.cc:769 +#: gtk2_ardour/sfdb_ui.cc:1092 +msgid "one track per channel" +msgstr "eine Spur pro Kanal" -#: gtk2_ardour/sfdb_ui.cc:437 -msgid "Embed" -msgstr "Einbetten" +#: gtk2_ardour/sfdb_ui.cc:777 +#: gtk2_ardour/sfdb_ui.cc:1094 +#, fuzzy +msgid "sequence files" +msgstr "aufgeräumte Dateien" -#: gtk2_ardour/sfdb_ui.cc:439 -msgid "Link to an external file" -msgstr "Bettet eine externe Datei ein, ohne sie zu ins Verzeichnis des Projekts zu importieren" +#: gtk2_ardour/sfdb_ui.cc:780 +#: gtk2_ardour/sfdb_ui.cc:794 +#: gtk2_ardour/sfdb_ui.cc:1098 +msgid "all files in one region" +msgstr "alle Dateien in einer Region" -#: gtk2_ardour/sfdb_ui.cc:441 -msgid "Import" -msgstr "Importieren" +#: gtk2_ardour/sfdb_ui.cc:786 +#: gtk2_ardour/sfdb_ui.cc:1096 +msgid "one region per file" +msgstr "eine Region pro Datei" -#: gtk2_ardour/sfdb_ui.cc:443 -msgid "Copy a file to the session folder" -msgstr "Kopiert eine Datei in das Verzeichnis des Projekts" +#: gtk2_ardour/sfdb_ui.cc:789 +#: gtk2_ardour/sfdb_ui.cc:1097 +msgid "one region per channel" +msgstr "eine Region pro Kanal" -#: gtk2_ardour/tempo_dialog.cc:17 +#: gtk2_ardour/sfdb_ui.cc:847 +msgid "" +"One or more of the selected files\n" +"cannot be used by Ardour" +msgstr "" +"Eine oder mehrere der ausgewählten Dateien\n" +"können nicht von Ardour benutzt werden" + +#: gtk2_ardour/sfdb_ui.cc:978 +msgid "Copy files to session" +msgstr "Kopiere Dateien zum Projekt" + +#: gtk2_ardour/sfdb_ui.cc:994 +#: gtk2_ardour/sfdb_ui.cc:1129 +msgid "use file timestamp" +msgstr "verwende Datei-Zeitstempel" + +#: gtk2_ardour/sfdb_ui.cc:995 +#: gtk2_ardour/sfdb_ui.cc:1131 +msgid "at edit point" +msgstr "am Arbeitspunkt" + +#: gtk2_ardour/sfdb_ui.cc:996 +#: gtk2_ardour/sfdb_ui.cc:1133 +msgid "at playhead" +msgstr "am Positionszeiger" + +#: gtk2_ardour/sfdb_ui.cc:997 +msgid "at session start" +msgstr "am Projektanfang" + +#: gtk2_ardour/sfdb_ui.cc:1002 +msgid "Add files:" +msgstr "Dateien hinzufügen:" + +#: gtk2_ardour/sfdb_ui.cc:1024 +msgid "Insert:" +msgstr "Einfügen:" + +#: gtk2_ardour/sfdb_ui.cc:1037 +msgid "Mapping:" +msgstr "" + +#: gtk2_ardour/sfdb_ui.cc:1055 +msgid "Conversion Quality:" +msgstr "Konvertierungsqualität:" + +#: gtk2_ardour/sfdb_ui.cc:1067 +#: gtk2_ardour/sfdb_ui.cc:1145 +msgid "Best" +msgstr "bestmöglich" + +#: gtk2_ardour/sfdb_ui.cc:1068 +#: gtk2_ardour/sfdb_ui.cc:1147 +msgid "Good" +msgstr "gut" + +#: gtk2_ardour/sfdb_ui.cc:1069 +#: gtk2_ardour/sfdb_ui.cc:1149 +msgid "Quick" +msgstr "schnell" + +#: gtk2_ardour/sfdb_ui.cc:1093 +msgid "merge files" +msgstr "Dateien zusammenfügen" + +#: gtk2_ardour/sfdb_ui.cc:1170 +msgid "programming error: %1 (%2)" +msgstr "Programmierfehler: %1 (%2)" + +#: gtk2_ardour/tempo_dialog.cc:36 msgid "edit tempo" msgstr "Tempo bearbeiten" -#: gtk2_ardour/tempo_dialog.cc:20 #: gtk2_ardour/tempo_dialog.cc:39 +#: gtk2_ardour/tempo_dialog.cc:59 msgid "Beats per minute" msgstr "Schläge pro Minute" -#: gtk2_ardour/tempo_dialog.cc:23 -#: gtk2_ardour/tempo_dialog.cc:42 -#: gtk2_ardour/tempo_dialog.cc:159 -#: gtk2_ardour/tempo_dialog.cc:177 +#: gtk2_ardour/tempo_dialog.cc:40 +msgid "BPM denominator" +msgstr "BPM Zählzeit" + +#: gtk2_ardour/tempo_dialog.cc:43 +#: gtk2_ardour/tempo_dialog.cc:62 +#: gtk2_ardour/tempo_dialog.cc:257 +#: gtk2_ardour/tempo_dialog.cc:275 msgid "Bar" msgstr "Takt" -#: gtk2_ardour/tempo_dialog.cc:24 -#: gtk2_ardour/tempo_dialog.cc:43 -#: gtk2_ardour/tempo_dialog.cc:160 -#: gtk2_ardour/tempo_dialog.cc:178 +#: gtk2_ardour/tempo_dialog.cc:44 +#: gtk2_ardour/tempo_dialog.cc:63 +#: gtk2_ardour/tempo_dialog.cc:258 +#: gtk2_ardour/tempo_dialog.cc:276 msgid "Beat" msgstr "Schlag" -#: gtk2_ardour/tempo_dialog.cc:26 -#: gtk2_ardour/tempo_dialog.cc:45 -#: gtk2_ardour/tempo_dialog.cc:161 -#: gtk2_ardour/tempo_dialog.cc:179 +#: gtk2_ardour/tempo_dialog.cc:46 +#: gtk2_ardour/tempo_dialog.cc:65 +#: gtk2_ardour/tempo_dialog.cc:259 +#: gtk2_ardour/tempo_dialog.cc:277 msgid "Location" msgstr "Position" -#: gtk2_ardour/tempo_dialog.cc:155 -#: gtk2_ardour/tempo_dialog.cc:173 -msgid "Meter denominator" -msgstr "Takteinteilung" - -#: gtk2_ardour/tempo_dialog.cc:156 -#: gtk2_ardour/tempo_dialog.cc:174 -msgid "Beats per bar" -msgstr "Schläge pro Takt" - -#: gtk2_ardour/tempo_dialog.cc:192 -#: gtk2_ardour/tempo_dialog.cc:203 +#: gtk2_ardour/tempo_dialog.cc:78 +#: gtk2_ardour/tempo_dialog.cc:95 +#: gtk2_ardour/tempo_dialog.cc:290 +#: gtk2_ardour/tempo_dialog.cc:308 msgid "whole (1)" msgstr "Ganze (1)" -#: gtk2_ardour/tempo_dialog.cc:193 -#: gtk2_ardour/tempo_dialog.cc:205 +#: gtk2_ardour/tempo_dialog.cc:79 +#: gtk2_ardour/tempo_dialog.cc:97 +#: gtk2_ardour/tempo_dialog.cc:291 +#: gtk2_ardour/tempo_dialog.cc:310 msgid "second (2)" msgstr "Halbe (2)" -#: gtk2_ardour/tempo_dialog.cc:194 -#: gtk2_ardour/tempo_dialog.cc:207 +#: gtk2_ardour/tempo_dialog.cc:80 +#: gtk2_ardour/tempo_dialog.cc:99 +#: gtk2_ardour/tempo_dialog.cc:292 +#: gtk2_ardour/tempo_dialog.cc:312 msgid "third (3)" msgstr "Triolen (3)" -#: gtk2_ardour/tempo_dialog.cc:195 -#: gtk2_ardour/tempo_dialog.cc:209 -#: gtk2_ardour/tempo_dialog.cc:217 +#: gtk2_ardour/tempo_dialog.cc:81 +#: gtk2_ardour/tempo_dialog.cc:101 +#: gtk2_ardour/tempo_dialog.cc:109 +#: gtk2_ardour/tempo_dialog.cc:293 +#: gtk2_ardour/tempo_dialog.cc:314 +#: gtk2_ardour/tempo_dialog.cc:322 msgid "quarter (4)" msgstr "Viertel (4)" -#: gtk2_ardour/tempo_dialog.cc:196 -#: gtk2_ardour/tempo_dialog.cc:211 +#: gtk2_ardour/tempo_dialog.cc:82 +#: gtk2_ardour/tempo_dialog.cc:103 +#: gtk2_ardour/tempo_dialog.cc:294 +#: gtk2_ardour/tempo_dialog.cc:316 msgid "eighth (8)" msgstr "Achtel (8)" -#: gtk2_ardour/tempo_dialog.cc:197 -#: gtk2_ardour/tempo_dialog.cc:213 +#: gtk2_ardour/tempo_dialog.cc:83 +#: gtk2_ardour/tempo_dialog.cc:105 +#: gtk2_ardour/tempo_dialog.cc:295 +#: gtk2_ardour/tempo_dialog.cc:318 msgid "sixteenth (16)" msgstr "Sechzehntel (16)" -#: gtk2_ardour/tempo_dialog.cc:198 -#: gtk2_ardour/tempo_dialog.cc:215 +#: gtk2_ardour/tempo_dialog.cc:84 +#: gtk2_ardour/tempo_dialog.cc:107 +#: gtk2_ardour/tempo_dialog.cc:296 +#: gtk2_ardour/tempo_dialog.cc:320 msgid "thirty-second (32)" msgstr "Zweiunddreissigstel (32)" -#: gtk2_ardour/tempo_dialog.cc:376 +#: gtk2_ardour/tempo_dialog.cc:225 +#: gtk2_ardour/tempo_dialog.cc:479 msgid "garbaged note type entry (%1)" msgstr "Fehlerhafter Notentyp (%1)" -#: gtk2_ardour/tempo_dialog.cc:386 +#: gtk2_ardour/tempo_dialog.cc:235 +#: gtk2_ardour/tempo_dialog.cc:489 msgid "incomprehensible note type entry (%1)" msgstr "Unverständlicher Notentyp (%1)" +#: gtk2_ardour/tempo_dialog.cc:253 +#: gtk2_ardour/tempo_dialog.cc:271 +msgid "Meter denominator" +msgstr "Takteinteilung" + +#: gtk2_ardour/tempo_dialog.cc:254 +#: gtk2_ardour/tempo_dialog.cc:272 +msgid "Beats per bar" +msgstr "Schläge pro Takt" + +#: gtk2_ardour/tempo_dialog.cc:303 +#, fuzzy +msgid "thirtq-second (32)" +msgstr "Zweiunddreissigstel (32)" + +#: gtk2_ardour/theme_manager.cc:51 +msgid "Object" +msgstr "" + +#: gtk2_ardour/theme_manager.cc:182 +msgid "Unable to find UI style file %1. Ardour will look strange" +msgstr "Kann die UI-Style Datei %1 nicht finden. Ardour wird merkwürdig aussehen." + #: gtk2_ardour/time_axis_view.cc:111 msgid "gTortnam" msgstr "" -#: gtk2_ardour/time_axis_view.cc:586 +#: gtk2_ardour/time_axis_view.cc:589 msgid "Largest" msgstr "Am größten" -#: gtk2_ardour/time_axis_view.cc:587 +#: gtk2_ardour/time_axis_view.cc:590 msgid "Large" msgstr "Groß" -#: gtk2_ardour/time_axis_view.cc:588 +#: gtk2_ardour/time_axis_view.cc:591 msgid "Larger" msgstr "Größer" -#: gtk2_ardour/time_axis_view.cc:590 +#: gtk2_ardour/time_axis_view.cc:593 msgid "Smaller" msgstr "Kleiner" -#: gtk2_ardour/time_axis_view.cc:591 +#: gtk2_ardour/time_axis_view.cc:594 msgid "Small" msgstr "Klein" -#: gtk2_ardour/time_axis_view.cc:906 +#: gtk2_ardour/time_axis_view.cc:909 msgid "unknown track height name \"%1\" in XML GUI information" msgstr "Unbekannte Spurhöhe \"%1\" in der XML GUI Information" -#: gtk2_ardour/time_axis_view_item.cc:78 +#: gtk2_ardour/time_axis_view_item.cc:80 msgid "TimeAxisViewItemName" msgstr "" -#: gtk2_ardour/time_axis_view_item.cc:330 +#: gtk2_ardour/time_axis_view_item.cc:332 msgid "new duration %1 frames is out of bounds for %2" msgstr "Neue Dauer %1 Frames ist außerhalb des erlaubten Bereichs %2" @@ -6243,16 +7131,52 @@ msgstr "Neue Dauer %1 Frames ist außerhalb des erlaubten Bereichs %2" msgid "programming error: request for non-existent audio range (%1)!" msgstr "Programmierfehler: request for non-existent audio range (%1)!" -#: gtk2_ardour/utils.cc:131 -#: gtk2_ardour/utils.cc:174 +#: gtk2_ardour/ui_config.cc:68 +msgid "loading default ui configuration file %1" +msgstr "lade voreingestellte UI-Konfigurationsdatei %1" + +#: gtk2_ardour/ui_config.cc:71 +msgid "Ardour: cannot read default ui configuration file \"%1\"" +msgstr "Ardour: kann die voreingestellte UI-Konfigurationsdatei \"%1\" nicht lesen" + +#: gtk2_ardour/ui_config.cc:76 +msgid "Ardour: default ui configuration file \"%1\" not loaded successfully." +msgstr "Ardour: Die voreingestellte UI-Konfigurationsdatei \"%1\" konnte nicht geladen werden." + +#: gtk2_ardour/ui_config.cc:88 +msgid "loading user ui configuration file %1" +msgstr "lade benutzerdefinierte UI-Konfigurationsdatei %1" + +#: gtk2_ardour/ui_config.cc:91 +msgid "Ardour: cannot read ui configuration file \"%1\"" +msgstr "Ardour: kann die UI-Konfigurationsdatei \"%1\" nicht lesen" + +#: gtk2_ardour/ui_config.cc:96 +msgid "Ardour: user ui configuration file \"%1\" not loaded successfully." +msgstr "Ardour: Die benutzerdefinierte UI-Konfigurationsdatei \"%1\" konnte nicht geladen werden." + +#: gtk2_ardour/ui_config.cc:120 +msgid "UI config file %1 not saved" +msgstr "UI-Konfigurationsdatei %1 nicht gespeichert." + +#: gtk2_ardour/utils.cc:132 +#: gtk2_ardour/utils.cc:175 msgid "bad XPM header %1" msgstr "Fehlerhafter XPM Header %1" -#: gtk2_ardour/utils.cc:313 +#: gtk2_ardour/utils.cc:314 msgid "missing RGBA style for \"%1\"" msgstr "Fehlender RGBA Style für \"%1\"" -#: gtk2_ardour/utils.cc:495 +#: gtk2_ardour/utils.cc:337 +msgid "no style found for %1, using red" +msgstr "" + +#: gtk2_ardour/utils.cc:376 +msgid "unknown style attribute %1 requested for color; using \"red\"" +msgstr "" + +#: gtk2_ardour/utils.cc:581 msgid "cannot find icon image for %1" msgstr "Konnte Icon-Bild für %1 nicht finden" @@ -6308,12 +7232,12 @@ msgstr "" #: gtk2_ardour/connection_editor.cc:531 #, c-format msgid "in %d" -msgstr "" +msgstr "In %d" #: gtk2_ardour/connection_editor.cc:533 #, c-format msgid "out %d" -msgstr "" +msgstr "Out %d" #: gtk2_ardour/connection_editor.cc:657 msgid "Name for new connection:" diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index e5ccc827f3..7ccef4ea53 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -104,7 +104,6 @@ ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, boost::shared_ptr<Ro processor_drag_in_progress = false; no_processor_redisplay = false; ignore_delete = false; - ab_direction = true; model = ListStore::create(columns); diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 3410dc025a..749c78dc50 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -212,15 +212,15 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual void add_toplevel_controls (Gtk::Container&) = 0; virtual void set_zoom_focus (Editing::ZoomFocus) = 0; virtual Editing::ZoomFocus get_zoom_focus () const = 0; - virtual gdouble get_current_zoom () = 0; - virtual PlaylistSelector& playlist_selector () const = 0; + virtual gdouble get_current_zoom () const = 0; + virtual PlaylistSelector& playlist_selector() const = 0; virtual void route_name_changed (TimeAxisView *) = 0; virtual void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>) = 0; virtual void new_playlists (TimeAxisView*) = 0; virtual void copy_playlists (TimeAxisView*) = 0; virtual void clear_playlists (TimeAxisView*) = 0; virtual void select_all_tracks () = 0; - virtual bool set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove = false) = 0; + virtual void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove = false) = 0; virtual void set_selected_mixer_strip (TimeAxisView&) = 0; virtual void hide_track_in_display (TimeAxisView& tv) = 0; virtual void show_track_in_display (TimeAxisView& tv) = 0; @@ -252,7 +252,8 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual void remove_last_capture () = 0; virtual void maximise_editing_space () = 0; virtual void restore_editing_space () = 0; - virtual nframes64_t get_preferred_edit_position () = 0; + virtual nframes64_t get_preferred_edit_position (bool ignore_playhead = false) = 0; + virtual void toggle_meter_updating() = 0; #ifdef WITH_CMT virtual void add_imageframe_time_axis(const std::string & track_name, void*) = 0; diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index fb715559a1..fa9ec5969b 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -123,6 +123,8 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) wait_for_data = wfd; sync_mark = 0; sync_line = 0; + sync_mark = 0; + sync_line = 0; compute_colors (basic_color); @@ -132,8 +134,6 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) name_text->set_data ("regionview", this); } - //reset_width_dependent_items ((double) _region->length() / samples_per_unit); - if (wfd) _enable_display = true; @@ -385,8 +385,8 @@ RegionView::fake_set_opaque (bool yn) } else { fill_opacity = 60; } - - TimeAxisViewItem::set_frame_color (); + + set_frame_color (); } void @@ -500,7 +500,7 @@ RegionView::region_sync_changed () points.clear (); points.push_back (Gnome::Art::Point (offset, 0)); - points.push_back (Gnome::Art::Point (offset, _height - NAME_HIGHLIGHT_SIZE)); + points.push_back (Gnome::Art::Point (offset, trackview.height - NAME_HIGHLIGHT_SIZE)); sync_line->property_points().set_value (points); sync_line->show (); diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc index cae24510c3..497e99ba61 100644 --- a/gtk2_ardour/route_params_ui.cc +++ b/gtk2_ardour/route_params_ui.cc @@ -352,9 +352,9 @@ void RouteParams_UI::cleanup_pre_view (bool stopupdate) { if (_active_pre_view) { - LadspaPluginUI * plugui = 0; + GenericPluginUI * plugui = 0; - if (stopupdate && (plugui = dynamic_cast<LadspaPluginUI*>(_active_pre_view)) != 0) { + if (stopupdate && (plugui = dynamic_cast<GenericPluginUI*>(_active_pre_view)) != 0) { plugui->stop_updating (0); } @@ -369,9 +369,9 @@ void RouteParams_UI::cleanup_post_view (bool stopupdate) { if (_active_post_view) { - LadspaPluginUI * plugui = 0; + GenericPluginUI * plugui = 0; - if (stopupdate && (plugui = dynamic_cast<LadspaPluginUI*>(_active_post_view)) != 0) { + if (stopupdate && (plugui = dynamic_cast<GenericPluginUI*>(_active_post_view)) != 0) { plugui->stop_updating (0); } _post_plugin_conn.disconnect(); @@ -581,7 +581,7 @@ RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Processor> insert, } } else if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) { - LadspaPluginUI *plugin_ui = new LadspaPluginUI (plugin_insert, session->frame_rate(), session->engine().frames_per_cycle(), true); + GenericPluginUI *plugin_ui = new GenericPluginUI (plugin_insert, true); if (place == PreFader) { cleanup_pre_view(); diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index f654a3056c..42b2e646ad 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -52,6 +52,7 @@ #include <ardour/session_playlist.h> #include <ardour/utils.h> #include <ardour/parameter.h> +#include <ardour/profile.h> #include "ardour_ui.h" #include "route_time_axis.h" @@ -105,6 +106,8 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh _view = 0; timestretch_rect = 0; no_redraw = false; + destructive_track_mode_item = 0; + normal_track_mode_item = 0; ignore_toggle = false; @@ -149,6 +152,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh rec_enable_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::rec_enable_release)); controls_table.attach (*rec_enable_button, 4, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record")); + } controls_hbox.pack_start(lm, false, false); @@ -172,17 +176,22 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh label_view (); - controls_table.attach (hide_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.attach (visual_button, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.attach (size_button, 2, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.attach (automation_button, 3, 4, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + if (!Profile->get_sae()) { + + controls_table.attach (hide_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.attach (visual_button, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.attach (size_button, 2, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.attach (automation_button, 3, 4, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + + } else { + + controls_table.attach (automation_button, 4, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + } if (is_track() && track()->mode() == ARDOUR::Normal) { controls_table.attach (playlist_button, 5, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); } - /* remove focus from the buttons */ - y_position = -1; _route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed)); @@ -325,7 +334,7 @@ RouteTimeAxisView::get_automation_child_xml_node (Parameter param) gint RouteTimeAxisView::edit_click (GdkEventButton *ev) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { _route->set_edit_group (0, this); return FALSE; } @@ -502,13 +511,15 @@ RouteTimeAxisView::build_display_menu () items.push_back (SeparatorElem()); build_remote_control_menu (); - items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu)); - build_automation_action_menu (); - items.push_back (MenuElem (_("Automation"), *automation_action_menu)); + + if (!Profile->get_sae()) { + items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu)); + items.push_back (MenuElem (_("Automation"), *automation_action_menu)); + items.push_back (SeparatorElem()); + } // Hook for derived classes to add type specific stuff - items.push_back (SeparatorElem()); append_extra_display_menu_items (); items.push_back (SeparatorElem()); @@ -545,7 +556,26 @@ RouteTimeAxisView::build_display_menu () if (get_diskstream()->alignment_style() == CaptureTime) align_capture_item->set_active(); - items.push_back (MenuElem (_("Alignment"), *alignment_menu)); + if (!Profile->get_sae()) { + items.push_back (MenuElem (_("Alignment"), *alignment_menu)); + get_diskstream()->AlignmentStyleChanged.connect (mem_fun(*this, &RouteTimeAxisView::align_style_changed)); + + RadioMenuItem::Group mode_group; + items.push_back (RadioMenuElem (mode_group, _("Normal mode"), + bind (mem_fun (*this, &RouteTimeAxisView::set_track_mode), ARDOUR::Normal))); + normal_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back()); + items.push_back (RadioMenuElem (mode_group, _("Tape mode"), + bind (mem_fun (*this, &RouteTimeAxisView::set_track_mode), ARDOUR::Destructive))); + destructive_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back()); + + switch (track()->mode()) { + case ARDOUR::Destructive: + destructive_track_mode_item->set_active (); + break; + case ARDOUR::Normal: + normal_track_mode_item->set_active (); + break; + } get_diskstream()->AlignmentStyleChanged.connect ( mem_fun(*this, &RouteTimeAxisView::align_style_changed)); @@ -553,9 +583,11 @@ RouteTimeAxisView::build_display_menu () mode_menu = build_mode_menu(); if (mode_menu) items.push_back (MenuElem (_("Mode"), *mode_menu)); + + items.push_back (SeparatorElem()); + } } - items.push_back (SeparatorElem()); items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active))); route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back()); route_active_menu_item->set_active (_route->active()); @@ -590,8 +622,8 @@ RouteTimeAxisView::set_track_mode (TrackMode mode) /*NOTREACHED*/ return; } - - if (item->get_active () && track()->mode() != mode) { + + if (item && other_item && item->get_active () && track()->mode() != mode) { _set_track_mode (track().get(), mode, other_item); } } @@ -740,7 +772,7 @@ RouteTimeAxisView::set_height (TrackHeight h) { int gmlen = (height_to_pixels (h)) - 5; bool height_changed = (height == 0) || (h != height_style); - + lm.setup_meters (gmlen); TimeAxisView::set_height (h); ensure_xml_node (); @@ -822,7 +854,6 @@ RouteTimeAxisView::set_height (TrackHeight h) break; case Small: - hide_meter(); hide_name_entry (); show_name_label (); @@ -1084,7 +1115,7 @@ RouteTimeAxisView::update_diskstream_display () void RouteTimeAxisView::selection_click (GdkEventButton* ev) { - if (Keyboard::modifier_state_equals (ev->state, (Keyboard::Shift|Keyboard::Control))) { + if (Keyboard::modifier_state_equals (ev->state, (Keyboard::TertiaryModifier|Keyboard::PrimaryModifier))) { /* special case: select/deselect all tracks */ if (editor.get_selection().selected (this)) { @@ -1292,6 +1323,19 @@ RouteTimeAxisView::find_next_region (nframes_t pos, RegionPoint point, int32_t d return boost::shared_ptr<Region> (); } +nframes64_t +RouteTimeAxisView::find_next_region_boundary (nframes64_t pos, int32_t dir) +{ + boost::shared_ptr<Diskstream> stream; + boost::shared_ptr<Playlist> playlist; + + if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) { + return playlist->find_next_region_boundary (pos, dir); + } + + return -1; +} + bool RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) { @@ -1497,6 +1541,7 @@ RouteTimeAxisView::color_handler () timestretch_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeStretchFill.get(); } + reset_meter(); } void diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h index de89d54d94..294a0e73ff 100644 --- a/gtk2_ardour/route_time_axis.h +++ b/gtk2_ardour/route_time_axis.h @@ -40,6 +40,7 @@ #include "canvas.h" #include "level_meter.h" + namespace ARDOUR { class Session; class Region; @@ -83,6 +84,7 @@ public: void set_layer_display (LayerDisplay d); boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t pos, ARDOUR::RegionPoint, int32_t dir); + nframes64_t find_next_region_boundary (nframes64_t pos, int32_t dir); /* Editing operations */ bool cut_copy_clear (Selection&, Editing::CutCopyOp); diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index f9325f5d68..659d3a04fe 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -148,10 +148,10 @@ RouteUI::mute_press(GdkEventButton* ev) } else { if (ev->button == 2) { - // ctrl-button2 click is the midi binding click + // Primary-button2 click is the midi binding click // button2-click is "momentary" - if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control))) { + if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) { wait_for_release = true; } else { return false; @@ -160,9 +160,9 @@ RouteUI::mute_press(GdkEventButton* ev) if (ev->button == 1 || ev->button == 2) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { - /* ctrl-shift-click applies change to all routes */ + /* Primary-Tertiary-click applies change to all routes */ _session.begin_reversible_command (_("mute change")); Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand(_session, this); @@ -171,10 +171,10 @@ RouteUI::mute_press(GdkEventButton* ev) _session.add_command(cmd); _session.commit_reversible_command (); - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - /* ctrl-click applies change to the mix group. - ctrl-button2 is MIDI learn. + /* Primary-button1 applies change to the mix group. + NOTE: Primary-button2 is MIDI learn. */ if (ev->button == 1) { @@ -226,10 +226,10 @@ RouteUI::solo_press(GdkEventButton* ev) if (ev->button == 2) { - // ctrl-button2 click is the midi binding click + // Primary-button2 click is the midi binding click // button2-click is "momentary" - if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control))) { + if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) { wait_for_release = true; } else { return false; @@ -238,9 +238,9 @@ RouteUI::solo_press(GdkEventButton* ev) if (ev->button == 1 || ev->button == 2) { - if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { - /* ctrl-shift-click applies change to all routes */ + /* Primary-Tertiary-click applies change to all routes */ _session.begin_reversible_command (_("solo change")); Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this); @@ -249,9 +249,9 @@ RouteUI::solo_press(GdkEventButton* ev) _session.add_command (cmd); _session.commit_reversible_command (); - } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) { + } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) { - // ctrl-alt-click: exclusively solo this track, not a toggle */ + // Primary-Secondary-click: exclusively solo this track, not a toggle */ _session.begin_reversible_command (_("solo change")); Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand (_session, this); @@ -261,17 +261,17 @@ RouteUI::solo_press(GdkEventButton* ev) _session.add_command(cmd); _session.commit_reversible_command (); - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { // shift-click: set this route to solo safe _route->set_solo_safe (!_route->solo_safe(), this); wait_for_release = false; - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - /* ctrl-click: solo mix group. - ctrl-button2 is MIDI learn. + /* Primary-button1: solo mix group. + NOTE: Primary-button2 is MIDI learn. */ if (ev->button == 1) { @@ -281,7 +281,7 @@ RouteUI::solo_press(GdkEventButton* ev) } else { /* click: solo this route */ - + reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this); } } @@ -318,11 +318,12 @@ RouteUI::rec_enable_press(GdkEventButton* ev) if (!ignore_toggle && is_track() && rec_enable_button) { - if (ev->button == 2 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + if (ev->button == 2 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { // do nothing on midi bind event + return false; - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { _session.begin_reversible_command (_("rec-enable change")); Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this); @@ -337,7 +338,11 @@ RouteUI::rec_enable_press(GdkEventButton* ev) _session.add_command(cmd); _session.commit_reversible_command (); - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { + + /* Primary-button1 applies change to the mix group. + NOTE: Primary-button2 is MIDI learn. + */ set_mix_group_rec_enable (_route, !_route->record_enabled()); diff --git a/gtk2_ardour/selectable.h b/gtk2_ardour/selectable.h index 51fc5da027..ca316c6450 100644 --- a/gtk2_ardour/selectable.h +++ b/gtk2_ardour/selectable.h @@ -34,7 +34,6 @@ class Selectable : public virtual sigc::trackable virtual void set_selected (bool yn) { if (yn != _selected) { _selected = yn; - Selected (_selected); /* EMIT_SIGNAL */ } } @@ -42,9 +41,6 @@ class Selectable : public virtual sigc::trackable return _selected; } - /** Emitted when the selected status of this Selectable changes */ - sigc::signal<void, bool> Selected ; - protected: bool _selected; }; diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc index f1511c6ffa..fac18393af 100644 --- a/gtk2_ardour/selection.cc +++ b/gtk2_ardour/selection.cc @@ -296,12 +296,22 @@ Selection::add (TimeAxisView* track) } void +Selection::add (const RegionSelection& rs) +{ + if (!rs.empty()) { + regions.insert (regions.end(), rs.begin(), rs.end()); + RegionsChanged(); /* EMIT SIGNAL */ + } +} + +void Selection::add (RegionView* r) { if (find (regions.begin(), regions.end(), r) == regions.end()) { regions.add (r); - select_edit_group_regions (); - add (&r->get_trackview()); + if (Config->get_link_region_and_track_selection()) { + add (&r->get_trackview()); + } RegionsChanged (); } } @@ -314,7 +324,7 @@ Selection::add (vector<RegionView*>& v) for (vector<RegionView*>::iterator i = v.begin(); i != v.end(); ++i) { if (find (regions.begin(), regions.end(), (*i)) == regions.end()) { changed = regions.add ((*i)); - if (changed) { + if (Config->get_link_region_and_track_selection() && changed) { add (&(*i)->get_trackview()); } } @@ -438,7 +448,7 @@ Selection::remove (RegionView* r) RegionsChanged (); } - if (!regions.involves (r->get_trackview())) { + if (Config->get_link_region_and_track_selection() && !regions.involves (r->get_trackview())) { remove (&r->get_trackview()); } } @@ -505,20 +515,32 @@ Selection::set (const list<boost::shared_ptr<Playlist> >& pllist) } void -Selection::set (RegionView* r) +Selection::set (const RegionSelection& rs) +{ + clear_regions(); + regions = rs; + RegionsChanged(); /* EMIT SIGNAL */ +} + +void +Selection::set (RegionView* r, bool also_clear_tracks) { clear_regions (); - clear_tracks (); + if (also_clear_tracks) { + clear_tracks (); + } add (r); } void Selection::set (vector<RegionView*>& v) { - clear_tracks (); clear_regions (); - // make sure to deselect any automation selections - clear_points(); + if (Config->get_link_region_and_track_selection()) { + clear_tracks (); + // make sure to deselect any automation selections + clear_points(); + } add (v); } diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h index 2b2db77360..17862e127b 100644 --- a/gtk2_ardour/selection.h +++ b/gtk2_ardour/selection.h @@ -102,7 +102,7 @@ class Selection : public sigc::trackable void set (TimeAxisView*); void set (const std::list<TimeAxisView*>&); - void set (RegionView*); + void set (RegionView*, bool also_clear_tracks = true); void set (std::vector<RegionView*>&); long set (TimeAxisView*, nframes_t, nframes_t); void set (ARDOUR::AutomationList*); @@ -110,6 +110,7 @@ class Selection : public sigc::trackable void set (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&); void set (AutomationSelectable*); void set (Marker*); + void set (const RegionSelection&); void toggle (TimeAxisView*); void toggle (const std::list<TimeAxisView*>&); @@ -131,6 +132,7 @@ class Selection : public sigc::trackable void add (boost::shared_ptr<ARDOUR::Playlist>); void add (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&); void add (Marker*); + void add (const RegionSelection&); void remove (TimeAxisView*); void remove (const std::list<TimeAxisView*>&); diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index ae8209e9da..9bb0c75795 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -395,6 +395,11 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S found_search_btn (_("Search")) { + if (ARDOUR::Profile->get_sae()) { + chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops"); + chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files"); + } + VBox* vbox; HBox* hbox; diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index f6d6924a76..633e60e252 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -379,7 +379,6 @@ StreamView::set_selected_regionviews (RegionSelection& regions) { bool selected; - // cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl; for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { selected = false; @@ -389,8 +388,7 @@ StreamView::set_selected_regionviews (RegionSelection& regions) selected = true; } } - - // cerr << "\tregion " << (*i)->region().name() << " selected = " << selected << endl; + (*i)->set_selected (selected); } } diff --git a/gtk2_ardour/sync-menu.c b/gtk2_ardour/sync-menu.c index 229802b324..60dff79e07 100644 --- a/gtk2_ardour/sync-menu.c +++ b/gtk2_ardour/sync-menu.c @@ -311,30 +311,45 @@ carbon_menu_item_update_accelerator (CarbonMenuItem *carbon_item, GdkKeymap *keymap = gdk_keymap_get_for_display (display); GdkKeymapKey *keys; gint n_keys; + gint use_command; if (gdk_keymap_get_entries_for_keyval (keymap, key->accel_key, &keys, &n_keys)) { - UInt8 modifiers = 0; + UInt8 modifiers = 0; /* implies Command key */ SetMenuItemCommandKey (carbon_item->menu, carbon_item->index, true, keys[0].keycode); g_free (keys); + use_command = 0; + if (key->accel_mods) { - if (key->accel_mods & GDK_SHIFT_MASK) + if (key->accel_mods & GDK_SHIFT_MASK) { modifiers |= kMenuShiftModifier; + } - if (key->accel_mods & GDK_MOD1_MASK) + if (key->accel_mods & (GDK_MOD1_MASK)) { modifiers |= kMenuOptionModifier; - } - - if (!(key->accel_mods & GDK_CONTROL_MASK)) - { - modifiers |= kMenuNoCommandModifier; - } + } + + if (key->accel_mods & GDK_CONTROL_MASK) { + modifiers |= kMenuControlModifier; + } + + if (key->accel_mods & GDK_MOD5_MASK) { + /* Mod5 is what ardour's binding file uses to mean "Command" + Nothing needs to be set in modifiers, but we need to notice + that there *is* an implicit modifier + */ + use_command = 1; + } + } + + if (!use_command) + modifiers |= kMenuNoCommandModifier; SetMenuItemModifiers (carbon_item->menu, carbon_item->index, modifiers); diff --git a/gtk2_ardour/tape_region_view.cc b/gtk2_ardour/tape_region_view.cc index f46d1c05dc..2cb06af63d 100644 --- a/gtk2_ardour/tape_region_view.cc +++ b/gtk2_ardour/tape_region_view.cc @@ -96,5 +96,5 @@ void TapeAudioRegionView::set_frame_color () { fill_opacity = 255; - TimeAxisViewItem::set_frame_color (); + AudioRegionView::set_frame_color (); } diff --git a/gtk2_ardour/tempo_dialog.cc b/gtk2_ardour/tempo_dialog.cc index d69acf7ef1..61adb7c0fe 100644 --- a/gtk2_ardour/tempo_dialog.cc +++ b/gtk2_ardour/tempo_dialog.cc @@ -34,6 +34,7 @@ using namespace PBD; TempoDialog::TempoDialog (TempoMap& map, nframes_t frame, const string & action) : ArdourDialog (_("edit tempo")), + note_frame (_("BPM denominator")), bpm_adjustment (60.0, 1.0, 999.9, 0.1, 1.0, 1.0), bpm_spinner (bpm_adjustment), bpm_frame (_("Beats per minute")), @@ -48,7 +49,7 @@ TempoDialog::TempoDialog (TempoMap& map, nframes_t frame, const string & action) Tempo tempo (map.tempo_at (frame)); map.bbt_time (frame, when); - init (when, tempo.beats_per_minute(), true); + init (when, tempo.beats_per_minute(), tempo.note_type(), true); } TempoDialog::TempoDialog (TempoSection& section, const string & action) @@ -63,23 +64,62 @@ TempoDialog::TempoDialog (TempoSection& section, const string & action) when_table (2, 2), when_frame (_("Location")) { - init (section.start(), section.beats_per_minute(), section.movable()); + init (section.start(), section.beats_per_minute(), section.note_type(), section.movable()); } void -TempoDialog::init (const BBT_Time& when, double bpm, bool movable) +TempoDialog::init (const BBT_Time& when, double bpm, double note_type, bool movable) { bpm_spinner.set_numeric (true); - bpm_spinner.set_digits (1); + bpm_spinner.set_digits (2); bpm_spinner.set_wrap (true); bpm_spinner.set_value (bpm); + strings.push_back (_("whole (1)")); + strings.push_back (_("second (2)")); + strings.push_back (_("third (3)")); + strings.push_back (_("quarter (4)")); + strings.push_back (_("eighth (8)")); + strings.push_back (_("sixteenth (16)")); + strings.push_back (_("thirty-second (32)")); + + /* the string here needs to be the longest one to display */ + const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button + // TRANSLATORS: this is not a mis-spelling of "thirty", we're including a vertical + // descender to make sure the height gets computed properly. + Gtkmm2ext::set_size_request_to_display_given_text (note_types, "thirtq-second (32)", 7+FUDGE, 15); + + set_popdown_strings (note_types, strings); + + if (note_type==1.0f) + note_types.set_active_text (_("whole (1)")); + else if (note_type==2.0f) + note_types.set_active_text (_("second (2)")); + else if (note_type==3.0f) + note_types.set_active_text (_("third (3)")); + else if (note_type==4.0f) + note_types.set_active_text (_("quarter (4)")); + else if (note_type==8.0f) + note_types.set_active_text (_("eighth (8)")); + else if (note_type==16.0f) + note_types.set_active_text (_("sixteenth (16)")); + else if (note_type==32.0f) + note_types.set_active_text (_("thirty-second (32)")); + else + note_types.set_active_text (_("quarter (4)")); + hspacer1.set_border_width (5); hspacer1.pack_start (bpm_spinner, false, false); vspacer1.set_border_width (5); vspacer1.pack_start (hspacer1, false, false); + hspacer2.set_border_width (5); + hspacer2.pack_start (note_types, false, false); + vspacer2.set_border_width (5); + vspacer2.pack_start (hspacer2, false, false); + bpm_frame.add (vspacer1); + note_frame.add (vspacer2); if (movable) { snprintf (buf, sizeof (buf), "%" PRIu32, when.bars); @@ -115,9 +155,12 @@ TempoDialog::init (const BBT_Time& when, double bpm, bool movable) bpm_frame.set_name ("MetricDialogFrame"); bpm_spinner.set_name ("MetricEntry"); + note_frame.set_name ("MetricDialogFrame"); + get_vbox()->set_border_width (12); get_vbox()->pack_start (bpm_frame, false, false); - + get_vbox()->pack_start (note_frame, false, false); + add_button (Stock::CANCEL, RESPONSE_CANCEL); add_button (Stock::APPLY, RESPONSE_ACCEPT); set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); @@ -131,6 +174,7 @@ TempoDialog::init (const BBT_Time& when, double bpm, bool movable) bpm_spinner.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT)); bpm_spinner.signal_button_press_event().connect (mem_fun (*this, &TempoDialog::bpm_button_press), false); bpm_spinner.signal_button_release_event().connect (mem_fun (*this, &TempoDialog::bpm_button_release), false); + note_types.signal_changed().connect (mem_fun (*this, &TempoDialog::note_types_change)); } bool @@ -168,6 +212,41 @@ TempoDialog::get_bbt_time (BBT_Time& requested) return true; } +double +TempoDialog::get_note_type () +{ + double note_type = 0; + vector<string>::iterator i; + string text = note_types.get_active_text(); + + for (i = strings.begin(); i != strings.end(); ++i) { + if (text == *i) { + if (sscanf (text.c_str(), "%*[^0-9]%lf", ¬e_type) != 1) { + error << string_compose(_("garbaged note type entry (%1)"), text) << endmsg; + return 0; + } else { + break; + } + } + } + + if (i == strings.end()) { + if (sscanf (text.c_str(), "%lf", ¬e_type) != 1) { + error << string_compose(_("incomprehensible note type entry (%1)"), text) << endmsg; + return 0; + } + } + + cerr << "returning " << note_type << " based on " << text << endl; + return note_type; +} + +void +TempoDialog::note_types_change () +{ + set_response_sensitive (Gtk::RESPONSE_ACCEPT, true); +} + MeterDialog::MeterDialog (TempoMap& map, nframes_t frame, const string & action) : ArdourDialog ("meter dialog"), @@ -216,6 +295,13 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova strings.push_back (_("sixteenth (16)")); strings.push_back (_("thirty-second (32)")); + /* the string here needs to be the longest one to display */ + const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button + + // TRANSLATORS: this is not a mis-spelling of "thirty", we're including a vertical + // descender to make sure the height gets computed properly. + Gtkmm2ext::set_size_request_to_display_given_text (note_types, _("thirtq-second (32)"), 7+FUDGE, 15); + set_popdown_strings (note_types, strings); if (note_type==1.0f) @@ -235,10 +321,6 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova else note_types.set_active_text (_("quarter (4)")); - /* the string here needs to be the longest one to display */ - const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button - Gtkmm2ext::set_size_request_to_display_given_text (note_types, "thirty-second (32)", 7+FUDGE, 7); - hspacer1.set_border_width (5); hspacer1.pack_start (note_types, false, false); vspacer1.set_border_width (5); @@ -283,6 +365,8 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova get_vbox()->pack_start (when_frame, false, false); } + + get_vbox()->set_border_width (12); get_vbox()->pack_start (bpb_frame, false, false); get_vbox()->pack_start (note_frame, false, false); diff --git a/gtk2_ardour/tempo_dialog.h b/gtk2_ardour/tempo_dialog.h index b9f6a16b24..a92f26f8e3 100644 --- a/gtk2_ardour/tempo_dialog.h +++ b/gtk2_ardour/tempo_dialog.h @@ -37,6 +37,9 @@ struct TempoDialog : public ArdourDialog { + Gtk::ComboBoxText note_types; + vector<string> strings; + Gtk::Frame note_frame; Gtk::Adjustment bpm_adjustment; Gtk::SpinButton bpm_spinner; Gtk::Frame bpm_frame; @@ -44,8 +47,8 @@ struct TempoDialog : public ArdourDialog Gtk::Button ok_button; Gtk::Button cancel_button; Gtk::HBox button_box; - Gtk::HBox hspacer1; - Gtk::VBox vspacer1; + Gtk::HBox hspacer1, hspacer2; + Gtk::VBox vspacer1, vspacer2; Gtk::Entry when_bar_entry; Gtk::Entry when_beat_entry; Gtk::Label when_bar_label; @@ -58,13 +61,15 @@ struct TempoDialog : public ArdourDialog TempoDialog (ARDOUR::TempoSection&, const string & action); double get_bpm (); + double get_note_type (); bool get_bbt_time (ARDOUR::BBT_Time&); private: - void init (const ARDOUR::BBT_Time& start, double, bool); + void init (const ARDOUR::BBT_Time& start, double, double, bool); void bpm_changed (); bool bpm_button_press (GdkEventButton* ); bool bpm_button_release (GdkEventButton* ); + void note_types_change (); }; struct MeterDialog : public ArdourDialog diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index 4815aff0a0..5788daf19d 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -247,14 +247,14 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev) { switch (ev->direction) { case GDK_SCROLL_UP: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { step_height (true); return true; } break; case GDK_SCROLL_DOWN: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { step_height (false); return true; } @@ -364,11 +364,12 @@ TimeAxisView::set_height_pixels (uint32_t h) { height = h; controls_frame.set_size_request (-1, height + ((order == 0) ? 1 : 0)); - + //cerr << "TimeAxisView::set_height_pixels() called h = " << h << endl;//DEBUG if (canvas_item_visible (selection_group)) { /* resize the selection rect */ show_selection (editor.get_selection().time); } + } bool @@ -518,10 +519,7 @@ TimeAxisView::popup_display_menu (guint32 when) build_display_menu (); } - if (!get_selected()) { - editor.set_selected_track (*this, Selection::Set); - } - + editor.set_selected_track (*this, Selection::Add); display_menu->popup (1, when); } diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h index 4be3d4eabb..18d6638738 100644 --- a/gtk2_ardour/time_axis_view_item.h +++ b/gtk2_ardour/time_axis_view_item.h @@ -201,7 +201,7 @@ class TimeAxisViewItem : public Selectable */ void set_name_text(const Glib::ustring& new_name) ; - virtual void set_y_position_and_height(double y, double h); + virtual void set_y_position_and_height(double y, double h) ; /** * @@ -357,7 +357,7 @@ class TimeAxisViewItem : public Selectable /** * Sets the frame color depending on whether this item is selected */ - void set_frame_color() ; + virtual void set_frame_color() ; /** * Sets the colors of the start and end trim handle depending on object state diff --git a/gtk2_ardour/ui_config.cc b/gtk2_ardour/ui_config.cc index 34f176f73a..13db1f8803 100644 --- a/gtk2_ardour/ui_config.cc +++ b/gtk2_ardour/ui_config.cc @@ -235,8 +235,6 @@ UIConfiguration::pack_canvasvars () #define CANVAS_VARIABLE(var,name) canvas_colors.push_back(&var); #include "canvas_vars.h" #undef CANVAS_VARIABLE - cerr << "Configuration::pack_canvasvars () called, canvas_colors.size() = " << canvas_colors.size() << endl; - } diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 941132396a..a523878446 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -406,7 +406,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) GtkWidget* focus = gtk_window_get_focus (win); bool special_handling_of_unmodified_accelerators = false; -#undef DEBUG_ACCELERATOR_HANDLING +#undef DEBUG_ACCELERATOR_HANDLING #ifdef DEBUG_ACCELERATOR_HANDLING bool debug = (getenv ("ARDOUR_DEBUG_ACCELERATOR_HANDLING") != 0); #endif @@ -490,15 +490,14 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) return true; } } - - if (!special_handling_of_unmodified_accelerators || - ev->state & (Gdk::MOD1_MASK| - Gdk::MOD3_MASK| - Gdk::MOD4_MASK| - Gdk::MOD5_MASK| - Gdk::CONTROL_MASK)) { - /* no special handling or modifiers in effect: accelerate first */ + /* consider all relevant modifiers but not LOCK or SHIFT */ + + guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK)); + + if (!special_handling_of_unmodified_accelerators || (ev->state & mask)) { + + /* no special handling or there are modifiers in effect: accelerate first */ #ifdef DEBUG_ACCELERATOR_HANDLING if (debug) { @@ -511,12 +510,17 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) } #endif if (!gtk_window_activate_key (win, ev)) { +#ifdef DEBUG_ACCELERATOR_HANDLING + if (debug) { + cerr << "\tnot accelerated, now propagate\n"; + } +#endif return gtk_window_propagate_key_event (win, ev); } else { #ifdef DEBUG_ACCELERATOR_HANDLING - if (debug) { - cerr << "\tnot handled\n"; - } + if (debug) { + cerr << "\taccelerated - done.\n"; + } #endif return true; } @@ -588,11 +592,24 @@ get_icon (const char* cname) sys::path data_file_path; - if(!find_file_in_search_path (spath, name, data_file_path)) { + if (!find_file_in_search_path (spath, name, data_file_path)) { fatal << string_compose (_("cannot find icon image for %1"), name) << endmsg; } - return Gdk::Pixbuf::create_from_file (data_file_path.to_string()); + Glib::RefPtr<Gdk::Pixbuf> img; + try { + img = Gdk::Pixbuf::create_from_file (data_file_path.to_string()); + } + catch (const Gdk::PixbufError &e) + { + cerr << "Caught PixbufError: " << e.what() << endl; + } + catch (...) + { + g_message("Caught ... "); + } + + return img; } string diff --git a/gtk2_ardour/vst_pluginui.cc b/gtk2_ardour/vst_pluginui.cc index e1378dbb2a..5072c42a8e 100644 --- a/gtk2_ardour/vst_pluginui.cc +++ b/gtk2_ardour/vst_pluginui.cc @@ -58,6 +58,12 @@ VSTPluginUI::get_preferred_height () } int +VSTPluginUI::get_preferred_width () +{ + return vst->fst()->width; +} + +int VSTPluginUI::package (Gtk::Window& win) { /* forward configure events to plugin window */ diff --git a/gtk2_ardour/x11.cc b/gtk2_ardour/x11.cc index b5908341df..5c5d5c9ab2 100644 --- a/gtk2_ardour/x11.cc +++ b/gtk2_ardour/x11.cc @@ -4,3 +4,8 @@ void ARDOUR_UI::platform_specific () { } + +void +ARDOUR_UI::platform_setup () +{ +} diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index 6661ea16a2..6a05bb2295 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -129,7 +129,6 @@ sndfile_helpers.cc sndfilesource.cc source.cc source_factory.cc -stretch.cc tape_file_matcher.cc template_utils.cc tempo.cc @@ -145,6 +144,7 @@ vst_files = [ 'vst_plugin.cc', 'session_vst.cc' ] audiounit_files = [ 'audio_unit.cc' ] coreaudio_files = [ 'coreaudiosource.cc' ] extra_sources = [ ] +timefx_sources = [ ] if ardour['VST']: extra_sources += vst_files @@ -296,22 +296,28 @@ ardour.Merge ([ libraries['samplerate'], libraries['sigc2'], libraries['pbd'], - libraries['soundtouch'], libraries['midi++2'], libraries['glib2'], libraries['glibmm2'] ]) +#if ardour['RUBBERBAND']: +# ardour.Merge ([ libraries['rubberband'], libraries['vamp'], libraries['fftw3f'] ]) +# timefx_sources += [ 'rb_effect.cc' ] +#else: +ardour.Merge ([ libraries['soundtouch'] ]) +timefx_sources += [ 'st_stretch.cc', 'st_pitch.cc' ] + if ardour['LIBLO']: - ardour.Merge ([ libraries['lo'] ]) + ardour.Merge ([ libraries['lo'] ]) if ardour['COREAUDIO'] or ardour['AUDIOUNITS']: - ardour.Merge ([ libraries['appleutility'] ]) + ardour.Merge ([ libraries['appleutility'] ]) def SharedAsmObjectEmitter(target, source, env): - for tgt in target: - tgt.attributes.shared = 1 - return (target, source) + for tgt in target: + tgt.attributes.shared = 1 + return (target, source) env['BUILDERS']['SharedAsmObject'] = Builder (action = '$CXX -c -fPIC $SOURCE -o $TARGET', @@ -341,12 +347,12 @@ if env['FPU_OPTIMIZATION']: arch_specific_objects = env.SharedAsmObject('sse_functions_64bit.os', 'sse_functions_64bit.s') always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ] -libardour = ardour.SharedLibrary('ardour', ardour_files + always_sse_objects + extra_sources + arch_specific_objects) +libardour = ardour.SharedLibrary('ardour', ardour_files + always_sse_objects + timefx_sources + extra_sources + arch_specific_objects) Default(libardour) if env['NLS']: - i18n (ardour, ardour_files + vst_files + coreaudio_files + audiounit_files, env) + i18n (ardour, ardour_files + vst_files + coreaudio_files + timefx_sources + audiounit_files, env) env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libardour)) @@ -354,6 +360,8 @@ env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ar env.Alias('version', ardour.VersionBuild(['version.cc', 'ardour/version.h'], [])) env.Alias('tarball', env.Distribute (env['DISTTREE'], - [ 'SConscript', 'i18n.h', 'gettext.h', 'sse_functions_xmm.cc', 'sse_functions.s', 'sse_functions_64bit.s' ] + + [ 'SConscript', 'i18n.h', 'gettext.h' ] + + [ 'sse_functions_xmm.cc', 'sse_functions.s', 'sse_functions_64bit.s' ] + + [ 'rb_effect.cc', 'st_stretch.cc', 'st_pitch.cc' ] + ardour_files + osc_files + vst_files + coreaudio_files + audiounit_files + glob.glob('po/*.po') + glob.glob('ardour/*.h'))) diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h index 6e7b494441..fcec83394f 100644 --- a/libs/ardour/ardour/ardour.h +++ b/libs/ardour/ardour/ardour.h @@ -48,6 +48,8 @@ namespace ARDOUR { int cleanup (); std::string get_ardour_revision (); + + const layer_t max_layer = UCHAR_MAX; microseconds_t get_microseconds (); diff --git a/libs/ardour/ardour/audio_buffer.h b/libs/ardour/ardour/audio_buffer.h index 09bf5946fa..1f6c2f63bf 100644 --- a/libs/ardour/ardour/audio_buffer.h +++ b/libs/ardour/ardour/audio_buffer.h @@ -43,6 +43,7 @@ public: /** Read @a len frames FROM THE START OF @a src into self at @a offset */ void read_from(const Buffer& src, nframes_t len, nframes_t offset) { + assert(&src != this); assert(_capacity > 0); assert(src.type() == DataType::AUDIO); assert(offset + len <= _capacity); diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h index 7b31b1937f..b0e4d34c28 100644 --- a/libs/ardour/ardour/audio_unit.h +++ b/libs/ardour/ardour/audio_unit.h @@ -22,6 +22,7 @@ #define __ardour_audio_unit_h__ #include <stdint.h> +#include <boost/shared_ptr.hpp> #include <list> #include <set> @@ -30,6 +31,8 @@ #include <ardour/plugin.h> +#include <AudioUnit/AudioUnit.h> + #include <boost/shared_ptr.hpp> class CAComponent; @@ -45,13 +48,13 @@ class Session; class AUPlugin : public ARDOUR::Plugin { public: - AUPlugin (AudioEngine& engine, Session& session, CAComponent* comp); + AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp); virtual ~AUPlugin (); - uint32_t unique_id () const; + std::string unique_id () const; const char * label () const; const char * name () const { return _info->name.c_str(); } - const char * maker () const; + const char * maker () const { return _info->creator.c_str(); } uint32_t parameter_count () const; float default_value (uint32_t port); nframes_t signal_latency () const; @@ -87,34 +90,65 @@ class AUPlugin : public ARDOUR::Plugin bool has_editor () const; - CAAudioUnit* get_au () { return unit; } - CAComponent* get_comp () { return comp; } - + bool fixed_io() const { return false; } + int32_t can_support_input_configuration (int32_t in); + int32_t compute_output_streams (int32_t nplugins); + uint32_t output_streams() const; + uint32_t input_streams() const; + + boost::shared_ptr<CAAudioUnit> get_au () { return unit; } + boost::shared_ptr<CAComponent> get_comp () { return comp; } + + OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData); private: - CAComponent* comp; - CAAudioUnit* unit; - - AudioBufferList* in_list; - AudioBufferList* out_list; + boost::shared_ptr<CAComponent> comp; + boost::shared_ptr<CAAudioUnit> unit; + + AudioStreamBasicDescription streamFormat; + bool initialized; + int format_set; + AudioBufferList* buffers; + + UInt32 global_elements; + UInt32 output_elements; + UInt32 input_elements; + + int set_output_format (); + int set_input_format (); + int set_stream_format (int scope, uint32_t cnt); + int _set_block_size (nframes_t nframes); std::vector<std::pair<uint32_t, uint32_t> > parameter_map; + uint32_t current_maxbuf; + nframes_t current_offset; + nframes_t cb_offset; + vector<Sample*>* current_buffers; + nframes_t frames_processed; }; - + typedef boost::shared_ptr<AUPlugin> AUPluginPtr; class AUPluginInfo : public PluginInfo { public: - AUPluginInfo () { }; + AUPluginInfo (boost::shared_ptr<CAComponentDescription>); ~AUPluginInfo (); - CAComponentDescription* desc; + PluginPtr load (Session& session); static PluginInfoList discover (); - PluginPtr load (Session& session); + static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker); + static std::string stringify_descriptor (const CAComponentDescription&); private: - static std::string get_name (CAComponentDescription&); - void setup_nchannels (CAComponentDescription&); + boost::shared_ptr<CAComponentDescription> descriptor; + + static void discover_music (PluginInfoList&); + static void discover_fx (PluginInfoList&); + static void discover_by_description (PluginInfoList&, CAComponentDescription&); }; typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr; diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index dc7ae8e000..88f1111a6c 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -106,7 +106,13 @@ class AudioEngine : public sigc::trackable class PortRegistrationFailure : public std::exception { public: - virtual const char *what() const throw() { return "failed port registration"; } + PortRegistrationFailure (const char* why = "") { + reason = why; + } + virtual const char *what() const throw() { return reason; } + + private: + const char* reason; }; class NoBackendAvailable : public std::exception { @@ -235,6 +241,8 @@ class AudioEngine : public sigc::trackable std::string get_nth_physical (DataType type, uint32_t n, int flags); + void port_registration_failure (const std::string& portname); + static int _xrun_callback (void *arg); static int _graph_order_callback (void *arg); static int _process_callback (nframes_t nframes, void *arg); diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index ba2bbaee22..b84d197c3f 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -76,8 +76,10 @@ class AudioRegion : public Region uint32_t chan_n=0, double samples_per_unit= 1.0) const; virtual nframes_t read_at (Sample *buf, Sample *mixdown_buf, - float *gain_buf, nframes_t position, nframes_t cnt, - uint32_t chan_n = 0) const; + float *gain_buf, nframes_t position, nframes_t cnt, + uint32_t chan_n = 0, + nframes_t read_frames = 0, + nframes_t skip_frames = 0) const; virtual nframes_t master_read_at (Sample *buf, Sample *mixdown_buf, float *gain_buf, @@ -146,8 +148,10 @@ class AudioRegion : public Region void recompute_gain_at_start (); nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, nframes_t position, nframes_t cnt, - uint32_t chan_n = 0) const; + float *gain_buffer, nframes_t position, nframes_t cnt, + uint32_t chan_n = 0, + nframes_t read_frames = 0, + nframes_t skip_frames = 0) const; void recompute_at_start (); void recompute_at_end (); @@ -174,13 +178,6 @@ class AudioRegion : public Region AudioRegion (boost::shared_ptr<const AudioRegion>); int set_live_state (const XMLNode&, Change&, bool send); - - virtual bool verify_start (nframes_t); - virtual bool verify_start_and_length (nframes_t, nframes_t); - virtual bool verify_start_mutable (nframes_t&_start); - virtual bool verify_length (nframes_t); - /*virtual void recompute_at_start () = 0; - virtual void recompute_at_end () = 0;*/ }; } /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index f02b28d9f5..93708a5b07 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -43,9 +43,7 @@ using std::vector; namespace ARDOUR { -const nframes_t frames_per_peak = 256; - - class AudioSource : public Source, public boost::enable_shared_from_this<ARDOUR::AudioSource> +class AudioSource : public Source, public boost::enable_shared_from_this<ARDOUR::AudioSource> { public: AudioSource (Session&, Glib::ustring name); @@ -72,7 +70,8 @@ const nframes_t frames_per_peak = 256; uint32_t read_data_count() const { return _read_data_count; } uint32_t write_data_count() const { return _write_data_count; } - virtual int read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit) const; + int read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const; + int build_peaks (); bool peaks_ready (sigc::slot<void>, sigc::connection&) const; @@ -129,6 +128,12 @@ const nframes_t frames_per_peak = 256; void update_length (nframes_t pos, nframes_t cnt); + virtual int read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, + double samples_per_visual_peak, nframes_t fpp) const; + + int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, + bool intermediate_peaks_ready_signal, nframes_t frames_per_peak); + private: int peakfile; nframes_t peak_leftover_cnt; diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index edae45a56a..aa27a3ef24 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -72,6 +72,8 @@ CONFIG_VARIABLE (uint32_t, destructive_xfade_msecs, "destructive-xfade-msecs", CONFIG_VARIABLE (EditMode, edit_mode, "edit-mode", Slide) CONFIG_VARIABLE (LayerModel, layer_model, "layer-model", MoveAddHigher) +CONFIG_VARIABLE (bool, link_region_and_track_selection, "link-region-and-track-selection", false) +CONFIG_VARIABLE (std::string, keyboard_layout_name, "keyboard-layout-name", "ansi") /* monitoring, mute, solo etc */ @@ -148,6 +150,8 @@ CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-bac CONFIG_VARIABLE (float, automation_interval, "automation-interval", 50) CONFIG_VARIABLE (bool, sync_all_route_ordering, "sync-all-route-ordering", true) CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", true) +CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi") +CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour") /* denormal management */ diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h index 78a137bde3..9ba3689e82 100644 --- a/libs/ardour/ardour/crossfade.h +++ b/libs/ardour/ardour/crossfade.h @@ -81,8 +81,10 @@ class Crossfade : public ARDOUR::AudioRegion boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; } nframes_t read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, nframes_t position, nframes_t cnt, - uint32_t chan_n) const; + float *gain_buffer, nframes_t position, nframes_t cnt, + uint32_t chan_n, + nframes_t read_frames = 0, + nframes_t skip_frames = 0) const; bool refresh (); diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h index e466e53215..7c0b0b2abe 100644 --- a/libs/ardour/ardour/ladspa_plugin.h +++ b/libs/ardour/ardour/ladspa_plugin.h @@ -53,7 +53,7 @@ class LadspaPlugin : public ARDOUR::Plugin /* Plugin interface */ - uint32_t unique_id() const { return descriptor->UniqueID; } + std::string unique_id() const; const char * label() const { return descriptor->Label; } const char * name() const { return descriptor->Name; } const char * maker() const { return descriptor->Maker; } diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index 5ffb716598..53d9489823 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -146,6 +146,8 @@ class Locations : public PBD::StatefulDestructible Locations (); ~Locations (); + const LocationList& list() { return locations; } + void add (Location *, bool make_current = false); void remove (Location *); void clear (); diff --git a/libs/ardour/ardour/pitch.h b/libs/ardour/ardour/pitch.h new file mode 100644 index 0000000000..38d8380f5d --- /dev/null +++ b/libs/ardour/ardour/pitch.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __ardour_pitch_h__ +#define __ardour_pitch_h__ + +#include <ardour/filter.h> + +namespace ARDOUR { + class AudioRegion; +} + +#ifdef USE_RUBBERBAND + +#include <ardour/rb_effect.h> + +namespace ARDOUR { + +class Pitch : public RBEffect { + public: + Pitch (ARDOUR::Session&, TimeFXRequest&); + ~Pitch () {} +}; + +} /* namespace */ + +# else + +namespace ARDOUR { + +class Pitch : public Filter { + public: + Pitch (ARDOUR::Session&, TimeFXRequest&); + ~Pitch () {} + + int run (boost::shared_ptr<ARDOUR::Region>); + + private: + TimeFXRequest& tsr; +}; + +} /* namespace */ + +#endif + +#endif /* __ardour_pitch_h__ */ diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index f2e07aa067..3f328de005 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -95,6 +95,7 @@ class Playlist : public SessionObject, public boost::enable_shared_from_this<Pla void partition (nframes_t start, nframes_t end, bool just_top_level); void duplicate (boost::shared_ptr<Region>, nframes_t position, float times); void nudge_after (nframes_t start, nframes_t distance, bool forwards); + void shuffle (boost::shared_ptr<Region>, int dir); boost::shared_ptr<Playlist> cut (list<AudioRange>&, bool result_is_hidden = true); boost::shared_ptr<Playlist> copy (list<AudioRange>&, bool result_is_hidden = true); @@ -102,9 +103,12 @@ class Playlist : public SessionObject, public boost::enable_shared_from_this<Pla RegionList* regions_at (nframes_t frame); RegionList* regions_touched (nframes_t start, nframes_t end); + RegionList* regions_to_read (nframes_t start, nframes_t end); boost::shared_ptr<Region> find_region (const PBD::ID&) const; boost::shared_ptr<Region> top_region_at (nframes_t frame); boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir); + nframes64_t find_next_region_boundary (nframes64_t frame, int dir); + bool region_is_shuffle_constrained (boost::shared_ptr<Region>); template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg); template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>)); @@ -124,6 +128,8 @@ class Playlist : public SessionObject, public boost::enable_shared_from_this<Pla void freeze (); void thaw (); + void raise_region (boost::shared_ptr<Region>); + void lower_region (boost::shared_ptr<Region>); void raise_region_to_top (boost::shared_ptr<Region>); void lower_region_to_bottom (boost::shared_ptr<Region>); @@ -182,6 +188,7 @@ class Playlist : public SessionObject, public boost::enable_shared_from_this<Pla bool first_set_state; bool _hidden; bool _splicing; + bool _shuffling; bool _nudging; uint32_t _refcnt; EditMode _edit_mode; @@ -227,12 +234,12 @@ class Playlist : public SessionObject, public boost::enable_shared_from_this<Pla void sort_regions (); - void possibly_splice (); - void possibly_splice_unlocked(); - void core_splice (); - void splice_locked (); - void splice_unlocked (); + void possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>()); + void possibly_splice_unlocked(nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>()); + void core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude); + void splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude); + void splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude); virtual void finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right) {} @@ -258,6 +265,7 @@ class Playlist : public SessionObject, public boost::enable_shared_from_this<Pla boost::shared_ptr<Playlist> cut (nframes_t start, nframes_t cnt, bool result_is_hidden); boost::shared_ptr<Playlist> copy (nframes_t start, nframes_t cnt, bool result_is_hidden); + int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir); void relayer (); void unset_freeze_parent (Playlist*); diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 830ed7c025..d721476db7 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -77,7 +77,7 @@ class PluginInfo { ChanCount n_outputs; ARDOUR::PluginType type; - long unique_id; + std::string unique_id; virtual PluginPtr load (Session& session) = 0; @@ -114,7 +114,7 @@ class Plugin : public PBD::StatefulDestructible, public Latent bool max_unbound; }; - virtual uint32_t unique_id() const = 0; + virtual std::string unique_id() const = 0; virtual const char * label() const = 0; virtual const char * name() const = 0; virtual const char * maker() const = 0; @@ -170,7 +170,7 @@ class Plugin : public PBD::StatefulDestructible, public Latent bool save_preset(string name, string domain /* vst, ladspa etc. */); }; -PluginPtr find_plugin(ARDOUR::Session&, string name, long unique_id, ARDOUR::PluginType); +PluginPtr find_plugin(ARDOUR::Session&, string unique_id, ARDOUR::PluginType); } // namespace ARDOUR diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h index bce723d857..64b871104b 100644 --- a/libs/ardour/ardour/plugin_manager.h +++ b/libs/ardour/ardour/plugin_manager.h @@ -40,6 +40,7 @@ class PluginManager { ARDOUR::PluginInfoList &vst_plugin_info () { return _vst_plugin_info; } ARDOUR::PluginInfoList &ladspa_plugin_info () { return _ladspa_plugin_info; } + ARDOUR::PluginInfoList &au_plugin_info () { return _au_plugin_info; } void refresh (); @@ -51,6 +52,8 @@ class PluginManager { private: ARDOUR::PluginInfoList _vst_plugin_info; ARDOUR::PluginInfoList _ladspa_plugin_info; + ARDOUR::PluginInfoList _au_plugin_info; + std::map<uint32_t, std::string> rdf_type; std::string ladspa_path; @@ -64,6 +67,9 @@ class PluginManager { void add_vst_presets (); void add_presets (std::string domain); + int au_discover (); + void au_refresh (); + int vst_discover_from_path (std::string path); int vst_discover (std::string path); @@ -71,6 +77,7 @@ class PluginManager { int ladspa_discover (std::string path); std::string get_ladspa_category (uint32_t id); + std::vector<uint32_t> ladspa_plugin_whitelist; static PluginManager* _manager; // singleton }; diff --git a/libs/ardour/ardour/rb_effect.h b/libs/ardour/ardour/rb_effect.h new file mode 100644 index 0000000000..bde0422335 --- /dev/null +++ b/libs/ardour/ardour/rb_effect.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __ardour_rbeffect_h__ +#define __ardour_rbeffect_h__ + +#include <ardour/audiofilter.h> + +namespace ARDOUR { + +class AudioRegion; + +class RBEffect : public Filter { + public: + RBEffect (ARDOUR::Session&, TimeFXRequest&); + ~RBEffect (); + + int run (boost::shared_ptr<ARDOUR::Region>); + + private: + TimeFXRequest& tsr; +}; + +} /* namespace */ + +#endif /* __ardour_rbeffect_h__ */ diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index c246da9cce..76b41a04cb 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -96,11 +96,17 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region> nframes_t length() const { return _length; } layer_t layer () const { return _layer; } + /* these two are valid ONLY during a StateChanged signal handler */ + + nframes_t last_position() const { return _last_position; } + nframes_t last_length() const { return _last_length; } + nframes64_t ancestral_start () const { return _ancestral_start; } nframes64_t ancestral_length () const { return _ancestral_length; } float stretch() const { return _stretch; } + float shift() const { return _shift; } - void set_ancestral_data (nframes64_t start, nframes64_t length, float stretch); + void set_ancestral_data (nframes64_t start, nframes64_t length, float stretch, float shift); nframes_t sync_offset(int& dir) const; nframes_t sync_position() const; @@ -129,7 +135,7 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region> void thaw (const string& why); bool covers (nframes_t frame) const { - return first_frame() <= frame && frame < last_frame(); + return first_frame() <= frame && frame <= last_frame(); } OverlapType coverage (nframes_t start, nframes_t end) const { @@ -149,7 +155,7 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region> void set_position (nframes_t, void *src); void set_position_on_top (nframes_t, void *src); void special_set_position (nframes_t); - void nudge_position (long, void *src); + void nudge_position (nframes64_t, void *src); bool at_natural_position () const; void move_to_natural_position (void *src); @@ -160,6 +166,8 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region> void trim_to (nframes_t position, nframes_t length, void *src); void set_layer (layer_t l); /* ONLY Playlist can call this */ + void raise (); + void lower (); void raise_to_top (); void lower_to_bottom (); @@ -232,10 +240,11 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region> void maybe_uncopy (); void first_edit (); - virtual bool verify_start (nframes_t); - virtual bool verify_start_and_length (nframes_t, nframes_t); - virtual bool verify_start_mutable (nframes_t&_start); - virtual bool verify_length (nframes_t); + bool verify_start (nframes_t); + bool verify_start_and_length (nframes_t, nframes_t&); + bool verify_start_mutable (nframes_t&_start); + bool verify_length (nframes_t); + virtual void recompute_at_start () = 0; virtual void recompute_at_end () = 0; @@ -243,7 +252,9 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region> Flag _flags; nframes_t _start; nframes_t _length; + nframes_t _last_length; nframes_t _position; + nframes_t _last_position; nframes_t _sync_position; layer_t _layer; mutable RegionEditState _first_edit; @@ -251,6 +262,7 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region> nframes64_t _ancestral_start; nframes64_t _ancestral_length; float _stretch; + float _shift; mutable uint32_t _read_data_count; ///< modified in read() Change _pending_changed; uint64_t _last_layer_op; ///< timestamp diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index fc17af06ee..d2e40501f1 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -109,7 +109,7 @@ class Route : public IO void set_gain (gain_t val, void *src); void inc_gain (gain_t delta, void *src); - + bool active() const { return _active; } void set_active (bool yn); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index d0add4e2aa..90a9563ad1 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -138,6 +138,7 @@ class Session : public PBD::StatefulDestructible SetDiskstreamSpeed, Locate, LocateRoll, + LocateRollLocate, SetLoop, PunchIn, PunchOut, @@ -224,9 +225,9 @@ class Session : public PBD::StatefulDestructible /* creating from an XML file */ Session (AudioEngine&, - string fullpath, - string snapshot_name, - string* mix_template = 0); + const string& fullpath, + const string& snapshot_name, + string mix_template = ""); /* creating a new Session */ @@ -354,7 +355,7 @@ class Session : public PBD::StatefulDestructible sigc::signal<void,RouteList&> RouteAdded; - void request_roll (); + void request_roll_at_and_return (nframes_t start, nframes_t return_to); void request_bounded_roll (nframes_t start, nframes_t end); void request_stop (bool abort = false); void request_locate (nframes_t frame, bool with_roll = false); @@ -499,6 +500,7 @@ class Session : public PBD::StatefulDestructible nframes_t transport_frame () const {return _transport_frame; } nframes_t audible_frame () const; + nframes64_t requested_return_frame() const { return _requested_return_frame; } enum PullupFormat { pullup_Plus4Plus1, @@ -542,6 +544,9 @@ class Session : public PBD::StatefulDestructible float transport_speed() const { return _transport_speed; } bool transport_stopped() const { return _transport_speed == 0.0f; } bool transport_rolling() const { return _transport_speed != 0.0f; } + + void set_silent (bool yn); + bool silent () { return _silent; } int jack_slave_sync (nframes_t); @@ -701,6 +706,13 @@ class Session : public PBD::StatefulDestructible uint32_t n_port_inserts() const { return _port_inserts.size(); } uint32_t n_plugin_inserts() const { return _plugin_inserts.size(); } uint32_t n_sends() const { return _sends.size(); } + + static void set_disable_all_loaded_plugins (bool yn) { + _disable_all_loaded_plugins = yn; + } + static bool get_disable_all_loaded_plugins() { + return _disable_all_loaded_plugins; + } uint32_t next_send_id(); uint32_t next_insert_id(); @@ -901,6 +913,18 @@ class Session : public PBD::StatefulDestructible long value, void* ptr, float opt); + + typedef float (*compute_peak_t) (Sample *, nframes_t, float); + typedef void (*find_peaks_t) (Sample *, nframes_t, float *, float*); + typedef void (*apply_gain_to_buffer_t) (Sample *, nframes_t, float); + typedef void (*mix_buffers_with_gain_t) (Sample *, Sample *, nframes_t, float); + typedef void (*mix_buffers_no_gain_t) (Sample *, Sample *, nframes_t); + + static compute_peak_t compute_peak; + static find_peaks_t find_peaks; + static apply_gain_to_buffer_t apply_gain_to_buffer; + static mix_buffers_with_gain_t mix_buffers_with_gain; + static mix_buffers_no_gain_t mix_buffers_no_gain; static sigc::signal<void> SendFeedback; @@ -927,12 +951,9 @@ class Session : public PBD::StatefulDestructible void update_latency_compensation (bool, bool); private: + int create (bool& new_session, const string& mix_template, nframes_t initial_length); void destroy (); - - void initialize_start_and_end_locations(nframes_t start, nframes_t end); - bool create_session_file(); - bool create_session_file_from_template (const string& template_path); - + nframes_t compute_initial_length (); enum SubState { @@ -949,35 +970,36 @@ class Session : public PBD::StatefulDestructible */ typedef void (Session::*process_function_type)(nframes_t); - - AudioEngine &_engine; - mutable gint processing_prohibited; - /// the function called when the main JACK process callback happens + + AudioEngine& _engine; + mutable gint processing_prohibited; process_function_type process_function; process_function_type last_process_function; bool waiting_for_sync_offset; - nframes_t _base_frame_rate; - nframes_t _current_frame_rate; //this includes video pullup offset + nframes_t _base_frame_rate; + nframes_t _current_frame_rate; //this includes video pullup offset int transport_sub_state; - mutable gint _record_status; - nframes_t _transport_frame; + mutable gint _record_status; + volatile nframes_t _transport_frame; Location* end_location; Location* start_location; - Slave *_slave; + Slave* _slave; + bool _silent; volatile float _transport_speed; volatile float _desired_transport_speed; float _last_transport_speed; bool auto_play_legal; - nframes_t _last_slave_transport_frame; - nframes_t maximum_output_latency; - nframes_t last_stop_frame; + nframes_t _last_slave_transport_frame; + nframes_t maximum_output_latency; + nframes_t last_stop_frame; + volatile nframes64_t _requested_return_frame; BufferSet* _scratch_buffers; BufferSet* _silent_buffers; BufferSet* _mix_buffers; - nframes_t current_block_size; - nframes_t _worst_output_latency; - nframes_t _worst_input_latency; - nframes_t _worst_track_latency; + nframes_t current_block_size; + nframes_t _worst_output_latency; + nframes_t _worst_input_latency; + nframes_t _worst_track_latency; bool _have_captured; float _meter_hold; float _meter_falloff; @@ -1675,6 +1697,8 @@ class Session : public PBD::StatefulDestructible void set_history_depth (uint32_t depth); void sync_order_keys (); + + static bool _disable_all_loaded_plugins; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/silentfilesource.h b/libs/ardour/ardour/silentfilesource.h index 92ef076a9b..e0103185c2 100644 --- a/libs/ardour/ardour/silentfilesource.h +++ b/libs/ardour/ardour/silentfilesource.h @@ -34,11 +34,6 @@ class SilentFileSource : public AudioFileSource { void set_length (nframes_t len); - int read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit) const { - memset (peaks, 0, sizeof (PeakData) * npeaks); - return 0; - } - bool destructive() const { return false; } protected: @@ -58,6 +53,11 @@ class SilentFileSource : public AudioFileSource { void set_header_timeline_position () {} + int read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit, nframes_t fpp) const { + memset (peaks, 0, sizeof (PeakData) * npeaks); + return 0; + } + }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index 73b66ca20e..509f8fa9d2 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -47,6 +47,7 @@ class Slave { virtual bool starting() const { return false; } virtual nframes_t resolution() const = 0; virtual bool requires_seekahead () const = 0; + virtual bool is_always_synced() const { return false; } }; @@ -139,6 +140,7 @@ class JACK_Slave : public Slave nframes_t resolution() const { return 1; } bool requires_seekahead () const { return false; } void reset_client (jack_client_t* jack); + bool is_always_synced() const { return true; } private: jack_client_t* jack; diff --git a/libs/ardour/ardour/sndfile_helpers.h b/libs/ardour/ardour/sndfile_helpers.h index 26a93ad124..cf6b15f3a4 100644 --- a/libs/ardour/ardour/sndfile_helpers.h +++ b/libs/ardour/ardour/sndfile_helpers.h @@ -28,7 +28,7 @@ using std::string; // Use this define when initializing arrarys for use in sndfile_*_format() #define SNDFILE_STR_LENGTH 32 -#define SNDFILE_HEADER_FORMATS 7 +#define SNDFILE_HEADER_FORMATS 5 extern const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1]; extern const char * const sndfile_file_endings_strings[SNDFILE_HEADER_FORMATS+1]; diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index 6f323dd878..869111bb07 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -63,6 +63,8 @@ class Source : public SessionObject XMLNode& get_state (); int set_state (const XMLNode&); + virtual bool destructive() const { return false; } + void use () { _in_use++; } void disuse () { if (_in_use) { _in_use--; } } diff --git a/libs/ardour/ardour/stretch.h b/libs/ardour/ardour/stretch.h index 4d00c9b17b..020d03270d 100644 --- a/libs/ardour/ardour/stretch.h +++ b/libs/ardour/ardour/stretch.h @@ -21,31 +21,46 @@ #define __ardour_stretch_h__ #include <ardour/filter.h> -#include <soundtouch/SoundTouch.h> namespace ARDOUR { + class AudioRegion; +} + +#ifdef USE_RUBBERBAND -class AudioRegion; +#include <ardour/rb_effect.h> + +namespace ARDOUR { -struct TimeStretchRequest : public InterThreadInfo { - float fraction; - bool quick_seek; - bool antialias; +class Stretch : public RBEffect { + public: + Stretch (ARDOUR::Session&, TimeFXRequest&); + ~Stretch() {} }; +} /* namespace */ + +#else + +#include <soundtouch/SoundTouch.h> + +namespace ARDOUR { + class Stretch : public Filter { public: - Stretch (ARDOUR::Session&, TimeStretchRequest&); + Stretch (ARDOUR::Session&, TimeFXRequest&); ~Stretch (); int run (boost::shared_ptr<ARDOUR::Region>); private: - TimeStretchRequest& tsr; - soundtouch::SoundTouch st; + TimeFXRequest& tsr; + soundtouch::SoundTouch st; }; } /* namespace */ +#endif + #endif /* __ardour_stretch_h__ */ diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 2d8462a751..72f24c1054 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -40,27 +40,29 @@ using std::list; using std::vector; namespace ARDOUR { - +class Meter; class Tempo { public: - Tempo (double bpm) - : _beats_per_minute (bpm) {} + Tempo (double bpm, double type=4.0) // defaulting to quarter note + : _beats_per_minute (bpm), _note_type(type) {} Tempo (const Tempo& other) { _beats_per_minute = other._beats_per_minute; + _note_type = other._note_type; } void operator= (const Tempo& other) { if (&other != this) { _beats_per_minute = other._beats_per_minute; + _note_type = other._note_type; } } - double beats_per_minute () const { return _beats_per_minute; } - double frames_per_beat (nframes_t sr) const { - return ((60.0 * sr) / _beats_per_minute); - } + double beats_per_minute () const { return _beats_per_minute;} + double note_type () const { return _note_type;} + double frames_per_beat (nframes_t sr, const Meter& meter) const; protected: double _beats_per_minute; + double _note_type; }; class Meter { @@ -149,8 +151,8 @@ class MeterSection : public MetricSection, public Meter { class TempoSection : public MetricSection, public Tempo { public: - TempoSection (const BBT_Time& start, double qpm) - : MetricSection (start), Tempo (qpm) {} + TempoSection (const BBT_Time& start, double qpm, double note_type) + : MetricSection (start), Tempo (qpm, note_type) {} TempoSection (const XMLNode&); static const string xml_state_node_name; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 0d32d35c7d..d7961babbd 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -379,6 +379,13 @@ namespace ARDOUR { SrcFastest }; + struct TimeFXRequest : public InterThreadInfo { + float time_fraction; + float pitch_fraction; + bool quick_seek; + bool antialias; + }; + } // namespace ARDOUR std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf); diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h index 1622df0c1a..3a05360f15 100644 --- a/libs/ardour/ardour/vst_plugin.h +++ b/libs/ardour/ardour/vst_plugin.h @@ -56,7 +56,7 @@ class VSTPlugin : public ARDOUR::Plugin /* Plugin interface */ - uint32_t unique_id() const; + std::string unique_id() const; const char * label() const; const char * name() const; const char * maker() const; diff --git a/libs/ardour/audio_buffer.cc b/libs/ardour/audio_buffer.cc index 4871035e80..8444304832 100644 --- a/libs/ardour/audio_buffer.cc +++ b/libs/ardour/audio_buffer.cc @@ -32,7 +32,7 @@ AudioBuffer::AudioBuffer(size_t capacity) , _owns_data (false) , _data (0) { - if (_capacity) { + if (_capacity > 0) { _owns_data = true; // prevent resize() from gagging resize (_capacity); silence (_capacity); diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index bc42cb0b5b..bc4a352c45 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -850,10 +850,18 @@ AudioDiskstream::commit (nframes_t nframes) } if (_slaved) { - need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2; + /*if (_io && _io->active()) {*/ + need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2; + /*} else { + need_butler = false; + }*/ } else { - need_butler = c->front()->playback_buf->write_space() >= disk_io_chunk_frames - || c->front()->capture_buf->read_space() >= disk_io_chunk_frames; + /*if (_io && _io->active()) {*/ + need_butler = c->front()->playback_buf->write_space() >= disk_io_chunk_frames + || c->front()->capture_buf->read_space() >= disk_io_chunk_frames; + /*} else { + need_butler = c->front()->capture_buf->read_space() >= disk_io_chunk_frames; + }*/ } if (commit_should_unlock) { @@ -1940,6 +1948,7 @@ AudioDiskstream::set_state (const XMLNode& node) if (nchans > _n_channels.n_audio()) { add_channel (nchans - _n_channels.n_audio()); + IO::PortCountChanged(_n_channels); } else if (nchans < _n_channels.n_audio()) { diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index 0631c9121b..1506d204f1 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -123,7 +123,10 @@ ARDOUR::nframes_t AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t start, nframes_t cnt, unsigned chan_n) { + nframes_t ret = cnt; nframes_t end; + nframes_t read_frames; + nframes_t skip_frames; /* optimizing this memset() away involves a lot of conditionals that may well cause more of a hit due to cache misses @@ -147,14 +150,24 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf Glib::Mutex::Lock rm (region_lock); end = start + cnt - 1; + read_frames = 0; + skip_frames = 0; + _read_data_count = 0; _read_data_count = 0; + RegionList* rlist = regions_to_read (start, start+cnt); + + if (rlist->empty()) { + delete rlist; + return cnt; + } + map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions; map<uint32_t,vector<boost::shared_ptr<Crossfade> > > relevant_xfades; vector<uint32_t> relevant_layers; - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + for (RegionList::iterator i = rlist->begin(); i != rlist->end(); ++i) { if ((*i)->coverage (start, end) != OverlapNone) { relevant_regions[(*i)->layer()].push_back (*i); relevant_layers.push_back ((*i)->layer()); @@ -186,7 +199,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) { boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i); assert(ar); - ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n); + ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames); _read_data_count += ar->read_data_count(); } @@ -199,7 +212,8 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf } } - return cnt; + delete rlist; + return ret; } diff --git a/libs/ardour/audio_port.cc b/libs/ardour/audio_port.cc index 66d31c63fe..714be28f34 100644 --- a/libs/ardour/audio_port.cc +++ b/libs/ardour/audio_port.cc @@ -25,10 +25,10 @@ using namespace ARDOUR; using namespace std; -AudioPort::AudioPort (const std::string& name, Flags flgs, bool external, nframes_t capacity) - : Port (name, flgs) - , BaseAudioPort (name, flgs) - , PortFacade (name, flgs) +AudioPort::AudioPort (const std::string& name, Flags flags, bool external, nframes_t capacity) + : Port (name, flags) + , BaseAudioPort (name, flags) + , PortFacade (name, flags) { if (!external || receives_input()) { @@ -43,6 +43,7 @@ AudioPort::AudioPort (const std::string& name, Flags flgs, bool external, nframe if (!external) { _ext_port = 0; + set_name (name); } else { @@ -52,7 +53,7 @@ AudioPort::AudioPort (const std::string& name, Flags flgs, bool external, nframe will in turn be using the JACK port buffer for data. */ - _ext_port = new JackAudioPort (name, flgs, 0); + _ext_port = new JackAudioPort (name, flags, 0); if (sends_output()) { _buffer = &dynamic_cast<JackAudioPort*>(_ext_port)->get_audio_buffer(); diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index dfcffb8cfe..f86e784169 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -1,6 +1,5 @@ /* Copyright (C) 2006 Paul Davis - Written by Taybin Rutkin 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 @@ -18,10 +17,16 @@ */ +#include <sstream> + #include <pbd/transmitter.h> #include <pbd/xml++.h> +#include <pbd/whitespace.h> + +#include <glibmm/thread.h> #include <ardour/audioengine.h> +#include <ardour/io.h> #include <ardour/audio_unit.h> #include <ardour/session.h> #include <ardour/utils.h> @@ -37,66 +42,93 @@ using namespace std; using namespace PBD; using namespace ARDOUR; -AUPlugin::AUPlugin (AudioEngine& engine, Session& session, CAComponent* _comp) +static OSStatus +_render_callback(void *userData, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData) +{ + return ((AUPlugin*)userData)->render_callback (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); +} + +AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> _comp) : Plugin (engine, session), comp (_comp), - unit (new CAAudioUnit) + unit (new CAAudioUnit), + initialized (false), + buffers (0), + current_maxbuf (0), + current_offset (0), + current_buffers (0), + frames_processed (0) { - OSErr err = CAAudioUnit::Open (*comp, *unit); + OSErr err = CAAudioUnit::Open (*(comp.get()), *unit); + if (err != noErr) { error << _("AudioUnit: Could not convert CAComponent to CAAudioUnit") << endmsg; - delete unit; - delete comp; throw failed_constructor (); } - unit->Initialize (); + AURenderCallbackStruct renderCallbackInfo; + + renderCallbackInfo.inputProc = _render_callback; + renderCallbackInfo.inputProcRefCon = this; + + if ((err = unit->SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, + 0, (void*) &renderCallbackInfo, sizeof(renderCallbackInfo))) != 0) { + cerr << "cannot install render callback (err = " << err << ')' << endl; + throw failed_constructor(); + } + + unit->GetElementCount (kAudioUnitScope_Input, input_elements); + unit->GetElementCount (kAudioUnitScope_Output, output_elements); + + // set up the basic stream format. these fields do not change + + streamFormat.mSampleRate = session.frame_rate(); + streamFormat.mFormatID = kAudioFormatLinearPCM; + streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved; + streamFormat.mBitsPerChannel = 32; + streamFormat.mFramesPerPacket = 1; + + // subject to later modification as we discover channel counts + + streamFormat.mBytesPerPacket = 4; + streamFormat.mBytesPerFrame = 4; + streamFormat.mChannelsPerFrame = 1; + + format_set = 0; + + if (_set_block_size (_session.get_block_size())) { + error << _("AUPlugin: cannot set processing block size") << endmsg; + throw failed_constructor(); + } } AUPlugin::~AUPlugin () { if (unit) { unit->Uninitialize (); - delete unit; - } - - if (comp) { - delete comp; - } - - if (in_list) { - delete in_list; } - - if (out_list) { - delete out_list; - } -} -AUPluginInfo::~AUPluginInfo () -{ - if (desc) { - delete desc; + if (buffers) { + free (buffers); } } -uint32_t +string AUPlugin::unique_id () const { - return 0; + return AUPluginInfo::stringify_descriptor (comp->Desc()); } const char * AUPlugin::label () const { - return "AUPlugin label"; -} - -const char * -AUPlugin::maker () const -{ - return "AUplugin maker"; + return _info->name.c_str(); } uint32_t @@ -125,7 +157,7 @@ AUPlugin::signal_latency () const void AUPlugin::set_parameter (uint32_t which, float val) { - unit->SetParameter (parameter_map[which].first, parameter_map[which].second, 0, val); + // unit->SetParameter (parameter_map[which].first, parameter_map[which].second, 0, val); } float @@ -133,7 +165,7 @@ AUPlugin::get_parameter (uint32_t which) const { float outValue = 0.0; - unit->GetParameter(parameter_map[which].first, parameter_map[which].second, 0, outValue); + // unit->GetParameter(parameter_map[which].first, parameter_map[which].second, 0, outValue); return outValue; } @@ -153,19 +185,174 @@ AUPlugin::nth_parameter (uint32_t which, bool& ok) const void AUPlugin::activate () { - unit->GlobalReset (); + if (!initialized) { + OSErr err; + if ((err = unit->Initialize()) != noErr) { + error << string_compose (_("AUPlugin: cannot initialize plugin (err = %1)"), err) << endmsg; + } else { + frames_processed = 0; + initialized = true; + } + } } void AUPlugin::deactivate () { - // not needed. GlobalReset () takes care of it. + unit->GlobalReset (); } void AUPlugin::set_block_size (nframes_t nframes) { + _set_block_size (nframes); +} + +int +AUPlugin::_set_block_size (nframes_t nframes) +{ + bool was_initialized = initialized; + UInt32 numFrames = nframes; + OSErr err; + + if (initialized) { + unit->Uninitialize (); + } + + if ((err = unit->SetProperty (kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, + 0, &numFrames, sizeof (numFrames))) != noErr) { + cerr << "cannot set max frames (err = " << err << ')' << endl; + return -1; + } + + if (was_initialized) { + activate (); + } + + return 0; +} + +int32_t +AUPlugin::can_support_input_configuration (int32_t in) +{ + streamFormat.mChannelsPerFrame = in; + /* apple says that for non-interleaved data, these + values always refer to a single channel. + */ + streamFormat.mBytesPerPacket = 4; + streamFormat.mBytesPerFrame = 4; + + if (set_input_format () == 0) { + return 1; + } else { + return -1; + } +} + +int +AUPlugin::set_input_format () +{ + return set_stream_format (kAudioUnitScope_Input, input_elements); +} + +int +AUPlugin::set_output_format () +{ + return set_stream_format (kAudioUnitScope_Output, output_elements); +} + +int +AUPlugin::set_stream_format (int scope, uint32_t cnt) +{ + OSErr result; + + for (uint32_t i = 0; i < cnt; ++i) { + if ((result = unit->SetFormat (scope, i, streamFormat)) != 0) { + error << string_compose (_("AUPlugin: could not set stream format for %1/%2 (err = %3)"), + (scope == kAudioUnitScope_Input ? "input" : "output"), i, result) << endmsg; + return -1; + } + } + + if (scope == kAudioUnitScope_Input) { + format_set |= 0x1; + } else { + format_set |= 0x2; + } + + return 0; +} + +int32_t +AUPlugin::compute_output_streams (int32_t nplugins) +{ + /* we will never replicate AU plugins - either they can do the I/O we need + or not. thus, we can ignore nplugins entirely. + */ + if (set_output_format() == 0) { + + if (buffers) { + free (buffers); + buffers = 0; + } + + buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) + + streamFormat.mChannelsPerFrame * sizeof(AudioBuffer)); + + Glib::Mutex::Lock em (_session.engine().process_lock()); + IO::MoreOutputs (streamFormat.mChannelsPerFrame); + + return streamFormat.mChannelsPerFrame; + } else { + return -1; + } +} + +uint32_t +AUPlugin::output_streams() const +{ + if (!(format_set & 0x2)) { + warning << _("AUPlugin: output_streams() called without any format set!") << endmsg; + return 1; + } + return streamFormat.mChannelsPerFrame; +} + + +uint32_t +AUPlugin::input_streams() const +{ + if (!(format_set & 0x1)) { + warning << _("AUPlugin: input_streams() called without any format set!") << endmsg; + return 1; + } + return streamFormat.mChannelsPerFrame; +} + +OSStatus +AUPlugin::render_callback(AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData) +{ + /* not much to do - the data is already in the buffers given to us in connect_and_run() */ + + if (current_maxbuf == 0) { + error << _("AUPlugin: render callback called illegally!") << endmsg; + return kAudioUnitErr_CannotDoInCurrentContext; + } + + for (uint32_t i = 0; i < current_maxbuf; ++i) { + ioData->mBuffers[i].mNumberChannels = 1; + ioData->mBuffers[i].mDataByteSize = sizeof (Sample) * inNumberFrames; + ioData->mBuffers[i].mData = (*current_buffers)[i] + cb_offset + current_offset; + } + + cb_offset += inNumberFrames; + + return noErr; } int @@ -173,17 +360,37 @@ AUPlugin::connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, { AudioUnitRenderActionFlags flags = 0; AudioTimeStamp ts; - - AudioBufferList abl; - abl.mNumberBuffers = 1; - abl.mBuffers[0].mNumberChannels = 1; - abl.mBuffers[0].mDataByteSize = nframes * sizeof(Sample); - abl.mBuffers[0].mData = &bufs[0]; - - - unit->Render (&flags, &ts, 0, 0, &abl); - - return 0; + + current_buffers = &bufs; + current_maxbuf = maxbuf; + current_offset = offset; + cb_offset = 0; + + buffers->mNumberBuffers = maxbuf; + + for (uint32_t i = 0; i < maxbuf; ++i) { + buffers->mBuffers[i].mNumberChannels = 1; + buffers->mBuffers[i].mDataByteSize = nframes * sizeof (Sample); + buffers->mBuffers[i].mData = 0; + } + + ts.mSampleTime = frames_processed; + ts.mFlags = kAudioTimeStampSampleTimeValid; + + if (unit->Render (&flags, &ts, 0, nframes, buffers) == noErr) { + + current_maxbuf = 0; + frames_processed += nframes; + + for (uint32_t i = 0; i < maxbuf; ++i) { + if (bufs[i] + offset != buffers->mBuffers[i].mData) { + memcpy (bufs[i]+offset, buffers->mBuffers[i].mData, nframes * sizeof (Sample)); + } + } + return 0; + } + + return -1; } set<uint32_t> @@ -245,8 +452,8 @@ AUPlugin::parameter_is_output (uint32_t) const XMLNode& AUPlugin::get_state() { - XMLNode* root = new XMLNode (state_node_name()); - + XMLNode *root = new XMLNode (state_node_name()); + LocaleGuard lg (X_("POSIX")); return *root; } @@ -279,7 +486,19 @@ AUPlugin::get_presets () bool AUPlugin::has_editor () const { - return false; + // even if the plugin doesn't have its own editor, the AU API can be used + // to create one that looks native. + return true; +} + +AUPluginInfo::AUPluginInfo (boost::shared_ptr<CAComponentDescription> d) + : descriptor (d) +{ + +} + +AUPluginInfo::~AUPluginInfo () +{ } PluginPtr @@ -288,7 +507,7 @@ AUPluginInfo::load (Session& session) try { PluginPtr plugin; - CAComponent* comp = new CAComponent(*desc); + boost::shared_ptr<CAComponent> comp (new CAComponent(*descriptor)); if (!comp->IsValid()) { error << ("AudioUnit: not a valid Component") << endmsg; @@ -296,7 +515,7 @@ AUPluginInfo::load (Session& session) plugin.reset (new AUPlugin (session.engine(), session, comp)); } - plugin->set_info(PluginInfoPtr(new AUPluginInfo(*this))); + plugin->set_info (PluginInfoPtr (new AUPluginInfo (*this))); return plugin; } @@ -310,6 +529,28 @@ AUPluginInfo::discover () { PluginInfoList plugs; + discover_fx (plugs); + discover_music (plugs); + + return plugs; +} + +void +AUPluginInfo::discover_music (PluginInfoList& plugs) +{ + CAComponentDescription desc; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + desc.componentSubType = 0; + desc.componentManufacturer = 0; + desc.componentType = kAudioUnitType_MusicEffect; + + discover_by_description (plugs, desc); +} + +void +AUPluginInfo::discover_fx (PluginInfoList& plugs) +{ CAComponentDescription desc; desc.componentFlags = 0; desc.componentFlagsMask = 0; @@ -317,35 +558,146 @@ AUPluginInfo::discover () desc.componentManufacturer = 0; desc.componentType = kAudioUnitType_Effect; + discover_by_description (plugs, desc); +} + +void +AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescription& desc) +{ Component comp = 0; comp = FindNextComponent (NULL, &desc); + while (comp != NULL) { CAComponentDescription temp; GetComponentInfo (comp, &temp, NULL, NULL, NULL); + + AUPluginInfoPtr info (new AUPluginInfo + (boost::shared_ptr<CAComponentDescription> (new CAComponentDescription(temp)))); + + /* no panners, format converters or i/o AU's for our purposes + */ + + switch (info->descriptor->Type()) { + case kAudioUnitType_Panner: + case kAudioUnitType_OfflineEffect: + case kAudioUnitType_FormatConverter: + continue; + default: + break; + } + + switch (info->descriptor->SubType()) { + case kAudioUnitSubType_DefaultOutput: + case kAudioUnitSubType_SystemOutput: + case kAudioUnitSubType_GenericOutput: + case kAudioUnitSubType_AUConverter: + continue; + break; + + case kAudioUnitSubType_DLSSynth: + info->category = "DLSSynth"; + break; + + case kAudioUnitType_MusicEffect: + info->category = "MusicEffect"; + break; + + case kAudioUnitSubType_Varispeed: + info->category = "Varispeed"; + break; + + case kAudioUnitSubType_Delay: + info->category = "Delay"; + break; + + case kAudioUnitSubType_LowPassFilter: + info->category = "LowPassFilter"; + break; + + case kAudioUnitSubType_HighPassFilter: + info->category = "HighPassFilter"; + break; + + case kAudioUnitSubType_BandPassFilter: + info->category = "BandPassFilter"; + break; + + case kAudioUnitSubType_HighShelfFilter: + info->category = "HighShelfFilter"; + break; + + case kAudioUnitSubType_LowShelfFilter: + info->category = "LowShelfFilter"; + break; + + case kAudioUnitSubType_ParametricEQ: + info->category = "ParametricEQ"; + break; + + case kAudioUnitSubType_GraphicEQ: + info->category = "GraphicEQ"; + break; + + case kAudioUnitSubType_PeakLimiter: + info->category = "PeakLimiter"; + break; + + case kAudioUnitSubType_DynamicsProcessor: + info->category = "DynamicsProcessor"; + break; + + case kAudioUnitSubType_MultiBandCompressor: + info->category = "MultiBandCompressor"; + break; + + case kAudioUnitSubType_MatrixReverb: + info->category = "MatrixReverb"; + break; + + case kAudioUnitType_Mixer: + info->category = "Mixer"; + break; + + case kAudioUnitSubType_StereoMixer: + info->category = "StereoMixer"; + break; + + case kAudioUnitSubType_3DMixer: + info->category = "3DMixer"; + break; + + case kAudioUnitSubType_MatrixMixer: + info->category = "MatrixMixer"; + break; + + default: + info->category = ""; + } + + AUPluginInfo::get_names (temp, info->name, info->creator); + + info->type = ARDOUR::AudioUnit; + info->unique_id = stringify_descriptor (*info->descriptor); + + /* mark the plugin as having flexible i/o */ - AUPluginInfoPtr plug(new AUPluginInfo); - plug->name = AUPluginInfo::get_name (temp); - plug->type = ARDOUR::AudioUnit; - plug->n_inputs = 0; - plug->n_outputs = 0; - // plug->setup_nchannels (temp); - plug->category = "AudioUnit"; - plug->desc = new CAComponentDescription(temp); - - plugs.push_back(plug); + info->n_inputs = -1; + info->n_outputs = -1; + + + plugs.push_back (info); comp = FindNextComponent (comp, &desc); } - - return plugs; } -string -AUPluginInfo::get_name (CAComponentDescription& comp_desc) +void +AUPluginInfo::get_names (CAComponentDescription& comp_desc, std::string& name, Glib::ustring& maker) { CFStringRef itemName = NULL; - // Marc Poirier -style item name + + // Marc Poirier-style item name CAComponent auComponent (comp_desc); if (auComponent.IsValid()) { CAComponentDescription dummydesc; @@ -379,23 +731,36 @@ AUPluginInfo::get_name (CAComponentDescription& comp_desc) CFRelease(compManufacturerString); } - return CFStringRefToStdString(itemName); -} - -void -AUPluginInfo::setup_nchannels (CAComponentDescription& comp_desc) -{ - CAAudioUnit unit; - - CAAudioUnit::Open (comp_desc, unit); - - if (unit.SupportsNumChannels()) { - n_inputs = n_outputs = 0; + string str = CFStringRefToStdString(itemName); + string::size_type colon = str.find (':'); + + if (colon) { + name = str.substr (colon+1); + maker = str.substr (0, colon); + // strip_whitespace_edges (maker); + // strip_whitespace_edges (name); } else { - AUChannelInfo cinfo; - size_t info_size = sizeof(cinfo); - OSStatus err = AudioUnitGetProperty (unit.AU(), kAudioUnitProperty_SupportedNumChannels, kAudioUnitScope_Global, - 0, &cinfo, &info_size); + name = str; + maker = "unknown"; } } +// from CAComponentDescription.cpp (in libs/appleutility in ardour source) +extern char *StringForOSType (OSType t, char *writeLocation); + +std::string +AUPluginInfo::stringify_descriptor (const CAComponentDescription& desc) +{ + char str[24]; + stringstream s; + + s << StringForOSType (desc.Type(), str); + s << " - "; + + s << StringForOSType (desc.SubType(), str); + s << " - "; + + s << StringForOSType (desc.Manu(), str); + + return s.str(); +} diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 91ff8b8d35..08d18c7cab 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -22,6 +22,7 @@ #include <vector> #include <exception> #include <stdexcept> +#include <sstream> #include <glibmm/timer.h> #include <pbd/pthread_utils.h> @@ -368,6 +369,20 @@ AudioEngine::process_callback (nframes_t nframes) last_monitor_check = next_processed_frames; } + if (session->silent()) { + + boost::shared_ptr<Ports> p = ports.reader(); + + for (Ports::iterator i = p->begin(); i != p->end(); ++i) { + + Port *port = (*i); + + if (port->sends_output()) { + port->get_buffer().silence(nframes); + } + } + } + _processed_frames = next_processed_frames; return 0; } @@ -510,6 +525,26 @@ AudioEngine::remove_session () remove_all_ports (); } +void +AudioEngine::port_registration_failure (const std::string& portname) +{ + string full_portname = jack_client_name; + full_portname += ':'; + full_portname += portname; + + + jack_port_t* p = jack_port_by_name (_jack, full_portname.c_str()); + string reason; + + if (p) { + reason = _("a port with this name already exists: check for duplicated track/bus names"); + } else { + reason = _("unknown error"); + } + + throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str()); +} + Port * AudioEngine::register_port (DataType dtype, const string& portname, bool input, bool publish) { @@ -533,7 +568,7 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input, } catch (...) { - throw PortRegistrationFailure(); + throw PortRegistrationFailure("unable to create port (unknown type?)"); } } @@ -563,7 +598,7 @@ AudioEngine::register_output_port (DataType type, const string& portname, bool p return register_port (type, portname, false, publish); } -int +int AudioEngine::unregister_port (Port& port) { /* caller must hold process lock */ @@ -590,6 +625,8 @@ AudioEngine::unregister_port (Port& port) /* writer goes out of scope, forces update */ } + + remove_connections_for (port); return 0; } @@ -1054,6 +1091,23 @@ AudioEngine::remove_all_ports () } } +void +AudioEngine::remove_connections_for (Port& port) +{ + for (PortConnections::iterator i = port_connections.begin(); i != port_connections.end(); ) { + PortConnections::iterator tmp; + + tmp = i; + ++tmp; + + if ((*i).first == port.name()) { + port_connections.erase (i); + } + + i = tmp; + } +} + #ifdef HAVE_JACK_CLIENT_OPEN diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 1284dd343b..81ad45e08a 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -135,18 +135,15 @@ AudioFileSource::removable () const int AudioFileSource::init (ustring pathstr, bool must_exist) { - bool is_new = false; - _length = 0; timeline_position = 0; _peaks_built = false; - file_is_new = false; - if (!find (pathstr, must_exist, is_new, _channel)) { + if (!find (pathstr, must_exist, file_is_new, _channel)) { throw non_existent_source (); } - if (is_new && must_exist) { + if (file_is_new && must_exist) { return -1; } diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 8034f3ddac..301351fe71 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -237,54 +237,6 @@ AudioRegion::listen_to_my_curves () _fade_out->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed)); } -bool -AudioRegion::verify_length (nframes_t len) -{ - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source()); - - if (afs && afs->destructive()) { - return true; - } else { - return Region::verify_length(len); - } -} - -bool -AudioRegion::verify_start_and_length (nframes_t new_start, nframes_t new_length) -{ - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source()); - - if (afs && afs->destructive()) { - return true; - } else { - return Region::verify_start_and_length(new_start, new_length); - } -} - -bool -AudioRegion::verify_start (nframes_t pos) -{ - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source()); - - if (afs && afs->destructive()) { - return true; - } else { - return Region::verify_start(pos); - } -} - -bool -AudioRegion::verify_start_mutable (nframes_t& new_start) -{ - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source()); - - if (afs && afs->destructive()) { - return true; - } else { - return Region::verify_start_mutable(new_start); - } -} - void AudioRegion::set_envelope_active (bool yn) { @@ -321,25 +273,26 @@ AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nfra } } -ARDOUR::nframes_t -AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, nframes_t cnt, uint32_t chan_n) const +nframes_t +AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, + nframes_t cnt, + uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const { - return _read_at (_sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n); + return _read_at (_sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames); } -ARDOUR::nframes_t +nframes_t AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, nframes_t cnt, uint32_t chan_n) const { - return _read_at (_master_sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n); + return _read_at (_master_sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0); } -ARDOUR::nframes_t +nframes_t AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buffer, float *gain_buffer, - nframes_t position, nframes_t cnt, uint32_t chan_n) const + nframes_t position, nframes_t cnt, + uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const { - // cerr << _name << "._read_at(" << position << ") - " << _position << endl; - nframes_t internal_offset; nframes_t buf_offset; nframes_t to_read; @@ -377,13 +330,12 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff _read_data_count = 0; if (chan_n < n_channels()) { - + boost::shared_ptr<AudioSource> src = audio_source(chan_n); if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) { - return 0; /* "read nothing" */ } - + _read_data_count += src->read_data_count(); } else { diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index a2ce7209f6..ce8aa95964 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -49,6 +49,8 @@ using Glib::ustring; bool AudioSource::_build_missing_peakfiles = false; bool AudioSource::_build_peakfiles = false; +#define _FPP 256 + AudioSource::AudioSource (Session& s, ustring name) : Source (s, name, DataType::AUDIO) { @@ -135,7 +137,7 @@ AudioSource::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) con /* check to see if the peak data is ready. if not connect the slot while still holding the lock. */ - + if (!(ret = _peaks_built)) { conn = PeaksReady.connect (the_slot); } @@ -192,44 +194,36 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path) peakpath = find_broken_peakfile (peakpath, audio_path); } - if (newfile) { - - if (!_build_peakfiles) { - return 0; + if (stat (peakpath.c_str(), &statbuf)) { + if (errno != ENOENT) { + /* it exists in the peaks dir, but there is some kind of error */ + + error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg; + return -1; } + /* peakfile does not exist */ + _peaks_built = false; - + } else { - - if (stat (peakpath.c_str(), &statbuf)) { - if (errno != ENOENT) { - /* it exists in the peaks dir, but there is some kind of error */ - - error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg; - return -1; - } - + + /* we found it in the peaks dir, so check it out */ + + if (statbuf.st_size == 0) { + // empty _peaks_built = false; - } else { + // Check if the audio file has changed since the peakfile was built. + struct stat stat_file; + int err = stat (audio_path.c_str(), &stat_file); - /* we found it in the peaks dir, so check it out */ - - if (statbuf.st_size == 0) { + if (!err && stat_file.st_mtime > statbuf.st_mtime){ _peaks_built = false; + _peak_byte_max = 0; } else { - // Check if the audio file has changed since the peakfile was built. - struct stat stat_file; - int err = stat (audio_path.c_str(), &stat_file); - - 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; - } + _peaks_built = true; + _peak_byte_max = statbuf.st_size; } } } @@ -255,9 +249,16 @@ AudioSource::write (Sample *dst, nframes_t cnt) return write_unlocked (dst, cnt); } -int +int AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const { + return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP); +} + +int +AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, + double samples_per_visual_peak, nframes_t samples_per_file_peak) const +{ Glib::Mutex::Lock lm (_lock); double scale; double expected_peaks; @@ -271,7 +272,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr Sample* raw_staging = 0; int _peakfile = -1; - expected_peaks = (cnt / (double) frames_per_peak); + expected_peaks = (cnt / (double) samples_per_file_peak); scale = npeaks/expected_peaks; #undef DEBUG_READ_PEAKS @@ -326,7 +327,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr if (scale == 1.0) { - off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData); + off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData); /* open, read, close */ @@ -390,10 +391,10 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr /* compute the rounded up frame position */ nframes_t current_frame = start; - nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) frames_per_peak); + nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) samples_per_file_peak); uint32_t next_visual_peak = (uint32_t) ceil (current_frame / samples_per_visual_peak); double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak; - uint32_t stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / frames_per_peak; + uint32_t stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / samples_per_file_peak; uint32_t nvisual_peaks = 0; uint32_t stored_peaks_read = 0; uint32_t i = 0; @@ -414,7 +415,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr if (i == stored_peaks_read) { uint32_t start_byte = current_stored_peak * sizeof(PeakData); - tnp = min ((_length/frames_per_peak - current_stored_peak), (nframes_t) expected_peaks); + tnp = min ((_length/samples_per_file_peak - current_stored_peak), (nframes_t) expected_peaks); to_read = min (chunksize, tnp); #ifdef DEBUG_READ_PEAKS @@ -437,7 +438,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr << ')' << " at start_byte = " << start_byte << " _length = " << _length << " versus len = " << fend - << " expected maxpeaks = " << (_length - current_frame)/frames_per_peak + << " expected maxpeaks = " << (_length - current_frame)/samples_per_file_peak << " npeaks was " << npeaks << endl; goto out; @@ -466,7 +467,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) ); next_visual_peak_frame = min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) ); - stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / frames_per_peak; + stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak; } if (zero_fill) { @@ -611,7 +612,7 @@ AudioSource::build_peaks_from_scratch () goto out; } - if (compute_and_write_peaks (buf, current_frame, frames_read, true, false)) { + if (compute_and_write_peaks (buf, current_frame, frames_read, true, false, _FPP)) { break; } @@ -662,7 +663,7 @@ void AudioSource::done_with_peakfile_writes (bool done) { if (peak_leftover_cnt) { - compute_and_write_peaks (0, 0, 0, true, false); + compute_and_write_peaks (0, 0, 0, true, false, _FPP); } if (done) { @@ -678,6 +679,13 @@ AudioSource::done_with_peakfile_writes (bool done) int AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, bool intermediate_peaks_ready) { + return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP); +} + +int +AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, + bool intermediate_peaks_ready, nframes_t fpp) +{ Sample* buf2 = 0; nframes_t to_do; uint32_t peaks_computed; @@ -707,9 +715,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframe x.min = peak_leftovers[0]; x.max = peak_leftovers[0]; - ARDOUR::find_peaks (peak_leftovers + 1, peak_leftover_cnt - 1, &x.min, &x.max); - - off_t byte = (peak_leftover_frame / frames_per_peak) * sizeof (PeakData); + off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData); if (::pwrite (peakfile, &x, sizeof (PeakData), byte) != sizeof (PeakData)) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; @@ -761,7 +767,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframe to_do = cnt; } - peakbuf = new PeakData[(to_do/frames_per_peak)+1]; + peakbuf = new PeakData[(to_do/fpp)+1]; peaks_computed = 0; current_frame = first_frame; frames_done = 0; @@ -769,11 +775,11 @@ AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframe while (to_do) { /* if some frames were passed in (i.e. we're not flushing leftovers) - and there are less than frames_per_peak to do, save them till + and there are less than fpp to do, save them till next time */ - if (force && (to_do < frames_per_peak)) { + if (force && (to_do < fpp)) { /* keep the left overs around for next time */ if (peak_leftover_size < to_do) { @@ -790,7 +796,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframe break; } - nframes_t this_time = min (frames_per_peak, to_do); + nframes_t this_time = min (fpp, to_do); peakbuf[peaks_computed].max = buf[0]; peakbuf[peaks_computed].min = buf[0]; @@ -804,7 +810,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframe current_frame += this_time; } - first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData); + first_peak_byte = (first_frame / fpp) * sizeof (PeakData); if (can_truncate_peaks()) { @@ -887,7 +893,7 @@ AudioSource::available_peaks (double zoom_factor) const { off_t end; - if (zoom_factor < frames_per_peak) { + if (zoom_factor < _FPP) { return length(); // peak data will come from the audio file } @@ -899,7 +905,7 @@ AudioSource::available_peaks (double zoom_factor) const end = _peak_byte_max; - return (end/sizeof(PeakData)) * frames_per_peak; + return (end/sizeof(PeakData)) * _FPP; } void diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc index 6085501470..d6f63c2f9d 100644 --- a/libs/ardour/auditioner.cc +++ b/libs/ardour/auditioner.cc @@ -151,8 +151,19 @@ Auditioner::audition_region (boost::shared_ptr<Region> region) reset_panner(); length = the_region->length(); - _diskstream->seek (0); - current_frame = 0; + + int dir; + nframes_t offset = the_region->sync_offset (dir); + + /* can't audition from a negative sync point */ + + if (dir < 0) { + offset = 0; + } + + _diskstream->seek (offset); + current_frame = offset; + g_atomic_int_set (&_active, 1); } diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc index 508e6515c9..f7711b3224 100644 --- a/libs/ardour/crossfade.cc +++ b/libs/ardour/crossfade.cc @@ -260,7 +260,8 @@ Crossfade::read_raw_internal (Sample* buf, nframes_t start, nframes_t cnt) const nframes_t Crossfade::read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n) const + float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n, + nframes_t read_frames, nframes_t skip_frames) const { nframes_t offset; nframes_t to_write; @@ -301,9 +302,9 @@ Crossfade::read_at (Sample *buf, Sample *mixdown_buffer, } else if (!(_in->opaque())) { memset (crossfade_buffer_in, 0, sizeof (Sample) * to_write); } - - _out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n); - _in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n); + + _out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames); + _in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames); float* fiv = new float[to_write]; float* fov = new float[to_write]; diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index f2d2e92169..9f2ce4fab9 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -164,7 +164,6 @@ setup_enum_writer () REGISTER_ENUM (SyncPoint); REGISTER (_RegionPoint); - REGISTER_ENUM (PreFader); REGISTER_ENUM (PostFader); REGISTER (_Placement); @@ -243,6 +242,7 @@ setup_enum_writer () REGISTER_CLASS_ENUM (Session::Event, SetDiskstreamSpeed); REGISTER_CLASS_ENUM (Session::Event, Locate); REGISTER_CLASS_ENUM (Session::Event, LocateRoll); + REGISTER_CLASS_ENUM (Session::Event, LocateRollLocate); REGISTER_CLASS_ENUM (Session::Event, SetLoop); REGISTER_CLASS_ENUM (Session::Event, PunchIn); REGISTER_CLASS_ENUM (Session::Event, PunchOut); diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index a8fb4050f9..91e5b9850c 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -34,11 +34,11 @@ #include <boost/scoped_array.hpp> #include <boost/shared_array.hpp> +#include <pbd/basename.h> #include <pbd/convert.h> #include <ardour/ardour.h> #include <ardour/session.h> -#include <ardour/session_directory.h> #include <ardour/audio_diskstream.h> #include <ardour/sndfilesource.h> #include <ardour/sndfile_helpers.h> @@ -52,22 +52,19 @@ using namespace ARDOUR; using namespace PBD; -std::auto_ptr<ImportableSource> -open_importable_source (const string& path, nframes_t samplerate, - ARDOUR::SrcQuality quality) +static std::auto_ptr<ImportableSource> +open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQuality quality) { std::auto_ptr<ImportableSource> source(new ImportableSource(path)); if (source->samplerate() == samplerate) { return source; } - - return std::auto_ptr<ImportableSource>( - new ResampledImportableSource(path, samplerate, quality) - ); + + return std::auto_ptr<ImportableSource>(new ResampledImportableSource(path, samplerate, quality)); } -std::string +static std::string get_non_existent_filename (const std::string& basename, uint channel, uint channels) { char buf[PATH_MAX+1]; @@ -86,8 +83,8 @@ get_non_existent_filename (const std::string& basename, uint channel, uint chann } else { snprintf (buf, sizeof(buf), "%s.wav", base.c_str()); } - - if (sys::exists (buf)) { + + if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) { /* if the file already exists, we must come up with * a new name for it. for now we just keep appending @@ -106,27 +103,27 @@ get_non_existent_filename (const std::string& basename, uint channel, uint chann return buf; } -vector<string> -get_paths_for_new_sources (const string& import_file_path, const string& session_dir, - uint channels) +static vector<string> +get_paths_for_new_sources (const string& import_file_path, const string& session_dir, uint channels) { vector<string> new_paths; - const string basename = sys::basename (import_file_path); - SessionDirectory sdir(session_dir); + const string basename = basename_nosuffix (import_file_path); for (uint n = 0; n < channels; ++n) { - std::string filename = get_non_existent_filename (basename, n, channels); + std::string filepath; - sys::path filepath = sdir.sound_path() / filename; + filepath = session_dir; + filepath += '/'; + filepath += get_non_existent_filename (basename, n, channels); - new_paths.push_back (filepath.to_string()); + new_paths.push_back (filepath); } return new_paths; } -bool +static bool create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess, uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles) { @@ -138,12 +135,12 @@ create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess, try { source = SourceFactory::createWritable ( - DataType::AUDIO, - sess, - i->c_str(), - false, // destructive - samplerate - ); + DataType::AUDIO, + sess, + i->c_str(), + false, // destructive + samplerate + ); } catch (const failed_constructor& err) { @@ -156,29 +153,29 @@ create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess, return true; } -Glib::ustring +static Glib::ustring compose_status_message (const string& path, - uint file_samplerate, - uint session_samplerate, - uint current_file, - uint total_files) + uint file_samplerate, + uint session_samplerate, + uint current_file, + uint total_files) { if (file_samplerate != session_samplerate) { return string_compose (_("converting %1\n(resample from %2KHz to %3KHz)\n(%4 of %5)"), - sys::path(path).leaf(), - file_samplerate/1000.0f, - session_samplerate/1000.0f, - current_file, total_files); + Glib::path_get_basename (path), + file_samplerate/1000.0f, + session_samplerate/1000.0f, + current_file, total_files); } return string_compose (_("converting %1\n(%2 of %3)"), - sys::path(path).leaf(), - current_file, total_files); + Glib::path_get_basename (path), + current_file, total_files); } -void +static void write_audio_data_to_new_files (ImportableSource* source, Session::import_status& status, - vector<boost::shared_ptr<AudioFileSource> >& newfiles) + vector<boost::shared_ptr<AudioFileSource> >& newfiles) { const nframes_t nframes = ResampledImportableSource::blocksize; uint channels = source->channels(); @@ -225,10 +222,10 @@ write_audio_data_to_new_files (ImportableSource* source, Session::import_status& } } -void +static void remove_file_source (boost::shared_ptr<AudioFileSource> file_source) { - sys::remove (std::string(file_source->path())); + ::unlink (file_source->path().c_str()); } void @@ -260,7 +257,7 @@ Session::import_audiofiles (import_status& status) vector<string> new_paths = get_paths_for_new_sources (*p, get_best_session_directory_for_new_source (), source->channels()); - + AudioSources newfiles; status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles); @@ -309,3 +306,4 @@ Session::import_audiofiles (import_status& status) status.done = true; } + diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 89c342e9cf..7a2ae2aad9 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -307,12 +307,12 @@ void IO::collect_input (BufferSet& outs, nframes_t nframes, nframes_t offset) { assert(outs.available() >= n_inputs()); - - outs.set_count(n_inputs()); - if (outs.count() == ChanCount::ZERO) + if (n_inputs() == ChanCount::ZERO) return; + outs.set_count(n_inputs()); + for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { BufferSet::iterator o = outs.begin(*t); @@ -2567,3 +2567,4 @@ IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b) sigc::mem_fun (*io, &IO::bundle_ports_have_changed) ); } + diff --git a/libs/ardour/jack_audio_port.cc b/libs/ardour/jack_audio_port.cc index 3a0b34ab19..b2ddb6d48e 100644 --- a/libs/ardour/jack_audio_port.cc +++ b/libs/ardour/jack_audio_port.cc @@ -29,10 +29,14 @@ JackAudioPort::JackAudioPort (const std::string& name, Flags flgs, AudioBuffer* { if (buf) { + cout << "jack audio port buffer" << endl; + _buffer = buf; _own_buffer = false; } else { + + cout << "jack audio port no buffer" << endl; /* data space will be provided by JACK */ diff --git a/libs/ardour/jack_midi_port.cc b/libs/ardour/jack_midi_port.cc index 7dbb8655f6..c9471c9d0c 100644 --- a/libs/ardour/jack_midi_port.cc +++ b/libs/ardour/jack_midi_port.cc @@ -71,8 +71,8 @@ JackMidiPort::cycle_start (nframes_t nframes, nframes_t offset_ignored_but_proba assert(_buffer->size() == event_count); - if (_buffer->size() > 0) - cerr << "MIDIPort got " << event_count << " events." << endl; + /*if (_buffer->size() > 0) + cerr << "JackMIDIPort got " << event_count << " events (buf " << _buffer << ")" << endl;*/ } void diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index 0614e3334d..696ada3b81 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -185,6 +185,14 @@ LadspaPlugin::restore_state (PluginState& state) } } +string +LadspaPlugin::unique_id() const +{ + char buf[32]; + snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID); + return string (buf); +} + float LadspaPlugin::default_value (uint32_t port) { diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc index d108374ba0..f85fd3ec33 100644 --- a/libs/ardour/meter.cc +++ b/libs/ardour/meter.cc @@ -41,7 +41,7 @@ PeakMeter::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_f // Meter what we have (midi) for ( ; n < meterable && n < bufs.count().n_midi(); ++n) { - + float val = 0; // GUI needs a better MIDI meter, not much information can be diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index a629fe458f..1ca6a5db72 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -104,21 +104,23 @@ void MidiBuffer::read_from(const Buffer& src, nframes_t nframes, nframes_t offset) { assert(src.type() == DataType::MIDI); - const MidiBuffer& msrc = (MidiBuffer&)src; + assert(&src != this); - assert(_capacity >= src.size()); + const MidiBuffer& msrc = (MidiBuffer&)src; + + assert(_capacity >= msrc.size()); clear(); assert(_size == 0); - + // FIXME: slow - for (size_t i=0; i < src.size(); ++i) { + for (size_t i=0; i < msrc.size(); ++i) { const MidiEvent& ev = msrc[i]; if (ev.time() >= offset && ev.time() < offset+nframes) { - //cerr << "MidiBuffer::read_from got event, " << ev.time() << endl; + //cout << "MidiBuffer::read_from got event, " << ev.time() << endl; push_back(ev); } else { - //cerr << "MidiBuffer event out of range, " << ev.time() << endl; + cerr << "MidiBuffer event out of range, " << ev.time() << endl; } } diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc index 7590c42e0b..3e8dea4f62 100644 --- a/libs/ardour/midi_port.cc +++ b/libs/ardour/midi_port.cc @@ -26,23 +26,23 @@ using namespace ARDOUR; using namespace std; -MidiPort::MidiPort (const std::string& name, Flags flags, bool external, nframes_t bufsize) +MidiPort::MidiPort (const std::string& name, Flags flags, bool external, nframes_t capacity) : Port (name, flags) , BaseMidiPort (name, flags) , PortFacade (name, flags) { - set_name (name); - - _buffer = new MidiBuffer (bufsize); + _buffer = new MidiBuffer (capacity); - cout << "MIDI port " << name << " external: " << external << endl; - - if (!external) { - _ext_port = 0; - } else { + if (external) { + /* external ports use the same buffer for the jack port (_ext_port) + * and internal ports (this) */ _ext_port = new JackMidiPort (name, flags, _buffer); + } else { + /* internal ports just have a single buffer, no jack port */ + _ext_port = 0; } + set_name (name); reset (); } @@ -70,7 +70,6 @@ MidiPort::cycle_start (nframes_t nframes, nframes_t offset) /* caller must hold process lock */ if (_ext_port) { - // cout << "external\n"; _ext_port->cycle_start (nframes, offset); } @@ -78,11 +77,9 @@ MidiPort::cycle_start (nframes_t nframes, nframes_t offset) if (_ext_port) { - // cout << "external in\n"; - - _buffer->read_from (dynamic_cast<BaseMidiPort*>(_ext_port)->get_midi_buffer(), nframes, offset); - - // cout << "read " << _buffer->size() << " events." << endl; + BaseMidiPort* mprt = dynamic_cast<BaseMidiPort*>(_ext_port); + assert(mprt); + assert(&mprt->get_midi_buffer() == _buffer); if (!_connections.empty()) { (*_mixdown) (_connections, _buffer, nframes, offset, false); @@ -90,8 +87,6 @@ MidiPort::cycle_start (nframes_t nframes, nframes_t offset) } else { - // cout << "internal in\n"; - if (_connections.empty()) { _buffer->silence (nframes, offset); } else { @@ -101,10 +96,6 @@ MidiPort::cycle_start (nframes_t nframes, nframes_t offset) } else { - // cout << "out\n"; - _buffer->silence (nframes, offset); } - - // cout << endl; } diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 8d20d8539d..04649a56fe 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -30,6 +30,7 @@ #include <pbd/failed_constructor.h> #include <pbd/stl_delete.h> #include <pbd/xml++.h> +#include <pbd/stacktrace.h> #include <ardour/playlist.h> #include <ardour/session.h> @@ -233,6 +234,7 @@ Playlist::init (bool hide) _refcnt = 0; _hidden = hide; _splicing = false; + _shuffling = false; _nudging = false; in_set_state = 0; _edit_mode = Config->get_edit_mode(); @@ -351,7 +353,7 @@ Playlist::notify_region_removed (boost::shared_ptr<Region> r) /* this might not be true, but we have to act as though it could be. */ - pending_length = false; + pending_length = false; LengthChanged (); /* EMIT SIGNAL */ pending_modified = false; Modified (); /* EMIT SIGNAL */ @@ -439,7 +441,6 @@ Playlist::flush_notifications () if (n || pending_modified) { if (!in_set_state) { - possibly_splice (); relayer (); } pending_modified = false; @@ -479,12 +480,7 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa --itimes; } - /* later regions will all be spliced anyway */ - if (!holding_state ()) { - possibly_splice_unlocked (); - } - /* note that itimes can be zero if we being asked to just insert a single fraction of the region. */ @@ -495,14 +491,18 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa pos += region->length(); } + nframes_t length = 0; + if (floor (times) != times) { - nframes_t length = (nframes_t) floor (region->length() * (times - floor (times))); + length = (nframes_t) floor (region->length() * (times - floor (times))); string name; _session.region_name (name, region->name(), false); boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags()); add_region_internal (sub, pos); } + + possibly_splice_unlocked (position, (pos + length) - position, boost::shared_ptr<Region>()); release_notifications (); } @@ -540,6 +540,8 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t posit regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region); all_regions.insert (region); + possibly_splice_unlocked (position, region->length(), region); + if (!holding_state () && !in_set_state) { /* layers get assigned from XML state */ relayer (); @@ -565,12 +567,15 @@ Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Regio { RegionLock rlock (this); + bool old_sp = _splicing; + _splicing = true; + remove_region_internal (old); add_region_internal (newr, pos); - if (!holding_state ()) { - possibly_splice_unlocked (); - } + _splicing = old_sp; + + possibly_splice_unlocked (pos, (nframes64_t) old->length() - (nframes64_t) newr->length()); } void @@ -578,14 +583,10 @@ Playlist::remove_region (boost::shared_ptr<Region> region) { RegionLock rlock (this); remove_region_internal (region); - - if (!holding_state ()) { - possibly_splice_unlocked (); - } } int -Playlist::remove_region_internal (boost::shared_ptr<Region>region) +Playlist::remove_region_internal (boost::shared_ptr<Region> region) { RegionList::iterator i; nframes_t old_length = 0; @@ -602,8 +603,13 @@ Playlist::remove_region_internal (boost::shared_ptr<Region>region) for (i = regions.begin(); i != regions.end(); ++i) { if (*i == region) { + nframes_t pos = (*i)->position(); + nframes64_t distance = (*i)->length(); + regions.erase (i); + possibly_splice_unlocked (pos, -distance); + if (!holding_state ()) { relayer (); remove_dependents (region); @@ -617,6 +623,9 @@ Playlist::remove_region_internal (boost::shared_ptr<Region>region) return 0; } } + + + return -1; } @@ -664,6 +673,7 @@ Playlist::partition (nframes_t start, nframes_t end, bool just_top_level) void Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist) { + RegionLock rlock (this); boost::shared_ptr<Region> region; boost::shared_ptr<Region> current; string new_name; @@ -671,19 +681,14 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi OverlapType overlap; nframes_t pos1, pos2, pos3, pos4; RegionList new_regions; - RegionList copy; in_partition = true; - delay_notifications(); - /* need to work from a copy, because otherwise the regions we add during the process get operated on as well. */ - { - RegionLock rlock (this); - copy = regions; - } + + RegionList copy = regions; for (RegionList::iterator i = copy.begin(); i != copy.end(); i = tmp) { @@ -691,10 +696,9 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi ++tmp; current = *i; - + if (current->first_frame() == start && current->last_frame() == end) { if (cutting) { - RegionLock rlock (this); remove_region_internal (current); } continue; @@ -703,14 +707,14 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi if ((overlap = current->coverage (start, end)) == OverlapNone) { continue; } - + pos1 = current->position(); pos2 = start; pos3 = end; pos4 = current->last_frame(); if (overlap == OverlapInternal) { - + /* split: we need 3 new regions, the front, middle and end. cut: we need 2 regions, the front and end. */ @@ -730,10 +734,9 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi /* "middle" ++++++ */ - _session.region_name (new_name, current->name(), false); //takes the session-wide region lock + _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)); - RegionLock rlock (this); add_region_internal (region, start); new_regions.push_back (region); } @@ -743,11 +746,10 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi _session.region_name (new_name, current->name(), false); region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name, regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit)); - { - RegionLock rlock (this); - add_region_internal (region, end); - new_regions.push_back (region); - } + + add_region_internal (region, end); + new_regions.push_back (region); + /* "front" ***** */ current->freeze (); @@ -772,9 +774,8 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi /* end +++++ */ _session.region_name (new_name, current->name(), false); - region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, regions.size(), + region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit)); - RegionLock rlock (this); add_region_internal (region, start); new_regions.push_back (region); } @@ -809,7 +810,6 @@ 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)); - RegionLock rlock (this); add_region_internal (region, pos1); new_regions.push_back (region); } @@ -839,7 +839,6 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi */ if (cutting) { - RegionLock rlock (this); remove_region_internal (current); } new_regions.push_back (current); @@ -851,8 +850,6 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi for (RegionList::iterator i = new_regions.begin(); i != new_regions.end(); ++i) { check_dependents (*i, false); } - - release_notifications (); } boost::shared_ptr<Playlist> @@ -919,7 +916,6 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden) } partition_internal (start, start+cnt-1, true, thawlist); - possibly_splice (); for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) { (*i)->thaw ("playlist cut"); @@ -973,7 +969,6 @@ Playlist::paste (boost::shared_ptr<Playlist> other, nframes_t position, float ti pos += shift; } - possibly_splice_unlocked (); /* XXX shall we handle fractional cases at some point? */ @@ -1033,10 +1028,14 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos string before_name; string after_name; + /* split doesn't change anything about length, so don't try to splice */ + + bool old_sp = _splicing; + _splicing = true; + before = playlist_position - region->position(); after = region->length() - before; - _session.region_name (before_name, region->name(), false); left = RegionFactory::create (region, 0, before, before_name, region->layer(), Region::Flag (region->flags()|Region::LeftOfSplit)); @@ -1045,7 +1044,7 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos add_region_internal (left, region->position()); add_region_internal (right, region->position() + before); - + uint64_t orig_layer_op = region->last_layer_op(); for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { if ((*i)->last_layer_op() > orig_layer_op) { @@ -1060,71 +1059,84 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos finalize_split_region (region, left, right); - if (remove_region_internal (region)) { - return; - } + remove_region_internal (region); + + _splicing = old_sp; } void -Playlist::possibly_splice () +Playlist::possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) { + if (_splicing || in_set_state) { + /* don't respond to splicing moves or state setting */ + return; + } + if (_edit_mode == Splice) { - splice_locked (); + splice_locked (at, distance, exclude); } } void -Playlist::possibly_splice_unlocked () +Playlist::possibly_splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) { + if (_splicing || in_set_state) { + /* don't respond to splicing moves or state setting */ + return; + } + if (_edit_mode == Splice) { - splice_unlocked (); + splice_unlocked (at, distance, exclude); } } void -Playlist::splice_locked () +Playlist::splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) { { RegionLock rl (this); - core_splice (); + core_splice (at, distance, exclude); } - - notify_length_changed (); } void -Playlist::splice_unlocked () +Playlist::splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) { - core_splice (); - notify_length_changed (); + core_splice (at, distance, exclude); } void -Playlist::core_splice () +Playlist::core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) { _splicing = true; - + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - RegionList::iterator next; - - next = i; - ++next; - - if (next == regions.end()) { - break; + + if (exclude && (*i) == exclude) { + continue; + } + + if ((*i)->position() >= at) { + nframes64_t new_pos = (*i)->position() + distance; + if (new_pos < 0) { + new_pos = 0; + } else if (new_pos >= max_frames - (*i)->length()) { + new_pos = max_frames - (*i)->length(); + } + + (*i)->set_position (new_pos, this); } - - (*next)->set_position ((*i)->last_frame() + 1, this); } - + _splicing = false; + + notify_length_changed (); } void Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region> region) { - if (in_set_state || _splicing || _nudging) { + if (in_set_state || _splicing || _nudging || _shuffling) { return; } @@ -1147,10 +1159,24 @@ Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region> regions.erase (i); regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region); - } if (what_changed & Change (ARDOUR::PositionChanged|ARDOUR::LengthChanged)) { + + nframes64_t delta = 0; + + if (what_changed & ARDOUR::PositionChanged) { + delta = (nframes64_t) region->position() - (nframes64_t) region->last_position(); + } + + if (what_changed & ARDOUR::LengthChanged) { + delta += (nframes64_t) region->length() - (nframes64_t) region->last_length(); + } + + if (delta) { + possibly_splice (region->last_position() + region->last_length(), delta, region); + } + if (holding_state ()) { pending_bounds.push_back (region); } else { @@ -1159,7 +1185,6 @@ Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region> timestamp_layer_op (region); } - possibly_splice (); notify_length_changed (); relayer (); check_dependents (region, false); @@ -1269,9 +1294,114 @@ Playlist::top_region_at (nframes_t frame) return region; } +Playlist::RegionList* +Playlist::regions_to_read (nframes_t start, nframes_t end) +{ + /* Caller must hold lock */ + + RegionList covering; + set<nframes_t> to_check; + set<boost::shared_ptr<Region> > unique; + RegionList here; + + to_check.insert (start); + to_check.insert (end); + + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + + /* find all/any regions that span start+end */ + + switch ((*i)->coverage (start, end)) { + case OverlapNone: + break; + + case OverlapInternal: + covering.push_back (*i); + break; + + case OverlapStart: + to_check.insert ((*i)->position()); + covering.push_back (*i); + break; + + case OverlapEnd: + to_check.insert ((*i)->last_frame()); + covering.push_back (*i); + break; + + case OverlapExternal: + covering.push_back (*i); + to_check.insert ((*i)->position()); + to_check.insert ((*i)->last_frame()); + break; + } + + /* don't go too far */ + + if ((*i)->position() > end) { + break; + } + } + + RegionList* rlist = new RegionList; + + /* find all the regions that cover each position .... */ + + if (covering.size() == 1) { + + rlist->push_back (covering.front()); + + } else { + + for (set<nframes_t>::iterator t = to_check.begin(); t != to_check.end(); ++t) { + + here.clear (); + + for (RegionList::iterator x = covering.begin(); x != covering.end(); ++x) { + + if ((*x)->covers (*t)) { + here.push_back (*x); + } + } + + RegionSortByLayer cmp; + here.sort (cmp); + + /* ... and get the top/transparent regions at "here" */ + + for (RegionList::reverse_iterator c = here.rbegin(); c != here.rend(); ++c) { + + unique.insert (*c); + + if ((*c)->opaque()) { + + /* the other regions at this position are hidden by this one */ + + break; + } + } + } + + for (set<boost::shared_ptr<Region> >::iterator s = unique.begin(); s != unique.end(); ++s) { + rlist->push_back (*s); + } + + if (rlist->size() > 1) { + /* now sort by time order */ + + RegionSortByPosition cmp; + rlist->sort (cmp); + } + } + + return rlist; +} + Playlist::RegionList * Playlist::find_regions_at (nframes_t frame) { + /* Caller must hold lock */ + RegionList *rlist = new RegionList; for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { @@ -1352,6 +1482,92 @@ Playlist::find_next_region (nframes_t frame, RegionPoint point, int dir) return ret; } +nframes64_t +Playlist::find_next_region_boundary (nframes64_t frame, int dir) +{ + RegionLock rlock (this); + + nframes64_t closest = max_frames; + nframes64_t ret = -1; + + if (dir > 0) { + + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + + boost::shared_ptr<Region> r = (*i); + nframes64_t distance; + nframes64_t end = r->position() + r->length(); + bool reset; + + reset = false; + + if (r->first_frame() > frame) { + + distance = r->first_frame() - frame; + + if (distance < closest) { + ret = r->first_frame(); + closest = distance; + reset = true; + } + } + + if (end > frame) { + + distance = end - frame; + + if (distance < closest) { + ret = end; + closest = distance; + reset = true; + } + } + + if (reset) { + break; + } + } + + } else { + + for (RegionList::reverse_iterator i = regions.rbegin(); i != regions.rend(); ++i) { + + boost::shared_ptr<Region> r = (*i); + nframes64_t distance; + bool reset; + + reset = false; + + if (r->last_frame() < frame) { + + distance = frame - r->last_frame(); + + if (distance < closest) { + ret = r->last_frame(); + closest = distance; + reset = true; + } + } + + if (r->first_frame() < frame) { + distance = frame - r->last_frame(); + + if (distance < closest) { + ret = r->first_frame(); + closest = distance; + reset = true; + } + } + + if (reset) { + break; + } + } + } + + return ret; +} + /***********************************************************************/ @@ -1686,6 +1902,33 @@ Playlist::relayer () /* XXX these layer functions are all deprecated */ void +Playlist::raise_region (boost::shared_ptr<Region> region) +{ + uint32_t rsz = regions.size(); + layer_t target = region->layer() + 1U; + + if (target >= rsz) { + /* its already at the effective top */ + return; + } + + move_region_to_layer (target, region, 1); +} + +void +Playlist::lower_region (boost::shared_ptr<Region> region) +{ + if (region->layer() == 0) { + /* its already at the bottom */ + return; + } + + layer_t target = region->layer() - 1U; + + move_region_to_layer (target, region, -1); +} + +void Playlist::raise_region_to_top (boost::shared_ptr<Region> region) { /* does nothing useful if layering mode is later=higher */ @@ -1707,6 +1950,79 @@ Playlist::lower_region_to_bottom (boost::shared_ptr<Region> region) } } +int +Playlist::move_region_to_layer (layer_t target_layer, boost::shared_ptr<Region> region, int dir) +{ + RegionList::iterator i; + typedef pair<boost::shared_ptr<Region>,layer_t> LayerInfo; + list<LayerInfo> layerinfo; + layer_t dest; + + { + RegionLock rlock (const_cast<Playlist *> (this)); + + for (i = regions.begin(); i != regions.end(); ++i) { + + if (region == *i) { + continue; + } + + if (dir > 0) { + + /* region is moving up, move all regions on intermediate layers + down 1 + */ + + if ((*i)->layer() > region->layer() && (*i)->layer() <= target_layer) { + dest = (*i)->layer() - 1; + } else { + /* not affected */ + continue; + } + } else { + + /* region is moving down, move all regions on intermediate layers + up 1 + */ + + if ((*i)->layer() < region->layer() && (*i)->layer() >= target_layer) { + dest = (*i)->layer() + 1; + } else { + /* not affected */ + continue; + } + } + + LayerInfo newpair; + + newpair.first = *i; + newpair.second = dest; + + layerinfo.push_back (newpair); + } + } + + /* now reset the layers without holding the region lock */ + + for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) { + x->first->set_layer (x->second); + } + + region->set_layer (target_layer); + +#if 0 + /* now check all dependents */ + + for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) { + check_dependents (x->first, false); + } + + check_dependents (region, false); +#endif + + return 0; +} + void Playlist::nudge_after (nframes_t start, nframes_t distance, bool forwards) { @@ -1817,3 +2133,129 @@ Playlist::timestamp_layer_op (boost::shared_ptr<Region> region) region->set_last_layer_op (++layer_op_counter); } + +void +Playlist::shuffle (boost::shared_ptr<Region> region, int dir) +{ + bool moved = false; + nframes_t new_pos; + + if (region->locked()) { + return; + } + + _shuffling = true; + + { + RegionLock rlock (const_cast<Playlist*> (this)); + + + if (dir > 0) { + + RegionList::iterator next; + + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i) == region) { + next = i; + ++next; + + if (next != regions.end()) { + + if ((*next)->locked()) { + break; + } + + if ((*next)->position() != region->last_frame() + 1) { + /* they didn't used to touch, so after shuffle, + just have them swap positions. + */ + new_pos = (*next)->position(); + } else { + /* they used to touch, so after shuffle, + make sure they still do. put the earlier + region where the later one will end after + it is moved. + */ + new_pos = region->position() + (*next)->length(); + } + + (*next)->set_position (region->position(), this); + region->set_position (new_pos, this); + + /* avoid a full sort */ + + regions.erase (i); // removes the region from the list */ + next++; + regions.insert (next, region); // adds it back after next + + moved = true; + } + break; + } + } + } else { + + RegionList::iterator prev = regions.end(); + + for (RegionList::iterator i = regions.begin(); i != regions.end(); prev = i, ++i) { + if ((*i) == region) { + + if (prev != regions.end()) { + + if ((*prev)->locked()) { + break; + } + + if (region->position() != (*prev)->last_frame() + 1) { + /* they didn't used to touch, so after shuffle, + just have them swap positions. + */ + new_pos = region->position(); + } else { + /* they used to touch, so after shuffle, + make sure they still do. put the earlier + one where the later one will end after + */ + new_pos = (*prev)->position() + region->length(); + } + + region->set_position ((*prev)->position(), this); + (*prev)->set_position (new_pos, this); + + /* avoid a full sort */ + + regions.erase (i); // remove region + regions.insert (prev, region); // insert region before prev + + moved = true; + } + + break; + } + } + } + } + + _shuffling = false; + + if (moved) { + + relayer (); + check_dependents (region, false); + + notify_modified(); + } + +} + +bool +Playlist::region_is_shuffle_constrained (boost::shared_ptr<Region>) +{ + RegionLock rlock (const_cast<Playlist*> (this)); + + if (regions.size() > 1) { + return true; + } + + return false; +} diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc index bc5688c318..7f3f21b1fe 100644 --- a/libs/ardour/plugin.cc +++ b/libs/ardour/plugin.cc @@ -40,6 +40,10 @@ #include <ardour/ladspa_plugin.h> #include <ardour/plugin_manager.h> +#ifdef HAVE_AUDIOUNITS +#include <ardour/audio_unit.h> +#endif + #include <pbd/stl_delete.h> #include "i18n.h" @@ -66,7 +70,21 @@ vector<string> Plugin::get_presets() { vector<string> labels; - lrdf_uris* set_uris = lrdf_get_setting_uris(unique_id()); + uint32_t id; + std::string unique (unique_id()); + + /* XXX problem: AU plugins don't have numeric ID's. + Solution: they have a different method of providing presets. + XXX sub-problem: implement it. + */ + + if (!isdigit (unique[0])) { + return labels; + } + + id = atol (unique.c_str()); + + lrdf_uris* set_uris = lrdf_get_setting_uris(id); if (set_uris) { for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) { @@ -108,6 +126,20 @@ Plugin::save_preset (string name, string domain) { lrdf_portvalue portvalues[parameter_count()]; lrdf_defaults defaults; + uint32_t id; + std::string unique (unique_id()); + + /* XXX problem: AU plugins don't have numeric ID's. + Solution: they have a different method of providing/saving presets. + XXX sub-problem: implement it. + */ + + if (!isdigit (unique[0])) { + return false; + } + + id = atol (unique.c_str()); + defaults.count = parameter_count(); defaults.items = portvalues; @@ -126,7 +158,7 @@ Plugin::save_preset (string name, string domain) string source(string_compose("file:%1/.%2/rdf/ardour-presets.n3", envvar, domain)); - free(lrdf_add_preset(source.c_str(), name.c_str(), unique_id(), &defaults)); + free(lrdf_add_preset(source.c_str(), name.c_str(), id, &defaults)); string path = string_compose("%1/.%2", envvar, domain); if (g_mkdir_with_parents (path.c_str(), 0775)) { @@ -149,7 +181,7 @@ Plugin::save_preset (string name, string domain) } PluginPtr -ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginType type) +ARDOUR::find_plugin(Session& session, string identifier, PluginType type) { PluginManager *mgr = PluginManager::the_manager(); PluginInfoList plugs; @@ -162,14 +194,12 @@ ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginType ty #ifdef VST_SUPPORT case ARDOUR::VST: plugs = mgr->vst_plugin_info(); - unique_id = 0; // VST plugins don't have a unique id. break; #endif #ifdef HAVE_AUDIOUNITS case ARDOUR::AudioUnit: - plugs = AUPluginInfo::discover (); - unique_id = 0; // Neither do AU. + plugs = mgr->au_plugin_info(); break; #endif @@ -178,10 +208,10 @@ ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginType ty } PluginInfoList::iterator i; + for (i = plugs.begin(); i != plugs.end(); ++i) { - if ((name == "" || (*i)->name == name) && - (unique_id == 0 || (*i)->unique_id == unique_id)) { - return (*i)->load (session); + if (identifier == (*i)->unique_id){ + return (*i)->load (session); } } diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 3faebd7179..4153f26e85 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -606,17 +606,10 @@ PluginInsert::get_state(void) XMLNode& PluginInsert::state (bool full) { - char buf[256]; XMLNode& node = Processor::state (full); node.add_property ("type", _plugins[0]->state_node_name()); - snprintf(buf, sizeof(buf), "%s", _plugins[0]->name()); - node.add_property("id", string(buf)); - if (_plugins[0]->state_node_name() == "ladspa") { - char buf[32]; - snprintf (buf, sizeof (buf), "%ld", _plugins[0]->get_info()->unique_id); - node.add_property("unique-id", string(buf)); - } + node.add_property("unique-id", _plugins[0]->unique_id()); node.add_property("count", string_compose("%1", _plugins.size())); node.add_child_nocopy (_plugins[0]->get_state()); @@ -648,7 +641,6 @@ PluginInsert::set_state(const XMLNode& node) XMLNodeIterator niter; XMLPropertyList plist; const XMLProperty *prop; - long unique = 0; ARDOUR::PluginType type; if ((prop = node.property ("type")) == 0) { @@ -666,24 +658,16 @@ PluginInsert::set_state(const XMLNode& node) << endmsg; return -1; } - + prop = node.property ("unique-id"); - if (prop != 0) { - unique = atol(prop->value().c_str()); - } - - if ((prop = node.property ("id")) == 0) { - error << _("XML node describing insert is missing the `id' field") << endmsg; - return -1; + if (prop == 0) { + error << _("Plugin has no unique ID field") << endmsg; + return -1; } boost::shared_ptr<Plugin> plugin; - if (unique != 0) { - plugin = find_plugin (_session, "", unique, type); - } else { - plugin = find_plugin (_session, prop->value(), 0, type); - } + plugin = find_plugin (_session, prop->value(), type); if (plugin == 0) { error << string_compose(_("Found a reference to a plugin (\"%1\") that is unknown.\n" diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index dac8a9eead..d866a0d49f 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -43,6 +43,10 @@ #include <ardour/vst_plugin.h> #endif +#ifdef HAVE_AUDIOUNITS +#include <ardour/audio_unit.h> +#endif + #include <pbd/error.h> #include <pbd/stl_delete.h> @@ -84,10 +88,23 @@ PluginManager::PluginManager () vst_path = s; } - refresh (); if (_manager == 0) { _manager = this; } + + /* the plugin manager is constructed too early to use Profile */ + + if (getenv ("ARDOUR_SAE")) { + ladspa_plugin_whitelist.push_back (1203); // single band parametric + ladspa_plugin_whitelist.push_back (1772); // caps compressor + ladspa_plugin_whitelist.push_back (1913); // fast lookahead limiter + ladspa_plugin_whitelist.push_back (1075); // simple RMS expander + ladspa_plugin_whitelist.push_back (1061); // feedback delay line (max 5s) + ladspa_plugin_whitelist.push_back (1216); // gverb + ladspa_plugin_whitelist.push_back (2150); // tap pitch shifter + } + + refresh (); } void @@ -99,6 +116,9 @@ PluginManager::refresh () vst_refresh (); } #endif // VST_SUPPORT +#ifdef HAVE_AUDIOUNITS + au_refresh (); +#endif } void @@ -113,6 +133,7 @@ PluginManager::ladspa_refresh () ladspa_discover_from_path (ladspa_path); } + int PluginManager::add_ladspa_directory (string path) { @@ -248,6 +269,12 @@ PluginManager::ladspa_discover (string path) break; } + if (!ladspa_plugin_whitelist.empty()) { + if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) { + continue; + } + } + PluginInfoPtr info(new LadspaPluginInfo); info->name = descriptor->Name; info->category = get_ladspa_category(descriptor->UniqueID); @@ -257,7 +284,10 @@ PluginManager::ladspa_discover (string path) info->n_inputs = ChanCount(); info->n_outputs = ChanCount(); info->type = ARDOUR::LADSPA; - info->unique_id = descriptor->UniqueID; + + char buf[32]; + snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID); + info->unique_id = buf; for (uint32_t n=0; n < descriptor->PortCount; ++n) { if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) { @@ -294,7 +324,7 @@ PluginManager::get_ladspa_category (uint32_t plugin_id) lrdf_statement* matches1 = lrdf_matches (&pattern); if (!matches1) { - return _("Unknown"); + return _(""); } pattern.subject = matches1->object; @@ -306,7 +336,7 @@ PluginManager::get_ladspa_category (uint32_t plugin_id) lrdf_free_statements(matches1); if (!matches2) { - return _("Unknown"); + return _(""); } string label = matches2->object; @@ -315,6 +345,22 @@ PluginManager::get_ladspa_category (uint32_t plugin_id) return label; } +#ifdef HAVE_AUDIOUNITS +void +PluginManager::au_refresh () +{ + au_discover(); +} + +int +PluginManager::au_discover () +{ + _au_plugin_info = AUPluginInfo::discover(); + return 0; +} + +#endif + #ifdef VST_SUPPORT void @@ -373,6 +419,7 @@ int PluginManager::vst_discover (string path) { FSTInfo* finfo; + char buf[32]; if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) { warning << "Cannot get VST information from " << path << endmsg; @@ -395,6 +442,9 @@ PluginManager::vst_discover (string path) info->name = finfo->name; } + + snprintf (buf, sizeof (buf), "%d", finfo->UniqueID); + info->unique_id = buf; info->category = "VST"; info->path = path; // need to set info->creator but FST doesn't provide it diff --git a/libs/ardour/rb_effect.cc b/libs/ardour/rb_effect.cc new file mode 100644 index 0000000000..0de5a5bf4a --- /dev/null +++ b/libs/ardour/rb_effect.cc @@ -0,0 +1,302 @@ +/* + Copyright (C) 2004-2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <algorithm> +#include <cmath> + +#include <pbd/error.h> +#include <rubberband/RubberBandStretcher.h> + +#include <ardour/types.h> +#include <ardour/stretch.h> +#include <ardour/pitch.h> +#include <ardour/audiofilesource.h> +#include <ardour/session.h> +#include <ardour/audioregion.h> + +#include "i18n.h" + +using namespace std; +using namespace ARDOUR; +using namespace PBD; +using namespace RubberBand; + +Pitch::Pitch (Session& s, TimeFXRequest& req) + : RBEffect (s, req) +{ +} + +Stretch::Stretch (Session& s, TimeFXRequest& req) + : RBEffect (s, req) +{ +} + +RBEffect::RBEffect (Session& s, TimeFXRequest& req) + : Filter (s) + , tsr (req) + +{ + tsr.progress = 0.0f; +} + +RBEffect::~RBEffect () +{ +} + +int +RBEffect::run (boost::shared_ptr<AudioRegion> region) +{ + SourceList nsrcs; + nframes_t done; + int ret = -1; + const nframes_t bufsize = 256; + gain_t* gain_buffer = 0; + Sample** buffers = 0; + char suffix[32]; + string new_name; + string::size_type at; + nframes_t pos = 0; + int avail = 0; + + RubberBandStretcher stretcher (session.frame_rate(), region->n_channels(), + RubberBandStretcher::DefaultOptions, + tsr.time_fraction, tsr.pitch_fraction); + + stretcher.setExpectedInputDuration(region->length()); + stretcher.setDebugLevel(1); + + tsr.progress = 0.0f; + tsr.done = false; + + uint32_t channels = region->n_channels(); + nframes_t duration = region->length(); + + /* the name doesn't need to be super-precise, but allow for 2 fractional + digits just to disambiguate close but not identical FX + */ + + if (tsr.time_fraction == 1.0) { + snprintf (suffix, sizeof (suffix), "@%d", (int) floor (tsr.pitch_fraction * 100.0f)); + } else if (tsr.pitch_fraction == 1.0) { + snprintf (suffix, sizeof (suffix), "@%d", (int) floor (tsr.time_fraction * 100.0f)); + } else { + snprintf (suffix, sizeof (suffix), "@%d-%d", + (int) floor (tsr.time_fraction * 100.0f), + (int) floor (tsr.pitch_fraction * 100.0f)); + } + + /* create new sources */ + + if (make_new_sources (region, nsrcs, suffix)) { + goto out; + } + + gain_buffer = new gain_t[bufsize]; + buffers = new float *[channels]; + + for (uint32_t i = 0; i < channels; ++i) { + buffers[i] = new float[bufsize]; + } + + /* we read from the master (original) sources for the region, + not the ones currently in use, in case it's already been + subject to timefx. */ + + /* study first, process afterwards. */ + + pos = 0; + avail = 0; + done = 0; + + try { + while (pos < duration && !tsr.cancel) { + + nframes_t this_read = 0; + + for (uint32_t i = 0; i < channels; ++i) { + + this_read = 0; + nframes_t this_time; + + this_time = min(bufsize, duration - pos); + + this_read = region->master_read_at + (buffers[i], + buffers[i], + gain_buffer, + pos + region->position(), + this_time, + i); + + if (this_read != this_time) { + error << string_compose + (_("tempoize: error reading data from %1"), + nsrcs[i]->name()) << endmsg; + goto out; + } + } + + pos += this_read; + done += this_read; + + tsr.progress = ((float) done / duration) * 0.75; + + stretcher.study(buffers, this_read, pos == duration); + } + + done = 0; + pos = 0; + + while (pos < duration && !tsr.cancel) { + + nframes_t this_read = 0; + + for (uint32_t i = 0; i < channels; ++i) { + + this_read = 0; + nframes_t this_time; + + this_time = min(bufsize, duration - pos); + + this_read = region->master_read_at + (buffers[i], + buffers[i], + gain_buffer, + pos + region->position(), + this_time, + i); + + if (this_read != this_time) { + error << string_compose + (_("tempoize: error reading data from %1"), + nsrcs[i]->name()) << endmsg; + goto out; + } + } + + pos += this_read; + done += this_read; + + tsr.progress = 0.75 + ((float) done / duration) * 0.25; + + stretcher.process(buffers, this_read, pos == duration); + + int avail = 0; + + while ((avail = stretcher.available()) > 0) { + + this_read = min(bufsize, uint32_t(avail)); + + stretcher.retrieve(buffers, this_read); + + for (uint32_t i = 0; i < nsrcs.size(); ++i) { + + if (nsrcs[i]->write(buffers[i], this_read) != + this_read) { + error << string_compose (_("error writing tempo-adjusted data to %1"), nsrcs[i]->name()) << endmsg; + goto out; + } + } + } + } + + while ((avail = stretcher.available()) >= 0) { + + uint32_t this_read = min(bufsize, uint32_t(avail)); + + stretcher.retrieve(buffers, this_read); + + for (uint32_t i = 0; i < nsrcs.size(); ++i) { + + if (nsrcs[i]->write(buffers[i], this_read) != + this_read) { + error << string_compose (_("error writing tempo-adjusted data to %1"), nsrcs[i]->name()) << endmsg; + goto out; + } + } + } + + } catch (runtime_error& err) { + error << _("timefx code failure. please notify ardour-developers.") << endmsg; + error << err.what() << endmsg; + goto out; + } + + new_name = region->name(); + at = new_name.find ('@'); + + // remove any existing stretch indicator + + if (at != string::npos && at > 2) { + new_name = new_name.substr (0, at - 1); + } + + new_name += suffix; + + ret = finish (region, nsrcs, new_name); + + /* now reset ancestral data for each new region */ + + for (vector<boost::shared_ptr<AudioRegion> >::iterator x = results.begin(); x != results.end(); ++x) { + nframes64_t astart = (*x)->ancestral_start(); + nframes64_t alength = (*x)->ancestral_length(); + nframes_t start; + nframes_t length; + + // note: tsr.time_fraction is a percentage of original length. 100 = no change, + // 50 is half as long, 200 is twice as long, etc. + + + float stretch = (*x)->stretch() * (tsr.time_fraction/100.0); + float shift = (*x)->shift() * tsr.pitch_fraction; + + start = (nframes_t) floor (astart + ((astart - (*x)->start()) / stretch)); + length = (nframes_t) floor (alength / stretch); + + (*x)->set_ancestral_data (start, length, stretch, shift); + } + + out: + + if (gain_buffer) { + delete [] gain_buffer; + } + + if (buffers) { + for (uint32_t i = 0; i < channels; ++i) { + delete buffers[i]; + } + delete [] buffers; + } + + if (ret || tsr.cancel) { + for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) { + (*si)->mark_for_remove (); + } + } + + tsr.done = true; + + return ret; +} + + + + + diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index ecc7b5e305..0505985aea 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -365,6 +365,8 @@ Region::set_length (nframes_t len, void *src) return; } + + _last_length = _length; _length = len; _flags = Region::Flag (_flags & ~WholeFile); @@ -443,6 +445,7 @@ Region::special_set_position (nframes_t pos) a way to store its "natural" or "captured" position. */ + _position = _position; _position = pos; } @@ -454,6 +457,7 @@ Region::set_position (nframes_t pos, void *src) } if (_position != pos) { + _last_position = _position; _position = pos; /* check that the new _position wouldn't make the current @@ -463,6 +467,7 @@ Region::set_position (nframes_t pos, void *src) */ if (max_frames - _length < _position) { + _last_length = _length; _length = max_frames - _position; } } @@ -482,6 +487,7 @@ Region::set_position_on_top (nframes_t pos, void *src) } if (_position != pos) { + _last_position = _position; _position = pos; } @@ -499,7 +505,7 @@ Region::set_position_on_top (nframes_t pos, void *src) } void -Region::nudge_position (long n, void *src) +Region::nudge_position (nframes64_t n, void *src) { if (_flags & Locked) { return; @@ -509,6 +515,8 @@ Region::nudge_position (long n, void *src) return; } + _last_position = _position; + if (n > 0) { if (_position > max_frames - n) { _position = max_frames; @@ -527,11 +535,12 @@ Region::nudge_position (long n, void *src) } void -Region::set_ancestral_data (nframes64_t s, nframes64_t l, float st) +Region::set_ancestral_data (nframes64_t s, nframes64_t l, float st, float sh) { _ancestral_length = l; _ancestral_start = s; _stretch = st; + _shift = sh; } void @@ -723,10 +732,16 @@ Region::trim_to_internal (nframes_t position, nframes_t length, void *src) what_changed = Change (what_changed|StartChanged); } if (_length != length) { + if (!_frozen) { + _last_length = _length; + } _length = length; what_changed = Change (what_changed|LengthChanged); } if (_position != position) { + if (!_frozen) { + _last_position = _position; + } _position = position; what_changed = Change (what_changed|PositionChanged); } @@ -867,14 +882,16 @@ Region::adjust_to_sync (nframes_t pos) { int sync_dir; nframes_t offset = sync_offset (sync_dir); + + // cerr << "adjusting pos = " << pos << " to sync at " << _sync_position << " offset = " << offset << " with dir = " << sync_dir << endl; if (sync_dir > 0) { if (max_frames - pos > offset) { - pos += offset; + pos -= offset; } } else { if (pos > offset) { - pos -= offset; + pos += offset; } else { pos = 0; } @@ -893,6 +910,24 @@ Region::sync_position() const } } +void +Region::raise () +{ + boost::shared_ptr<Playlist> pl (playlist()); + if (pl) { + pl->raise_region (shared_from_this ()); + } +} + +void +Region::lower () +{ + boost::shared_ptr<Playlist> pl (playlist()); + if (pl) { + pl->lower_region (shared_from_this ()); + } +} + void Region::raise_to_top () @@ -945,6 +980,8 @@ Region::state (bool full_state) node->add_property ("ancestral-length", buf); snprintf (buf, sizeof (buf), "%.12g", _stretch); node->add_property ("stretch", buf); + snprintf (buf, sizeof (buf), "%.12g", _shift); + node->add_property ("shift", buf); switch (_first_edit) { case EditChangesNothing: @@ -1017,9 +1054,11 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) sscanf (prop->value().c_str(), "%" PRIu32, &val); if (val != _length) { what_changed = Change (what_changed|LengthChanged); + _last_length = _length; _length = val; } } else { + _last_length = _length; _length = 1; } @@ -1027,9 +1066,11 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) sscanf (prop->value().c_str(), "%" PRIu32, &val); if (val != _position) { what_changed = Change (what_changed|PositionChanged); + _last_position = _position; _position = val; } } else { + _last_position = _position; _position = 0; } @@ -1076,6 +1117,12 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) _stretch = 1.0; } + if ((prop = node.property ("shift")) != 0) { + _shift = atof (prop->value()); + } else { + _shift = 1.0; + } + /* note: derived classes set flags */ if (_extra_xml) { @@ -1128,6 +1175,8 @@ void Region::freeze () { _frozen++; + _last_length = _length; + _last_position = _position; } void @@ -1261,27 +1310,46 @@ Region::source_equivalent (boost::shared_ptr<const Region> other) const bool Region::verify_length (nframes_t len) { + if (source() && source()->destructive()) { + return true; + } + + nframes_t maxlen = 0; + for (uint32_t n=0; n < _sources.size(); ++n) { - if (_start > _sources[n]->length() - len) { - return false; - } + maxlen = max (maxlen, _sources[n]->length() - _start); } + + len = min (len, maxlen); + return true; } bool -Region::verify_start_and_length (nframes_t new_start, nframes_t new_length) +Region::verify_start_and_length (nframes_t new_start, nframes_t& new_length) { + if (source() && source()->destructive()) { + return true; + } + + nframes_t maxlen = 0; + for (uint32_t n=0; n < _sources.size(); ++n) { - if (new_length > _sources[n]->length() - new_start) { - return false; - } + maxlen = max (maxlen, _sources[n]->length() - new_start); } + + new_length = min (new_length, maxlen); + return true; } + bool Region::verify_start (nframes_t pos) { + if (source() && source()->destructive()) { + return true; + } + for (uint32_t n=0; n < _sources.size(); ++n) { if (pos > _sources[n]->length() - _length) { return false; @@ -1293,6 +1361,10 @@ Region::verify_start (nframes_t pos) bool Region::verify_start_mutable (nframes_t& new_start) { + if (source() && source()->destructive()) { + return true; + } + for (uint32_t n=0; n < _sources.size(); ++n) { if (new_start > _sources[n]->length() - _length) { new_start = _sources[n]->length() - _length; diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 8193d4ed77..084c4e58b5 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -80,10 +80,11 @@ Route::init () _muted = false; _soloed = false; _solo_safe = false; + _recordable = true; + _active = true; _phase_invert = false; _denormal_protection = false; order_keys[strdup (N_("signal"))] = order_key_cnt++; - _active = true; _silent = false; _meter_point = MeterPostFader; _initial_delay = 0; @@ -1662,10 +1663,14 @@ Route::add_processor_from_xml (const XMLNode& node) if ((prop = node.property ("type")) != 0) { boost::shared_ptr<Processor> processor; + bool have_insert = false; - if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") { - + if (prop->value() == "ladspa" || prop->value() == "Ladspa" || + prop->value() == "vst" || + prop->value() == "audiounit") { + processor.reset (new PluginInsert(_session, node)); + have_insert = true; } else if (prop->value() == "port") { @@ -1674,19 +1679,20 @@ Route::add_processor_from_xml (const XMLNode& node) } else if (prop->value() == "send") { processor.reset (new Send (_session, node)); + have_insert = true; } else { error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg; } - + add_processor (processor); } else { error << _("Processor XML node has no type property") << endmsg; } } - + catch (failed_constructor &err) { warning << _("processor could not be created. Ignored.") << endmsg; return; @@ -1732,7 +1738,8 @@ Route::_set_state (const XMLNode& node, bool call_base) if ((prop = node.property (X_("denormal-protection"))) != 0) { set_denormal_protection (prop->value()=="yes"?true:false, this); } - + + _active = true; if ((prop = node.property (X_("active"))) != 0) { set_active (prop->value() == "yes"); } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index e155800d23..a7f85a5c84 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -97,6 +97,14 @@ static const int CPU_CACHE_ALIGN = 64; static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */ #endif +bool Session::_disable_all_loaded_plugins = false; + +Session::compute_peak_t Session::compute_peak = 0; +Session::find_peaks_t Session::find_peaks = 0; +Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0; +Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0; +Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0; + sigc::signal<int> Session::AskAboutPendingState; sigc::signal<void> Session::SendFeedback; @@ -105,9 +113,9 @@ sigc::signal<void> Session::StartTimeChanged; sigc::signal<void> Session::EndTimeChanged; Session::Session (AudioEngine &eng, - string fullpath, - string snapshot_name, - string* mix_template) + const string& fullpath, + const string& snapshot_name, + string mix_template) : _engine (eng), _scratch_buffers(new BufferSet()), @@ -127,62 +135,29 @@ Session::Session (AudioEngine &eng, _click_io ((IO*) 0), main_outs (0) { + bool new_session; + if (!eng.connected()) { throw failed_constructor(); } + + cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl; n_physical_outputs = _engine.n_physical_outputs(); n_physical_inputs = _engine.n_physical_inputs(); first_stage_init (fullpath, snapshot_name); - initialize_start_and_end_locations(0, compute_initial_length ()); - - if(mix_template) { - // try and create a new session directory - try - { - if(!_session_dir->create()) { - // an existing session. - // throw a_more_meaningful_exception() - destroy (); - throw failed_constructor (); - } - } - catch(sys::filesystem_error& ex) - { - destroy (); - throw failed_constructor (); - } - - if(!create_session_file_from_template (*mix_template)) { - destroy (); - throw failed_constructor (); - } - - cerr << "Creating session " << fullpath - <<" using template" << *mix_template - << endl; - } else { - // must be an existing session - try - { - // ensure the necessary session subdirectories exist - // in case the directory structure has changed etc. - _session_dir->create(); - } - catch(sys::filesystem_error& ex) - { + new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)); + if (new_session) { + if (create (new_session, mix_template, compute_initial_length())) { + cerr << "create failed\n"; destroy (); throw failed_constructor (); } - - cerr << "Loading session " << fullpath - << " using snapshot " << snapshot_name << " (1)" - << endl; } - - if (second_stage_init (false)) { + + if (second_stage_init (new_session)) { destroy (); throw failed_constructor (); } @@ -228,6 +203,8 @@ Session::Session (AudioEngine &eng, main_outs (0) { + bool new_session; + if (!eng.connected()) { throw failed_constructor(); } @@ -247,11 +224,13 @@ Session::Session (AudioEngine &eng, first_stage_init (fullpath, snapshot_name); - initialize_start_and_end_locations(0, initial_length); - - if (!_session_dir->create () || !create_session_file ()) { - destroy (); - throw failed_constructor (); + new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)); + + if (new_session) { + if (create (new_session, string(), initial_length)) { + destroy (); + throw failed_constructor (); + } } { @@ -286,7 +265,7 @@ Session::Session (AudioEngine &eng, Config->set_input_auto_connect (input_ac); Config->set_output_auto_connect (output_ac); - if (second_stage_init (true)) { + if (second_stage_init (new_session)) { destroy (); throw failed_constructor (); } @@ -3273,7 +3252,7 @@ Session::midi_path_from_name (string name) return spath; } - + boost::shared_ptr<MidiSource> Session::create_midi_source_for_session (MidiDiskstream& ds) { diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index afb284b0f4..148ff92739 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -233,10 +233,6 @@ Session::butler_thread_work () } } - //for (i = diskstreams.begin(); i != diskstreams.end(); ++i) { - // cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl; - //} - if (transport_work_requested()) { butler_transport_work (); } @@ -249,10 +245,23 @@ Session::butler_thread_work () boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader (); +// for (i = dsl->begin(); i != dsl->end(); ++i) { +// cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl; +// } + for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) { boost::shared_ptr<Diskstream> ds = *i; + /* don't read inactive tracks */ + + /*IO* io = ds->io(); + + if (ds->io() && !ds->io()->active()) { + cerr << "Skip inactive diskstream " << ds->io()->name() << endl; + continue; + }*/ + switch (ds->do_refill ()) { case 0: bytes += ds->read_data_count(); @@ -294,6 +303,9 @@ Session::butler_thread_work () for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) { // cerr << "write behind for " << (*i)->name () << endl; + + /* note that we still try to flush diskstreams attached to inactive routes + */ switch ((*i)->do_flush (Session::ButlerContext)) { case 0: diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc index bf1d9f1a09..f1355b331b 100644 --- a/libs/ardour/session_events.cc +++ b/libs/ardour/session_events.cc @@ -41,6 +41,7 @@ static const char* event_names[] = { "SetDiskstreamSpeed", "Locate", "LocateRoll", + "LocateRollLocate", "SetLoop", "PunchIn", "PunchOut", @@ -351,6 +352,13 @@ Session::process_event (Event* ev) _send_smpte_update = true; break; + case Event::LocateRollLocate: + // locate is handled by ::request_roll_at_and_return() + _requested_return_frame = ev->target_frame; + set_transport_speed (ev->speed, true); + break; + + case Event::SetTransportSpeed: set_transport_speed (ev->speed, ev->yes_or_no); break; diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index b0addd21f6..b1058f2e7e 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -428,6 +428,10 @@ AudioExportSpecification::process (nframes_t nframes) int Session::start_audio_export (AudioExportSpecification& spec) { + if (!_engine.connected()) { + return -1; + } + if (spec.prepare (current_block_size, frame_rate())) { return -1; } diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 44b63e0875..6476ab30f7 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -52,6 +52,8 @@ Session::process (nframes_t nframes) { MIDI::Manager::instance()->cycle_start(nframes); + _silent = false; + if (synced_to_jack() && waiting_to_start) { if ( _engine.transport_state() == AudioEngine::TransportRolling) { actually_start_transport (); @@ -302,7 +304,7 @@ Session::process_with_events (nframes_t nframes) } if (!process_can_proceed()) { - no_roll (nframes, 0); + _silent = true; return; } @@ -317,8 +319,8 @@ Session::process_with_events (nframes_t nframes) Event* this_event; Events::iterator the_next_one; - if (post_transport_work & (PostTransportLocate|PostTransportStop)) { - no_roll (nframes, 0); + if (!process_can_proceed()) { + _silent = true; return; } @@ -494,7 +496,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) << endl; #endif - if (Config->get_timecode_source_is_synced()) { + if (_slave->is_always_synced() || Config->get_timecode_source_is_synced()) { /* if the TC source is synced, then we assume that its speed is binary: 0.0 or 1.0 @@ -642,7 +644,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) slave_state = Stopped; } - if (slave_state == Running && !Config->get_timecode_source_is_synced()) { + if (slave_state == Running && !_slave->is_always_synced() && !Config->get_timecode_source_is_synced()) { if (_transport_speed != 0.0f) { @@ -743,67 +745,64 @@ Session::process_without_events (nframes_t nframes) long frames_moved; nframes_t offset = 0; - { - if (post_transport_work & (PostTransportLocate|PostTransportStop)) { - no_roll (nframes, 0); - return; - } - - if (!_exporting && _slave) { - if (!follow_slave (nframes, 0)) { - return; - } - } + if (!process_can_proceed()) { + _silent = true; + return; + } - if (_transport_speed == 0) { - no_roll (nframes, 0); + if (!_exporting && _slave) { + if (!follow_slave (nframes, 0)) { return; } send_midi_time_code_for_cycle(nframes); + } + + if (_transport_speed == 0) { + no_roll (nframes, 0); + return; + } - if (actively_recording()) { - stop_limit = max_frames; + if (actively_recording()) { + stop_limit = max_frames; + } else { + if (Config->get_stop_at_session_end()) { + stop_limit = current_end_frame(); } else { - if (Config->get_stop_at_session_end()) { - stop_limit = current_end_frame(); - } else { - stop_limit = max_frames; - } + stop_limit = max_frames; } + } - if (maybe_stop (stop_limit)) { - no_roll (nframes, 0); - return; - } + if (maybe_stop (stop_limit)) { + no_roll (nframes, 0); + return; + } - if (maybe_sync_start (nframes, offset)) { - return; - } + if (maybe_sync_start (nframes, offset)) { + return; + } - click (_transport_frame, nframes, offset); + click (_transport_frame, nframes, offset); - prepare_diskstreams (); + prepare_diskstreams (); - frames_moved = (long) floor (_transport_speed * nframes); + frames_moved = (long) floor (_transport_speed * nframes); - if (process_routes (nframes, offset)) { - no_roll (nframes, offset); - return; - } - - commit_diskstreams (nframes, session_needs_butler); + if (process_routes (nframes, offset)) { + no_roll (nframes, offset); + return; + } - if (frames_moved < 0) { - decrement_transport_position (-frames_moved); - } else { - increment_transport_position (frames_moved); - } + commit_diskstreams (nframes, session_needs_butler); - maybe_stop (stop_limit); - check_declick_out (); + if (frames_moved < 0) { + decrement_transport_position (-frames_moved); + } else { + increment_transport_position (frames_moved); + } - } /* implicit release of route lock */ + maybe_stop (stop_limit); + check_declick_out (); if (session_needs_butler) summon_butler (); diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 877047d93a..fa4b103958 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -418,49 +418,106 @@ Session::setup_raid_path (string path) last_rr_session_dir = session_dirs.begin(); } -void -Session::initialize_start_and_end_locations (nframes_t start, nframes_t end) +int +Session::create (bool& new_session, const string& mix_template, nframes_t initial_length) { - start_location->set_end (start); - _locations.add (start_location); + string dir; - end_location->set_end (end); - _locations.add (end_location); -} + if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg; + return -1; + } -bool -Session::create_session_file () -{ - _state_of_the_state = Clean; + dir = session_directory().peak_path().to_string(); - if (save_state (_current_snapshot_name)) { - error << "Could not create new session file" << endmsg; - return false; + if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; + return -1; } - return true; -} -bool -Session::create_session_file_from_template (const string& template_path) -{ - sys::path session_file_path(_session_dir->root_path()); + dir = session_directory().sound_path().to_string(); - session_file_path /= _name + statefile_suffix; + if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; + return -1; + } + + dir = session_directory().midi_path().to_string(); - try - { - sys::copy_file (template_path, session_file_path); + if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; + return -1; } - catch(sys::filesystem_error& ex) - { - error << string_compose (_("Could not use session template %1 to create new session (%2)."), - template_path, ex.what()) - << endmsg; - return false; + + dir = session_directory().dead_sound_path().to_string(); + + if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; + return -1; } - return true; + + dir = session_directory().export_path().to_string(); + + if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; + return -1; + } + + + /* check new_session so we don't overwrite an existing one */ + + if (!mix_template.empty()) { + std::string in_path = mix_template; + + ifstream in(in_path.c_str()); + + if (in){ + string out_path = _path; + out_path += _name; + out_path += statefile_suffix; + + ofstream out(out_path.c_str()); + + if (out){ + out << in.rdbuf(); + + // okay, session is set up. Treat like normal saved + // session from now on. + + new_session = false; + return 0; + + } else { + error << string_compose (_("Could not open %1 for writing mix template"), out_path) + << endmsg; + return -1; + } + + } else { + error << string_compose (_("Could not open mix template %1 for reading"), in_path) + << endmsg; + return -1; + } + + } + + /* set initial start + end point */ + + start_location->set_end (0); + _locations.add (start_location); + + end_location->set_end (initial_length); + _locations.add (end_location); + + _state_of_the_state = Clean; + + + save_state (""); + + return 0; } + int Session::load_diskstreams (const XMLNode& node) { @@ -2767,7 +2824,7 @@ Session::restore_history (string snapshot_name) const string xml_filename = snapshot_name + history_suffix; const sys::path xml_path = _session_dir->root_path() / xml_filename; - info << string_compose(_("Loading history from '%1'."), xml_path.to_string()) << endmsg; + cerr << "Loading history from " << xml_path.to_string() << endmsg; if (!sys::exists (xml_path)) { info << string_compose (_("%1: no history file \"%2\" for this session."), diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 2776fbf41d..1398872b36 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -29,6 +29,7 @@ #include <glibmm/thread.h> #include <pbd/pthread_utils.h> #include <pbd/memento_command.h> +#include <pbd/stacktrace.h> #include <midi++/mmc.h> #include <midi++/port.h> @@ -392,17 +393,35 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) update_latency_compensation (true, abort); } - if ((Config->get_slave_source() == None && Config->get_auto_return()) || (post_transport_work & PostTransportLocate) || synced_to_jack()) { + if ((Config->get_slave_source() == None && Config->get_auto_return()) || + (post_transport_work & PostTransportLocate) || + (_requested_return_frame >= 0) || + synced_to_jack()) { if (pending_locate_flush) { flush_all_inserts (); } - if (((Config->get_slave_source() == None && Config->get_auto_return()) || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) { + if (((Config->get_slave_source() == None && Config->get_auto_return()) || + synced_to_jack() || + _requested_return_frame >= 0) && + !(post_transport_work & PostTransportLocate)) { - _transport_frame = last_stop_frame; + bool do_locate = false; + + if (_requested_return_frame >= 0) { + _transport_frame = _requested_return_frame; + _requested_return_frame = -1; + do_locate = true; + } else { + _transport_frame = last_stop_frame; + } if (synced_to_jack() && !play_loop) { + do_locate = true; + } + + if (do_locate) { // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl; _engine.transport_locate (_transport_frame); } @@ -478,7 +497,9 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) } - PositionChanged (_transport_frame); /* EMIT SIGNAL */ + nframes_t tf = _transport_frame; + + PositionChanged (tf); /* EMIT SIGNAL */ TransportStateChange (); /* EMIT SIGNAL */ /* and start it up again if relevant */ @@ -1203,6 +1224,14 @@ Session::setup_auto_play () } void +Session::request_roll_at_and_return (nframes_t start, nframes_t return_to) +{ + request_locate (start, false); + Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0); + queue_event (ev); +} + +void Session::request_bounded_roll (nframes_t start, nframes_t end) { request_stop (); diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index b8d82bdb9d..29f36cc2cd 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -345,7 +345,8 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n // FIXME: assumes tempo never changes after start const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat( - _session.engine().frame_rate()); + _session.engine().frame_rate(), + _session.tempo_map().meter_at(_timeline_position)); const uint64_t start_ticks = (uint64_t)((start / frames_per_beat) * _ppqn); @@ -456,8 +457,9 @@ SMFSource::append_event_unlocked(const MidiEvent& ev) assert(ev.time() >= _last_ev_time); // FIXME: assumes tempo never changes after start - const double frames_per_beat = _session.tempo_map().tempo_at - (_timeline_position).frames_per_beat(_session.engine().frame_rate()); + const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat( + _session.engine().frame_rate(), + _session.tempo_map().meter_at(_timeline_position)); const uint32_t delta_time = (uint32_t)((ev.time() - _last_ev_time) / frames_per_beat * _ppqn); @@ -888,7 +890,8 @@ SMFSource::load_model(bool lock, bool force_reload) // FIXME: assumes tempo never changes after start const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat( - _session.engine().frame_rate()); + _session.engine().frame_rate(), + _session.tempo_map().meter_at(_timeline_position)); uint32_t delta_t = 0; int ret; diff --git a/libs/ardour/sndfile_helpers.cc b/libs/ardour/sndfile_helpers.cc index 96dc2c7779..58a51f8bbe 100644 --- a/libs/ardour/sndfile_helpers.cc +++ b/libs/ardour/sndfile_helpers.cc @@ -33,33 +33,27 @@ using namespace std; const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1] = { N_("WAV"), N_("AIFF"), - N_("raw (no header)"), - N_("PAF (Ensoniq Paris)"), - N_("AU (Sun/NeXT)"), - N_("IRCAM"), + N_("CAF"), N_("W64 (64 bit WAV)"), + N_("raw (no header)"), 0 }; const char* const sndfile_file_endings_strings[SNDFILE_HEADER_FORMATS+1] = { N_(".wav"), N_(".aiff"), - N_(".raw"), - N_(".paf"), - N_(".au"), - N_(".ircam"), + N_(".caf"), N_(".w64"), + N_(".raw"), 0 }; int sndfile_header_formats[SNDFILE_HEADER_FORMATS] = { SF_FORMAT_WAV, SF_FORMAT_AIFF, - SF_FORMAT_RAW, - SF_FORMAT_PAF, - SF_FORMAT_AU, - SF_FORMAT_IRCAM, - SF_FORMAT_W64 + SF_FORMAT_CAF, + SF_FORMAT_W64, + SF_FORMAT_RAW }; const char * const sndfile_bitdepth_formats_strings[SNDFILE_BITDEPTH_FORMATS+1] = { diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc index 89d4e3ed79..661beef40b 100644 --- a/libs/ardour/source_factory.cc +++ b/libs/ardour/source_factory.cc @@ -60,7 +60,7 @@ peak_thread_work () if (SourceFactory::files_with_peaks.empty()) { goto wait; } - + boost::shared_ptr<AudioSource> as (SourceFactory::files_with_peaks.front().lock()); SourceFactory::files_with_peaks.pop_front (); SourceFactory::peak_building_lock.unlock (); @@ -68,7 +68,6 @@ peak_thread_work () if (!as) { continue; } - as->setup_peakfile (); } } diff --git a/libs/ardour/st_pitch.cc b/libs/ardour/st_pitch.cc new file mode 100644 index 0000000000..3999c1a746 --- /dev/null +++ b/libs/ardour/st_pitch.cc @@ -0,0 +1,52 @@ +/* + Copyright (C) 2004-2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <algorithm> +#include <cmath> + +#include <pbd/error.h> + +#include <ardour/types.h> +#include <ardour/pitch.h> +#include <ardour/audiofilesource.h> +#include <ardour/session.h> +#include <ardour/audioregion.h> + +#include "i18n.h" + +using namespace std; +using namespace ARDOUR; +using namespace PBD; + +Pitch::Pitch (Session& s, TimeFXRequest& req) + : Filter (s) + , tsr (req) + +{ + tsr.progress = 0.0f; +} + +int +Pitch::run (boost::shared_ptr<Region> region) +{ + tsr.progress = 1.0f; + tsr.done = true; + + return 1; +} diff --git a/libs/ardour/stretch.cc b/libs/ardour/st_stretch.cc index 64b741d1af..e96cd79f2d 100644 --- a/libs/ardour/stretch.cc +++ b/libs/ardour/st_stretch.cc @@ -35,7 +35,7 @@ using namespace ARDOUR; using namespace PBD; using namespace soundtouch; -Stretch::Stretch (Session& s, TimeStretchRequest& req) +Stretch::Stretch (Session& s, TimeFXRequest& req) : Filter (s) , tsr (req) { @@ -45,7 +45,7 @@ Stretch::Stretch (Session& s, TimeStretchRequest& req) of opposite sign to the length change. */ - percentage = -tsr.fraction; + percentage = -tsr.time_fraction; st.setSampleRate (s.frame_rate()); st.setChannels (1); @@ -64,14 +64,8 @@ Stretch::~Stretch () } int -Stretch::run (boost::shared_ptr<Region> r) +Stretch::run (boost::shared_ptr<Region> a_region) { - boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r); - - if (!region) { - return -1; - } - SourceList nsrcs; nframes_t total_frames; nframes_t done; @@ -85,6 +79,8 @@ Stretch::run (boost::shared_ptr<Region> r) tsr.progress = 0.0f; tsr.done = false; + + boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion>(a_region); total_frames = region->length() * region->n_channels(); done = 0; @@ -93,7 +89,7 @@ Stretch::run (boost::shared_ptr<Region> r) digits just to disambiguate close but not identical stretches. */ - snprintf (suffix, sizeof (suffix), "@%d", (int) floor (tsr.fraction * 100.0f)); + snprintf (suffix, sizeof (suffix), "@%d", (int) floor (tsr.time_fraction * 100.0f)); /* create new sources */ @@ -109,12 +105,9 @@ Stretch::run (boost::shared_ptr<Region> r) try { for (uint32_t i = 0; i < nsrcs.size(); ++i) { - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (nsrcs[i]); + boost::shared_ptr<AudioSource> asrc + = boost::dynamic_pointer_cast<AudioSource>(nsrcs[i]); - if (!afs) { - continue; - } - nframes_t pos = 0; nframes_t this_read = 0; @@ -131,7 +124,7 @@ Stretch::run (boost::shared_ptr<Region> r) */ if ((this_read = region->master_read_at (buffer, buffer, gain_buffer, pos + region->position(), this_time)) != this_time) { - error << string_compose (_("tempoize: error reading data from %1"), afs->name()) << endmsg; + error << string_compose (_("tempoize: error reading data from %1"), asrc->name()) << endmsg; goto out; } @@ -143,8 +136,8 @@ Stretch::run (boost::shared_ptr<Region> r) st.putSamples (buffer, this_read); while ((this_read = st.receiveSamples (buffer, bufsize)) > 0 && !tsr.cancel) { - if (afs->write (buffer, this_read) != this_read) { - error << string_compose (_("error writing tempo-adjusted data to %1"), afs->name()) << endmsg; + if (asrc->write (buffer, this_read) != this_read) { + error << string_compose (_("error writing tempo-adjusted data to %1"), asrc->name()) << endmsg; goto out; } } @@ -155,8 +148,8 @@ Stretch::run (boost::shared_ptr<Region> r) } while (!tsr.cancel && (this_read = st.receiveSamples (buffer, bufsize)) > 0) { - if (afs->write (buffer, this_read) != this_read) { - error << string_compose (_("error writing tempo-adjusted data to %1"), afs->name()) << endmsg; + if (asrc->write (buffer, this_read) != this_read) { + error << string_compose (_("error writing tempo-adjusted data to %1"), asrc->name()) << endmsg; goto out; } } @@ -184,25 +177,20 @@ Stretch::run (boost::shared_ptr<Region> r) /* now reset ancestral data for each new region */ for (vector<boost::shared_ptr<Region> >::iterator x = results.begin(); x != results.end(); ++x) { - - boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (*x); - - assert (region != 0); - - nframes64_t astart = region->ancestral_start(); - nframes64_t alength = region->ancestral_length(); + nframes64_t astart = (*x)->ancestral_start(); + nframes64_t alength = (*x)->ancestral_length(); nframes_t start; nframes_t length; // note: tsr.fraction is a percentage of original length. 100 = no change, // 50 is half as long, 200 is twice as long, etc. - float stretch = region->stretch() * (tsr.fraction/100.0); + float stretch = (*x)->stretch() * (tsr.time_fraction/100.0); - start = (nframes_t) floor (astart + ((astart - region->start()) / stretch)); + start = (nframes_t) floor (astart + ((astart - (*x)->start()) / stretch)); length = (nframes_t) floor (alength / stretch); - region->set_ancestral_data (start, length, stretch); + (*x)->set_ancestral_data (start, length, stretch, (*x)->shift()); } out: diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index cd59e93054..780f5c6a5d 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -43,12 +43,17 @@ Tempo TempoMap::_default_tempo (120.0); const double Meter::ticks_per_beat = 1920.0; +double Tempo::frames_per_beat (nframes_t sr, const Meter& meter) const +{ + return ((60.0 * sr) / (_beats_per_minute * meter.note_divisor()/_note_type)); +} + /***********************************************************************/ double Meter::frames_per_bar (const Tempo& tempo, nframes_t sr) const { - return ((60.0 * sr * _beats_per_bar) / tempo.beats_per_minute()); + return ((60.0 * sr * _beats_per_bar) / (tempo.beats_per_minute() * _note_type/tempo.note_type())); } /***********************************************************************/ @@ -86,6 +91,16 @@ TempoSection::TempoSection (const XMLNode& node) error << _("TempoSection XML node has an illegal \"beats_per_minute\" value") << endmsg; throw failed_constructor(); } + + if ((prop = node.property ("note-type")) == 0) { + /* older session, make note type be quarter by default */ + _note_type = 4.0; + } else { + if (sscanf (prop->value().c_str(), "%lf", &_note_type) != 1 || _note_type < 1.0) { + error << _("TempoSection XML node has an illegal \"note-type\" value") << endmsg; + throw failed_constructor(); + } + } if ((prop = node.property ("movable")) == 0) { error << _("TempoSection XML node has no \"movable\" property") << endmsg; @@ -109,6 +124,8 @@ TempoSection::get_state() const root->add_property ("start", buf); snprintf (buf, sizeof (buf), "%f", _beats_per_minute); root->add_property ("beats-per-minute", buf); + snprintf (buf, sizeof (buf), "%f", _note_type); + root->add_property ("note-type", buf); snprintf (buf, sizeof (buf), "%s", movable()?"yes":"no"); root->add_property ("movable", buf); @@ -210,7 +227,7 @@ TempoMap::TempoMap (nframes_t fr) start.beats = 1; start.ticks = 0; - TempoSection *t = new TempoSection (start, _default_tempo.beats_per_minute()); + TempoSection *t = new TempoSection (start, _default_tempo.beats_per_minute(), _default_tempo.note_type()); MeterSection *m = new MeterSection (start, _default_meter.beats_per_bar(), _default_meter.note_divisor()); t->set_movable (false); @@ -359,7 +376,7 @@ TempoMap::add_tempo (const Tempo& tempo, BBT_Time where) where.ticks = 0; - do_insert (new TempoSection (where, tempo.beats_per_minute())); + do_insert (new TempoSection (where, tempo.beats_per_minute(), tempo.note_type())); } StateChanged (Change (0)); @@ -614,7 +631,7 @@ TempoMap::bbt_time_with_metric (nframes_t frame, BBT_Time& bbt, const Metric& me const double beats_per_bar = metric.meter().beats_per_bar(); const double frames_per_bar = metric.meter().frames_per_bar (metric.tempo(), _frame_rate); - const double beat_frames = metric.tempo().frames_per_beat (_frame_rate); + const double beat_frames = metric.tempo().frames_per_beat (_frame_rate, metric.meter()); /* now compute how far beyond that point we actually are. */ @@ -667,7 +684,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con + start.ticks/Meter::ticks_per_beat; - start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate)); + start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); m = metric_at(end); @@ -676,7 +693,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con beat_offset = bar_offset * m.meter().beats_per_bar() - (m.start().beats -1) + (end.beats - 1) + end.ticks/Meter::ticks_per_beat; - end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate)); + end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); frames = end_frame - start_frame; @@ -697,7 +714,7 @@ TempoMap::count_frames_between_metrics (const Meter& meter, const Tempo& tempo, double beat_frames = 0; beats_per_bar = meter.beats_per_bar(); - beat_frames = tempo.frames_per_beat (_frame_rate); + beat_frames = tempo.frames_per_beat (_frame_rate,meter); frames = 0; @@ -1088,7 +1105,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const beats_per_bar = meter->beats_per_bar (); frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); - beat_frames = tempo->frames_per_beat (_frame_rate); + beat_frames = tempo->frames_per_beat (_frame_rate, *meter); if (meter->frame() > tempo->frame()) { bar = meter->start().bars; @@ -1198,7 +1215,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const beats_per_bar = meter->beats_per_bar (); frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); - beat_frames = tempo->frames_per_beat (_frame_rate); + beat_frames = tempo->frames_per_beat (_frame_rate, *meter); ++i; } @@ -1304,7 +1321,7 @@ TempoMap::dump (std::ostream& o) const for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) { - o << "Tempo @ " << *i << ' ' << t->beats_per_minute() << " BPM at " << t->start() << " frame= " << t->frame() << " (move? " + o << "Tempo @ " << *i << ' ' << t->beats_per_minute() << " BPM (denom = " << t->note_type() << ") at " << t->start() << " frame= " << t->frame() << " (move? " << t->movable() << ')' << endl; } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) { o << "Meter @ " << *i << ' ' << m->beats_per_bar() << '/' << m->note_divisor() << " at " << m->start() << " frame= " << m->frame() diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index ac0e6849f9..5969d91982 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -142,7 +142,7 @@ VSTPlugin::get_state() { XMLNode *root = new XMLNode (state_node_name()); LocaleGuard lg (X_("POSIX")); - + if (_plugin->flags & effFlagsProgramChunks) { /* fetch the current chunk */ @@ -418,10 +418,12 @@ VSTPlugin::activate () _plugin->dispatcher (_plugin, effMainsChanged, 0, 1, NULL, 0.0f); } -uint32_t +string VSTPlugin::unique_id() const { - return _plugin->uniqueID; + char buf[32]; + snprintf (buf, sizeof (buf), "%d", _plugin->uniqueID); + return string (buf); } |