Merge lp:~zequence/ubuntu/trusty/ardour3/fix-for-1450992 into lp:ubuntu/trusty/ardour3

Proposed by Kaj Ailomaa
Status: Needs review
Proposed branch: lp:~zequence/ubuntu/trusty/ardour3/fix-for-1450992
Merge into: lp:ubuntu/trusty/ardour3
Diff against target: 7848 lines (+3913/-931) (has conflicts)
125 files modified
.pc/applied-patches (+2/-0)
.pc/log-stdout.patch/wscript (+822/-0)
.pc/midi-data-loss.patch/libs/ardour/smf_source.cc (+764/-0)
.pc/wscript.patch/wscript (+4/-4)
debian/changelog (+75/-12)
debian/control (+6/-0)
debian/control.in (+1/-1)
debian/patches/log-stdout.patch (+25/-0)
debian/patches/midi-data-loss.patch (+62/-0)
debian/patches/series (+2/-0)
debian/rules (+2/-1)
gtk2_ardour/add_video_dialog.cc (+4/-1)
gtk2_ardour/ardev_common.sh.in (+1/-0)
gtk2_ardour/ardour.menus.in (+1/-0)
gtk2_ardour/ardour_ui.cc (+6/-3)
gtk2_ardour/ardour_ui.h (+1/-0)
gtk2_ardour/ardour_ui_dialogs.cc (+15/-0)
gtk2_ardour/ardour_ui_ed.cc (+1/-0)
gtk2_ardour/audio_region_view.cc (+2/-2)
gtk2_ardour/audio_region_view.h (+1/-1)
gtk2_ardour/automation_region_view.cc (+9/-3)
gtk2_ardour/automation_region_view.h (+1/-1)
gtk2_ardour/automation_time_axis.cc (+2/-2)
gtk2_ardour/automation_time_axis.h (+1/-1)
gtk2_ardour/editor.bindings (+1/-0)
gtk2_ardour/editor.h (+1/-1)
gtk2_ardour/editor_actions.cc (+30/-30)
gtk2_ardour/editor_audio_import.cc (+30/-18)
gtk2_ardour/editor_drag.cc (+17/-3)
gtk2_ardour/editor_mouse.cc (+8/-4)
gtk2_ardour/editor_ops.cc (+11/-6)
gtk2_ardour/editor_regions.cc (+1/-1)
gtk2_ardour/editor_rulers.cc (+15/-15)
gtk2_ardour/ergonomic-us.bindings.in (+1/-0)
gtk2_ardour/gain_meter.cc (+8/-2)
gtk2_ardour/level_meter.cc (+1/-0)
gtk2_ardour/midi_time_axis.cc (+42/-3)
gtk2_ardour/mixer_strip.cc (+60/-28)
gtk2_ardour/mixer_ui.cc (+39/-0)
gtk2_ardour/mixer_ui.h (+6/-0)
gtk2_ardour/mnemonic-us.bindings.in (+2/-1)
gtk2_ardour/opts.cc (+1/-1)
gtk2_ardour/panner_ui.cc (+81/-1)
gtk2_ardour/panner_ui.h (+1/-0)
gtk2_ardour/plugin_ui.cc (+2/-0)
gtk2_ardour/processor_box.cc (+70/-0)
gtk2_ardour/route_ui.cc (+2/-2)
gtk2_ardour/sfdb_ui.cc (+94/-3)
gtk2_ardour/stereo_panner.cc (+36/-16)
gtk2_ardour/transcode_ffmpeg.cc (+34/-15)
gtk2_ardour/transcode_ffmpeg.h (+1/-0)
gtk2_ardour/transcode_video_dialog.cc (+22/-10)
gtk2_ardour/transcode_video_dialog.h (+3/-3)
gtk2_ardour/video_server_dialog.cc (+7/-2)
gtk2_ardour/video_timeline.cc (+36/-5)
libs/ardour/amp.cc (+4/-19)
libs/ardour/ardour/audio_buffer.h (+5/-4)
libs/ardour/ardour/audio_diskstream.h (+0/-1)
libs/ardour/ardour/audiofilesource.h (+6/-4)
libs/ardour/ardour/buffer.h (+2/-10)
libs/ardour/ardour/diskstream.h (+2/-0)
libs/ardour/ardour/file_source.h (+9/-2)
libs/ardour/ardour/midi_buffer.h (+3/-0)
libs/ardour/ardour/midi_diskstream.h (+1/-1)
libs/ardour/ardour/midi_region.h (+1/-0)
libs/ardour/ardour/midi_source.h (+15/-3)
libs/ardour/ardour/public_diskstream.h (+1/-1)
libs/ardour/ardour/session.h (+8/-11)
libs/ardour/ardour/smf_source.h (+7/-4)
libs/ardour/ardour/sndfilesource.h (+10/-1)
libs/ardour/ardour/source.h (+2/-1)
libs/ardour/ardour/source_factory.h (+3/-0)
libs/ardour/ardour/track.h (+1/-1)
libs/ardour/ardour/vestige/aeffectx.h (+21/-0)
libs/ardour/audio_buffer.cc (+4/-7)
libs/ardour/audio_diskstream.cc (+26/-20)
libs/ardour/audiofilesource.cc (+17/-0)
libs/ardour/automation_control.cc (+14/-6)
libs/ardour/automation_watch.cc (+1/-1)
libs/ardour/coreaudiosource.cc (+14/-1)
libs/ardour/delivery.cc (+4/-0)
libs/ardour/diskstream.cc (+0/-1)
libs/ardour/enums.cc (+1/-0)
libs/ardour/export_channel.cc (+1/-1)
libs/ardour/file_source.cc (+71/-55)
libs/ardour/filter.cc (+2/-3)
libs/ardour/import.cc (+26/-76)
libs/ardour/internal_send.cc (+1/-1)
libs/ardour/lv2_evbuf.c (+1/-1)
libs/ardour/lv2_plugin.cc (+2/-22)
libs/ardour/midi_diskstream.cc (+30/-19)
libs/ardour/midi_region.cc (+21/-3)
libs/ardour/midi_source.cc (+10/-27)
libs/ardour/plugin_insert.cc (+21/-5)
libs/ardour/plugin_manager.cc (+3/-1)
libs/ardour/route.cc (+46/-2)
libs/ardour/session.cc (+199/-245)
libs/ardour/session_state.cc (+80/-60)
libs/ardour/smf_source.cc (+154/-16)
libs/ardour/sndfilesource.cc (+67/-12)
libs/ardour/source_factory.cc (+37/-0)
libs/ardour/tempo.cc (+10/-5)
libs/ardour/track.cc (+3/-3)
libs/evoral/evoral/ControlList.hpp (+1/-1)
libs/evoral/evoral/SMF.hpp (+1/-0)
libs/evoral/src/Control.cpp (+9/-2)
libs/evoral/src/ControlList.cpp (+20/-14)
libs/evoral/src/SMF.cpp (+22/-0)
libs/evoral/test/SequenceTest.cpp (+1/-1)
libs/midi++2/midnam_patch.cc (+3/-4)
libs/panners/vbap/vbap.cc (+1/-1)
libs/panners/vbap/vbap_speakers.cc (+81/-20)
libs/pbd/clear_dir.cc (+37/-0)
libs/pbd/file_utils.cc (+67/-18)
libs/pbd/pbd/clear_dir.h (+1/-0)
libs/surfaces/generic_midi/midicontrollable.cc (+19/-2)
libs/surfaces/mackie/mackie_control_protocol.cc (+16/-2)
libs/surfaces/mackie/mackie_control_protocol.h (+2/-0)
libs/surfaces/mackie/strip.cc (+10/-1)
libs/surfaces/mackie/strip.h (+1/-0)
libs/surfaces/mackie/surface.cc (+32/-3)
patchfiles/Korg_Volca_Bass.midnam (+37/-0)
patchfiles/Korg_Volca_Beats.midnam (+58/-0)
patchfiles/Korg_Volca_Keys.midnam (+41/-0)
wscript (+13/-4)
Text conflict in debian/changelog
Text conflict in debian/control
Text conflict in gtk2_ardour/mixer_strip.cc
Text conflict in gtk2_ardour/panner_ui.cc
Text conflict in gtk2_ardour/processor_box.cc
Text conflict in gtk2_ardour/sfdb_ui.cc
Text conflict in gtk2_ardour/stereo_panner.cc
Text conflict in libs/ardour/ardour/audio_buffer.h
Text conflict in libs/ardour/ardour/vestige/aeffectx.h
Text conflict in libs/ardour/audio_buffer.cc
Text conflict in libs/ardour/delivery.cc
Text conflict in libs/ardour/plugin_insert.cc
Text conflict in libs/ardour/route.cc
Text conflict in libs/ardour/smf_source.cc
Text conflict in libs/ardour/source_factory.cc
Text conflict in libs/panners/vbap/vbap_speakers.cc
To merge this branch: bzr merge lp:~zequence/ubuntu/trusty/ardour3/fix-for-1450992
Reviewer Review Type Date Requested Status
Micah Gersten (community) Disapprove
Review via email: mp+258099@code.launchpad.net

Description of the change

Fix for bug 1450992.

This is the last release of ardour3.

To post a comment you must log in.
Revision history for this message
Micah Gersten (micahg) wrote :

Rejecting in favor of a full backport SRU

review: Disapprove

Unmerged revisions

15. By Adrian Knoth

Fix MIDI data loss when editing (Closes: #772118)

14. By Adrian Knoth

Reupload with waf fixes from 3.5.380~dfsg-2 and -3

13. By Felipe Sateler

Prevent build failures in slower architectures by
forcing waf logging to stdout instead of stderr.

12. By Felipe Sateler

* Team upload.
* Pass correct -j flag to waf. Closes: #748584

11. By Adrian Knoth

Imported Upstream version 3.5.380~dfsg

10. By Adrian Knoth

* Imported Upstream version 3.5.357~dfsg
* Critical bugfix release. All users are recommended to upgrade.
* Details: https://community.ardour.org/node/8015

9. By Adrian Knoth

[ Jaromír Mikeš ]
* Use higher resolution picture for desktop icon (Closes: #729890).

[ Adrian Knoth ]
* Change Name entry in desktop file (Closes: #729890)
* Remove python runtime dependencies
* Imported Upstream version 3.5.308~dfsg (Closes: #734079 #733969)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.pc/applied-patches'
2--- .pc/applied-patches 2013-11-06 13:22:44 +0000
3+++ .pc/applied-patches 2015-05-02 14:23:30 +0000
4@@ -1,2 +1,4 @@
5 waf.patch
6 wscript.patch
7+log-stdout.patch
8+midi-data-loss.patch
9
10=== added directory '.pc/log-stdout.patch'
11=== added file '.pc/log-stdout.patch/wscript'
12--- .pc/log-stdout.patch/wscript 1970-01-01 00:00:00 +0000
13+++ .pc/log-stdout.patch/wscript 2015-05-02 14:23:30 +0000
14@@ -0,0 +1,822 @@
15+#!/usr/bin/env python
16+from waflib.extras import autowaf as autowaf
17+from waflib import Options
18+import os
19+import re
20+import string
21+import subprocess
22+import sys
23+
24+def fetch_git_revision ():
25+ cmd = "git describe HEAD"
26+ output = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0].splitlines()
27+ rev = output[0].decode ('utf-8')
28+ return rev
29+
30+def fetch_tarball_revision ():
31+ if not os.path.exists ('libs/ardour/revision.cc'):
32+ print 'This tarball was not created correctly - it is missing libs/ardour/revision.cc'
33+ sys.exit (1)
34+ with open('libs/ardour/revision.cc') as f:
35+ content = f.readlines()
36+ remove_punctuation_map = dict((ord(char), None) for char in '";')
37+ return content[1].decode('utf-8').strip().split(' ')[7].translate (remove_punctuation_map)
38+
39+rev = fetch_tarball_revision ()
40+
41+#
42+# rev is now of the form MAJOR.MINOR-rev-commit
43+#
44+
45+parts = rev.split ('.')
46+MAJOR = parts[0]
47+MINOR = parts[1]
48+MICRO = parts[2]
49+
50+V = MAJOR + '.' + MINOR + '.' + MICRO
51+#
52+# it is important that VERSION *not* be unicode string
53+# because if it is, it breaks waf somehow.
54+#
55+VERSION = V.encode ('ascii', 'ignore')
56+APPNAME = 'Ardour' + MAJOR
57+
58+# Mandatory variables
59+top = '.'
60+out = 'build'
61+
62+children = [
63+ 'libs/pbd',
64+ 'libs/midi++2',
65+ 'libs/evoral',
66+ 'libs/vamp-sdk',
67+ 'libs/qm-dsp',
68+ 'libs/vamp-plugins',
69+ 'libs/taglib',
70+ 'libs/libltc',
71+ 'libs/rubberband',
72+ 'libs/surfaces',
73+ 'libs/panners',
74+ 'libs/backends',
75+ 'libs/timecode',
76+ 'libs/ardour',
77+ 'libs/gtkmm2ext',
78+ 'libs/clearlooks-newer',
79+ 'libs/audiographer',
80+ 'libs/plugins/reasonablesynth.lv2',
81+ 'gtk2_ardour',
82+ 'export',
83+ 'midi_maps',
84+ 'mcp',
85+ 'patchfiles'
86+]
87+
88+i18n_children = [
89+ 'gtk2_ardour',
90+ 'libs/ardour',
91+ 'libs/gtkmm2ext',
92+]
93+
94+if sys.platform == 'linux2':
95+ children += [ 'tools/sanity_check' ]
96+ lxvst_default = True
97+elif sys.platform == 'darwin':
98+ children += [ 'libs/appleutility' ]
99+ lxvst_default = False
100+else:
101+ lxvst_default = False
102+
103+# Version stuff
104+
105+def fetch_gcc_version (CC):
106+ cmd = "LANG= %s --version" % CC
107+ output = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0].splitlines()
108+ o = output[0].decode('utf-8')
109+ version = o.split(' ')[2].split('.')
110+ return version
111+
112+def create_stored_revision():
113+ rev = ""
114+ if os.path.exists('.git'):
115+ rev = fetch_git_revision();
116+ print("Git version: " + rev + "\n")
117+ elif os.path.exists('libs/ardour/revision.cc'):
118+ print("Using packaged revision")
119+ return
120+ else:
121+ print("Missing libs/ardour/revision.cc. Blame the packager.")
122+ sys.exit(-1)
123+
124+ try:
125+ #
126+ # if you change the format of this, be sure to fix fetch_tarball_revision() above
127+ # so that it still works.
128+ #
129+ text = '#include "ardour/revision.h"\n'
130+ text += 'namespace ARDOUR { const char* revision = \"%s\"; }\n' % rev
131+ print('Writing revision info to libs/ardour/revision.cc using ' + rev)
132+ o = open('libs/ardour/revision.cc', 'w')
133+ o.write(text)
134+ o.close()
135+ except IOError:
136+ print('Could not open libs/ardour/revision.cc for writing\n')
137+ sys.exit(-1)
138+
139+def set_compiler_flags (conf,opt):
140+ #
141+ # Compiler flags and other system-dependent stuff
142+ #
143+
144+ build_host_supports_sse = False
145+
146+ # Flags necessary for building
147+ compiler_flags = [] # generic
148+ c_flags = [] # C-specific
149+ cxx_flags = [] # C++-specific
150+ linker_flags = []
151+
152+ # Optimization flags (overridable)
153+ optimization_flags = []
154+
155+ # Debugging flags
156+ debug_flags = []
157+
158+ u = os.uname ()
159+ cpu = u[4]
160+ platform = u[0].lower()
161+ version = u[2]
162+
163+ # waf adds -O0 -g itself. thanks waf!
164+ is_clang = conf.env['CXX'][0].endswith('clang++')
165+
166+ if conf.options.cxx11:
167+ conf.check_cxx(cxxflags=["-std=c++11"])
168+ cxx_flags.append('-std=c++11')
169+ if platform == "darwin":
170+ cxx_flags.append('-stdlib=libc++')
171+ link_flags.append('-lc++')
172+ # Prevents visibility issues in standard headers
173+ conf.define("_DARWIN_C_SOURCE", 1)
174+
175+ if conf.options.asan:
176+ conf.check_cxx(cxxflags=["-fsanitize=address", "-fno-omit-frame-pointer"], linkflags=["-fsanitize=address"])
177+ cxx_flags.append('-fsanitize=address')
178+ cxx_flags.append('-fno-omit-frame-pointer')
179+ linker_flags.append('-fsanitize=address')
180+
181+ if is_clang and platform == "darwin":
182+ # Silence warnings about the non-existing osx clang compiler flags
183+ # -compatibility_version and -current_version. These are Waf
184+ # generated and not needed with clang
185+ cxx_flags.append("-Qunused-arguments")
186+
187+ if opt.gprofile:
188+ debug_flags = [ '-pg' ]
189+
190+ # Autodetect
191+ if opt.dist_target == 'auto':
192+ if platform == 'darwin':
193+ # The [.] matches to the dot after the major version, "." would match any character
194+ if re.search ("^[0-7][.]", version) != None:
195+ conf.env['build_target'] = 'panther'
196+ elif re.search ("^8[.]", version) != None:
197+ conf.env['build_target'] = 'tiger'
198+ elif re.search ("^9[.]", version) != None:
199+ conf.env['build_target'] = 'leopard'
200+ elif re.search ("^10[.]", version) != None:
201+ conf.env['build_target'] = 'snowleopard'
202+ elif re.search ("^11[.]", version) != None:
203+ conf.env['build_target'] = 'lion'
204+ else:
205+ conf.env['build_target'] = 'mountainlion'
206+ else:
207+ match = re.search(
208+ "(?P<cpu>i[0-6]86|x86_64|powerpc|ppc|ppc64|arm|s390x?)",
209+ cpu)
210+ if (match):
211+ conf.env['build_target'] = match.group("cpu")
212+ if re.search("i[0-5]86", conf.env['build_target']):
213+ conf.env['build_target'] = "i386"
214+ else:
215+ conf.env['build_target'] = 'none'
216+ else:
217+ conf.env['build_target'] = opt.dist_target
218+
219+ if conf.env['build_target'] == 'snowleopard':
220+ #
221+ # stupid OS X 10.6 has a bug in math.h that prevents llrint and friends
222+ # from being visible.
223+ #
224+ compiler_flags.append ('-U__STRICT_ANSI__')
225+
226+ if cpu == 'powerpc' and conf.env['build_target'] != 'none':
227+ #
228+ # Apple/PowerPC optimization options
229+ #
230+ # -mcpu=7450 does not reliably work with gcc 3.*
231+ #
232+ if opt.dist_target == 'panther' or opt.dist_target == 'tiger':
233+ if platform == 'darwin':
234+ # optimization_flags.extend ([ "-mcpu=7450", "-faltivec"])
235+ # to support g3s but still have some optimization for above
236+ compiler_flags.extend ([ "-mcpu=G3", "-mtune=7450"])
237+ else:
238+ compiler_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
239+ else:
240+ compiler_flags.extend([ "-mcpu=750", "-mmultiple" ])
241+ compiler_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
242+ optimization_flags.extend (["-Os"])
243+
244+ elif ((re.search ("i[0-9]86", cpu) != None) or (re.search ("x86_64", cpu) != None)) and conf.env['build_target'] != 'none':
245+
246+
247+ #
248+ # ARCH_X86 means anything in the x86 family from i386 to x86_64
249+ # the compile-time presence of the macro _LP64 is used to
250+ # distingush 32 and 64 bit assembler
251+ #
252+
253+ if (re.search ("(i[0-9]86|x86_64)", cpu) != None):
254+ compiler_flags.append ("-DARCH_X86")
255+
256+ if platform == 'linux' :
257+
258+ #
259+ # determine processor flags via /proc/cpuinfo
260+ #
261+
262+ if conf.env['build_target'] != 'i386':
263+
264+ flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
265+ x86_flags = flag_line.split (": ")[1:][0].split ()
266+
267+ if "mmx" in x86_flags:
268+ compiler_flags.append ("-mmmx")
269+ if "sse" in x86_flags:
270+ build_host_supports_sse = True
271+ if "3dnow" in x86_flags:
272+ compiler_flags.append ("-m3dnow")
273+
274+ if cpu == "i586":
275+ compiler_flags.append ("-march=i586")
276+ elif cpu == "i686":
277+ compiler_flags.append ("-march=i686")
278+
279+ if not is_clang and ((conf.env['build_target'] == 'i686') or (conf.env['build_target'] == 'x86_64')) and build_host_supports_sse:
280+ compiler_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
281+
282+ # end of processor-specific section
283+
284+ # optimization section
285+ if conf.env['FPU_OPTIMIZATION']:
286+ if sys.platform == 'darwin':
287+ compiler_flags.append("-DBUILD_VECLIB_OPTIMIZATIONS");
288+ linker_flags.append("-framework Accelerate")
289+ elif conf.env['build_target'] == 'i686' or conf.env['build_target'] == 'x86_64':
290+ compiler_flags.append ("-DBUILD_SSE_OPTIMIZATIONS")
291+ if not build_host_supports_sse:
292+ print("\nWarning: you are building Ardour with SSE support even though your system does not support these instructions. (This may not be an error, especially if you are a package maintainer)")
293+
294+ # end optimization section
295+
296+ #
297+ # no VST on x86_64
298+ #
299+
300+ if conf.env['build_target'] == 'x86_64' and opt.windows_vst:
301+ print("\n\n==================================================")
302+ print("You cannot use VST plugins with a 64 bit host. Please run waf with --windows-vst=0")
303+ print("\nIt is theoretically possible to build a 32 bit host on a 64 bit system.")
304+ print("However, this is tricky and not recommended for beginners.")
305+ sys.exit (-1)
306+
307+ if opt.lxvst:
308+ if conf.env['build_target'] == 'x86_64':
309+ compiler_flags.append("-DLXVST_64BIT")
310+ else:
311+ compiler_flags.append("-DLXVST_32BIT")
312+
313+ #
314+ # a single way to test if we're on OS X
315+ #
316+
317+ if conf.env['build_target'] in ['panther', 'tiger', 'leopard', 'snowleopard' ]:
318+ conf.define ('IS_OSX', 1)
319+ # force tiger or later, to avoid issues on PPC which defaults
320+ # back to 10.1 if we don't tell it otherwise.
321+
322+ compiler_flags.extend(
323+ ("-DMAC_OS_X_VERSION_MIN_REQUIRED=1040",
324+ '-mmacosx-version-min=10.4'))
325+
326+ elif conf.env['build_target'] in [ 'lion', 'mountainlion' ]:
327+ compiler_flags.extend(
328+ ("-DMAC_OS_X_VERSION_MIN_REQUIRED=1070",
329+ '-mmacosx-version-min=10.7'))
330+ else:
331+ conf.define ('IS_OSX', 0)
332+
333+ #
334+ # save off CPU element in an env
335+ #
336+ conf.define ('CONFIG_ARCH', cpu)
337+
338+ #
339+ # ARCH="..." overrides all
340+ #
341+
342+ if opt.arch != None:
343+ optimization_flags = opt.arch.split()
344+
345+ #
346+ # prepend boiler plate optimization flags that work on all architectures
347+ #
348+
349+ optimization_flags[:0] = ["-pipe"]
350+
351+ # don't prepend optimization flags if "-O<something>" is present
352+ prepend_opt_flags = True
353+ for flag in optimization_flags:
354+ if flag.startswith("-O"):
355+ prepend_opt_flags = False
356+ break
357+
358+ if prepend_opt_flags:
359+ optimization_flags[:0] = [
360+ "-O3",
361+ "-fomit-frame-pointer",
362+ "-ffast-math",
363+ "-fstrength-reduce"
364+ ]
365+
366+ if opt.stl_debug:
367+ cxx_flags.append("-D_GLIBCXX_DEBUG")
368+
369+ if conf.env['DEBUG_RT_ALLOC']:
370+ compiler_flags.append('-DDEBUG_RT_ALLOC')
371+ linker_flags.append('-ldl')
372+
373+ if conf.env['DEBUG_DENORMAL_EXCEPTION']:
374+ compiler_flags.append('-DDEBUG_DENORMAL_EXCEPTION')
375+
376+ if opt.universal:
377+ if opt.generic:
378+ print ('Specifying Universal and Generic builds at the same time is not supported')
379+ sys.exit (1)
380+ else:
381+ if not Options.options.nocarbon:
382+ compiler_flags.extend(("-arch", "i386", "-arch", "ppc"))
383+ linker_flags.extend(("-arch", "i386", "-arch", "ppc"))
384+ else:
385+ compiler_flags.extend(
386+ ("-arch", "x86_64", "-arch", "i386", "-arch", "ppc"))
387+ linker_flags.extend(
388+ ("-arch", "x86_64", "-arch", "i386", "-arch", "ppc"))
389+ else:
390+ if opt.generic:
391+ compiler_flags.extend(('-arch', 'i386'))
392+ linker_flags.extend(('-arch', 'i386'))
393+
394+ #
395+ # warnings flags
396+ #
397+
398+ compiler_flags.extend(
399+ ('-Wall', '-Wpointer-arith', '-Wcast-qual', '-Wcast-align'))
400+
401+ c_flags.extend(('-Wstrict-prototypes', '-Wmissing-prototypes'))
402+ cxx_flags.append('-Woverloaded-virtual')
403+
404+ #
405+ # more boilerplate
406+ #
407+
408+ # need ISOC9X for llabs()
409+ compiler_flags.extend(
410+ ('-DBOOST_SYSTEM_NO_DEPRECATED', '-D_ISOC9X_SOURCE',
411+ '-D_LARGEFILE64_SOURCE', '-D_FILE_OFFSET_BITS=64'))
412+ cxx_flags.extend(('-D__STDC_LIMIT_MACROS', '-D__STDC_FORMAT_MACROS'))
413+
414+ if opt.nls:
415+ compiler_flags.append('-DENABLE_NLS')
416+
417+ if opt.debug:
418+ conf.env.append_value('CFLAGS', debug_flags)
419+ conf.env.append_value('CXXFLAGS', debug_flags)
420+ else:
421+ conf.env.append_value('CFLAGS', optimization_flags)
422+ conf.env.append_value('CXXFLAGS', optimization_flags)
423+
424+ if opt.backtrace:
425+ if platform != 'darwin' and not is_clang:
426+ linker_flags += [ '-rdynamic' ]
427+
428+ conf.env.append_value('CFLAGS', compiler_flags)
429+ conf.env.append_value('CFLAGS', c_flags)
430+ conf.env.append_value('CXXFLAGS', compiler_flags)
431+ conf.env.append_value('CXXFLAGS', cxx_flags)
432+ conf.env.append_value('LINKFLAGS', linker_flags)
433+
434+#----------------------------------------------------------------
435+
436+# Waf stages
437+
438+def options(opt):
439+ opt.load('compiler_c')
440+ opt.load('compiler_cxx')
441+ autowaf.set_options(opt, debug_by_default=True)
442+ opt.add_option('--program-name', type='string', action='store', default='Ardour', dest='program_name',
443+ help='The user-visible name of the program being built')
444+ opt.add_option('--arch', type='string', action='store', dest='arch',
445+ help='Architecture-specific compiler flags')
446+ opt.add_option('--backtrace', action='store_true', default=True, dest='backtrace',
447+ help='Compile with -rdynamic -- allow obtaining backtraces from within Ardour')
448+ opt.add_option('--no-carbon', action='store_true', default=False, dest='nocarbon',
449+ help='Compile without support for AU Plugins with only CARBON UI (needed for 64bit)')
450+ opt.add_option('--boost-sp-debug', action='store_true', default=False, dest='boost_sp_debug',
451+ help='Compile with Boost shared pointer debugging')
452+ opt.add_option('--depstack-root', type='string', default='~', dest='depstack_root',
453+ help='Directory/folder where dependency stack trees (gtk, a3) can be found (defaults to ~)')
454+ opt.add_option('--dist-target', type='string', default='auto', dest='dist_target',
455+ help='Specify the target for cross-compiling [auto,none,x86,i386,i686,x86_64,powerpc,tiger,leopard]')
456+ opt.add_option('--fpu-optimization', action='store_true', default=True, dest='fpu_optimization',
457+ help='Build runtime checked assembler code (default)')
458+ opt.add_option('--no-fpu-optimization', action='store_false', dest='fpu_optimization')
459+ opt.add_option('--freedesktop', action='store_true', default=False, dest='freedesktop',
460+ help='Install MIME type, icons and .desktop file as per freedesktop.org standards')
461+ opt.add_option('--freebie', action='store_true', default=False, dest='freebie',
462+ help='Build a version suitable for distribution as a zero-cost binary')
463+ opt.add_option('--gprofile', action='store_true', default=False, dest='gprofile',
464+ help='Compile for use with gprofile')
465+ opt.add_option('--internal-shared-libs', action='store_true', default=True, dest='internal_shared_libs',
466+ help='Build internal libs as shared libraries')
467+ opt.add_option('--internal-static-libs', action='store_false', dest='internal_shared_libs',
468+ help='Build internal libs as static libraries')
469+ opt.add_option('--use-external-libs', action='store_true', default=False, dest='use_external_libs',
470+ help='Use external/system versions of some bundled libraries')
471+ opt.add_option('--lv2', action='store_true', default=True, dest='lv2',
472+ help='Compile with support for LV2 (if Lilv+Suil is available)')
473+ opt.add_option('--no-lv2', action='store_false', dest='lv2',
474+ help='Do not compile with support for LV2')
475+ opt.add_option('--lxvst', action='store_true', default=lxvst_default, dest='lxvst',
476+ help='Compile with support for linuxVST plugins')
477+ opt.add_option('--nls', action='store_true', default=True, dest='nls',
478+ help='Enable i18n (native language support) (default)')
479+ opt.add_option('--no-nls', action='store_false', dest='nls')
480+ opt.add_option('--phone-home', action='store_true', default=True, dest='phone_home',
481+ help='Contact ardour.org at startup for new announcements')
482+ opt.add_option('--no-phone-home', action='store_false', dest='phone_home',
483+ help='Do not contact ardour.org at startup for new announcements')
484+ opt.add_option('--stl-debug', action='store_true', default=False, dest='stl_debug',
485+ help='Build with debugging for the STL')
486+ opt.add_option('--rt-alloc-debug', action='store_true', default=False, dest='rt_alloc_debug',
487+ help='Build with debugging for memory allocation in the real-time thread')
488+ opt.add_option('--pt-timing', action='store_true', default=False, dest='pt_timing',
489+ help='Build with logging of timing in the process thread(s)')
490+ opt.add_option('--denormal-exception', action='store_true', default=False, dest='denormal_exception',
491+ help='Raise a floating point exception if a denormal is detected')
492+ opt.add_option('--test', action='store_true', default=False, dest='build_tests',
493+ help="Build unit tests")
494+ opt.add_option('--run-tests', action='store_true', default=False, dest='run_tests',
495+ help="Run tests after build")
496+ opt.add_option('--single-tests', action='store_true', default=False, dest='single_tests',
497+ help="Build a single executable for each unit test")
498+ #opt.add_option('--tranzport', action='store_true', default=False, dest='tranzport',
499+ # help='Compile with support for Frontier Designs Tranzport (if libusb is available)')
500+ opt.add_option('--universal', action='store_true', default=False, dest='universal',
501+ help='Compile as universal binary (OS X ONLY, requires that external libraries are universal)')
502+ opt.add_option('--generic', action='store_true', default=False, dest='generic',
503+ help='Compile with -arch i386 (OS X ONLY)')
504+ opt.add_option('--versioned', action='store_true', default=False, dest='versioned',
505+ help='Add revision information to executable name inside the build directory')
506+ opt.add_option('--windows-vst', action='store_true', default=False, dest='windows_vst',
507+ help='Compile with support for Windows VST')
508+ opt.add_option('--windows-key', type='string', action='store', dest='windows_key', default='Mod4><Super',
509+ help='X Modifier(s) (Mod1,Mod2, etc) for the Windows key (X11 builds only). ' +
510+ 'Multiple modifiers must be separated by \'><\'')
511+ opt.add_option('--boost-include', type='string', action='store', dest='boost_include', default='',
512+ help='directory where Boost header files can be found')
513+ opt.add_option('--also-include', type='string', action='store', dest='also_include', default='',
514+ help='additional include directory where header files can be found (split multiples with commas)')
515+ opt.add_option('--also-libdir', type='string', action='store', dest='also_libdir', default='',
516+ help='additional include directory where shared libraries can be found (split multiples with commas)')
517+ opt.add_option('--wine-include', type='string', action='store', dest='wine_include', default='/usr/include/wine/windows',
518+ help='directory where Wine\'s Windows header files can be found')
519+ opt.add_option('--noconfirm', action='store_true', default=False, dest='noconfirm',
520+ help='Do not ask questions that require confirmation during the build')
521+ opt.add_option('--cxx11', action='store_true', default=False, dest='cxx11',
522+ help='Turn on c++11 compiler flags (-std=c++11)')
523+ opt.add_option('--address-sanitizer', action='store_true', default=False, dest='asan',
524+ help='Turn on AddressSanitizer (requires GCC >= 4.8 or clang >= 3.1)')
525+ for i in children:
526+ opt.recurse(i)
527+
528+def sub_config_and_use(conf, name, has_objects = True):
529+ conf.recurse(name)
530+ autowaf.set_local_lib(conf, name, has_objects)
531+
532+def configure(conf):
533+ conf.load('compiler_c')
534+ conf.load('compiler_cxx')
535+ conf.env['VERSION'] = VERSION
536+ conf.env['MAJOR'] = MAJOR
537+ conf.env['MINOR'] = MINOR
538+ conf.line_just = 52
539+ autowaf.set_recursive()
540+ autowaf.configure(conf)
541+ autowaf.display_header('Ardour Configuration')
542+
543+ gcc_versions = fetch_gcc_version(str(conf.env['CC']))
544+ if not Options.options.debug and gcc_versions[0] == '4' and gcc_versions[1] > '4':
545+ print('Version 4.5 of gcc is not ready for use when compiling Ardour with optimization.')
546+ print('Please use a different version or re-configure with --debug')
547+ exit (1)
548+
549+ # systems with glibc have libintl builtin. systems without require explicit
550+ # linkage against libintl.
551+ #
552+
553+ pkg_config_path = os.getenv('PKG_CONFIG_PATH')
554+ user_gtk_root = os.path.expanduser (Options.options.depstack_root + '/gtk/inst')
555+
556+ if pkg_config_path is not None and pkg_config_path.find (user_gtk_root) >= 0:
557+ # told to search user_gtk_root
558+ prefinclude = ''.join ([ '-I', user_gtk_root + '/include'])
559+ preflib = ''.join ([ '-L', user_gtk_root + '/lib'])
560+ conf.env.append_value('CFLAGS', [ prefinclude ])
561+ conf.env.append_value('CXXFLAGS', [prefinclude ])
562+ conf.env.append_value('LINKFLAGS', [ preflib ])
563+ autowaf.display_msg(conf, 'Will build against private GTK dependency stack in ' + user_gtk_root, 'yes')
564+ else:
565+ autowaf.display_msg(conf, 'Will build against private GTK dependency stack', 'no')
566+
567+ if sys.platform == 'darwin':
568+ conf.define ('NEED_INTL', 1)
569+ autowaf.display_msg(conf, 'Will use explicit linkage against libintl in ' + user_gtk_root, 'yes')
570+ else:
571+ # libintl is part of the system, so use it
572+ autowaf.display_msg(conf, 'Will rely on libintl built into libc', 'yes')
573+
574+ user_ardour_root = os.path.expanduser (Options.options.depstack_root + '/a3/inst')
575+ if pkg_config_path is not None and pkg_config_path.find (user_ardour_root) >= 0:
576+ # told to search user_ardour_root
577+ prefinclude = ''.join ([ '-I', user_ardour_root + '/include'])
578+ preflib = ''.join ([ '-L', user_ardour_root + '/lib'])
579+ conf.env.append_value('CFLAGS', [ prefinclude ])
580+ conf.env.append_value('CXXFLAGS', [prefinclude ])
581+ conf.env.append_value('LINKFLAGS', [ preflib ])
582+ autowaf.display_msg(conf, 'Will build against private Ardour dependency stack in ' + user_ardour_root, 'yes')
583+ else:
584+ autowaf.display_msg(conf, 'Will build against private Ardour dependency stack', 'no')
585+
586+ if Options.options.freebie:
587+ conf.env.append_value ('CFLAGS', '-DNO_PLUGIN_STATE')
588+ conf.env.append_value ('CXXFLAGS', '-DNO_PLUGIN_STATE')
589+ conf.define ('NO_PLUGIN_STATE', 1)
590+
591+ if sys.platform == 'darwin':
592+
593+ # this is required, potentially, for anything we link and then relocate into a bundle
594+ conf.env.append_value('LINKFLAGS', [ '-Xlinker', '-headerpad_max_install_names' ])
595+
596+ conf.define ('HAVE_COREAUDIO', 1)
597+ conf.define ('AUDIOUNIT_SUPPORT', 1)
598+
599+ conf.define ('GTKOSX', 1)
600+ conf.define ('TOP_MENUBAR',1)
601+ conf.define ('GTKOSX',1)
602+
603+ # It would be nice to be able to use this to force back-compatibility with 10.4
604+ # but even by the time of 11, the 10.4 SDK is no longer available in any normal
605+ # way.
606+ #
607+ #conf.env.append_value('CXXFLAGS_OSX', "-isysroot /Developer/SDKs/MacOSX10.4u.sdk")
608+ #conf.env.append_value('CFLAGS_OSX', "-isysroot /Developer/SDKs/MacOSX10.4u.sdk")
609+ #conf.env.append_value('LINKFLAGS_OSX', "-sysroot /Developer/SDKs/MacOSX10.4u.sdk")
610+ #conf.env.append_value('LINKFLAGS_OSX', "-sysroot /Developer/SDKs/MacOSX10.4u.sdk")
611+
612+ conf.env.append_value('CXXFLAGS_OSX', "-msse")
613+ conf.env.append_value('CFLAGS_OSX', "-msse")
614+ conf.env.append_value('CXXFLAGS_OSX', "-msse2")
615+ conf.env.append_value('CFLAGS_OSX', "-msse2")
616+ #
617+ # TODO: The previous sse flags NEED to be based
618+ # off processor type. Need to add in a check
619+ # for that.
620+ #
621+ conf.env.append_value('CXXFLAGS_OSX', '-F/System/Library/Frameworks')
622+ conf.env.append_value('CXXFLAGS_OSX', '-F/Library/Frameworks')
623+
624+ conf.env.append_value('LINKFLAGS_OSX', ['-framework', 'AppKit'])
625+ conf.env.append_value('LINKFLAGS_OSX', ['-framework', 'CoreAudio'])
626+ conf.env.append_value('LINKFLAGS_OSX', ['-framework', 'CoreAudioKit'])
627+ conf.env.append_value('LINKFLAGS_OSX', ['-framework', 'CoreFoundation'])
628+ conf.env.append_value('LINKFLAGS_OSX', ['-framework', 'CoreServices'])
629+
630+ conf.env.append_value('LINKFLAGS_OSX', ['-undefined', 'dynamic_lookup' ])
631+ conf.env.append_value('LINKFLAGS_OSX', ['-flat_namespace'])
632+
633+ conf.env.append_value('CXXFLAGS_AUDIOUNITS', "-DAUDIOUNIT_SUPPORT")
634+ conf.env.append_value('LINKFLAGS_AUDIOUNITS', ['-framework', 'AudioToolbox', '-framework', 'AudioUnit'])
635+ conf.env.append_value('LINKFLAGS_AUDIOUNITS', ['-framework', 'Cocoa'])
636+
637+ if re.search ("^[1-9][0-9]\.", os.uname()[2]) == None and not Options.options.nocarbon:
638+ conf.env.append_value('CXXFLAGS_AUDIOUNITS', "-DWITH_CARBON")
639+ conf.env.append_value('LINKFLAGS_AUDIOUNITS', ['-framework', 'Carbon'])
640+ else:
641+ print ('No Carbon support available for this build\n')
642+
643+
644+ if Options.options.internal_shared_libs:
645+ conf.define('INTERNAL_SHARED_LIBS', 1)
646+
647+ if Options.options.use_external_libs:
648+ conf.define('USE_EXTERNAL_LIBS', 1)
649+
650+ if Options.options.boost_include != '':
651+ conf.env.append_value('CXXFLAGS', '-I' + Options.options.boost_include)
652+
653+ if Options.options.also_include != '':
654+ conf.env.append_value('CXXFLAGS', '-I' + Options.options.also_include)
655+ conf.env.append_value('CFLAGS', '-I' + Options.options.also_include)
656+
657+ if Options.options.also_libdir != '':
658+ conf.env.append_value('LDFLAGS', '-L' + Options.options.also_libdir)
659+
660+ if Options.options.boost_sp_debug:
661+ conf.env.append_value('CXXFLAGS', '-DBOOST_SP_ENABLE_DEBUG_HOOKS')
662+
663+ conf.check_cxx(fragment = "#include <boost/version.hpp>\nint main(void) { return (BOOST_VERSION >= 103900 ? 0 : 1); }\n",
664+ execute = "1",
665+ mandatory = True,
666+ msg = 'Checking for boost library >= 1.39',
667+ okmsg = 'ok',
668+ errmsg = 'too old\nPlease install boost version 1.39 or higher.')
669+
670+ autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB', atleast_version='2.2')
671+ autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD', atleast_version='2.2')
672+ autowaf.check_pkg(conf, 'glibmm-2.4', uselib_store='GLIBMM', atleast_version='2.32.0')
673+ autowaf.check_pkg(conf, 'sndfile', uselib_store='SNDFILE', atleast_version='1.0.18')
674+ autowaf.check_pkg(conf, 'giomm-2.4', uselib_store='GIOMM', atleast_version='2.2')
675+ autowaf.check_pkg(conf, 'libcurl', uselib_store='CURL', atleast_version='7.0.0')
676+ autowaf.check_pkg(conf, 'liblo', uselib_store='LO', atleast_version='0.26')
677+
678+ conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL')
679+
680+ # Tell everyone that this is a waf build
681+
682+ conf.env.append_value('CFLAGS', '-DWAF_BUILD')
683+ conf.env.append_value('CXXFLAGS', '-DWAF_BUILD')
684+
685+ # Set up waf environment and C defines
686+ opts = Options.options
687+ if opts.phone_home:
688+ conf.define('PHONE_HOME', 1)
689+ conf.env['PHONE_HOME'] = True
690+ if opts.fpu_optimization:
691+ conf.env['FPU_OPTIMIZATION'] = True
692+ if opts.nls:
693+ conf.define('ENABLE_NLS', 1)
694+ conf.env['ENABLE_NLS'] = True
695+ if opts.build_tests:
696+ conf.env['BUILD_TESTS'] = True
697+ conf.env['RUN_TESTS'] = opts.run_tests
698+ if opts.single_tests:
699+ conf.env['SINGLE_TESTS'] = opts.single_tests
700+ #if opts.tranzport:
701+ # conf.env['TRANZPORT'] = 1
702+ if opts.windows_vst:
703+ conf.define('WINDOWS_VST_SUPPORT', 1)
704+ conf.env['WINDOWS_VST_SUPPORT'] = True
705+ conf.env.append_value('CFLAGS', '-I' + Options.options.wine_include)
706+ conf.env.append_value('CXXFLAGS', '-I' + Options.options.wine_include)
707+ autowaf.check_header(conf, 'cxx', 'windows.h', mandatory = True)
708+ if opts.lxvst:
709+ conf.define('LXVST_SUPPORT', 1)
710+ conf.env['LXVST_SUPPORT'] = True
711+ conf.define('WINDOWS_KEY', opts.windows_key)
712+ conf.env['PROGRAM_NAME'] = opts.program_name
713+ if opts.rt_alloc_debug:
714+ conf.define('DEBUG_RT_ALLOC', 1)
715+ conf.env['DEBUG_RT_ALLOC'] = True
716+ if opts.pt_timing:
717+ conf.define('PT_TIMING', 1)
718+ conf.env['PT_TIMING'] = True
719+ if opts.denormal_exception:
720+ conf.define('DEBUG_DENORMAL_EXCEPTION', 1)
721+ conf.env['DEBUG_DENORMAL_EXCEPTION'] = True
722+ if opts.build_tests:
723+ autowaf.check_pkg(conf, 'cppunit', uselib_store='CPPUNIT', atleast_version='1.12.0', mandatory=True)
724+
725+ set_compiler_flags (conf, Options.options)
726+
727+ for i in children:
728+ sub_config_and_use(conf, i)
729+
730+ # Fix utterly braindead FLAC include path to not smash assert.h
731+ conf.env['INCLUDES_FLAC'] = []
732+
733+ config_text = open('libs/ardour/config_text.cc', "w")
734+ config_text.write('''#include "ardour/ardour.h"
735+namespace ARDOUR {
736+const char* const ardour_config_info = "\\n\\
737+''')
738+
739+ def write_config_text(title, val):
740+ autowaf.display_msg(conf, title, val)
741+ config_text.write(title + ': ')
742+ config_text.write(str(val))
743+ config_text.write("\\n\\\n")
744+
745+ write_config_text('Build documentation', conf.env['DOCS'])
746+ write_config_text('Debuggable build', conf.env['DEBUG'])
747+ write_config_text('Export all symbols (backtrace)', opts.backtrace)
748+ write_config_text('Install prefix', conf.env['PREFIX'])
749+ write_config_text('Strict compiler flags', conf.env['STRICT'])
750+ write_config_text('Internal Shared Libraries', conf.is_defined('INTERNAL_SHARED_LIBS'))
751+ write_config_text('Use External Libraries', conf.is_defined('USE_EXTERNAL_LIBS'))
752+
753+ write_config_text('Architecture flags', opts.arch)
754+ write_config_text('Aubio', conf.is_defined('HAVE_AUBIO'))
755+ write_config_text('AudioUnits', conf.is_defined('AUDIOUNIT_SUPPORT'))
756+ write_config_text('No plugin state', conf.is_defined('NO_PLUGIN_STATE'))
757+ write_config_text('Build target', conf.env['build_target'])
758+ write_config_text('CoreAudio', conf.is_defined('HAVE_COREAUDIO'))
759+ write_config_text('Debug RT allocations', conf.is_defined('DEBUG_RT_ALLOC'))
760+ write_config_text('Process thread timing', conf.is_defined('PT_TIMING'))
761+ write_config_text('Denormal exceptions', conf.is_defined('DEBUG_DENORMAL_EXCEPTION'))
762+ write_config_text('FLAC', conf.is_defined('HAVE_FLAC'))
763+ write_config_text('FPU optimization', opts.fpu_optimization)
764+ write_config_text('Freedesktop files', opts.freedesktop)
765+ write_config_text('LV2 UI embedding', conf.is_defined('HAVE_SUIL'))
766+ write_config_text('LV2 support', conf.is_defined('LV2_SUPPORT'))
767+ write_config_text('LXVST support', conf.is_defined('LXVST_SUPPORT'))
768+ write_config_text('OGG', conf.is_defined('HAVE_OGG'))
769+ write_config_text('Phone home', conf.is_defined('PHONE_HOME'))
770+ write_config_text('Program name', opts.program_name)
771+ write_config_text('Rubberband', conf.is_defined('HAVE_RUBBERBAND'))
772+ write_config_text('Samplerate', conf.is_defined('HAVE_SAMPLERATE'))
773+# write_config_text('Soundtouch', conf.is_defined('HAVE_SOUNDTOUCH'))
774+ write_config_text('Translation', opts.nls)
775+# write_config_text('Tranzport', opts.tranzport)
776+ write_config_text('Unit tests', conf.env['BUILD_TESTS'])
777+ write_config_text('Universal binary', opts.universal)
778+ write_config_text('Generic x86 CPU', opts.generic)
779+ write_config_text('Windows VST support', opts.windows_vst)
780+ write_config_text('Wiimote support', conf.is_defined('BUILD_WIIMOTE'))
781+ write_config_text('Windows key', opts.windows_key)
782+
783+ write_config_text('C compiler flags', conf.env['CFLAGS'])
784+ write_config_text('C++ compiler flags', conf.env['CXXFLAGS'])
785+ write_config_text('Linker flags', conf.env['LINKFLAGS'])
786+
787+ config_text.write ('";\n}\n')
788+ config_text.close ()
789+ print('')
790+
791+def build(bld):
792+ create_stored_revision()
793+
794+ # add directories that contain only headers, to workaround an issue with waf
795+
796+ bld.path.find_dir ('libs/evoral/evoral')
797+ if not bld.is_defined('USE_EXTERNAL_LIBS'):
798+ bld.path.find_dir ('libs/vamp-sdk/vamp-sdk')
799+ bld.path.find_dir ('libs/surfaces/control_protocol/control_protocol')
800+ bld.path.find_dir ('libs/timecode/timecode')
801+ if not bld.is_defined('USE_EXTERNAL_LIBS'):
802+ bld.path.find_dir ('libs/libltc/ltc')
803+ bld.path.find_dir ('libs/rubberband/rubberband')
804+ bld.path.find_dir ('libs/gtkmm2ext/gtkmm2ext')
805+ bld.path.find_dir ('libs/ardour/ardour')
806+ if not bld.is_defined('USE_EXTERNAL_LIBS'):
807+ bld.path.find_dir ('libs/taglib/taglib')
808+ bld.path.find_dir ('libs/pbd/pbd')
809+
810+ autowaf.set_recursive()
811+
812+ for i in children:
813+ bld.recurse(i)
814+
815+ bld.install_files (os.path.join(bld.env['SYSCONFDIR'], 'ardour3', ), 'ardour_system.rc')
816+
817+ if bld.env['RUN_TESTS']:
818+ bld.add_post_fun(test)
819+
820+def i18n(bld):
821+ bld.recurse (i18n_children)
822+
823+def i18n_pot(bld):
824+ bld.recurse (i18n_children)
825+
826+def i18n_po(bld):
827+ bld.recurse (i18n_children)
828+
829+def i18n_mo(bld):
830+ bld.recurse (i18n_children)
831+
832+def tarball(bld):
833+ create_stored_revision()
834+
835+def test(bld):
836+ subprocess.call("gtk2_ardour/artest")
837
838=== added directory '.pc/midi-data-loss.patch'
839=== added directory '.pc/midi-data-loss.patch/libs'
840=== added directory '.pc/midi-data-loss.patch/libs/ardour'
841=== added file '.pc/midi-data-loss.patch/libs/ardour/smf_source.cc'
842--- .pc/midi-data-loss.patch/libs/ardour/smf_source.cc 1970-01-01 00:00:00 +0000
843+++ .pc/midi-data-loss.patch/libs/ardour/smf_source.cc 2015-05-02 14:23:30 +0000
844@@ -0,0 +1,764 @@
845+/*
846+ Copyright (C) 2006 Paul Davis
847+ Author: David Robillard
848+
849+ This program is free software; you can redistribute it and/or modify
850+ it under the terms of the GNU General Public License as published by
851+ the Free Software Foundation; either version 2 of the License, or
852+ (at your option) any later version.
853+
854+ This program is distributed in the hope that it will be useful,
855+ but WITHOUT ANY WARRANTY; without even the implied warranty of
856+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
857+ GNU General Public License for more details.
858+
859+ You should have received a copy of the GNU General Public License
860+ along with this program; if not, write to the Free Software
861+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
862+
863+*/
864+
865+#include <vector>
866+
867+#include <sys/time.h>
868+#include <sys/stat.h>
869+#include <unistd.h>
870+#include <errno.h>
871+#include <regex.h>
872+
873+#include "pbd/pathscanner.h"
874+#include "pbd/stl_delete.h"
875+#include "pbd/strsplit.h"
876+
877+#include <glibmm/miscutils.h>
878+#include <glibmm/fileutils.h>
879+
880+#include "evoral/Control.hpp"
881+#include "evoral/evoral/SMF.hpp"
882+
883+#include "ardour/event_type_map.h"
884+#include "ardour/midi_model.h"
885+#include "ardour/midi_ring_buffer.h"
886+#include "ardour/midi_state_tracker.h"
887+#include "ardour/session.h"
888+#include "ardour/smf_source.h"
889+#include "ardour/debug.h"
890+
891+#include "i18n.h"
892+
893+using namespace ARDOUR;
894+using namespace Glib;
895+using namespace PBD;
896+using namespace Evoral;
897+
898+/** Constructor used for new internal-to-session files. File cannot exist. */
899+SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
900+ : Source(s, DataType::MIDI, path, flags)
901+ , MidiSource(s, path, flags)
902+ , FileSource(s, DataType::MIDI, path, string(), flags)
903+ , Evoral::SMF()
904+ , _last_ev_time_beats(0.0)
905+ , _last_ev_time_frames(0)
906+ , _smf_last_read_end (0)
907+ , _smf_last_read_time (0)
908+{
909+ /* note that origin remains empty */
910+
911+ if (init (_path, false)) {
912+ throw failed_constructor ();
913+ }
914+
915+ assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
916+ existence_check ();
917+
918+ _flags = Source::Flag (_flags | Empty);
919+
920+ /* file is not opened until write */
921+
922+ if (flags & Writable) {
923+ return;
924+ }
925+
926+ if (open (_path)) {
927+ throw failed_constructor ();
928+ }
929+
930+ _open = true;
931+}
932+
933+/** Constructor used for external-to-session files. File must exist. */
934+SMFSource::SMFSource (Session& s, const string& path)
935+ : Source(s, DataType::MIDI, path, Source::Flag (0))
936+ , MidiSource(s, path, Source::Flag (0))
937+ , FileSource(s, DataType::MIDI, path, string(), Source::Flag (0))
938+ , Evoral::SMF()
939+ , _last_ev_time_beats(0.0)
940+ , _last_ev_time_frames(0)
941+ , _smf_last_read_end (0)
942+ , _smf_last_read_time (0)
943+{
944+ /* note that origin remains empty */
945+
946+ if (init (_path, true)) {
947+ throw failed_constructor ();
948+ }
949+
950+ assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
951+ existence_check ();
952+
953+ if (_flags & Writable) {
954+ /* file is not opened until write */
955+ return;
956+ }
957+
958+ if (open (_path)) {
959+ throw failed_constructor ();
960+ }
961+
962+ _open = true;
963+}
964+
965+/** Constructor used for existing internal-to-session files. */
966+SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist)
967+ : Source(s, node)
968+ , MidiSource(s, node)
969+ , FileSource(s, node, must_exist)
970+ , _last_ev_time_beats(0.0)
971+ , _last_ev_time_frames(0)
972+ , _smf_last_read_end (0)
973+ , _smf_last_read_time (0)
974+{
975+ if (set_state(node, Stateful::loading_state_version)) {
976+ throw failed_constructor ();
977+ }
978+
979+ /* we expect the file to exist, but if no MIDI data was ever added
980+ it will have been removed at last session close. so, we don't
981+ require it to exist if it was marked Empty.
982+ */
983+
984+ try {
985+
986+ if (init (_path, true)) {
987+ throw failed_constructor ();
988+ }
989+
990+ } catch (MissingSource& err) {
991+
992+ if (_flags & Source::Empty) {
993+ /* we don't care that the file was not found, because
994+ it was empty. But FileSource::init() will have
995+ failed to set our _path correctly, so we have to do
996+ this ourselves. Use the first entry in the search
997+ path for MIDI files, which is assumed to be the
998+ correct "main" location.
999+ */
1000+ std::vector<Glib::ustring> sdirs;
1001+ split (s.source_search_path (DataType::MIDI), sdirs, ':');
1002+ if (sdirs.empty()) {
1003+ fatal << _("Empty MIDI source search path!") << endmsg;
1004+ /*NOTREACHED*/
1005+ }
1006+ _path = Glib::build_filename (sdirs.front(), _path);
1007+ /* This might be important, too */
1008+ _file_is_new = true;
1009+ } else {
1010+ /* pass it on */
1011+ throw;
1012+ }
1013+ }
1014+
1015+ if (!(_flags & Source::Empty)) {
1016+ assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
1017+ existence_check ();
1018+ } else {
1019+ assert (_flags & Source::Writable);
1020+ /* file will be opened on write */
1021+ return;
1022+ }
1023+
1024+ if (open(_path)) {
1025+ throw failed_constructor ();
1026+ }
1027+
1028+ _open = true;
1029+}
1030+
1031+SMFSource::~SMFSource ()
1032+{
1033+ if (removable()) {
1034+ unlink (_path.c_str());
1035+ }
1036+}
1037+
1038+int
1039+SMFSource::open_for_write ()
1040+{
1041+ if (create (_path)) {
1042+ return -1;
1043+ }
1044+ _open = true;
1045+ return 0;
1046+}
1047+
1048+/** All stamps in audio frames */
1049+framecnt_t
1050+SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination,
1051+ framepos_t const source_start,
1052+ framepos_t start,
1053+ framecnt_t duration,
1054+ MidiStateTracker* tracker) const
1055+{
1056+ int ret = 0;
1057+ uint64_t time = 0; // in SMF ticks, 1 tick per _ppqn
1058+
1059+ if (writable() && !_open) {
1060+ /* nothing to read since nothing has ben written */
1061+ return duration;
1062+ }
1063+
1064+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: start %1 duration %2\n", start, duration));
1065+
1066+ // Output parameters for read_event (which will allocate scratch in buffer as needed)
1067+ uint32_t ev_delta_t = 0;
1068+ uint32_t ev_type = 0;
1069+ uint32_t ev_size = 0;
1070+ uint8_t* ev_buffer = 0;
1071+
1072+ size_t scratch_size = 0; // keep track of scratch to minimize reallocs
1073+
1074+ BeatsFramesConverter converter(_session.tempo_map(), source_start);
1075+
1076+ const uint64_t start_ticks = (uint64_t)(converter.from(start) * ppqn());
1077+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: start in ticks %1\n", start_ticks));
1078+
1079+ if (_smf_last_read_end == 0 || start != _smf_last_read_end) {
1080+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: seek to %1\n", start));
1081+ Evoral::SMF::seek_to_start();
1082+ while (time < start_ticks) {
1083+ gint ignored;
1084+
1085+ ret = read_event(&ev_delta_t, &ev_size, &ev_buffer, &ignored);
1086+ if (ret == -1) { // EOF
1087+ _smf_last_read_end = start + duration;
1088+ return duration;
1089+ }
1090+ time += ev_delta_t; // accumulate delta time
1091+ }
1092+ } else {
1093+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: set time to %1\n", _smf_last_read_time));
1094+ time = _smf_last_read_time;
1095+ }
1096+
1097+ _smf_last_read_end = start + duration;
1098+
1099+ while (true) {
1100+ gint ignored; /* XXX don't ignore note id's ??*/
1101+
1102+ ret = read_event(&ev_delta_t, &ev_size, &ev_buffer, &ignored);
1103+ if (ret == -1) { // EOF
1104+ break;
1105+ }
1106+
1107+ time += ev_delta_t; // accumulate delta time
1108+ _smf_last_read_time = time;
1109+
1110+ if (ret == 0) { // meta-event (skipped, just accumulate time)
1111+ continue;
1112+ }
1113+
1114+ ev_type = EventTypeMap::instance().midi_event_type(ev_buffer[0]);
1115+
1116+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked delta %1, time %2, buf[0] %3, type %4\n",
1117+ ev_delta_t, time, ev_buffer[0], ev_type));
1118+
1119+ assert(time >= start_ticks);
1120+
1121+ /* Note that we add on the source start time (in session frames) here so that ev_frame_time
1122+ is in session frames.
1123+ */
1124+ const framepos_t ev_frame_time = converter.to(time / (double)ppqn()) + source_start;
1125+
1126+ if (ev_frame_time < start + duration) {
1127+ destination.write (ev_frame_time, ev_type, ev_size, ev_buffer);
1128+
1129+ if (tracker) {
1130+ if (ev_buffer[0] & MIDI_CMD_NOTE_ON) {
1131+ tracker->add (ev_buffer[1], ev_buffer[0] & 0xf);
1132+ } else if (ev_buffer[0] & MIDI_CMD_NOTE_OFF) {
1133+ tracker->remove (ev_buffer[1], ev_buffer[0] & 0xf);
1134+ }
1135+ }
1136+ } else {
1137+ break;
1138+ }
1139+
1140+ if (ev_size > scratch_size) {
1141+ scratch_size = ev_size;
1142+ }
1143+ ev_size = scratch_size; // ensure read_event only allocates if necessary
1144+ }
1145+
1146+ return duration;
1147+}
1148+
1149+framecnt_t
1150+SMFSource::write_unlocked (MidiRingBuffer<framepos_t>& source,
1151+ framepos_t position,
1152+ framecnt_t cnt)
1153+{
1154+ if (!_writing) {
1155+ mark_streaming_write_started ();
1156+ }
1157+
1158+ framepos_t time;
1159+ Evoral::EventType type;
1160+ uint32_t size;
1161+
1162+ size_t buf_capacity = 4;
1163+ uint8_t* buf = (uint8_t*)malloc(buf_capacity);
1164+
1165+ if (_model && !_model->writing()) {
1166+ _model->start_write();
1167+ }
1168+
1169+ Evoral::MIDIEvent<framepos_t> ev;
1170+ while (true) {
1171+ /* Get the event time, in frames since session start but ignoring looping. */
1172+ bool ret;
1173+ if (!(ret = source.peek ((uint8_t*)&time, sizeof (time)))) {
1174+ /* Ring is empty, no more events. */
1175+ break;
1176+ }
1177+
1178+ if ((cnt != max_framecnt) &&
1179+ (time > position + _capture_length + cnt)) {
1180+ /* The diskstream doesn't want us to write everything, and this
1181+ event is past the end of this block, so we're done for now. */
1182+ break;
1183+ }
1184+
1185+ /* Read the time, type, and size of the event. */
1186+ if (!(ret = source.read_prefix (&time, &type, &size))) {
1187+ error << _("Unable to read event prefix, corrupt MIDI ring") << endmsg;
1188+ break;
1189+ }
1190+
1191+ /* Enlarge body buffer if necessary now that we know the size. */
1192+ if (size > buf_capacity) {
1193+ buf_capacity = size;
1194+ buf = (uint8_t*)realloc(buf, size);
1195+ }
1196+
1197+ /* Read the event body into buffer. */
1198+ ret = source.read_contents(size, buf);
1199+ if (!ret) {
1200+ error << _("Event has time and size but no body, corrupt MIDI ring") << endmsg;
1201+ break;
1202+ }
1203+
1204+ /* Convert event time from absolute to source relative. */
1205+ if (time < position) {
1206+ error << _("Event time is before MIDI source position") << endmsg;
1207+ break;
1208+ }
1209+ time -= position;
1210+
1211+ ev.set(buf, size, time);
1212+ ev.set_event_type(EventTypeMap::instance().midi_event_type(ev.buffer()[0]));
1213+ ev.set_id(Evoral::next_event_id());
1214+
1215+ if (!(ev.is_channel_event() || ev.is_smf_meta_event() || ev.is_sysex())) {
1216+ continue;
1217+ }
1218+
1219+ append_event_unlocked_frames(ev, position);
1220+ }
1221+
1222+ Evoral::SMF::flush ();
1223+ free (buf);
1224+
1225+ return cnt;
1226+}
1227+
1228+/** Append an event with a timestamp in beats (double) */
1229+void
1230+SMFSource::append_event_unlocked_beats (const Evoral::Event<double>& ev)
1231+{
1232+ if (!_writing || ev.size() == 0) {
1233+ return;
1234+ }
1235+
1236+ /*printf("SMFSource: %s - append_event_unlocked_beats ID = %d time = %lf, size = %u, data = ",
1237+ name().c_str(), ev.id(), ev.time(), ev.size());
1238+ for (size_t i = 0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");*/
1239+
1240+ if (ev.time() < _last_ev_time_beats) {
1241+ warning << string_compose(_("Skipping event with unordered time %1"), ev.time())
1242+ << endmsg;
1243+ return;
1244+ }
1245+
1246+ Evoral::event_id_t event_id;
1247+
1248+ if (ev.id() < 0) {
1249+ event_id = Evoral::next_event_id();
1250+ } else {
1251+ event_id = ev.id();
1252+ }
1253+
1254+ if (_model) {
1255+ _model->append (ev, event_id);
1256+ }
1257+
1258+ _length_beats = max(_length_beats, ev.time());
1259+
1260+ const double delta_time_beats = ev.time() - _last_ev_time_beats;
1261+ const uint32_t delta_time_ticks = (uint32_t)lrint(delta_time_beats * (double)ppqn());
1262+
1263+ Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id);
1264+ _last_ev_time_beats = ev.time();
1265+ _flags = Source::Flag (_flags & ~Empty);
1266+}
1267+
1268+/** Append an event with a timestamp in frames (framepos_t) */
1269+void
1270+SMFSource::append_event_unlocked_frames (const Evoral::Event<framepos_t>& ev, framepos_t position)
1271+{
1272+ if (!_writing || ev.size() == 0) {
1273+ return;
1274+ }
1275+
1276+ // printf("SMFSource: %s - append_event_unlocked_frames ID = %d time = %u, size = %u, data = ",
1277+ // name().c_str(), ev.id(), ev.time(), ev.size());
1278+ // for (size_t i=0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");
1279+
1280+ if (ev.time() < _last_ev_time_frames) {
1281+ warning << string_compose(_("Skipping event with unordered time %1"), ev.time())
1282+ << endmsg;
1283+ return;
1284+ }
1285+
1286+ BeatsFramesConverter converter(_session.tempo_map(), position);
1287+ const double ev_time_beats = converter.from(ev.time());
1288+ Evoral::event_id_t event_id;
1289+
1290+ if (ev.id() < 0) {
1291+ event_id = Evoral::next_event_id();
1292+ } else {
1293+ event_id = ev.id();
1294+ }
1295+
1296+ if (_model) {
1297+ const Evoral::Event<double> beat_ev (ev.event_type(),
1298+ ev_time_beats,
1299+ ev.size(),
1300+ const_cast<uint8_t*>(ev.buffer()));
1301+ _model->append (beat_ev, event_id);
1302+ }
1303+
1304+ _length_beats = max(_length_beats, ev_time_beats);
1305+
1306+ const Evoral::MusicalTime last_time_beats = converter.from (_last_ev_time_frames);
1307+ const Evoral::MusicalTime delta_time_beats = ev_time_beats - last_time_beats;
1308+ const uint32_t delta_time_ticks = (uint32_t)(lrint(delta_time_beats * (double)ppqn()));
1309+
1310+ Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id);
1311+ _last_ev_time_frames = ev.time();
1312+ _flags = Source::Flag (_flags & ~Empty);
1313+}
1314+
1315+XMLNode&
1316+SMFSource::get_state ()
1317+{
1318+ XMLNode& node = MidiSource::get_state();
1319+ node.add_property (X_("origin"), _origin);
1320+ return node;
1321+}
1322+
1323+int
1324+SMFSource::set_state (const XMLNode& node, int version)
1325+{
1326+ if (Source::set_state (node, version)) {
1327+ return -1;
1328+ }
1329+
1330+ if (MidiSource::set_state (node, version)) {
1331+ return -1;
1332+ }
1333+
1334+ if (FileSource::set_state (node, version)) {
1335+ return -1;
1336+ }
1337+
1338+ return 0;
1339+}
1340+
1341+void
1342+SMFSource::mark_streaming_midi_write_started (NoteMode mode)
1343+{
1344+ /* CALLER MUST HOLD LOCK */
1345+
1346+ if (!_open && open_for_write()) {
1347+ error << string_compose (_("cannot open MIDI file %1 for write"), _path) << endmsg;
1348+ /* XXX should probably throw or return something */
1349+ return;
1350+ }
1351+
1352+ MidiSource::mark_streaming_midi_write_started (mode);
1353+ Evoral::SMF::begin_write ();
1354+ _last_ev_time_beats = 0.0;
1355+ _last_ev_time_frames = 0;
1356+}
1357+
1358+void
1359+SMFSource::mark_streaming_write_completed ()
1360+{
1361+ mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::DeleteStuckNotes);
1362+}
1363+
1364+void
1365+SMFSource::mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption stuck_notes_option, Evoral::MusicalTime when)
1366+{
1367+ Glib::Threads::Mutex::Lock lm (_lock);
1368+ MidiSource::mark_midi_streaming_write_completed (stuck_notes_option, when);
1369+
1370+ if (!writable()) {
1371+ warning << string_compose ("attempt to write to unwritable SMF file %1", _path) << endmsg;
1372+ return;
1373+ }
1374+
1375+ if (_model) {
1376+ _model->set_edited(false);
1377+ }
1378+
1379+ Evoral::SMF::end_write ();
1380+
1381+ /* data in the file now, not removable */
1382+
1383+ mark_nonremovable ();
1384+}
1385+
1386+bool
1387+SMFSource::valid_midi_file (const string& file)
1388+{
1389+ if (safe_midi_file_extension (file) ) {
1390+ return (SMF::test (file) );
1391+ }
1392+ return false;
1393+}
1394+
1395+bool
1396+SMFSource::safe_midi_file_extension (const string& file)
1397+{
1398+ static regex_t compiled_pattern;
1399+ static bool compile = true;
1400+ const int nmatches = 2;
1401+ regmatch_t matches[nmatches];
1402+
1403+ if (Glib::file_test (file, Glib::FILE_TEST_EXISTS)) {
1404+ if (!Glib::file_test (file, Glib::FILE_TEST_IS_REGULAR)) {
1405+ /* exists but is not a regular file */
1406+ return false;
1407+ }
1408+ }
1409+
1410+ if (compile && regcomp (&compiled_pattern, "\\.[mM][iI][dD][iI]?$", REG_EXTENDED)) {
1411+ return false;
1412+ } else {
1413+ compile = false;
1414+ }
1415+
1416+ if (regexec (&compiled_pattern, file.c_str(), nmatches, matches, 0)) {
1417+ return false;
1418+ }
1419+
1420+ return true;
1421+}
1422+
1423+static bool compare_eventlist (
1424+ const std::pair< Evoral::Event<double>*, gint >& a,
1425+ const std::pair< Evoral::Event<double>*, gint >& b) {
1426+ return ( a.first->time() < b.first->time() );
1427+}
1428+
1429+void
1430+SMFSource::load_model (bool lock, bool force_reload)
1431+{
1432+ if (_writing) {
1433+ return;
1434+ }
1435+
1436+ boost::shared_ptr<Glib::Threads::Mutex::Lock> lm;
1437+ if (lock)
1438+ lm = boost::shared_ptr<Glib::Threads::Mutex::Lock>(new Glib::Threads::Mutex::Lock(_lock));
1439+
1440+ if (_model && !force_reload) {
1441+ return;
1442+ }
1443+
1444+ if (!_model) {
1445+ _model = boost::shared_ptr<MidiModel> (new MidiModel (shared_from_this ()));
1446+ } else {
1447+ _model->clear();
1448+ }
1449+
1450+ if (writable() && !_open) {
1451+ return;
1452+ }
1453+
1454+ _model->start_write();
1455+ Evoral::SMF::seek_to_start();
1456+
1457+ uint64_t time = 0; /* in SMF ticks */
1458+ Evoral::Event<double> ev;
1459+
1460+ uint32_t scratch_size = 0; // keep track of scratch and minimize reallocs
1461+
1462+ uint32_t delta_t = 0;
1463+ uint32_t size = 0;
1464+ uint8_t* buf = NULL;
1465+ int ret;
1466+ gint event_id;
1467+ bool have_event_id;
1468+
1469+ // TODO simplify event allocation
1470+ std::list< std::pair< Evoral::Event<double>*, gint > > eventlist;
1471+
1472+ for (unsigned i = 1; i <= num_tracks(); ++i) {
1473+ if (seek_to_track(i)) continue;
1474+
1475+ time = 0;
1476+ have_event_id = false;
1477+
1478+ while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
1479+
1480+ time += delta_t;
1481+
1482+ if (ret == 0) {
1483+ /* meta-event : did we get an event ID ? */
1484+ if (event_id >= 0) {
1485+ have_event_id = true;
1486+ }
1487+ continue;
1488+ }
1489+
1490+ if (ret > 0) {
1491+ /* not a meta-event */
1492+
1493+ if (!have_event_id) {
1494+ event_id = Evoral::next_event_id();
1495+ }
1496+ uint32_t event_type = EventTypeMap::instance().midi_event_type(buf[0]);
1497+ double event_time = time / (double) ppqn();
1498+#ifndef NDEBUG
1499+ std::string ss;
1500+
1501+ for (uint32_t xx = 0; xx < size; ++xx) {
1502+ char b[8];
1503+ snprintf (b, sizeof (b), "0x%x ", buf[xx]);
1504+ ss += b;
1505+ }
1506+
1507+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
1508+ delta_t, time, size, ss , event_type, name()));
1509+#endif
1510+
1511+ eventlist.push_back(make_pair (
1512+ new Evoral::Event<double> (
1513+ event_type, event_time,
1514+ size, buf, true)
1515+ , event_id));
1516+
1517+ // Set size to max capacity to minimize allocs in read_event
1518+ scratch_size = std::max(size, scratch_size);
1519+ size = scratch_size;
1520+
1521+ _length_beats = max(_length_beats, event_time);
1522+ }
1523+
1524+ /* event ID's must immediately precede the event they are for */
1525+ have_event_id = false;
1526+ }
1527+ }
1528+
1529+ eventlist.sort(compare_eventlist);
1530+
1531+ std::list< std::pair< Evoral::Event<double>*, gint > >::iterator it;
1532+ for (it=eventlist.begin(); it!=eventlist.end(); ++it) {
1533+ _model->append (*it->first, it->second);
1534+ delete it->first;
1535+ }
1536+
1537+ _model->end_write (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, _length_beats);
1538+ _model->set_edited (false);
1539+
1540+ _model_iter = _model->begin();
1541+
1542+ free(buf);
1543+}
1544+
1545+void
1546+SMFSource::destroy_model ()
1547+{
1548+ //cerr << _name << " destroying model " << _model.get() << endl;
1549+ _model.reset();
1550+}
1551+
1552+void
1553+SMFSource::flush_midi ()
1554+{
1555+ if (!writable() || _length_beats == 0.0) {
1556+ return;
1557+ }
1558+
1559+ ensure_disk_file ();
1560+
1561+ Evoral::SMF::end_write ();
1562+ /* data in the file means its no longer removable */
1563+ mark_nonremovable ();
1564+}
1565+
1566+void
1567+SMFSource::set_path (const string& p)
1568+{
1569+ FileSource::set_path (p);
1570+ SMF::set_path (_path);
1571+}
1572+
1573+/** Ensure that this source has some file on disk, even if it's just a SMF header */
1574+void
1575+SMFSource::ensure_disk_file ()
1576+{
1577+ if (!writable()) {
1578+ return;
1579+ }
1580+
1581+ if (_model) {
1582+ /* We have a model, so write it to disk; see MidiSource::session_saved
1583+ for an explanation of what we are doing here.
1584+ */
1585+ boost::shared_ptr<MidiModel> mm = _model;
1586+ _model.reset ();
1587+ mm->sync_to_source ();
1588+ _model = mm;
1589+ } else {
1590+ /* No model; if it's not already open, it's an empty source, so create
1591+ and open it for writing.
1592+ */
1593+ if (!_open) {
1594+ open_for_write ();
1595+ }
1596+ }
1597+}
1598+
1599+void
1600+SMFSource::prevent_deletion ()
1601+{
1602+ /* Unlike the audio case, the MIDI file remains mutable (because we can
1603+ edit MIDI data)
1604+ */
1605+
1606+ _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy));
1607+}
1608+
1609
1610=== modified file '.pc/wscript.patch/wscript'
1611--- .pc/wscript.patch/wscript 2014-01-24 16:31:54 +0000
1612+++ .pc/wscript.patch/wscript 2015-05-02 14:23:30 +0000
1613@@ -177,10 +177,6 @@
1614 if opt.gprofile:
1615 debug_flags = [ '-pg' ]
1616
1617- if opt.backtrace:
1618- if platform != 'darwin' and not is_clang:
1619- debug_flags = [ '-rdynamic' ]
1620-
1621 # Autodetect
1622 if opt.dist_target == 'auto':
1623 if platform == 'darwin':
1624@@ -415,6 +411,10 @@
1625 conf.env.append_value('CFLAGS', optimization_flags)
1626 conf.env.append_value('CXXFLAGS', optimization_flags)
1627
1628+ if opt.backtrace:
1629+ if platform != 'darwin' and not is_clang:
1630+ linker_flags += [ '-rdynamic' ]
1631+
1632 conf.env.append_value('CFLAGS', compiler_flags)
1633 conf.env.append_value('CFLAGS', c_flags)
1634 conf.env.append_value('CXXFLAGS', compiler_flags)
1635
1636=== modified file 'debian/changelog'
1637--- debian/changelog 2014-01-24 16:31:54 +0000
1638+++ debian/changelog 2015-05-02 14:23:30 +0000
1639@@ -1,15 +1,78 @@
1640-ardour3 (3.5.308~dfsg-1) unstable; urgency=low
1641-
1642- [ Jaromír Mikeš ]
1643- * Use higher resolution picture for desktop icon (Closes: #729890).
1644-
1645- [ Adrian Knoth ]
1646- * Change Name entry in desktop file (Closes: #729890)
1647- * Remove python runtime dependencies
1648- * Imported Upstream version 3.5.308~dfsg (Closes: #734079 #733969)
1649-
1650- -- Adrian Knoth <adi@drcomp.erfurt.thur.de> Fri, 24 Jan 2014 16:31:54 +0100
1651-
1652+<<<<<<< TREE
1653+ardour3 (3.5.308~dfsg-1) unstable; urgency=low
1654+
1655+ [ Jaromír Mikeš ]
1656+ * Use higher resolution picture for desktop icon (Closes: #729890).
1657+
1658+ [ Adrian Knoth ]
1659+ * Change Name entry in desktop file (Closes: #729890)
1660+ * Remove python runtime dependencies
1661+ * Imported Upstream version 3.5.308~dfsg (Closes: #734079 #733969)
1662+
1663+ -- Adrian Knoth <adi@drcomp.erfurt.thur.de> Fri, 24 Jan 2014 16:31:54 +0100
1664+
1665+=======
1666+ardour3 (3.5.403~dfsg-3) unstable; urgency=medium
1667+
1668+ * Fix MIDI data loss when editing (Closes: #772118)
1669+
1670+ -- Adrian Knoth <adi@drcomp.erfurt.thur.de> Thu, 04 Dec 2014 19:34:45 +0100
1671+
1672+ardour3 (3.5.403~dfsg-2) unstable; urgency=high
1673+
1674+ * Reupload with waf fixes from 3.5.380~dfsg-2 and -3
1675+
1676+ -- Adrian Knoth <adi@drcomp.erfurt.thur.de> Fri, 03 Oct 2014 14:01:07 +0200
1677+
1678+ardour3 (3.5.403~dfsg-1) unstable; urgency=high
1679+
1680+ * Imported Upstream version 3.5.403~dfsg
1681+ * Critical bugfix release. All users are recommended to upgrade.
1682+ * Details: https://community.ardour.org/node/8457
1683+
1684+ -- Adrian Knoth <adi@drcomp.erfurt.thur.de> Fri, 03 Oct 2014 13:02:45 +0200
1685+
1686+ardour3 (3.5.380~dfsg-3) unstable; urgency=medium
1687+
1688+ * Prevent build failures in slower architectures by
1689+ forcing waf logging to stdout instead of stderr.
1690+
1691+ -- Felipe Sateler <fsateler@debian.org> Fri, 11 Jul 2014 12:46:37 -0400
1692+
1693+ardour3 (3.5.380~dfsg-2) unstable; urgency=medium
1694+
1695+ * Team upload.
1696+ * Pass correct -j flag to waf. Closes: #748584
1697+
1698+ -- Felipe Sateler <fsateler@debian.org> Mon, 16 Jun 2014 11:03:20 -0400
1699+
1700+ardour3 (3.5.380~dfsg-1) unstable; urgency=low
1701+
1702+ * Imported Upstream version 3.5.380~dfsg
1703+
1704+ -- Adrian Knoth <adi@drcomp.erfurt.thur.de> Thu, 15 May 2014 14:33:48 +0200
1705+
1706+ardour3 (3.5.357~dfsg-1) unstable; urgency=high
1707+
1708+ * Imported Upstream version 3.5.357~dfsg
1709+ * Critical bugfix release. All users are recommended to upgrade.
1710+ * Details: https://community.ardour.org/node/8015
1711+
1712+ -- Adrian Knoth <adi@drcomp.erfurt.thur.de> Tue, 25 Feb 2014 14:13:18 +0100
1713+
1714+ardour3 (3.5.308~dfsg-1) unstable; urgency=low
1715+
1716+ [ Jaromír Mikeš ]
1717+ * Use higher resolution picture for desktop icon (Closes: #729890).
1718+
1719+ [ Adrian Knoth ]
1720+ * Change Name entry in desktop file (Closes: #729890)
1721+ * Remove python runtime dependencies
1722+ * Imported Upstream version 3.5.308~dfsg (Closes: #734079 #733969)
1723+
1724+ -- Adrian Knoth <adi@drcomp.erfurt.thur.de> Fri, 24 Jan 2014 16:31:54 +0100
1725+
1726+>>>>>>> MERGE-SOURCE
1727 ardour3 (3.5.143~dfsg-1) unstable; urgency=low
1728
1729 * Imported Upstream version 3.5.143~dfsg
1730
1731=== modified file 'debian/control'
1732--- debian/control 2014-01-24 16:31:54 +0000
1733+++ debian/control 2015-05-02 14:23:30 +0000
1734@@ -47,9 +47,15 @@
1735 vamp-plugin-sdk (>=2.1),
1736 python-setuptools,
1737 python-isodate,
1738+<<<<<<< TREE
1739 libpcre3-dev,
1740 python-rdflib
1741 Standards-Version: 3.9.4
1742+=======
1743+ libpcre3-dev,
1744+ python-rdflib
1745+Standards-Version: 3.9.6
1746+>>>>>>> MERGE-SOURCE
1747 Homepage: http://www.ardour.org/
1748 Vcs-Git: git://anonscm.debian.org/pkg-multimedia/ardour3.git
1749 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-multimedia/ardour3.git
1750
1751=== modified file 'debian/control.in'
1752--- debian/control.in 2014-01-24 16:31:54 +0000
1753+++ debian/control.in 2015-05-02 14:23:30 +0000
1754@@ -7,7 +7,7 @@
1755 Jaromír Mikeš <mira.mikes@seznam.cz>
1756 Build-Depends:
1757 @cdbs@
1758-Standards-Version: 3.9.4
1759+Standards-Version: 3.9.6
1760 Homepage: http://www.ardour.org/
1761 Vcs-Git: git://anonscm.debian.org/pkg-multimedia/ardour3.git
1762 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-multimedia/ardour3.git
1763
1764=== added file 'debian/patches/log-stdout.patch'
1765--- debian/patches/log-stdout.patch 1970-01-01 00:00:00 +0000
1766+++ debian/patches/log-stdout.patch 2015-05-02 14:23:30 +0000
1767@@ -0,0 +1,25 @@
1768+Description: Log waf messages to stdout, not stderr
1769+ The buildds kill the build if they don't see messages in stdout for a
1770+ long time. Unfortunately, waf defaults to printing such messages to
1771+ stderr, so ardour takes too long on slower archs. Work around that
1772+ by printing to stdout.
1773+Author: Felipe Sateler <fsateler@debian.org>
1774+Forwarded: no
1775+--- ardour3-3.5.380~dfsg.orig/wscript
1776++++ ardour3-3.5.380~dfsg/wscript
1777+@@ -777,6 +777,15 @@ const char* const ardour_config_info = "
1778+ def build(bld):
1779+ create_stored_revision()
1780+
1781++ # Log command executions to stdout, not err
1782++ def our_log(msg):
1783++ if not msg:
1784++ return
1785++ sys.stdout.write(str(msg))
1786++ sys.stdout.flush()
1787++
1788++ bld.to_log = our_log
1789++
1790+ # add directories that contain only headers, to workaround an issue with waf
1791+
1792+ bld.path.find_dir ('libs/evoral/evoral')
1793
1794=== added file 'debian/patches/midi-data-loss.patch'
1795--- debian/patches/midi-data-loss.patch 1970-01-01 00:00:00 +0000
1796+++ debian/patches/midi-data-loss.patch 2015-05-02 14:23:30 +0000
1797@@ -0,0 +1,62 @@
1798+From: David Robillard <d@drobilla.net>
1799+Description: Fix MIDI data loss when editing
1800+Forwarded: not-needed
1801+Last-Update: 2014-12-04
1802+Bug-Vendor: http://tracker.ardour.org/view.php?id=5669
1803+Applied-Upstream: 3.5.404; https://github.com/Ardour/ardour/commit/94954f852ead97bcda7afa548d543222733228ef
1804+--- ardour3.orig/libs/ardour/smf_source.cc
1805++++ ardour3/libs/ardour/smf_source.cc
1806+@@ -393,10 +393,22 @@ SMFSource::append_event_unlocked_beats (
1807+ name().c_str(), ev.id(), ev.time(), ev.size());
1808+ for (size_t i = 0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");*/
1809+
1810+- if (ev.time() < _last_ev_time_beats) {
1811+- warning << string_compose(_("Skipping event with unordered time %1"), ev.time())
1812+- << endmsg;
1813+- return;
1814++ double time = ev.time();
1815++ if (time < _last_ev_time_beats) {
1816++ const double difference = _last_ev_time_beats - time;
1817++ if (difference / (double)ppqn() < 1.0) {
1818++ /* Close enough. This problem occurs because Sequence is not
1819++ actually ordered due to fuzzy time comparison. I'm pretty sure
1820++ this is inherently a bad idea which causes problems all over the
1821++ place, but tolerate it here for now anyway. */
1822++ time = _last_ev_time_beats;
1823++ } else {
1824++ /* Out of order by more than a tick. */
1825++ warning << string_compose(_("Skipping event with unordered beat time %1 < %2 (off by %3 beats, %4 ticks)"),
1826++ ev.time(), _last_ev_time_beats, difference, difference / (double)ppqn())
1827++ << endmsg;
1828++ return;
1829++ }
1830+ }
1831+
1832+ Evoral::event_id_t event_id;
1833+@@ -411,13 +423,13 @@ SMFSource::append_event_unlocked_beats (
1834+ _model->append (ev, event_id);
1835+ }
1836+
1837+- _length_beats = max(_length_beats, ev.time());
1838++ _length_beats = max(_length_beats, time);
1839+
1840+- const double delta_time_beats = ev.time() - _last_ev_time_beats;
1841++ const double delta_time_beats = time - _last_ev_time_beats;
1842+ const uint32_t delta_time_ticks = (uint32_t)lrint(delta_time_beats * (double)ppqn());
1843+
1844+ Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id);
1845+- _last_ev_time_beats = ev.time();
1846++ _last_ev_time_beats = time;
1847+ _flags = Source::Flag (_flags & ~Empty);
1848+ }
1849+
1850+@@ -434,7 +446,8 @@ SMFSource::append_event_unlocked_frames
1851+ // for (size_t i=0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");
1852+
1853+ if (ev.time() < _last_ev_time_frames) {
1854+- warning << string_compose(_("Skipping event with unordered time %1"), ev.time())
1855++ warning << string_compose(_("Skipping event with unordered frame time %1 < %2"),
1856++ ev.time(), _last_ev_time_frames)
1857+ << endmsg;
1858+ return;
1859+ }
1860
1861=== modified file 'debian/patches/series'
1862--- debian/patches/series 2013-11-06 13:22:44 +0000
1863+++ debian/patches/series 2015-05-02 14:23:30 +0000
1864@@ -1,2 +1,4 @@
1865 waf.patch
1866 wscript.patch
1867+log-stdout.patch
1868+midi-data-loss.patch
1869
1870=== modified file 'debian/rules'
1871--- debian/rules 2014-01-24 16:31:54 +0000
1872+++ debian/rules 2015-05-02 14:23:30 +0000
1873@@ -37,7 +37,8 @@
1874 --optimize \
1875
1876
1877-DEB_MAKE_EXTRA_ARGS = -v --destdir=$(CURDIR)/debian/tmp
1878+DEB_MAKE_PARALLEL = -j$(if $(DEB_PARALLEL_JOBS),$(DEB_PARALLEL_JOBS),1)
1879+DEB_MAKE_EXTRA_ARGS = -v --destdir=$(CURDIR)/debian/tmp $(DEB_MAKE_PARALLEL)
1880 DEB_MAKE_BUILD_TARGET = build i18n_mo
1881 DEB_MAKE_ENVVARS = CFLAGS="$(or $(CFLAGS_$(cdbs_curpkg)),$(CFLAGS))" CXXFLAGS="$(or $(CXXFLAGS_$(cdbs_curpkg)),$(CXXFLAGS))" CPPFLAGS="$(or $(CPPFLAGS_$(cdbs_curpkg)),$(CPPFLAGS))" LDFLAGS="$(or $(LDFLAGS_$(cdbs_curpkg)),$(LDFLAGS))"
1882 DEB_MAKE_INVOKE = $(DEB_MAKE_ENVVARS) $(CURDIR)/waf-light $(DEB_MAKE_EXTRA_ARGS)
1883
1884=== modified file 'gtk2_ardour/add_video_dialog.cc'
1885--- gtk2_ardour/add_video_dialog.cc 2013-09-21 19:05:02 +0000
1886+++ gtk2_ardour/add_video_dialog.cc 2015-05-02 14:23:30 +0000
1887@@ -258,7 +258,8 @@
1888 ".ogg" , ".OGG" ,
1889 ".ogv" , ".OGV" ,
1890 ".mpg" , ".MPG" ,
1891- ".mov" , ".MOV" ,
1892+ ".mpeg" , ".MPEG" ,
1893+ ".mts" , ".MTS" ,
1894 ".mp4" , ".MP4" ,
1895 ".mkv" , ".MKV" ,
1896 ".vob" , ".VOB" ,
1897@@ -272,6 +273,8 @@
1898 ".dv" , ".DV" ,
1899 ".dirac" , ".DIRAC" ,
1900 ".webm" , ".WEBM" ,
1901+ ".wmv" , ".wmv" ,
1902+ ".ts" , ".ts" ,
1903 };
1904
1905 for (size_t n = 0; n < sizeof(suffixes)/sizeof(suffixes[0]); ++n) {
1906
1907=== modified file 'gtk2_ardour/ardev_common.sh.in'
1908--- gtk2_ardour/ardev_common.sh.in 2014-01-24 16:31:54 +0000
1909+++ gtk2_ardour/ardev_common.sh.in 2015-05-02 14:23:30 +0000
1910@@ -18,6 +18,7 @@
1911 export ARDOUR_MCP_PATH=$TOP/mcp:.
1912 export ARDOUR_EXPORT_FORMATS_PATH=$TOP/export:.
1913 export ARDOUR_BACKEND_PATH=$libs/backends/jack
1914+export ARDOUR_TEST_PATH=$libs/ardour/test/data
1915
1916 #
1917 # even though we set the above variables, ardour requires that these
1918
1919=== modified file 'gtk2_ardour/ardour.menus.in'
1920--- gtk2_ardour/ardour.menus.in 2014-01-24 16:31:54 +0000
1921+++ gtk2_ardour/ardour.menus.in 2015-05-02 14:23:30 +0000
1922@@ -341,6 +341,7 @@
1923
1924 <menu name='View' action = 'View'>
1925 <menuitem action='ToggleMaximalEditor'/>
1926+ <menuitem action='ToggleMaximalMixer'/>
1927 <menuitem action='KeepTearoffs'/>
1928
1929 <separator/>
1930
1931=== modified file 'gtk2_ardour/ardour_ui.cc'
1932--- gtk2_ardour/ardour_ui.cc 2014-01-24 16:31:54 +0000
1933+++ gtk2_ardour/ardour_ui.cc 2015-05-02 14:23:30 +0000
1934@@ -496,10 +496,13 @@
1935
1936 vector<string>::iterator n;
1937 vector<string>::iterator k;
1938- for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
1939- cout << "Action: " << (*n) << " bound to " << (*k) << endl;
1940+ vector<string>::iterator p;
1941+ for (n = names.begin(), k = keys.begin(), p = paths.begin(); n != names.end(); ++n, ++k, ++p) {
1942+ cout << "Action: '" << (*n) << "' bound to '" << (*k) << "' Path: '" << (*p) << "'" << endl;
1943 }
1944
1945+ halt_connection.disconnect ();
1946+ AudioEngine::instance()->stop ();
1947 exit (0);
1948 }
1949
1950@@ -3264,7 +3267,7 @@
1951 } else {
1952 for (TrackSelection::iterator s = editor->get_selection().tracks.begin(); s != editor->get_selection().tracks.end(); ++s) {
1953 RouteTimeAxisView* tav = dynamic_cast<RouteTimeAxisView*> (*s);
1954- if (tav->route()->order_key() > order_hint) {
1955+ if (tav && tav->route() && tav->route()->order_key() > order_hint) {
1956 order_hint = tav->route()->order_key();
1957 }
1958 }
1959
1960=== modified file 'gtk2_ardour/ardour_ui.h'
1961--- gtk2_ardour/ardour_ui.h 2013-11-06 13:22:44 +0000
1962+++ gtk2_ardour/ardour_ui.h 2015-05-02 14:23:30 +0000
1963@@ -171,6 +171,7 @@
1964
1965 void new_midi_tracer_window ();
1966 void toggle_editing_space();
1967+ void toggle_mixer_space();
1968 void toggle_keep_tearoffs();
1969
1970 Gtk::Tooltips& tooltips() { return _tooltips; }
1971
1972=== modified file 'gtk2_ardour/ardour_ui_dialogs.cc'
1973--- gtk2_ardour/ardour_ui_dialogs.cc 2013-12-23 22:07:52 +0000
1974+++ gtk2_ardour/ardour_ui_dialogs.cc 2015-05-02 14:23:30 +0000
1975@@ -565,3 +565,18 @@
1976 }
1977 return true;
1978 }
1979+
1980+void
1981+ARDOUR_UI::toggle_mixer_space()
1982+{
1983+ Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalMixer");
1984+
1985+ if (act) {
1986+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
1987+ if (tact->get_active()) {
1988+ mixer->maximise_mixer_space ();
1989+ } else {
1990+ mixer->restore_mixer_space ();
1991+ }
1992+ }
1993+}
1994
1995=== modified file 'gtk2_ardour/ardour_ui_ed.cc'
1996--- gtk2_ardour/ardour_ui_ed.cc 2013-10-17 11:16:21 +0000
1997+++ gtk2_ardour/ardour_ui_ed.cc 2015-05-02 14:23:30 +0000
1998@@ -191,6 +191,7 @@
1999 /* windows visibility actions */
2000
2001 ActionManager::register_toggle_action (common_actions, X_("ToggleMaximalEditor"), _("Maximise Editor Space"), sigc::mem_fun (*this, &ARDOUR_UI::toggle_editing_space));
2002+ ActionManager::register_toggle_action (common_actions, X_("ToggleMaximalMixer"), _("Maximise Mixer Space"), sigc::mem_fun (*this, &ARDOUR_UI::toggle_mixer_space));
2003 act = ActionManager::register_toggle_action (common_actions, X_("KeepTearoffs"), _("Show Toolbars"), mem_fun (*this, &ARDOUR_UI::toggle_keep_tearoffs));
2004 ActionManager::session_sensitive_actions.push_back (act);
2005
2006
2007=== modified file 'gtk2_ardour/audio_region_view.cc'
2008--- gtk2_ardour/audio_region_view.cc 2013-09-21 19:05:02 +0000
2009+++ gtk2_ardour/audio_region_view.cc 2015-05-02 14:23:30 +0000
2010@@ -963,7 +963,7 @@
2011 }
2012
2013 void
2014-AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
2015+AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, bool with_guard_points)
2016 {
2017 if (!gain_line) {
2018 return;
2019@@ -1008,7 +1008,7 @@
2020 trackview.session()->add_command (new MementoCommand<AudioRegion>(*(audio_region().get()), &region_before, &region_after));
2021 }
2022
2023- audio_region()->envelope()->add (fx, y);
2024+ audio_region()->envelope()->add (fx, y, with_guard_points);
2025
2026 XMLNode &after = audio_region()->envelope()->get_state();
2027 trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
2028
2029=== modified file 'gtk2_ardour/audio_region_view.h'
2030--- gtk2_ardour/audio_region_view.h 2013-09-21 19:05:02 +0000
2031+++ gtk2_ardour/audio_region_view.h 2015-05-02 14:23:30 +0000
2032@@ -81,7 +81,7 @@
2033
2034 void update_envelope_visibility ();
2035
2036- void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
2037+ void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event, bool with_guard_points);
2038 void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
2039
2040 boost::shared_ptr<AudioRegionGainLine> get_gain_line() const { return gain_line; }
2041
2042=== modified file 'gtk2_ardour/automation_region_view.cc'
2043--- gtk2_ardour/automation_region_view.cc 2013-09-21 19:05:02 +0000
2044+++ gtk2_ardour/automation_region_view.cc 2015-05-02 14:23:30 +0000
2045@@ -27,6 +27,8 @@
2046 #include "ardour/midi_region.h"
2047 #include "ardour/session.h"
2048
2049+#include "gtkmm2ext/keyboard.h"
2050+
2051 #include "automation_region_view.h"
2052 #include "editing.h"
2053 #include "editor.h"
2054@@ -120,7 +122,11 @@
2055 y = std::max (y, 0.0);
2056 y = std::min (y, _height - NAME_HIGHLIGHT_SIZE);
2057
2058- add_automation_event (ev, trackview.editor().pixel_to_frame (x) - _region->position() + _region->start(), y);
2059+ /* guard points only if primary modifier is used */
2060+
2061+ bool with_guard_points = Gtkmm2ext::Keyboard::modifier_state_equals (ev->button.state, Gtkmm2ext::Keyboard::PrimaryModifier);
2062+
2063+ add_automation_event (ev, trackview.editor().pixel_to_frame (x) - _region->position() + _region->start(), y, with_guard_points);
2064 }
2065
2066 return false;
2067@@ -130,7 +136,7 @@
2068 * @param y y position, relative to our TimeAxisView.
2069 */
2070 void
2071-AutomationRegionView::add_automation_event (GdkEvent *, framepos_t when, double y)
2072+AutomationRegionView::add_automation_event (GdkEvent *, framepos_t when, double y, bool with_guard_points)
2073 {
2074 if (!_line) {
2075 boost::shared_ptr<Evoral::Control> c = _region->control(_parameter, true);
2076@@ -160,7 +166,7 @@
2077 view->session()->begin_reversible_command (_("add automation event"));
2078 XMLNode& before = _line->the_list()->get_state();
2079
2080- _line->the_list()->add (when_d, y);
2081+ _line->the_list()->add (when_d, y, with_guard_points);
2082
2083 XMLNode& after = _line->the_list()->get_state();
2084
2085
2086=== modified file 'gtk2_ardour/automation_region_view.h'
2087--- gtk2_ardour/automation_region_view.h 2013-09-21 19:05:02 +0000
2088+++ gtk2_ardour/automation_region_view.h 2015-05-02 14:23:30 +0000
2089@@ -66,7 +66,7 @@
2090 bool set_position(framepos_t pos, void* src, double* ignored);
2091 void region_resized (const PBD::PropertyChange&);
2092 bool canvas_event(GdkEvent* ev);
2093- void add_automation_event (GdkEvent* event, framepos_t when, double y);
2094+ void add_automation_event (GdkEvent* event, framepos_t when, double y, bool with_guard_points);
2095 void entered (bool);
2096 void exited();
2097
2098
2099=== modified file 'gtk2_ardour/automation_time_axis.cc'
2100--- gtk2_ardour/automation_time_axis.cc 2013-09-21 19:05:02 +0000
2101+++ gtk2_ardour/automation_time_axis.cc 2015-05-02 14:23:30 +0000
2102@@ -550,7 +550,7 @@
2103 }
2104
2105 void
2106-AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when, double y)
2107+AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when, double y, bool with_guard_points)
2108 {
2109 if (!_line) {
2110 return;
2111@@ -583,7 +583,7 @@
2112 _session->begin_reversible_command (_("add automation event"));
2113 XMLNode& before = list->get_state();
2114
2115- list->add (when, y);
2116+ list->add (when, y, with_guard_points);
2117
2118 XMLNode& after = list->get_state();
2119 _session->commit_reversible_command (new MementoCommand<ARDOUR::AutomationList> (*list, &before, &after));
2120
2121=== modified file 'gtk2_ardour/automation_time_axis.h'
2122--- gtk2_ardour/automation_time_axis.h 2013-09-21 19:05:02 +0000
2123+++ gtk2_ardour/automation_time_axis.h 2015-05-02 14:23:30 +0000
2124@@ -72,7 +72,7 @@
2125 void set_samples_per_unit (double);
2126 std::string name() const { return _name; }
2127
2128- void add_automation_event (GdkEvent *, framepos_t, double);
2129+ void add_automation_event (GdkEvent *, framepos_t, double, bool with_guard_points);
2130
2131 void clear_lines ();
2132
2133
2134=== modified file 'gtk2_ardour/editor.bindings'
2135--- gtk2_ardour/editor.bindings 2013-09-21 19:05:02 +0000
2136+++ gtk2_ardour/editor.bindings 2015-05-02 14:23:30 +0000
2137@@ -167,6 +167,7 @@
2138 <Binding action="Editor/pitch-shift-region" key="F5"/>
2139 <Binding action="Editor/select-range-between-cursors" key="F6"/>
2140 <Binding action="Common/ToggleMaximalEditor" key="F11"/>
2141+ <Binding action="Common/ToggleMaximalMixer" key="F12"/>
2142 <Binding action="Editor/save-visual-state-1" key="Primary-F1"/>
2143 <Binding action="Editor/save-visual-state-2" key="Primary-F2"/>
2144 <Binding action="Editor/save-visual-state-3" key="Primary-F3"/>
2145
2146=== modified file 'gtk2_ardour/editor.h'
2147--- gtk2_ardour/editor.h 2014-01-24 16:31:54 +0000
2148+++ gtk2_ardour/editor.h 2015-05-02 14:23:30 +0000
2149@@ -1262,7 +1262,7 @@
2150 int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::Track>&, bool add_channel_suffix);
2151
2152 int finish_bringing_in_material (boost::shared_ptr<ARDOUR::Region> region, uint32_t, uint32_t, framepos_t& pos, Editing::ImportMode mode,
2153- boost::shared_ptr<ARDOUR::Track>& existing_track);
2154+ boost::shared_ptr<ARDOUR::Track>& existing_track, const std::string& new_track_name);
2155
2156 boost::shared_ptr<ARDOUR::AudioTrack> get_nth_selected_audio_track (int nth) const;
2157 boost::shared_ptr<ARDOUR::MidiTrack> get_nth_selected_midi_track (int nth) const;
2158
2159=== modified file 'gtk2_ardour/editor_actions.cc'
2160--- gtk2_ardour/editor_actions.cc 2013-09-21 19:05:02 +0000
2161+++ gtk2_ardour/editor_actions.cc 2015-05-02 14:23:30 +0000
2162@@ -1143,94 +1143,94 @@
2163 {
2164 switch (_snap_type) {
2165 case Editing::SnapToCDFrame:
2166- set_snap_to (Editing::SnapToTimecodeFrame);
2167+ set_snap_to (Editing::SnapToRegionBoundary);
2168 break;
2169 case Editing::SnapToTimecodeFrame:
2170- set_snap_to (Editing::SnapToTimecodeSeconds);
2171+ set_snap_to (Editing::SnapToCDFrame);
2172 break;
2173 case Editing::SnapToTimecodeSeconds:
2174- set_snap_to (Editing::SnapToTimecodeMinutes);
2175+ set_snap_to (Editing::SnapToTimecodeFrame);
2176 break;
2177 case Editing::SnapToTimecodeMinutes:
2178- set_snap_to (Editing::SnapToSeconds);
2179+ set_snap_to (Editing::SnapToTimecodeSeconds);
2180 break;
2181 case Editing::SnapToSeconds:
2182- set_snap_to (Editing::SnapToMinutes);
2183+ set_snap_to (Editing::SnapToTimecodeMinutes);
2184 break;
2185 case Editing::SnapToMinutes:
2186- set_snap_to (Editing::SnapToBeatDiv128);
2187+ set_snap_to (Editing::SnapToSeconds);
2188 break;
2189 case Editing::SnapToBeatDiv128:
2190- set_snap_to (Editing::SnapToBeatDiv64);
2191+ set_snap_to (Editing::SnapToMinutes);
2192 break;
2193 case Editing::SnapToBeatDiv64:
2194- set_snap_to (Editing::SnapToBeatDiv32);
2195+ set_snap_to (Editing::SnapToBeatDiv128);
2196 break;
2197 case Editing::SnapToBeatDiv32:
2198- set_snap_to (Editing::SnapToBeatDiv28);
2199+ set_snap_to (Editing::SnapToBeatDiv64);
2200 break;
2201 case Editing::SnapToBeatDiv28:
2202- set_snap_to (Editing::SnapToBeatDiv24);
2203+ set_snap_to (Editing::SnapToBeatDiv32);
2204 break;
2205 case Editing::SnapToBeatDiv24:
2206- set_snap_to (Editing::SnapToBeatDiv20);
2207+ set_snap_to (Editing::SnapToBeatDiv28);
2208 break;
2209 case Editing::SnapToBeatDiv20:
2210- set_snap_to (Editing::SnapToBeatDiv16);
2211+ set_snap_to (Editing::SnapToBeatDiv24);
2212 break;
2213 case Editing::SnapToBeatDiv16:
2214- set_snap_to (Editing::SnapToBeatDiv14);
2215+ set_snap_to (Editing::SnapToBeatDiv20);
2216 break;
2217 case Editing::SnapToBeatDiv14:
2218- set_snap_to (Editing::SnapToBeatDiv12);
2219+ set_snap_to (Editing::SnapToBeatDiv16);
2220 break;
2221 case Editing::SnapToBeatDiv12:
2222- set_snap_to (Editing::SnapToBeatDiv10);
2223+ set_snap_to (Editing::SnapToBeatDiv14);
2224 break;
2225 case Editing::SnapToBeatDiv10:
2226- set_snap_to (Editing::SnapToBeatDiv8);
2227+ set_snap_to (Editing::SnapToBeatDiv12);
2228 break;
2229 case Editing::SnapToBeatDiv8:
2230- set_snap_to (Editing::SnapToBeatDiv7);
2231+ set_snap_to (Editing::SnapToBeatDiv10);
2232 break;
2233 case Editing::SnapToBeatDiv7:
2234- set_snap_to (Editing::SnapToBeatDiv6);
2235+ set_snap_to (Editing::SnapToBeatDiv8);
2236 break;
2237 case Editing::SnapToBeatDiv6:
2238- set_snap_to (Editing::SnapToBeatDiv5);
2239+ set_snap_to (Editing::SnapToBeatDiv7);
2240 break;
2241 case Editing::SnapToBeatDiv5:
2242- set_snap_to (Editing::SnapToBeatDiv4);
2243+ set_snap_to (Editing::SnapToBeatDiv6);
2244 break;
2245 case Editing::SnapToBeatDiv4:
2246- set_snap_to (Editing::SnapToBeatDiv3);
2247+ set_snap_to (Editing::SnapToBeatDiv5);
2248 break;
2249 case Editing::SnapToBeatDiv3:
2250- set_snap_to (Editing::SnapToBeatDiv2);
2251+ set_snap_to (Editing::SnapToBeatDiv4);
2252 break;
2253 case Editing::SnapToBeatDiv2:
2254- set_snap_to (Editing::SnapToBeat);
2255+ set_snap_to (Editing::SnapToBeatDiv3);
2256 break;
2257 case Editing::SnapToBeat:
2258- set_snap_to (Editing::SnapToBar);
2259+ set_snap_to (Editing::SnapToBeatDiv2);
2260 break;
2261 case Editing::SnapToBar:
2262- set_snap_to (Editing::SnapToMark);
2263+ set_snap_to (Editing::SnapToBeat);
2264 break;
2265 case Editing::SnapToMark:
2266- set_snap_to (Editing::SnapToRegionStart);
2267+ set_snap_to (Editing::SnapToBar);
2268 break;
2269 case Editing::SnapToRegionStart:
2270- set_snap_to (Editing::SnapToRegionEnd);
2271+ set_snap_to (Editing::SnapToMark);
2272 break;
2273 case Editing::SnapToRegionEnd:
2274- set_snap_to (Editing::SnapToRegionSync);
2275+ set_snap_to (Editing::SnapToRegionStart);
2276 break;
2277 case Editing::SnapToRegionSync:
2278- set_snap_to (Editing::SnapToRegionBoundary);
2279+ set_snap_to (Editing::SnapToRegionEnd);
2280 break;
2281 case Editing::SnapToRegionBoundary:
2282- set_snap_to (Editing::SnapToCDFrame);
2283+ set_snap_to (Editing::SnapToRegionSync);
2284 break;
2285 }
2286 }
2287
2288=== modified file 'gtk2_ardour/editor_audio_import.cc'
2289--- gtk2_ardour/editor_audio_import.cc 2014-01-24 16:31:54 +0000
2290+++ gtk2_ardour/editor_audio_import.cc 2015-05-02 14:23:30 +0000
2291@@ -611,7 +611,7 @@
2292
2293 boost::shared_ptr<Source> s;
2294
2295- if ((s = _session->source_by_path_and_channel (path, n)) == 0) {
2296+ if ((s = _session->audio_source_by_path_and_channel (path, n)) == 0) {
2297
2298 source = boost::dynamic_pointer_cast<AudioFileSource> (
2299 SourceFactory::createExternal (DataType::AUDIO, *_session,
2300@@ -657,7 +657,8 @@
2301 uint32_t input_chan = 0;
2302 uint32_t output_chan = 0;
2303 bool use_timestamp;
2304-
2305+ vector<string> track_names;
2306+
2307 use_timestamp = (pos == -1);
2308
2309 // kludge (for MIDI we're abusing "channel" for "track" here)
2310@@ -694,6 +695,11 @@
2311
2312 regions.push_back (r);
2313
2314+ /* if we're creating a new track, name it after the cleaned-up
2315+ * and "merged" region name.
2316+ */
2317+
2318+ track_names.push_back (region_name);
2319
2320 } else if (target_regions == -1 || target_regions > 1) {
2321
2322@@ -724,29 +730,26 @@
2323 region_name = (*x)->name();
2324 }
2325
2326- switch (sources.size()) {
2327- /* zero and one channel handled
2328- by previous if() condition
2329- */
2330- case 2:
2331+ if (sources.size() == 2) {
2332 if (n == 0) {
2333 region_name += "-L";
2334 } else {
2335 region_name += "-R";
2336 }
2337- break;
2338- default:
2339- region_name += (char) '-';
2340- region_name += (char) ('1' + n);
2341- break;
2342+ } else if (sources.size() > 2) {
2343+ region_name += string_compose ("-%1", n+1);
2344 }
2345
2346+ track_names.push_back (region_name);
2347+
2348 } else {
2349 if (fs) {
2350 region_name = region_name_from_path (fs->path(), false, false, sources.size(), n);
2351- } else{
2352+ } else {
2353 region_name = (*x)->name();
2354 }
2355+
2356+ track_names.push_back (PBD::basename_nosuffix (paths[n]));
2357 }
2358
2359 PropertyList plist;
2360@@ -798,6 +801,12 @@
2361 framepos_t rlen = 0;
2362
2363 begin_reversible_command (Operations::insert_file);
2364+
2365+ /* we only use tracks names when importing to new tracks, but we
2366+ * require that one is defined for every region, just to keep
2367+ * the API simpler.
2368+ */
2369+ assert (regions.size() == track_names.size());
2370
2371 for (vector<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
2372 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (*r);
2373@@ -830,9 +839,8 @@
2374 pos = get_preferred_edit_position ();
2375 }
2376 }
2377-
2378-
2379- finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track);
2380+
2381+ finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track, track_names[n]);
2382
2383 rlen = (*r)->length();
2384
2385@@ -859,7 +867,7 @@
2386
2387 int
2388 Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t in_chans, uint32_t out_chans, framepos_t& pos,
2389- ImportMode mode, boost::shared_ptr<Track>& existing_track)
2390+ ImportMode mode, boost::shared_ptr<Track>& existing_track, const string& new_track_name)
2391 {
2392 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(region);
2393 boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
2394@@ -916,7 +924,11 @@
2395 existing_track = mt.front();
2396 }
2397
2398- existing_track->set_name (region->name());
2399+ if (!new_track_name.empty()) {
2400+ existing_track->set_name (new_track_name);
2401+ } else {
2402+ existing_track->set_name (region->name());
2403+ }
2404 }
2405
2406 boost::shared_ptr<Playlist> playlist = existing_track->playlist();
2407
2408=== modified file 'gtk2_ardour/editor_drag.cc'
2409--- gtk2_ardour/editor_drag.cc 2013-11-06 13:22:44 +0000
2410+++ gtk2_ardour/editor_drag.cc 2015-05-02 14:23:30 +0000
2411@@ -3275,10 +3275,24 @@
2412 }
2413
2414 void
2415-LineDrag::finished (GdkEvent* event, bool)
2416+LineDrag::finished (GdkEvent* event, bool movement_occured)
2417 {
2418- motion (event, false);
2419- _line->end_drag (false, 0);
2420+ if (movement_occured) {
2421+ motion (event, false);
2422+ _line->end_drag (false, 0);
2423+ } else {
2424+ /* add a new control point on the line */
2425+
2426+ AutomationTimeAxisView* atv;
2427+
2428+ _line->end_drag (false, 0);
2429+
2430+ if ((atv = dynamic_cast<AutomationTimeAxisView*>(_editor->clicked_axisview)) != 0) {
2431+ framepos_t where = _editor->event_frame (event, 0, 0);
2432+ atv->add_automation_event (event, where, event->button.y, false);
2433+ }
2434+ }
2435+
2436 _editor->session()->commit_reversible_command ();
2437 }
2438
2439
2440=== modified file 'gtk2_ardour/editor_mouse.cc'
2441--- gtk2_ardour/editor_mouse.cc 2013-11-06 13:22:44 +0000
2442+++ gtk2_ardour/editor_mouse.cc 2015-05-02 14:23:30 +0000
2443@@ -1682,7 +1682,8 @@
2444 case AutomationTrackItem:
2445 atv = dynamic_cast<AutomationTimeAxisView*>(clicked_axisview);
2446 if (atv) {
2447- atv->add_automation_event (event, where, event->button.y);
2448+ bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
2449+ atv->add_automation_event (event, where, event->button.y, with_guard_points);
2450 }
2451 return true;
2452 break;
2453@@ -1701,17 +1702,20 @@
2454 */
2455 AudioRegionView* arv = dynamic_cast<AudioRegionView*> (clicked_regionview);
2456 if (!were_dragging && arv) {
2457- arv->add_gain_point_event (item, event);
2458+ bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
2459+ arv->add_gain_point_event (item, event, with_guard_points);
2460 }
2461 return true;
2462 break;
2463 }
2464
2465- case AutomationTrackItem:
2466+ case AutomationTrackItem: {
2467+ bool with_guard_points = Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier);
2468 dynamic_cast<AutomationTimeAxisView*>(clicked_axisview)->
2469- add_automation_event (event, where, event->button.y);
2470+ add_automation_event (event, where, event->button.y, with_guard_points);
2471 return true;
2472 break;
2473+ }
2474 default:
2475 break;
2476 }
2477
2478=== modified file 'gtk2_ardour/editor_ops.cc'
2479--- gtk2_ardour/editor_ops.cc 2013-11-06 13:22:44 +0000
2480+++ gtk2_ardour/editor_ops.cc 2015-05-02 14:23:30 +0000
2481@@ -4772,12 +4772,17 @@
2482 MidiRegionView* const mrv = dynamic_cast<MidiRegionView*>(*r);
2483
2484 if (mrv) {
2485- boost::shared_ptr<Playlist> playlist = mrv->region()->playlist();
2486- boost::shared_ptr<MidiRegion> newregion = mrv->midi_region()->clone ();
2487-
2488- playlist->clear_changes ();
2489- playlist->replace_region (mrv->region(), newregion, mrv->region()->position());
2490- _session->add_command(new StatefulDiffCommand (playlist));
2491+ try {
2492+ boost::shared_ptr<Playlist> playlist = mrv->region()->playlist();
2493+ boost::shared_ptr<MidiSource> new_source = _session->create_midi_source_by_stealing_name (mrv->midi_view()->track());
2494+ boost::shared_ptr<MidiRegion> newregion = mrv->midi_region()->clone (new_source);
2495+
2496+ playlist->clear_changes ();
2497+ playlist->replace_region (mrv->region(), newregion, mrv->region()->position());
2498+ _session->add_command(new StatefulDiffCommand (playlist));
2499+ } catch (...) {
2500+ error << string_compose (_("Could not unlink %1"), mrv->region()->name()) << endmsg;
2501+ }
2502 }
2503
2504 r = tmp;
2505
2506=== modified file 'gtk2_ardour/editor_regions.cc'
2507--- gtk2_ardour/editor_regions.cc 2013-12-23 22:07:52 +0000
2508+++ gtk2_ardour/editor_regions.cc 2015-05-02 14:23:30 +0000
2509@@ -114,7 +114,7 @@
2510 { 3, _("Length"), _("Length of the region") },
2511 { 4, _("Sync"), _("Position of region sync point, relative to start of the region") },
2512 { 5, _("Fade In"), _("Length of region fade-in (units: secondary clock), () if disabled") },
2513- { 6, _("Fade Out"), _("Length of region fade-out (units: secondary clock), () if dsisabled") },
2514+ { 6, _("Fade Out"), _("Length of region fade-out (units: secondary clock), () if disabled") },
2515 { 7, _("L"), _("Region position locked?") },
2516 { 8, _("G"), _("Region position glued to Bars|Beats time?") },
2517 { 9, _("M"), _("Region muted?") },
2518
2519=== modified file 'gtk2_ardour/editor_rulers.cc'
2520--- gtk2_ardour/editor_rulers.cc 2013-09-21 19:05:02 +0000
2521+++ gtk2_ardour/editor_rulers.cc 2015-05-02 14:23:30 +0000
2522@@ -1862,13 +1862,13 @@
2523 long millisecs;
2524
2525 left = sample;
2526- hrs = left / (sample_rate * 60 * 60);
2527- left -= hrs * sample_rate * 60 * 60;
2528- mins = left / (sample_rate * 60);
2529- left -= mins * sample_rate * 60;
2530- secs = left / sample_rate;
2531- left -= secs * sample_rate;
2532- millisecs = left * 1000 / sample_rate;
2533+ hrs = left / (sample_rate * 60 * 60 * 1000);
2534+ left -= hrs * sample_rate * 60 * 60 * 1000;
2535+ mins = left / (sample_rate * 60 * 1000);
2536+ left -= mins * sample_rate * 60 * 1000;
2537+ secs = left / (sample_rate * 1000);
2538+ left -= secs * sample_rate * 1000;
2539+ millisecs = left / sample_rate;
2540
2541 *millisecs_p = millisecs;
2542 *secs_p = secs;
2543@@ -1888,7 +1888,7 @@
2544 return;
2545 }
2546
2547- fr = _session->frame_rate();
2548+ fr = _session->frame_rate() * 1000;
2549
2550 /* to prevent 'flashing' */
2551 if (lower > (spacer = (framepos_t)(128 * Editor::get_current_zoom ()))) {
2552@@ -1897,7 +1897,7 @@
2553 lower = 0;
2554 }
2555 upper += spacer;
2556- framecnt_t const range = upper - lower;
2557+ framecnt_t const range = (upper - lower) * 1000;
2558
2559 if (range < (fr / 50)) {
2560 minsec_mark_interval = fr / 1000; /* show 1/1000 seconds */
2561@@ -1997,7 +1997,7 @@
2562 }
2563
2564 *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * minsec_nmarks);
2565- pos = ((((framepos_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
2566+ pos = (((1000 * (framepos_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
2567 switch (minsec_ruler_scale) {
2568 case minsec_show_seconds:
2569 for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
2570@@ -2014,7 +2014,7 @@
2571 (*marks)[n].style = GtkCustomRulerMarkMicro;
2572 }
2573 (*marks)[n].label = g_strdup (buf);
2574- (*marks)[n].position = pos;
2575+ (*marks)[n].position = pos/1000.0;
2576 }
2577 break;
2578 case minsec_show_minutes:
2579@@ -2032,7 +2032,7 @@
2580 (*marks)[n].style = GtkCustomRulerMarkMicro;
2581 }
2582 (*marks)[n].label = g_strdup (buf);
2583- (*marks)[n].position = pos;
2584+ (*marks)[n].position = pos/1000.0;
2585 }
2586 break;
2587 case minsec_show_hours:
2588@@ -2046,14 +2046,14 @@
2589 (*marks)[n].style = GtkCustomRulerMarkMicro;
2590 }
2591 (*marks)[n].label = g_strdup (buf);
2592- (*marks)[n].position = pos;
2593+ (*marks)[n].position = pos/1000.0;
2594 }
2595 break;
2596 case minsec_show_frames:
2597 for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
2598 sample_to_clock_parts (pos, _session->frame_rate(), &hrs, &mins, &secs, &millisecs);
2599 if (millisecs % minsec_mark_modulo == 0) {
2600- if (secs == 0) {
2601+ if (millisecs == 0) {
2602 (*marks)[n].style = GtkCustomRulerMarkMajor;
2603 } else {
2604 (*marks)[n].style = GtkCustomRulerMarkMinor;
2605@@ -2064,7 +2064,7 @@
2606 (*marks)[n].style = GtkCustomRulerMarkMicro;
2607 }
2608 (*marks)[n].label = g_strdup (buf);
2609- (*marks)[n].position = pos;
2610+ (*marks)[n].position = pos/1000.0;
2611 }
2612 break;
2613 }
2614
2615=== modified file 'gtk2_ardour/ergonomic-us.bindings.in'
2616--- gtk2_ardour/ergonomic-us.bindings.in 2013-09-21 19:05:02 +0000
2617+++ gtk2_ardour/ergonomic-us.bindings.in 2015-05-02 14:23:30 +0000
2618@@ -163,6 +163,7 @@
2619 ; (gtk_accel_path "<Actions>/Snap/snap-to-eighths" "")
2620 (gtk_accel_path "<Actions>/Editor/select-all-after-playhead" "<@TERTIARY@><@PRIMARY@>p")
2621 (gtk_accel_path "<Actions>/Common/ToggleMaximalEditor" "F11")
2622+(gtk_accel_path "<Actions>/Common/ToggleMaximalMixer" "F12")
2623 ; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileLength" "")
2624 ; (gtk_accel_path "<Actions>/Editor/Timecode" "")
2625 ; (gtk_accel_path "<Actions>/Transport/PlaySelection" "")
2626
2627=== modified file 'gtk2_ardour/gain_meter.cc'
2628--- gtk2_ardour/gain_meter.cc 2014-01-24 16:31:54 +0000
2629+++ gtk2_ardour/gain_meter.cc 2015-05-02 14:23:30 +0000
2630@@ -274,18 +274,24 @@
2631 GainMeterBase::setup_meters (int len)
2632 {
2633 int meter_width = 5;
2634+ uint32_t meter_channels = 0;
2635+ if (_meter) {
2636+ meter_channels = _meter->input_streams().n_total();
2637+ } else if (_route) {
2638+ meter_channels = _route->shared_peak_meter()->input_streams().n_total();
2639+ }
2640
2641 switch (_width) {
2642 case Wide:
2643 //meter_ticks1_area.show();
2644 //meter_ticks2_area.show();
2645 meter_metric_area.show();
2646- if (_route && _route->shared_peak_meter()->input_streams().n_total() == 1) {
2647+ if (meter_channels == 1) {
2648 meter_width = 10;
2649 }
2650 break;
2651 case Narrow:
2652- if (_route && _route->shared_peak_meter()->input_streams().n_total() > 1) {
2653+ if (meter_channels > 1) {
2654 meter_width = 4;
2655 }
2656 //meter_ticks1_area.hide();
2657
2658=== modified file 'gtk2_ardour/level_meter.cc'
2659--- gtk2_ardour/level_meter.cc 2013-12-23 22:07:52 +0000
2660+++ gtk2_ardour/level_meter.cc 2015-05-02 14:23:30 +0000
2661@@ -78,6 +78,7 @@
2662 _meter_type_connection.disconnect();
2663
2664 _meter = meter;
2665+ color_changed = true;
2666
2667 if (_meter) {
2668 _meter->ConfigurationChanged.connect (_configuration_connection, parent_invalidator, boost::bind (&LevelMeterBase::configuration_changed, this, _1, _2), gui_context());
2669
2670=== modified file 'gtk2_ardour/midi_time_axis.cc'
2671--- gtk2_ardour/midi_time_axis.cc 2014-01-24 16:31:54 +0000
2672+++ gtk2_ardour/midi_time_axis.cc 2015-05-02 14:23:30 +0000
2673@@ -757,7 +757,7 @@
2674 Evoral::Parameter fully_qualified_param (MidiCCAutomation, chn, ctl);
2675 ctl_items.push_back (
2676 CheckMenuElem (
2677- string_compose ("<b>%1</b>: %2 [%3]", ctl, name, int (chn)),
2678+ string_compose ("<b>%1</b>: %2 [%3]", ctl, name, int (chn + 1)),
2679 sigc::bind (
2680 sigc::mem_fun (*this, &RouteTimeAxisView::toggle_automation_track),
2681 fully_qualified_param)));
2682@@ -1199,16 +1199,56 @@
2683 void
2684 MidiTimeAxisView::show_all_automation (bool apply_to_selection)
2685 {
2686+ using namespace MIDI::Name;
2687+
2688 if (apply_to_selection) {
2689 _editor.get_selection().tracks.foreach_midi_time_axis (
2690 boost::bind (&MidiTimeAxisView::show_all_automation, _1, false));
2691 } else {
2692 if (midi_track()) {
2693+ // Show existing automation
2694 const set<Evoral::Parameter> params = midi_track()->midi_playlist()->contained_automation();
2695
2696 for (set<Evoral::Parameter>::const_iterator i = params.begin(); i != params.end(); ++i) {
2697 create_automation_child(*i, true);
2698 }
2699+
2700+ // Show automation for all controllers named in midnam file
2701+ boost::shared_ptr<MasterDeviceNames> device_names = get_device_names();
2702+ if (gui_property (X_("midnam-model-name")) != "Generic" &&
2703+ device_names && !device_names->controls().empty()) {
2704+ const std::string device_mode = _midnam_custom_device_mode_selector.get_active_text();
2705+ const uint16_t selected_channels = midi_track()->get_playback_channel_mask();
2706+ for (uint32_t chn = 0; chn < 16; ++chn) {
2707+ if ((selected_channels & (0x0001 << chn)) == 0) {
2708+ // Channel not in use
2709+ continue;
2710+ }
2711+
2712+ boost::shared_ptr<ChannelNameSet> chan_names = device_names->channel_name_set_by_channel(
2713+ device_mode, chn);
2714+ if (!chan_names) {
2715+ continue;
2716+ }
2717+
2718+ boost::shared_ptr<ControlNameList> control_names = device_names->control_name_list(
2719+ chan_names->control_list_name());
2720+ if (!control_names) {
2721+ continue;
2722+ }
2723+
2724+ for (ControlNameList::Controls::const_iterator c = control_names->controls().begin();
2725+ c != control_names->controls().end();
2726+ ++c) {
2727+ const uint16_t ctl = c->second->number();
2728+ if (ctl != MIDI_CTL_MSB_BANK && ctl != MIDI_CTL_LSB_BANK) {
2729+ /* Skip bank select controllers since they're handled specially */
2730+ const Evoral::Parameter param(MidiCCAutomation, chn, ctl);
2731+ create_automation_child(param, true);
2732+ }
2733+ }
2734+ }
2735+ }
2736 }
2737
2738 RouteTimeAxisView::show_all_automation ();
2739@@ -1524,8 +1564,7 @@
2740
2741 real_editor->snap_to (pos, 0);
2742
2743- boost::shared_ptr<Source> src = _session->create_midi_source_for_session (
2744- view()->trackview().track().get(), view()->trackview().track()->name());
2745+ boost::shared_ptr<Source> src = _session->create_midi_source_by_stealing_name (view()->trackview().track());
2746 PropertyList plist;
2747
2748 plist.add (ARDOUR::Properties::start, 0);
2749
2750=== modified file 'gtk2_ardour/mixer_strip.cc'
2751--- gtk2_ardour/mixer_strip.cc 2014-01-24 16:31:54 +0000
2752+++ gtk2_ardour/mixer_strip.cc 2015-05-02 14:23:30 +0000
2753@@ -37,6 +37,7 @@
2754 #include "ardour/audio_track.h"
2755 #include "ardour/audioengine.h"
2756 #include "ardour/internal_send.h"
2757+#include "ardour/meter.h"
2758 #include "ardour/midi_track.h"
2759 #include "ardour/pannable.h"
2760 #include "ardour/panner.h"
2761@@ -1023,32 +1024,62 @@
2762 p->automation_state_changed.connect (panstate_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_state_changed, &panners), gui_context());
2763 p->automation_style_changed.connect (panstyle_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_style_changed, &panners), gui_context());
2764
2765- /* This call reduncant, PannerUI::set_panner() connects to _panshell->Changed itself
2766- * However, that only works a panner was previously set.
2767- *
2768- * PannerUI must remain subscribed to _panshell->Changed() in case
2769- * we switch the panner eg. AUX-Send and back
2770- * _route->panner_shell()->Changed() vs _panshell->Changed
2771- */
2772- if (panners._panner == 0) {
2773- panners.panshell_changed ();
2774- }
2775-}
2776-
2777-void
2778-MixerStrip::update_panner_choices ()
2779-{
2780- ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices)
2781- if (!_route->panner_shell()) { return; }
2782-
2783- uint32_t in = _route->output()->n_ports().n_audio();
2784- uint32_t out = in;
2785- if (_route->panner()) {
2786- in = _route->panner()->in().n_audio();
2787- }
2788-
2789- panners.set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out));
2790-}
2791+<<<<<<< TREE
2792+ /* This call reduncant, PannerUI::set_panner() connects to _panshell->Changed itself
2793+ * However, that only works a panner was previously set.
2794+ *
2795+ * PannerUI must remain subscribed to _panshell->Changed() in case
2796+ * we switch the panner eg. AUX-Send and back
2797+ * _route->panner_shell()->Changed() vs _panshell->Changed
2798+ */
2799+ if (panners._panner == 0) {
2800+ panners.panshell_changed ();
2801+ }
2802+}
2803+
2804+void
2805+MixerStrip::update_panner_choices ()
2806+{
2807+ ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices)
2808+ if (!_route->panner_shell()) { return; }
2809+
2810+ uint32_t in = _route->output()->n_ports().n_audio();
2811+ uint32_t out = in;
2812+ if (_route->panner()) {
2813+ in = _route->panner()->in().n_audio();
2814+ }
2815+
2816+ panners.set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out));
2817+}
2818+=======
2819+ /* This call reduncant, PannerUI::set_panner() connects to _panshell->Changed itself
2820+ * However, that only works a panner was previously set.
2821+ *
2822+ * PannerUI must remain subscribed to _panshell->Changed() in case
2823+ * we switch the panner eg. AUX-Send and back
2824+ * _route->panner_shell()->Changed() vs _panshell->Changed
2825+ */
2826+ if (panners._panner == 0) {
2827+ panners.panshell_changed ();
2828+ }
2829+ update_panner_choices();
2830+}
2831+
2832+void
2833+MixerStrip::update_panner_choices ()
2834+{
2835+ ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices)
2836+ if (!_route->panner_shell()) { return; }
2837+
2838+ uint32_t in = _route->output()->n_ports().n_audio();
2839+ uint32_t out = in;
2840+ if (_route->panner()) {
2841+ in = _route->panner()->in().n_audio();
2842+ }
2843+
2844+ panners.set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out));
2845+}
2846+>>>>>>> MERGE-SOURCE
2847
2848 /*
2849 * Output port labelling
2850@@ -1869,6 +1900,7 @@
2851
2852 set_current_delivery (send);
2853
2854+ send->meter()->set_type(_route->shared_peak_meter()->get_type());
2855 send->set_metering (true);
2856 _current_delivery->DropReferences.connect (send_gone_connection, invalidator (*this), boost::bind (&MixerStrip::revert_to_default_display, this), gui_context());
2857
2858@@ -2159,8 +2191,8 @@
2859
2860 _suspend_menu_callbacks = true;
2861 add_level_meter_item_point (items, group, _("Input"), MeterInput);
2862- add_level_meter_item_point (items, group, _("Pre-fader"), MeterPreFader);
2863- add_level_meter_item_point (items, group, _("Post-fader"), MeterPostFader);
2864+ add_level_meter_item_point (items, group, _("Pre Fader"), MeterPreFader);
2865+ add_level_meter_item_point (items, group, _("Post Fader"), MeterPostFader);
2866 add_level_meter_item_point (items, group, _("Output"), MeterOutput);
2867 add_level_meter_item_point (items, group, _("Custom"), MeterCustom);
2868
2869
2870=== modified file 'gtk2_ardour/mixer_ui.cc'
2871--- gtk2_ardour/mixer_ui.cc 2013-11-06 13:22:44 +0000
2872+++ gtk2_ardour/mixer_ui.cc 2015-05-02 14:23:30 +0000
2873@@ -240,6 +240,7 @@
2874 group_display.show();
2875
2876 _in_group_rebuild_or_clear = false;
2877+ _maximised = false;
2878
2879 MixerStrip::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::remove_strip, this, _1), gui_context());
2880
2881@@ -1559,6 +1560,19 @@
2882 }
2883 }
2884
2885+ if ((prop = node.property ("maximised"))) {
2886+ bool yn = string_is_affirmative (prop->value());
2887+ Glib::RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleMaximalMixer"));
2888+ assert (act);
2889+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
2890+ bool fs = tact && tact->get_active();
2891+ if (yn ^ fs) {
2892+ ActionManager::do_action ("Common",
2893+ "ToggleMaximalMixer");
2894+ }
2895+ }
2896+
2897+
2898 return 0;
2899 }
2900
2901@@ -1601,6 +1615,8 @@
2902
2903 node->add_property ("show-mixer", _visible ? "yes" : "no");
2904
2905+ node->add_property ("maximised", _maximised ? "yes" : "no");
2906+
2907 return *node;
2908 }
2909
2910@@ -1942,3 +1958,26 @@
2911 _session->set_exclusive_input_active (rl, onoff, flip_others);
2912 }
2913
2914+void
2915+Mixer_UI::maximise_mixer_space ()
2916+{
2917+ if (_maximised) {
2918+ return;
2919+ }
2920+
2921+ fullscreen ();
2922+
2923+ _maximised = true;
2924+}
2925+
2926+void
2927+Mixer_UI::restore_mixer_space ()
2928+{
2929+ if (!_maximised) {
2930+ return;
2931+ }
2932+
2933+ unfullscreen();
2934+
2935+ _maximised = false;
2936+}
2937
2938=== modified file 'gtk2_ardour/mixer_ui.h'
2939--- gtk2_ardour/mixer_ui.h 2013-11-06 13:22:44 +0000
2940+++ gtk2_ardour/mixer_ui.h 2015-05-02 14:23:30 +0000
2941@@ -80,6 +80,9 @@
2942 void show_strip (MixerStrip *);
2943 void hide_strip (MixerStrip *);
2944
2945+ void maximise_mixer_space();
2946+ void restore_mixer_space();
2947+
2948 void ensure_float (Gtk::Window&);
2949
2950 MonitorSection* monitor_section() const { return _monitor_section; }
2951@@ -279,6 +282,9 @@
2952 bool _following_editor_selection;
2953
2954 void monitor_section_going_away ();
2955+
2956+ /// true if we are in fullscreen mode
2957+ bool _maximised;
2958 };
2959
2960 #endif /* __ardour_mixer_ui_h__ */
2961
2962=== modified file 'gtk2_ardour/mnemonic-us.bindings.in'
2963--- gtk2_ardour/mnemonic-us.bindings.in 2013-09-21 19:05:02 +0000
2964+++ gtk2_ardour/mnemonic-us.bindings.in 2015-05-02 14:23:30 +0000
2965@@ -189,6 +189,7 @@
2966 @trans|Editor/toggle-follow-playhead|<@PRIMARY@>f|toggle playhead tracking
2967 @trans|Transport/ToggleFollowEdits|<@TERTIARY@>f|toggle playhead follows edits
2968 @wvis|Common/ToggleMaximalEditor|<@PRIMARY@><@SECONDARY@>f|maximise editor space
2969+@wvis|Common/ToggleMaximalMixer|F12|maximise mixer space
2970 @wvis|Region/show-rhythm-ferret|<@WINDOW@>f|show rhythm ferret window
2971 @mmode|MouseMode/set-mouse-mode-gain|g|region gain mode
2972 @epp|Region/play-selected-regions|h|play selected region(s)
2973@@ -338,7 +339,7 @@
2974 @trans|Transport/ToggleAutoPlay|5|toggle auto play
2975 @trans|Transport/ToggleAutoReturn|6|toggle auto return
2976 @trans|Transport/ToggleClick|7|toggle click (metronome)
2977-@ranges|Editor/set-tempo-from-region|9|set tempo (1 bar) from region(s)
2978+@ranges|Region/set-tempo-from-region|9|set tempo (1 bar) from region(s)
2979 @ranges|Editor/set-tempo-from-edit-range|0|set tempo (1 bar) from edit range
2980
2981 ; mouse stuff
2982
2983=== modified file 'gtk2_ardour/opts.cc'
2984--- gtk2_ardour/opts.cc 2013-10-17 11:16:21 +0000
2985+++ gtk2_ardour/opts.cc 2015-05-02 14:23:30 +0000
2986@@ -102,7 +102,7 @@
2987 { "help", 0, 0, 'h' },
2988 { "no-announcements", 0, 0, 'a' },
2989 { "bindings", 0, 0, 'b' },
2990- { "disable-plugins", 1, 0, 'd' },
2991+ { "disable-plugins", 0, 0, 'd' },
2992 { "debug", 1, 0, 'D' },
2993 { "no-splash", 0, 0, 'n' },
2994 { "menus", 1, 0, 'm' },
2995
2996=== modified file 'gtk2_ardour/panner_ui.cc'
2997--- gtk2_ardour/panner_ui.cc 2014-01-24 16:31:54 +0000
2998+++ gtk2_ardour/panner_ui.cc 2015-05-02 14:23:30 +0000
2999@@ -49,6 +49,7 @@
3000 PannerUI::PannerUI (Session* s)
3001 : _current_nouts (-1)
3002 , _current_nins (-1)
3003+ , _current_uri ("")
3004 , pan_automation_style_button ("")
3005 , pan_automation_state_button ("")
3006 , _panner_list()
3007@@ -214,12 +215,17 @@
3008 int const nouts = _panner ? _panner->out().n_audio() : -1;
3009 int const nins = _panner ? _panner->in().n_audio() : -1;
3010
3011- if (nouts == _current_nouts && nins == _current_nins) {
3012+ if (nouts == _current_nouts
3013+ && nins == _current_nins
3014+ && _current_uri == _panshell->panner_gui_uri()
3015+ )
3016+ {
3017 return;
3018 }
3019
3020 _current_nins = nins;
3021 _current_nouts = nouts;
3022+ _current_uri = _panshell->panner_gui_uri();
3023
3024 container_clear (pan_vbox);
3025
3026@@ -236,6 +242,7 @@
3027 return;
3028 }
3029
3030+<<<<<<< TREE
3031 if (_panshell->panner_gui_uri() == "http://ardour.org/plugin/panner_2in2out#ui")
3032 {
3033 delete big_window;
3034@@ -286,6 +293,58 @@
3035 }
3036 else if (_panshell->panner_gui_uri() == "http://ardour.org/plugin/panner_vbap#ui")
3037 {
3038+=======
3039+ if (_current_uri == "http://ardour.org/plugin/panner_2in2out#ui")
3040+ {
3041+ delete big_window;
3042+ big_window = 0;
3043+
3044+ boost::shared_ptr<Pannable> pannable = _panner->pannable();
3045+
3046+ _stereo_panner = new StereoPanner (_panshell);
3047+ _stereo_panner->set_size_request (-1, pan_bar_height);
3048+ pan_vbox.pack_start (*_stereo_panner, false, false);
3049+
3050+ boost::shared_ptr<AutomationControl> ac;
3051+
3052+ ac = pannable->pan_azimuth_control;
3053+ _stereo_panner->StartPositionGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch),
3054+ boost::weak_ptr<AutomationControl> (ac)));
3055+ _stereo_panner->StopPositionGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch),
3056+ boost::weak_ptr<AutomationControl>(ac)));
3057+
3058+ ac = pannable->pan_width_control;
3059+ _stereo_panner->StartWidthGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch),
3060+ boost::weak_ptr<AutomationControl> (ac)));
3061+ _stereo_panner->StopWidthGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch),
3062+ boost::weak_ptr<AutomationControl>(ac)));
3063+ _stereo_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event));
3064+ }
3065+ else if (_current_uri == "http://ardour.org/plugin/panner_1in2out#ui"
3066+ || _current_uri == "http://ardour.org/plugin/panner_balance#ui")
3067+ {
3068+ delete big_window;
3069+ big_window = 0;
3070+ boost::shared_ptr<Pannable> pannable = _panner->pannable();
3071+ boost::shared_ptr<AutomationControl> ac = pannable->pan_azimuth_control;
3072+
3073+ _mono_panner = new MonoPanner (_panshell);
3074+
3075+ _mono_panner->StartGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch),
3076+ boost::weak_ptr<AutomationControl> (ac)));
3077+ _mono_panner->StopGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch),
3078+ boost::weak_ptr<AutomationControl>(ac)));
3079+
3080+ _mono_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event));
3081+
3082+ _mono_panner->set_size_request (-1, pan_bar_height);
3083+
3084+ update_pan_sensitive ();
3085+ pan_vbox.pack_start (*_mono_panner, false, false);
3086+ }
3087+ else if (_current_uri == "http://ardour.org/plugin/panner_vbap#ui")
3088+ {
3089+>>>>>>> MERGE-SOURCE
3090 if (!twod_panner) {
3091 twod_panner = new Panner2d (_panshell, 61);
3092 twod_panner->set_name ("MixerPanZone");
3093@@ -383,6 +442,7 @@
3094 bypass_menu_item->set_active (_panshell->bypassed());
3095 bypass_menu_item->signal_toggled().connect (sigc::mem_fun(*this, &PannerUI::pan_bypass_toggle));
3096
3097+<<<<<<< TREE
3098 if (!_panshell->bypassed()) {
3099 items.push_back (MenuElem (_("Reset"), sigc::mem_fun (*this, &PannerUI::pan_reset)));
3100 items.push_back (MenuElem (_("Edit..."), sigc::mem_fun (*this, &PannerUI::pan_edit)));
3101@@ -404,6 +464,26 @@
3102 }
3103 _suspend_menu_callbacks = false;
3104 }
3105+=======
3106+ if (!_panshell->bypassed()) {
3107+ items.push_back (MenuElem (_("Reset"), sigc::mem_fun (*this, &PannerUI::pan_reset)));
3108+ items.push_back (MenuElem (_("Edit..."), sigc::mem_fun (*this, &PannerUI::pan_edit)));
3109+ }
3110+
3111+ if (_panner_list.size() > 1 && !_panshell->bypassed()) {
3112+ RadioMenuItem::Group group;
3113+ items.push_back (SeparatorElem());
3114+
3115+ _suspend_menu_callbacks = true;
3116+ for (std::map<std::string,std::string>::const_iterator p = _panner_list.begin(); p != _panner_list.end(); ++p) {
3117+ items.push_back (RadioMenuElem (group, p->second,
3118+ sigc::bind(sigc::mem_fun (*this, &PannerUI::pan_set_custom_type), p->first)));
3119+ RadioMenuItem* i = dynamic_cast<RadioMenuItem *> (&items.back ());
3120+ i->set_active (_panshell->current_panner_uri() == p->first);
3121+ }
3122+ _suspend_menu_callbacks = false;
3123+ }
3124+>>>>>>> MERGE-SOURCE
3125 }
3126
3127 void
3128
3129=== modified file 'gtk2_ardour/panner_ui.h'
3130--- gtk2_ardour/panner_ui.h 2014-01-24 16:31:54 +0000
3131+++ gtk2_ardour/panner_ui.h 2015-05-02 14:23:30 +0000
3132@@ -96,6 +96,7 @@
3133 bool in_pan_update;
3134 int _current_nouts;
3135 int _current_nins;
3136+ std::string _current_uri;
3137
3138 static const int pan_bar_height;
3139
3140
3141=== modified file 'gtk2_ardour/plugin_ui.cc'
3142--- gtk2_ardour/plugin_ui.cc 2013-10-17 11:16:21 +0000
3143+++ gtk2_ardour/plugin_ui.cc 2015-05-02 14:23:30 +0000
3144@@ -161,7 +161,9 @@
3145
3146 PluginUIWindow::~PluginUIWindow ()
3147 {
3148+#ifndef NDEBUG
3149 cerr << "PluginWindow deleted for " << this << endl;
3150+#endif
3151 delete _pluginui;
3152 }
3153
3154
3155=== modified file 'gtk2_ardour/processor_box.cc'
3156--- gtk2_ardour/processor_box.cc 2014-01-24 16:31:54 +0000
3157+++ gtk2_ardour/processor_box.cc 2015-05-02 14:23:30 +0000
3158@@ -820,6 +820,7 @@
3159 Gdk::Color const fg = get_style()->get_fg (STATE_NORMAL);
3160 cairo_set_source_rgb (cr, fg.get_red_p (), fg.get_green_p (), fg.get_blue_p ());
3161
3162+<<<<<<< TREE
3163 const uint32_t sources = _sources.n_total();
3164 const uint32_t sinks = _sinks.n_total();
3165
3166@@ -878,6 +879,75 @@
3167 cairo_stroke (cr);
3168 }
3169 cairo_destroy(cr);
3170+=======
3171+ const uint32_t sources = _sources.n_total();
3172+ const uint32_t sinks = _sinks.n_total();
3173+
3174+ /* MIDI */
3175+ const uint32_t midi_sources = _sources.n_midi();
3176+ const uint32_t midi_sinks = _sinks.n_midi();
3177+
3178+ cairo_set_source_rgb (cr,
3179+ UINT_RGBA_R_FLT(midi_port_color),
3180+ UINT_RGBA_G_FLT(midi_port_color),
3181+ UINT_RGBA_B_FLT(midi_port_color));
3182+ if (midi_sources > 0 && midi_sinks > 0 && sinks > 1 && sources > 1) {
3183+ for (uint32_t i = 0 ; i < midi_sources; ++i) {
3184+ const float si_x = rintf(width * (.2f + .6f * i / (sinks - 1.f))) + .5f;
3185+ const float si_x0 = rintf(width * (.2f + .6f * i / (sources - 1.f))) + .5f;
3186+ cairo_move_to (cr, si_x, height);
3187+ cairo_curve_to (cr, si_x, 0, si_x0, height, si_x0, 0);
3188+ cairo_stroke (cr);
3189+ }
3190+ } else if (midi_sources == 1 && midi_sinks == 1 && sinks == 1 && sources == 1) {
3191+ const float si_x = rintf(width * .5f) + .5f;
3192+ cairo_move_to (cr, si_x, height);
3193+ cairo_line_to (cr, si_x, 0);
3194+ cairo_stroke (cr);
3195+ } else if (midi_sources == 1 && midi_sinks == 1) {
3196+ /* unusual cases -- removed synth, midi-track w/audio plugins */
3197+ const float si_x = rintf(width * (sinks > 1 ? .2f : .5f)) + .5f;
3198+ const float si_x0 = rintf(width * (sources > 1 ? .2f : .5f)) + .5f;
3199+ cairo_move_to (cr, si_x, height);
3200+ cairo_curve_to (cr, si_x, 0, si_x0, height, si_x0, 0);
3201+ cairo_stroke (cr);
3202+ }
3203+
3204+ /* AUDIO */
3205+ const uint32_t audio_sources = _sources.n_audio();
3206+ const uint32_t audio_sinks = _sinks.n_audio();
3207+ cairo_set_source_rgb (cr,
3208+ UINT_RGBA_R_FLT(audio_port_color),
3209+ UINT_RGBA_G_FLT(audio_port_color),
3210+ UINT_RGBA_B_FLT(audio_port_color));
3211+
3212+ if (_splitting) {
3213+ assert(audio_sources < 2);
3214+ assert(audio_sinks > 1);
3215+ /* assume there is only ever one MIDI port */
3216+ const float si_x0 = rintf(width * (midi_sources > 0 ? .8f : .5f)) + .5f;
3217+ for (uint32_t i = midi_sinks; i < sinks; ++i) {
3218+ const float si_x = rintf(width * (.2f + .6f * i / (sinks - 1.f))) + .5f;
3219+ cairo_move_to (cr, si_x, height);
3220+ cairo_curve_to (cr, si_x, 0, si_x0, height, si_x0, 0);
3221+ cairo_stroke (cr);
3222+ }
3223+ } else if (audio_sources > 1) {
3224+ for (uint32_t i = 0 ; i < audio_sources; ++i) {
3225+ const float si_x = rintf(width * (.2f + .6f * (i + midi_sinks) / (sinks - 1.f))) + .5f;
3226+ const float si_x0 = rintf(width * (.2f + .6f * (i + midi_sources) / (sources - 1.f))) + .5f;
3227+ cairo_move_to (cr, si_x, height);
3228+ cairo_curve_to (cr, si_x, 0, si_x0, height, si_x0, 0);
3229+ cairo_stroke (cr);
3230+ }
3231+ } else if (audio_sources == 1 && audio_sinks == 1) {
3232+ const float si_x = rintf(width * .5f) + .5f;
3233+ cairo_move_to (cr, si_x, height);
3234+ cairo_line_to (cr, si_x, 0);
3235+ cairo_stroke (cr);
3236+ }
3237+ cairo_destroy(cr);
3238+>>>>>>> MERGE-SOURCE
3239 return true;
3240 }
3241
3242
3243=== modified file 'gtk2_ardour/route_ui.cc'
3244--- gtk2_ardour/route_ui.cc 2013-11-06 13:22:44 +0000
3245+++ gtk2_ardour/route_ui.cc 2015-05-02 14:23:30 +0000
3246@@ -1237,13 +1237,13 @@
3247
3248 MenuList& items = mute_menu->items();
3249
3250- pre_fader_mute_check = manage (new CheckMenuItem(_("Pre Fader")));
3251+ pre_fader_mute_check = manage (new CheckMenuItem(_("Pre Fader Sends")));
3252 init_mute_menu(MuteMaster::PreFader, pre_fader_mute_check);
3253 pre_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PreFader, pre_fader_mute_check));
3254 items.push_back (CheckMenuElem(*pre_fader_mute_check));
3255 pre_fader_mute_check->show_all();
3256
3257- post_fader_mute_check = manage (new CheckMenuItem(_("Post Fader")));
3258+ post_fader_mute_check = manage (new CheckMenuItem(_("Post Fader Sends")));
3259 init_mute_menu(MuteMaster::PostFader, post_fader_mute_check);
3260 post_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PostFader, post_fader_mute_check));
3261 items.push_back (CheckMenuElem(*post_fader_mute_check));
3262
3263=== modified file 'gtk2_ardour/sfdb_ui.cc'
3264--- gtk2_ardour/sfdb_ui.cc 2014-01-24 16:31:54 +0000
3265+++ gtk2_ardour/sfdb_ui.cc 2015-05-02 14:23:30 +0000
3266@@ -116,7 +116,7 @@
3267 return _("as new tracks");
3268 }
3269
3270-SoundFileBox::SoundFileBox (bool persistent)
3271+SoundFileBox::SoundFileBox (bool /*persistent*/)
3272 : table (6, 2),
3273 length_clock ("sfboxLengthClock", true, "", false, false, true, false),
3274 timecode_clock ("sfboxTimecodeClock", true, "", false, false, false, false),
3275@@ -279,6 +279,7 @@
3276
3277 string error_msg;
3278
3279+<<<<<<< TREE
3280 if (SMFSource::safe_midi_file_extension (path)) {
3281
3282 boost::shared_ptr<SMFSource> ms =
3283@@ -311,6 +312,40 @@
3284 return true;
3285 }
3286
3287+=======
3288+ if (SMFSource::valid_midi_file (path)) {
3289+
3290+ boost::shared_ptr<SMFSource> ms =
3291+ boost::dynamic_pointer_cast<SMFSource> (
3292+ SourceFactory::createExternal (DataType::MIDI, *_session,
3293+ path, 0, Source::Flag (0), false));
3294+
3295+ preview_label.set_markup (_("<b>Midi File Information</b>"));
3296+
3297+ format_text.set_text ("MIDI");
3298+ samplerate_value.set_text ("-");
3299+ tags_entry.get_buffer()->set_text ("");
3300+ timecode_clock.set (0);
3301+ tags_entry.set_sensitive (false);
3302+
3303+ if (ms) {
3304+ channels_value.set_text (to_string(ms->num_tracks(), std::dec));
3305+ length_clock.set (ms->length(ms->timeline_position()));
3306+ } else {
3307+ channels_value.set_text ("");
3308+ length_clock.set (0);
3309+ }
3310+
3311+ if (_session && ms) {
3312+ play_btn.set_sensitive (true);
3313+ } else {
3314+ play_btn.set_sensitive (false);
3315+ }
3316+
3317+ return true;
3318+ }
3319+
3320+>>>>>>> MERGE-SOURCE
3321 if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
3322
3323 preview_label.set_markup (_("<b>Sound File Information</b>"));
3324@@ -403,6 +438,7 @@
3325 }
3326
3327 boost::shared_ptr<Region> r;
3328+<<<<<<< TREE
3329
3330 if (SMFSource::safe_midi_file_extension (path)) {
3331
3332@@ -456,6 +492,61 @@
3333 AudioSource::set_build_peakfiles (old_sbp);
3334
3335 if (srclist.empty()) {
3336+=======
3337+
3338+ if (SMFSource::valid_midi_file (path)) {
3339+
3340+ boost::shared_ptr<SMFSource> ms =
3341+ boost::dynamic_pointer_cast<SMFSource> (
3342+ SourceFactory::createExternal (DataType::MIDI, *_session,
3343+ path, 0, Source::Flag (0), false));
3344+
3345+ string rname = region_name_from_path (ms->path(), false);
3346+
3347+ PropertyList plist;
3348+
3349+ plist.add (ARDOUR::Properties::start, 0);
3350+ plist.add (ARDOUR::Properties::length, ms->length(ms->timeline_position()));
3351+ plist.add (ARDOUR::Properties::name, rname);
3352+ plist.add (ARDOUR::Properties::layer, 0);
3353+
3354+ r = boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (boost::dynamic_pointer_cast<Source>(ms), plist, false));
3355+ assert(r);
3356+
3357+ } else {
3358+
3359+ SourceList srclist;
3360+ boost::shared_ptr<AudioFileSource> afs;
3361+ bool old_sbp = AudioSource::get_build_peakfiles ();
3362+
3363+ /* don't even think of building peakfiles for these files */
3364+
3365+ AudioSource::set_build_peakfiles (false);
3366+
3367+ for (int n = 0; n < sf_info.channels; ++n) {
3368+ try {
3369+ afs = boost::dynamic_pointer_cast<AudioFileSource> (
3370+ SourceFactory::createExternal (DataType::AUDIO, *_session,
3371+ path, n,
3372+ Source::Flag (0), false));
3373+ if (afs->sample_rate() != _session->nominal_frame_rate()) {
3374+ boost::shared_ptr<SrcFileSource> sfs (new SrcFileSource(*_session, afs, _src_quality));
3375+ srclist.push_back(sfs);
3376+ } else {
3377+ srclist.push_back(afs);
3378+ }
3379+
3380+ } catch (failed_constructor& err) {
3381+ error << _("Could not access soundfile: ") << path << endmsg;
3382+ AudioSource::set_build_peakfiles (old_sbp);
3383+ return;
3384+ }
3385+ }
3386+
3387+ AudioSource::set_build_peakfiles (old_sbp);
3388+
3389+ if (srclist.empty()) {
3390+>>>>>>> MERGE-SOURCE
3391 return;
3392 }
3393
3394@@ -1307,7 +1398,7 @@
3395
3396 /* See if we are thinking about importing any MIDI files */
3397 vector<string>::iterator i = paths.begin ();
3398- while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
3399+ while (i != paths.end() && SMFSource::valid_midi_file (*i) == false) {
3400 ++i;
3401 }
3402 bool const have_a_midi_file = (i != paths.end ());
3403@@ -1535,7 +1626,7 @@
3404 src_needed = true;
3405 }
3406
3407- } else if (SMFSource::safe_midi_file_extension (*i)) {
3408+ } else if (SMFSource::valid_midi_file (*i)) {
3409
3410 Evoral::SMF reader;
3411 reader.open(*i);
3412
3413=== modified file 'gtk2_ardour/stereo_panner.cc'
3414--- gtk2_ardour/stereo_panner.cc 2014-01-24 16:31:54 +0000
3415+++ gtk2_ardour/stereo_panner.cc 2015-05-02 14:23:30 +0000
3416@@ -83,22 +83,42 @@
3417 set_colors ();
3418 have_colors = true;
3419 }
3420- if (!have_font) {
3421- Pango::FontDescription font;
3422- Pango::AttrFontDesc* font_attr;
3423- font = Pango::FontDescription ("ArdourMono");
3424- font.set_weight (Pango::WEIGHT_BOLD);
3425- font.set_size(9 * PANGO_SCALE);
3426- font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font));
3427- panner_font_attributes.change(*font_attr);
3428- delete font_attr;
3429- have_font = true;
3430- }
3431-
3432- position_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
3433- width_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
3434-
3435- _panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&StereoPanner::bypass_handler, this), gui_context());
3436+<<<<<<< TREE
3437+ if (!have_font) {
3438+ Pango::FontDescription font;
3439+ Pango::AttrFontDesc* font_attr;
3440+ font = Pango::FontDescription ("ArdourMono");
3441+ font.set_weight (Pango::WEIGHT_BOLD);
3442+ font.set_size(9 * PANGO_SCALE);
3443+ font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font));
3444+ panner_font_attributes.change(*font_attr);
3445+ delete font_attr;
3446+ have_font = true;
3447+ }
3448+
3449+ position_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
3450+ width_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
3451+
3452+ _panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&StereoPanner::bypass_handler, this), gui_context());
3453+=======
3454+ if (!have_font) {
3455+ Pango::FontDescription font;
3456+ Pango::AttrFontDesc* font_attr;
3457+ font = Pango::FontDescription ("ArdourMono");
3458+ font.set_weight (Pango::WEIGHT_BOLD);
3459+ font.set_size(9 * PANGO_SCALE);
3460+ font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font));
3461+ panner_font_attributes.change(*font_attr);
3462+ delete font_attr;
3463+ have_font = true;
3464+ }
3465+
3466+ position_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
3467+ width_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
3468+
3469+ _panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&StereoPanner::bypass_handler, this), gui_context());
3470+ _panner_shell->PannableChanged.connect (panshell_connections, invalidator (*this), boost::bind (&StereoPanner::pannable_handler, this), gui_context());
3471+>>>>>>> MERGE-SOURCE
3472
3473 ColorsChanged.connect (sigc::mem_fun (*this, &StereoPanner::color_handler));
3474
3475
3476=== modified file 'gtk2_ardour/transcode_ffmpeg.cc'
3477--- gtk2_ardour/transcode_ffmpeg.cc 2013-09-21 19:05:02 +0000
3478+++ gtk2_ardour/transcode_ffmpeg.cc 2015-05-02 14:23:30 +0000
3479@@ -46,6 +46,7 @@
3480 m_avoffset = m_lead_in = m_lead_out = 0;
3481 m_width = m_height = 0;
3482 m_aspect = m_fps = 0;
3483+ m_sar = "";
3484 #if 1 /* tentative debug mode */
3485 debug_enable = false;
3486 #endif
3487@@ -70,17 +71,19 @@
3488 if (ffmpeg_exe.empty() || ffprobe_exe.empty()) {
3489 warning << string_compose(
3490 _(
3491- "No ffprobe or ffmpeg executables could be found on this system.\n"
3492- "Video import and export is not possible until you install those tools.\n"
3493- "%1 requires ffmpeg and ffprobe from ffmpeg.org - version 1.1 or newer.\n"
3494- "\n"
3495- "The tools are included with the %1 releases from ardour.org "
3496- "and also available with the video-server at http://x42.github.com/harvid/\n"
3497- "\n"
3498- "Important: the files need to be installed in $PATH and named ffmpeg_harvid and ffprobe_harvid.\n"
3499- "If you already have a suitable ffmpeg installation on your system, we recommend creating "
3500- "symbolic links from ffmpeg to ffmpeg_harvid and from ffprobe to ffprobe_harvid.\n"
3501- ), PROGRAM_NAME) << endmsg;
3502+ "No ffprobe or ffmpeg executables could be found on this system.\n"
3503+ "Video import and export is not possible until you install those tools.\n"
3504+ "%1 requires ffmpeg and ffprobe from ffmpeg.org - version 1.1 or newer.\n"
3505+ "\n"
3506+ "The tools are included with the %1 releases from ardour.org "
3507+ "and also available with the video-server at http://x42.github.com/harvid/\n"
3508+ "\n"
3509+ "Important: the files need to be installed in $PATH and named ffmpeg_harvid and ffprobe_harvid.\n"
3510+ "If you already have a suitable ffmpeg installation on your system, we recommend creating "
3511+ "symbolic links from ffmpeg to ffmpeg_harvid and from ffprobe to ffprobe_harvid.\n"
3512+ "\n"
3513+ "see also http://manual.ardour.org/video-timeline/setup/"
3514+ ), PROGRAM_NAME) << endmsg;
3515 return;
3516 }
3517 ffexecok = true;
3518@@ -138,6 +141,7 @@
3519 m_width = m_height = 0;
3520 m_fps = m_aspect = 0;
3521 m_duration = 0;
3522+ m_sar.clear();
3523 m_codec.clear();
3524 m_audio.clear();
3525
3526@@ -199,6 +203,13 @@
3527 m_duration = atof(value) * m_fps * timebase;
3528 } else if (key == X_("duration") && m_fps != 0 && m_duration == 0) {
3529 m_duration = atof(value) * m_fps;
3530+ } else if (key == X_("sample_aspect_ratio")) {
3531+ std::string::size_type pos;
3532+ pos = value.find_first_of(':');
3533+ if (pos != std::string::npos && atof(value.substr(pos+1)) != 0) {
3534+ m_sar = value;
3535+ m_sar.replace(pos, 1, "/");
3536+ }
3537 } else if (key == X_("display_aspect_ratio")) {
3538 std::string::size_type pos;
3539 pos = value.find_first_of(':');
3540@@ -340,20 +351,28 @@
3541 if (m_lead_in != 0 && m_lead_out != 0) {
3542 std::ostringstream osstream;
3543 argp[a++] = strdup("-vf");
3544- osstream << X_("color=c=black:s=") << m_width << X_("x") << m_height << X_(":d=") << m_lead_in << X_(" [pre]; ");
3545- osstream << X_("color=c=black:s=") << m_width << X_("x") << m_height << X_(":d=") << m_lead_out << X_(" [post]; ");
3546+ osstream << X_("color=c=black:s=") << m_width << X_("x") << m_height << X_(":d=") << m_lead_in;
3547+ if (!m_sar.empty()) osstream << X_(":sar=") << m_sar;
3548+ osstream << X_(" [pre]; ");
3549+ osstream << X_("color=c=black:s=") << m_width << X_("x") << m_height << X_(":d=") << m_lead_out;
3550+ if (!m_sar.empty()) osstream << X_(":sar=") << m_sar;
3551+ osstream << X_(" [post]; ");
3552 osstream << X_("[pre] [in] [post] concat=n=3");
3553 argp[a++] = strdup(osstream.str().c_str());
3554 } else if (m_lead_in != 0) {
3555 std::ostringstream osstream;
3556 argp[a++] = strdup("-vf");
3557- osstream << X_("color=c=black:s=") << m_width << X_("x") << m_height << X_(":d=") << m_lead_in << X_(" [pre]; ");
3558+ osstream << X_("color=c=black:s=") << m_width << X_("x") << m_height << X_(":d=") << m_lead_in;
3559+ if (!m_sar.empty()) osstream << X_(":sar=") << m_sar;
3560+ osstream << X_(" [pre]; ");
3561 osstream << X_("[pre] [in] concat=n=2");
3562 argp[a++] = strdup(osstream.str().c_str());
3563 } else if (m_lead_out != 0) {
3564 std::ostringstream osstream;
3565 argp[a++] = strdup("-vf");
3566- osstream << X_("color=c=black:s=") << m_width << X_("x") << m_height << X_(":d=") << m_lead_out << X_(" [post]; ");
3567+ osstream << X_("color=c=black:s=") << m_width << X_("x") << m_height << X_(":d=") << m_lead_out;
3568+ if (!m_sar.empty()) osstream << X_(":sar=") << m_sar;
3569+ osstream << X_(" [post]; ");
3570 osstream << X_("[in] [post] concat=n=2");
3571 argp[a++] = strdup(osstream.str().c_str());
3572 }
3573
3574=== modified file 'gtk2_ardour/transcode_ffmpeg.h'
3575--- gtk2_ardour/transcode_ffmpeg.h 2013-09-21 19:05:02 +0000
3576+++ gtk2_ardour/transcode_ffmpeg.h 2015-05-02 14:23:30 +0000
3577@@ -134,6 +134,7 @@
3578
3579 double m_fps;
3580 double m_aspect;
3581+ std::string m_sar;
3582 ARDOUR::framecnt_t m_duration;
3583 int m_width;
3584 int m_height;
3585
3586=== modified file 'gtk2_ardour/transcode_video_dialog.cc'
3587--- gtk2_ardour/transcode_video_dialog.cc 2013-10-17 11:16:21 +0000
3588+++ gtk2_ardour/transcode_video_dialog.cc 2015-05-02 14:23:30 +0000
3589@@ -177,16 +177,18 @@
3590 options_box->pack_start (*l, false, true, 4);
3591
3592 video_combo.set_name ("PaddedButton");
3593- video_combo.append_text(_("Do Not Import Video"));
3594- video_combo.append_text(_("Reference From Current Location"));
3595+ video_combo.append_text(_("Reference From Current Location (Previously Transcoded Files Only)"));
3596 if (ffok) {
3597 video_combo.append_text(_("Import/Transcode Video to Session"));
3598- video_combo.set_active(2);
3599- } else {
3600 video_combo.set_active(1);
3601+ } else {
3602+ video_combo.set_active(0);
3603 video_combo.set_sensitive(false);
3604 audio_combo.set_sensitive(false);
3605 }
3606+ if (as.size() > 0) {
3607+ video_combo.append_text(_("Do Not Import Video (Audio Import Only)"));
3608+ }
3609
3610 options_box->pack_start (video_combo, false, false, 4);
3611
3612@@ -225,8 +227,11 @@
3613 t->attach (*l, 0, 1, 2, 3);
3614 audio_combo.set_name ("PaddedButton");
3615 t->attach (audio_combo, 1, 4, 2, 3);
3616- audio_combo.append_text("No audio");
3617- if (as.size() > 0) {
3618+ if (as.size() == 0) {
3619+ audio_combo.append_text(_("No Audio Track Present"));
3620+ audio_combo.set_sensitive(false);
3621+ } else {
3622+ audio_combo.append_text(_("Do Not Extract Audio"));
3623 for (TranscodeFfmpeg::FFAudioStreams::iterator it = as.begin(); it < as.end(); ++it) {
3624 audio_combo.append_text((*it).name);
3625 }
3626@@ -364,7 +369,7 @@
3627 void
3628 TranscodeVideoDialog::launch_transcode ()
3629 {
3630- if (video_combo.get_active_row_number() != 2) {
3631+ if (video_combo.get_active_row_number() != 1) {
3632 launch_audioonly();
3633 return;
3634 }
3635@@ -413,8 +418,8 @@
3636 void
3637 TranscodeVideoDialog::video_combo_changed ()
3638 {
3639- int i = video_combo.get_active_row_number();
3640- if (i != 2) {
3641+ const int i = video_combo.get_active_row_number();
3642+ if (i != 1) {
3643 scale_combo.set_sensitive(false);
3644 aspect_checkbox.set_sensitive(false);
3645 height_spinner.set_sensitive(false);
3646@@ -427,12 +432,19 @@
3647 bitrate_checkbox.set_sensitive(true);
3648 bitrate_spinner.set_sensitive(true);
3649 }
3650+ if (i == 2 && audio_combo.get_active_row_number() == 0) {
3651+ audio_combo.set_active(1);
3652+ }
3653 }
3654
3655 void
3656 TranscodeVideoDialog::audio_combo_changed ()
3657 {
3658- ;
3659+ if (video_combo.get_active_row_number() == 2
3660+ && audio_combo.get_active_row_number() == 0)
3661+ {
3662+ audio_combo.set_active(1);
3663+ }
3664 }
3665
3666 void
3667
3668=== modified file 'gtk2_ardour/transcode_video_dialog.h'
3669--- gtk2_ardour/transcode_video_dialog.h 2013-09-21 19:05:02 +0000
3670+++ gtk2_ardour/transcode_video_dialog.h 2015-05-02 14:23:30 +0000
3671@@ -31,9 +31,9 @@
3672 #include "transcode_ffmpeg.h"
3673
3674 enum VtlTranscodeOption {
3675- VTL_IMPORT_NO_VIDEO = 0,
3676- VTL_IMPORT_REFERENCE = 1,
3677- VTL_IMPORT_TRANSCODED = 2
3678+ VTL_IMPORT_REFERENCE = 0,
3679+ VTL_IMPORT_TRANSCODED = 1,
3680+ VTL_IMPORT_NO_VIDEO = 2
3681 };
3682
3683 /** @class TranscodeVideoDialog
3684
3685=== modified file 'gtk2_ardour/video_server_dialog.cc'
3686--- gtk2_ardour/video_server_dialog.cc 2013-10-17 11:16:21 +0000
3687+++ gtk2_ardour/video_server_dialog.cc 2015-05-02 14:23:30 +0000
3688@@ -89,8 +89,13 @@
3689 else {
3690 PBD::warning <<
3691 string_compose(
3692- _("The external video server 'harvid' can not be found. The tool is included with the %1 releases from ardour.org, "
3693- "alternatively you can download it from http://x42.github.com/harvid/ or acquire it from your distribution."), PROGRAM_NAME)
3694+ _("The external video server 'harvid' can not be found.\n"
3695+ "The tool is included with the %1 releases from ardour.org, "
3696+ "alternatively you can download it from http://x42.github.com/harvid/ "
3697+ "or acquire it from your distribution.\n"
3698+ "\n"
3699+ "see also http://manual.ardour.org/video-timeline/setup/"
3700+ ), PROGRAM_NAME)
3701 << endmsg;
3702 }
3703
3704
3705=== modified file 'gtk2_ardour/video_timeline.cc'
3706--- gtk2_ardour/video_timeline.cc 2013-09-21 19:05:02 +0000
3707+++ gtk2_ardour/video_timeline.cc 2015-05-02 14:23:30 +0000
3708@@ -39,6 +39,10 @@
3709 #include <pthread.h>
3710 #include <curl/curl.h>
3711
3712+#ifdef PLATFORM_WINDOWS
3713+#include <windows.h>
3714+#endif
3715+
3716 #include "i18n.h"
3717
3718 using namespace std;
3719@@ -718,25 +722,52 @@
3720 VideoTimeLine::find_xjadeo () {
3721 std::string xjadeo_file_path;
3722 if (getenv("XJREMOTE")) {
3723- _xjadeo_bin = strdup(getenv("XJREMOTE")); // XXX TODO: free it?!
3724- } else if (find_file_in_search_path (SearchPath(Glib::getenv("PATH")), X_("xjremote"), xjadeo_file_path)) {
3725- _xjadeo_bin = xjadeo_file_path;
3726+ _xjadeo_bin = getenv("XJREMOTE");
3727+ }
3728+ else if (find_file_in_search_path (SearchPath(Glib::getenv("PATH")), X_("xjremote"), xjadeo_file_path)) {
3729+ _xjadeo_bin = xjadeo_file_path;
3730+ }
3731+ else if (find_file_in_search_path (SearchPath(Glib::getenv("PATH")), X_("xjadeo"), xjadeo_file_path)) {
3732+ _xjadeo_bin = xjadeo_file_path;
3733+ }
3734+#ifdef __APPLE__
3735+ else if (Glib::file_test(X_("/Applications/Xjadeo.app/Contents/MacOS/xjremote"), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) {
3736+ _xjadeo_bin = X_("/Applications/Xjadeo.app/Contents/MacOS/xjremote");
3737 }
3738 else if (Glib::file_test(X_("/Applications/Jadeo.app/Contents/MacOS/xjremote"), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) {
3739 _xjadeo_bin = X_("/Applications/Jadeo.app/Contents/MacOS/xjremote");
3740 }
3741- /* TODO: win32: allow to configure PATH to xjremote */
3742+#endif
3743+#ifdef PLATFORM_WINDOWS
3744+ else {
3745+ HKEY key;
3746+ DWORD size = PATH_MAX;
3747+ char path[PATH_MAX+1];
3748+ xjadeo_file_path = X_("");
3749+ if ( (ERROR_SUCCESS == RegOpenKeyExA (HKEY_LOCAL_MACHINE, "Software\\RSS\\xjadeo", 0, KEY_READ, &key))
3750+ && (ERROR_SUCCESS == RegQueryValueExA (key, "Install_Dir", 0, NULL, (LPBYTE)path, &size))
3751+ )
3752+ {
3753+ xjadeo_file_path = g_build_filename(path, X_("xjadeo.exe"));
3754+ }
3755+ }
3756+ if (Glib::file_test(xjadeo_file_path, Glib::FILE_TEST_EXISTS)) {
3757+ _xjadeo_bin = xjadeo_file_path;
3758+ }
3759 else if (Glib::file_test(X_("C:\\Program Files\\xjadeo\\xjremote.exe"), Glib::FILE_TEST_EXISTS)) {
3760 _xjadeo_bin = X_("C:\\Program Files\\xjadeo\\xjremote.exe");
3761 }
3762 else if (Glib::file_test(X_("C:\\Program Files\\xjadeo\\xjremote.bat"), Glib::FILE_TEST_EXISTS)) {
3763 _xjadeo_bin = X_("C:\\Program Files\\xjadeo\\xjremote.bat");
3764 }
3765+#endif
3766 else {
3767 _xjadeo_bin = X_("");
3768 warning << _("Video-monitor 'xjadeo' was not found. Please install http://xjadeo.sf.net/ "
3769 "(a custom path to xjadeo can be specified by setting the XJREMOTE environment variable. "
3770- "It should point to an application compatible with xjadeo's remote-control interface 'xjremote').")
3771+ "It should point to an application compatible with xjadeo's remote-control interface 'xjremote').\n"
3772+ "\n"
3773+ "see also http://manual.ardour.org/video-timeline/setup/")
3774 << endmsg;
3775 }
3776 }
3777
3778=== modified file 'libs/ardour/amp.cc'
3779--- libs/ardour/amp.cc 2013-09-21 19:05:02 +0000
3780+++ libs/ardour/amp.cc 2015-05-02 14:23:30 +0000
3781@@ -372,19 +372,9 @@
3782 }
3783
3784 void
3785-Amp::set_gain (gain_t val, void *src)
3786+Amp::set_gain (gain_t val, void *)
3787 {
3788- val = min (val, max_gain_coefficient);
3789-
3790- if (src != _gain_control.get()) {
3791- _gain_control->set_value (val);
3792- // bit twisty, this will come back and call us again
3793- // (this keeps control in sync with reality)
3794- return;
3795- }
3796-
3797- _gain_control->set_double (val);
3798- _session.set_dirty();
3799+ _gain_control->set_value (val);
3800 }
3801
3802 XMLNode&
3803@@ -414,13 +404,8 @@
3804 void
3805 Amp::GainControl::set_value (double val)
3806 {
3807- if (val > max_gain_coefficient) {
3808- val = max_gain_coefficient;
3809- }
3810-
3811- _amp->set_gain (val, this);
3812-
3813- AutomationControl::set_value(val);
3814+ AutomationControl::set_value (min (val, (double) max_gain_coefficient));
3815+ _amp->session().set_dirty ();
3816 }
3817
3818 double
3819
3820=== modified file 'libs/ardour/ardour/audio_buffer.h'
3821--- libs/ardour/ardour/audio_buffer.h 2014-01-24 16:31:54 +0000
3822+++ libs/ardour/ardour/audio_buffer.h 2015-05-02 14:23:30 +0000
3823@@ -62,7 +62,7 @@
3824 assert(&src != this);
3825 assert(_capacity > 0);
3826 assert(src.type() == DataType::AUDIO);
3827- assert(len <= _capacity);
3828+ assert(dst_offset + len <= _capacity);
3829 assert( src_offset <= ((framecnt_t) src.capacity()-len));
3830 memcpy(_data + dst_offset, ((const AudioBuffer&)src).data() + src_offset, sizeof(Sample) * len);
3831 if (dst_offset == 0 && src_offset == 0 && len == _capacity) {
3832@@ -173,7 +173,6 @@
3833 void set_data (Sample* data, size_t size) {
3834 assert(!_owns_data); // prevent leaks
3835 _capacity = size;
3836- _size = size;
3837 _data = data;
3838 _silent = false;
3839 _written = false;
3840@@ -185,8 +184,6 @@
3841 */
3842 void resize (size_t nframes);
3843
3844- bool empty() const { return _size == 0; }
3845-
3846 const Sample* data (framecnt_t offset = 0) const {
3847 assert(offset <= _capacity);
3848 return _data + offset;
3849@@ -198,7 +195,11 @@
3850 return _data + offset;
3851 }
3852
3853+<<<<<<< TREE
3854 bool check_silence (pframes_t, bool, pframes_t&) const;
3855+=======
3856+ bool check_silence (pframes_t, pframes_t&) const;
3857+>>>>>>> MERGE-SOURCE
3858
3859 void prepare () { _written = false; _silent = false; }
3860 bool written() const { return _written; }
3861
3862=== modified file 'libs/ardour/ardour/audio_diskstream.h'
3863--- libs/ardour/ardour/audio_diskstream.h 2014-01-24 16:31:54 +0000
3864+++ libs/ardour/ardour/audio_diskstream.h 2015-05-02 14:23:30 +0000
3865@@ -139,7 +139,6 @@
3866 void set_block_size (pframes_t);
3867 int internal_playback_seek (framecnt_t distance);
3868 int can_internal_playback_seek (framecnt_t distance);
3869- std::list<boost::shared_ptr<Source> > steal_write_sources();
3870 void reset_write_sources (bool, bool force = false);
3871 void non_realtime_input_change ();
3872 void non_realtime_locate (framepos_t location);
3873
3874=== modified file 'libs/ardour/ardour/audiofilesource.h'
3875--- libs/ardour/ardour/audiofilesource.h 2013-09-21 19:05:02 +0000
3876+++ libs/ardour/ardour/audiofilesource.h 2015-05-02 14:23:30 +0000
3877@@ -39,10 +39,6 @@
3878 public:
3879 virtual ~AudioFileSource ();
3880
3881- bool set_name (const std::string& newname) {
3882- return (set_source_name(newname, destructive()) == 0);
3883- }
3884-
3885 std::string peak_path (std::string audio_path);
3886 std::string find_broken_peakfile (std::string missing_peak_path,
3887 std::string audio_path);
3888@@ -97,6 +93,12 @@
3889 /** Constructor to be called for existing in-session files */
3890 AudioFileSource (Session&, const XMLNode&, bool must_exist = true);
3891
3892+ /** Constructor to be called for crash recovery. Final argument is not
3893+ * used but exists to differentiate from the external-to-session
3894+ * constructor above.
3895+ */
3896+ AudioFileSource (Session&, const std::string& path, Source::Flag flags, bool);
3897+
3898 int init (const std::string& idstr, bool must_exist);
3899
3900 virtual void set_header_timeline_position () = 0;
3901
3902=== modified file 'libs/ardour/ardour/buffer.h'
3903--- libs/ardour/ardour/buffer.h 2014-01-24 16:31:54 +0000
3904+++ libs/ardour/ardour/buffer.h 2015-05-02 14:23:30 +0000
3905@@ -46,16 +46,9 @@
3906 /** Factory function */
3907 static Buffer* create(DataType type, size_t capacity);
3908
3909- /** Maximum capacity of buffer.
3910- * Note in some cases the entire buffer may not contain valid data, use size. */
3911+ /** Maximum capacity of buffer. */
3912 size_t capacity() const { return _capacity; }
3913
3914- /** Amount of valid data in buffer. Use this over capacity almost always. */
3915- size_t size() const { return _size; }
3916-
3917- /** Return true if the buffer contains no data, false otherwise */
3918- virtual bool empty() const { return _size == 0; }
3919-
3920 /** Type of this buffer.
3921 * Based on this you can static cast a Buffer* to the desired type. */
3922 DataType type() const { return _type; }
3923@@ -80,12 +73,11 @@
3924
3925 protected:
3926 Buffer(DataType type)
3927- : _type(type), _capacity(0), _size(0), _silent (true)
3928+ : _type(type), _capacity(0), _silent (true)
3929 {}
3930
3931 DataType _type;
3932 pframes_t _capacity;
3933- pframes_t _size;
3934 bool _silent;
3935 };
3936
3937
3938=== modified file 'libs/ardour/ardour/diskstream.h'
3939--- libs/ardour/ardour/diskstream.h 2013-10-17 11:16:21 +0000
3940+++ libs/ardour/ardour/diskstream.h 2015-05-02 14:23:30 +0000
3941@@ -70,6 +70,8 @@
3942
3943 virtual bool set_name (const std::string& str);
3944
3945+ virtual std::string steal_write_source_name () { return std::string(); }
3946+
3947 boost::shared_ptr<ARDOUR::IO> io() const { return _io; }
3948 void set_track (ARDOUR::Track *);
3949
3950
3951=== modified file 'libs/ardour/ardour/file_source.h'
3952--- libs/ardour/ardour/file_source.h 2013-09-21 19:05:02 +0000
3953+++ libs/ardour/ardour/file_source.h 2015-05-02 14:23:30 +0000
3954@@ -44,7 +44,7 @@
3955 /** A source associated with a file on disk somewhere */
3956 class FileSource : virtual public Source {
3957 public:
3958- virtual ~FileSource () {}
3959+ virtual ~FileSource ();
3960
3961 virtual const std::string& path() const { return _path; }
3962
3963@@ -74,6 +74,7 @@
3964
3965 void inc_use_count ();
3966 bool removable () const;
3967+ bool is_stub () const;
3968
3969 const std::string& origin() const { return _origin; }
3970
3971@@ -81,6 +82,13 @@
3972
3973 static PBD::Signal3<int,std::string,std::string,std::vector<std::string> > AmbiguousFileName;
3974
3975+ void existence_check ();
3976+ virtual void prevent_deletion ();
3977+
3978+ /** Rename the file on disk referenced by this source to \param newname
3979+ */
3980+ int rename (const std::string& name);
3981+
3982 protected:
3983 FileSource (Session& session, DataType type,
3984 const std::string& path,
3985@@ -102,7 +110,6 @@
3986 std::string _origin;
3987 bool _open;
3988
3989- void prevent_deletion ();
3990 };
3991
3992 } // namespace ARDOUR
3993
3994=== modified file 'libs/ardour/ardour/midi_buffer.h'
3995--- libs/ardour/ardour/midi_buffer.h 2013-10-17 11:16:21 +0000
3996+++ libs/ardour/ardour/midi_buffer.h 2015-05-02 14:23:30 +0000
3997@@ -48,6 +48,8 @@
3998 uint8_t* reserve(TimeType time, size_t size);
3999
4000 void resize(size_t);
4001+ size_t size() const { return _size; }
4002+ bool empty() const { return _size == 0; }
4003
4004 bool merge_in_place(const MidiBuffer &other);
4005
4006@@ -159,6 +161,7 @@
4007 friend class iterator_base< const MidiBuffer, const Evoral::MIDIEvent<TimeType> >;
4008
4009 uint8_t* _data; ///< timestamp, event, timestamp, event, ...
4010+ pframes_t _size;
4011 };
4012
4013
4014
4015=== modified file 'libs/ardour/ardour/midi_diskstream.h'
4016--- libs/ardour/ardour/midi_diskstream.h 2014-01-24 16:31:54 +0000
4017+++ libs/ardour/ardour/midi_diskstream.h 2015-05-02 14:23:30 +0000
4018@@ -111,7 +111,7 @@
4019 void set_block_size (pframes_t);
4020 int internal_playback_seek (framecnt_t distance);
4021 int can_internal_playback_seek (framecnt_t distance);
4022- std::list<boost::shared_ptr<Source> > steal_write_sources();
4023+ std::string steal_write_source_name();
4024 void reset_write_sources (bool, bool force = false);
4025 void non_realtime_input_change ();
4026 void non_realtime_locate (framepos_t location);
4027
4028=== modified file 'libs/ardour/ardour/midi_region.h'
4029--- libs/ardour/ardour/midi_region.h 2013-09-21 19:05:02 +0000
4030+++ libs/ardour/ardour/midi_region.h 2015-05-02 14:23:30 +0000
4031@@ -63,6 +63,7 @@
4032 ~MidiRegion();
4033
4034 boost::shared_ptr<MidiRegion> clone (std::string path = std::string()) const;
4035+ boost::shared_ptr<MidiRegion> clone (boost::shared_ptr<MidiSource>) const;
4036
4037 boost::shared_ptr<MidiSource> midi_source (uint32_t n=0) const;
4038
4039
4040=== modified file 'libs/ardour/ardour/midi_source.h'
4041--- libs/ardour/ardour/midi_source.h 2013-09-21 19:05:02 +0000
4042+++ libs/ardour/ardour/midi_source.h 2015-05-02 14:23:30 +0000
4043@@ -48,9 +48,21 @@
4044 MidiSource (Session& session, const XMLNode&);
4045 virtual ~MidiSource ();
4046
4047- boost::shared_ptr<MidiSource> clone (const std::string& path,
4048- Evoral::MusicalTime begin = Evoral::MinMusicalTime,
4049- Evoral::MusicalTime end = Evoral::MaxMusicalTime);
4050+ /** Write the data in the given time range to another MidiSource
4051+ * \param newsrc MidiSource to which data will be written. Should be a
4052+ * new, empty source. If it already has contents, the results are
4053+ * undefined. Source must be writable.
4054+ *
4055+ * \param begin time of earliest event that can be written.
4056+ * \param end time of latest event that can be written.
4057+ *
4058+ * Returns zero on success, non-zero if the write failed for any
4059+ * reason.
4060+ *
4061+ */
4062+ int write_to (boost::shared_ptr<MidiSource> newsrc,
4063+ Evoral::MusicalTime begin = Evoral::MinMusicalTime,
4064+ Evoral::MusicalTime end = Evoral::MaxMusicalTime);
4065
4066 /** Read the data in a given time range from the MIDI source.
4067 * All time stamps in parameters are in audio frames (even if the source has tempo time).
4068
4069=== modified file 'libs/ardour/ardour/public_diskstream.h'
4070--- libs/ardour/ardour/public_diskstream.h 2013-10-17 11:16:21 +0000
4071+++ libs/ardour/ardour/public_diskstream.h 2015-05-02 14:23:30 +0000
4072@@ -38,7 +38,7 @@
4073 virtual bool destructive () const = 0;
4074 virtual std::list<boost::shared_ptr<Source> > & last_capture_sources () = 0;
4075 virtual void set_capture_offset () = 0;
4076- virtual std::list<boost::shared_ptr<Source> > steal_write_sources () = 0;
4077+ virtual std::string steal_write_source_name () = 0;
4078 virtual void reset_write_sources (bool, bool force = false) = 0;
4079 virtual float playback_buffer_load () const = 0;
4080 virtual float capture_buffer_load () const = 0;
4081
4082=== modified file 'libs/ardour/ardour/session.h'
4083--- libs/ardour/ardour/session.h 2014-01-24 16:31:54 +0000
4084+++ libs/ardour/ardour/session.h 2015-05-02 14:23:30 +0000
4085@@ -194,13 +194,11 @@
4086
4087 std::string peak_path (std::string) const;
4088
4089- std::string change_source_path_by_name (std::string oldpath, std::string oldname, std::string newname, bool destructive);
4090-
4091 std::string peak_path_from_audio_path (std::string) const;
4092- std::string new_audio_source_name (const std::string&, uint32_t nchans, uint32_t chan, bool destructive);
4093- std::string new_midi_source_name (const std::string&);
4094- std::string new_source_path_from_name (DataType type, const std::string&);
4095+ std::string new_audio_source_path (const std::string&, uint32_t nchans, uint32_t chan, bool destructive, bool take_required);
4096+ std::string new_midi_source_path (const std::string&);
4097 RouteList new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name);
4098+ std::vector<std::string> get_paths_for_new_sources (bool allow_replacing, const std::string& import_file_path, uint32_t channels);
4099
4100 void process (pframes_t nframes);
4101
4102@@ -528,8 +526,6 @@
4103
4104 boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const;
4105
4106- std::string path_from_region_name (DataType type, std::string name, std::string identifier);
4107-
4108 boost::shared_ptr<Region> XMLRegionFactory (const XMLNode&, bool full);
4109 boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full);
4110 boost::shared_ptr<MidiRegion> XMLMidiRegionFactory (const XMLNode&, bool full);
4111@@ -582,11 +578,12 @@
4112 boost::shared_ptr<AudioFileSource> create_audio_source_for_session (
4113 size_t, std::string const &, uint32_t, bool destructive);
4114
4115- boost::shared_ptr<MidiSource> create_midi_source_for_session (
4116- Track*, std::string const &);
4117+ boost::shared_ptr<MidiSource> create_midi_source_for_session (std::string const &);
4118+ boost::shared_ptr<MidiSource> create_midi_source_by_stealing_name (boost::shared_ptr<Track>);
4119
4120 boost::shared_ptr<Source> source_by_id (const PBD::ID&);
4121- boost::shared_ptr<Source> source_by_path_and_channel (const std::string&, uint16_t);
4122+ boost::shared_ptr<AudioFileSource> audio_source_by_path_and_channel (const std::string&, uint16_t) const;
4123+ boost::shared_ptr<MidiSource> midi_source_by_path (const std::string&) const;
4124 uint32_t count_sources_by_origin (const std::string&);
4125
4126 void add_playlist (boost::shared_ptr<Playlist>, bool unused = false);
4127@@ -1434,7 +1431,7 @@
4128
4129 bool no_questions_about_missing_files;
4130
4131- std::string get_best_session_directory_for_new_source ();
4132+ std::string get_best_session_directory_for_new_audio ();
4133
4134 mutable gint _playback_load;
4135 mutable gint _capture_load;
4136
4137=== modified file 'libs/ardour/ardour/smf_source.h'
4138--- libs/ardour/ardour/smf_source.h 2013-09-21 19:05:02 +0000
4139+++ libs/ardour/ardour/smf_source.h 2015-05-02 14:23:30 +0000
4140@@ -36,9 +36,11 @@
4141 /** Standard Midi File (Type 0) Source */
4142 class SMFSource : public MidiSource, public FileSource, public Evoral::SMF {
4143 public:
4144+ /** Constructor for new internal-to-session files */
4145+ SMFSource (Session& session, const std::string& path, Source::Flag flags);
4146+
4147 /** Constructor for existing external-to-session files */
4148- SMFSource (Session& session, const std::string& path,
4149- Source::Flag flags = Source::Flag(0));
4150+ SMFSource (Session& session, const std::string& path);
4151
4152 /** Constructor for existing in-session files */
4153 SMFSource (Session& session, const XMLNode&, bool must_exist = false);
4154@@ -49,8 +51,6 @@
4155 return safe_midi_file_extension(path);
4156 }
4157
4158- bool set_name (const std::string& newname) { return (set_source_name(newname, false) == 0); }
4159-
4160 void append_event_unlocked_beats (const Evoral::Event<Evoral::MusicalTime>& ev);
4161 void append_event_unlocked_frames (const Evoral::Event<framepos_t>& ev, framepos_t source_start);
4162
4163@@ -68,6 +68,9 @@
4164 void ensure_disk_file ();
4165
4166 static bool safe_midi_file_extension (const std::string& path);
4167+ static bool valid_midi_file (const std::string& path);
4168+
4169+ void prevent_deletion ();
4170
4171 protected:
4172 void set_path (const std::string& newpath);
4173
4174=== modified file 'libs/ardour/ardour/sndfilesource.h'
4175--- libs/ardour/ardour/sndfilesource.h 2013-09-21 19:05:02 +0000
4176+++ libs/ardour/ardour/sndfilesource.h 2015-05-02 14:23:30 +0000
4177@@ -38,7 +38,16 @@
4178 SampleFormat samp_format, HeaderFormat hdr_format, framecnt_t rate,
4179 Flag flags = SndFileSource::default_writable_flags);
4180
4181- /** Constructor to be called for existing in-session files */
4182+ /* Constructor to be called for recovering files being used for
4183+ * capture. They are in-session, they already exist, they should not
4184+ * be writable. They are an odd hybrid (from a constructor point of
4185+ * view) of the previous two constructors.
4186+ */
4187+ SndFileSource (Session&, const std::string& path, int chn);
4188+
4189+ /** Constructor to be called for existing in-session files during
4190+ * session loading
4191+ */
4192 SndFileSource (Session&, const XMLNode&);
4193
4194 ~SndFileSource ();
4195
4196=== modified file 'libs/ardour/ardour/source.h'
4197--- libs/ardour/ardour/source.h 2013-09-21 19:05:02 +0000
4198+++ libs/ardour/ardour/source.h 2015-05-02 14:23:30 +0000
4199@@ -47,7 +47,8 @@
4200 RemovableIfEmpty = 0x10,
4201 RemoveAtDestroy = 0x20,
4202 NoPeakFile = 0x40,
4203- Destructive = 0x80
4204+ Destructive = 0x80,
4205+ Empty = 0x100, /* used for MIDI only */
4206 };
4207
4208 Source (Session&, DataType type, const std::string& name, Flag flags=Flag(0));
4209
4210=== modified file 'libs/ardour/ardour/source_factory.h'
4211--- libs/ardour/ardour/source_factory.h 2013-09-21 19:05:02 +0000
4212+++ libs/ardour/ardour/source_factory.h 2015-05-02 14:23:30 +0000
4213@@ -57,6 +57,9 @@
4214 bool destructive, framecnt_t rate, bool announce = true, bool async = false);
4215
4216
4217+ static boost::shared_ptr<Source> createForRecovery
4218+ (DataType type, Session&, const std::string& path, int chn);
4219+
4220 static boost::shared_ptr<Source> createFromPlaylist
4221 (DataType type, Session& s, boost::shared_ptr<Playlist> p, const PBD::ID& orig, const std::string& name,
4222 uint32_t chn, frameoffset_t start, framecnt_t len, bool copy, bool defer_peaks);
4223
4224=== modified file 'libs/ardour/ardour/track.h'
4225--- libs/ardour/ardour/track.h 2013-10-17 11:16:21 +0000
4226+++ libs/ardour/ardour/track.h 2015-05-02 14:23:30 +0000
4227@@ -120,7 +120,7 @@
4228 bool destructive () const;
4229 std::list<boost::shared_ptr<Source> > & last_capture_sources ();
4230 void set_capture_offset ();
4231- std::list<boost::shared_ptr<Source> > steal_write_sources();
4232+ std::string steal_write_source_name ();
4233 void reset_write_sources (bool, bool force = false);
4234 float playback_buffer_load () const;
4235 float capture_buffer_load () const;
4236
4237=== modified file 'libs/ardour/ardour/vestige/aeffectx.h'
4238--- libs/ardour/ardour/vestige/aeffectx.h 2014-01-24 16:31:54 +0000
4239+++ libs/ardour/ardour/vestige/aeffectx.h 2015-05-02 14:23:30 +0000
4240@@ -251,6 +251,7 @@
4241
4242 typedef struct _VstTimeInfo
4243 {
4244+<<<<<<< TREE
4245 /* info from online documentation of VST provided by Steinberg */
4246
4247 double samplePos;
4248@@ -271,6 +272,26 @@
4249 } VstTimeInfo;
4250
4251 typedef struct _VstTimeInfo VstTimeInfo;
4252+=======
4253+ /* info from online documentation of VST provided by Steinberg */
4254+
4255+ double samplePos;
4256+ double sampleRate;
4257+ double nanoSeconds;
4258+ double ppqPos;
4259+ double tempo;
4260+ double barStartPos;
4261+ double cycleStartPos;
4262+ double cycleEndPos;
4263+ int32_t timeSigNumerator;
4264+ int32_t timeSigDenominator;
4265+ int32_t smpteOffset;
4266+ int32_t smpteFrameRate;
4267+ int32_t samplesToNextClock;
4268+ int32_t flags;
4269+
4270+} VstTimeInfo;
4271+>>>>>>> MERGE-SOURCE
4272
4273 typedef intptr_t (* audioMasterCallback) (AEffect *, int32_t, int32_t, intptr_t, void *, float);
4274
4275
4276=== modified file 'libs/ardour/audio_buffer.cc'
4277--- libs/ardour/audio_buffer.cc 2014-01-24 16:31:54 +0000
4278+++ libs/ardour/audio_buffer.cc 2015-05-02 14:23:30 +0000
4279@@ -57,12 +57,6 @@
4280
4281 if (_data && size < _capacity) {
4282 /* buffer is already large enough */
4283-
4284- if (size < _size) {
4285- /* truncate */
4286- _size = size;
4287- }
4288-
4289 return;
4290 }
4291
4292@@ -71,14 +65,17 @@
4293 cache_aligned_malloc ((void**) &_data, sizeof (Sample) * size);
4294
4295 _capacity = size;
4296- _size = 0;
4297 _silent = false;
4298 }
4299
4300 bool
4301 AudioBuffer::check_silence (pframes_t nframes, bool wholebuffer, pframes_t& n) const
4302 {
4303+<<<<<<< TREE
4304 for (n = 0; (wholebuffer || n < _size) && n < nframes; ++n) {
4305+=======
4306+ for (n = 0; n < nframes; ++n) {
4307+>>>>>>> MERGE-SOURCE
4308 if (_data[n] != Sample (0)) {
4309 return false;
4310 }
4311
4312=== modified file 'libs/ardour/audio_diskstream.cc'
4313--- libs/ardour/audio_diskstream.cc 2013-10-17 11:16:21 +0000
4314+++ libs/ardour/audio_diskstream.cc 2015-05-02 14:23:30 +0000
4315@@ -1928,14 +1928,6 @@
4316 return 0;
4317 }
4318
4319-list<boost::shared_ptr<Source> >
4320-AudioDiskstream::steal_write_sources()
4321-{
4322- /* not possible to steal audio write sources */
4323- list<boost::shared_ptr<Source> > ret;
4324- return ret;
4325-}
4326-
4327 void
4328 AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
4329 {
4330@@ -2189,11 +2181,16 @@
4331 continue;
4332 }
4333
4334+ /* XXX as of June 2014, we always record to mono
4335+ files. Since this Source is being created as part of
4336+ crash recovery, we know that we need the first
4337+ channel (the final argument to the SourceFactory
4338+ call below). If we ever support non-mono files for
4339+ capture, this will need rethinking.
4340+ */
4341+
4342 try {
4343- fs = boost::dynamic_pointer_cast<AudioFileSource> (
4344- SourceFactory::createWritable (
4345- DataType::AUDIO, _session,
4346- prop->value(), false, _session.frame_rate()));
4347+ fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createForRecovery (DataType::AUDIO, _session, prop->value(), 0));
4348 }
4349
4350 catch (failed_constructor& err) {
4351@@ -2224,21 +2221,31 @@
4352 return -1;
4353 }
4354
4355- boost::shared_ptr<AudioRegion> region;
4356-
4357 try {
4358
4359+ boost::shared_ptr<AudioRegion> wf_region;
4360+ boost::shared_ptr<AudioRegion> region;
4361+
4362+ /* First create the whole file region */
4363+
4364 PropertyList plist;
4365-
4366+
4367 plist.add (Properties::start, 0);
4368 plist.add (Properties::length, first_fs->length (first_fs->timeline_position()));
4369 plist.add (Properties::name, region_name_from_path (first_fs->name(), true));
4370
4371+ wf_region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
4372+
4373+ wf_region->set_automatic (true);
4374+ wf_region->set_whole_file (true);
4375+ wf_region->special_set_position (position);
4376+
4377+ /* Now create a region that isn't the whole file for adding to
4378+ * the playlist */
4379+
4380 region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
4381-
4382- region->set_automatic (true);
4383- region->set_whole_file (true);
4384- region->special_set_position (0);
4385+
4386+ _playlist->add_region (region, position);
4387 }
4388
4389 catch (failed_constructor& err) {
4390@@ -2249,7 +2256,6 @@
4391 return -1;
4392 }
4393
4394- _playlist->add_region (region, position);
4395
4396 return 0;
4397 }
4398
4399=== modified file 'libs/ardour/audiofilesource.cc'
4400--- libs/ardour/audiofilesource.cc 2013-09-21 19:05:02 +0000
4401+++ libs/ardour/audiofilesource.cc 2015-05-02 14:23:30 +0000
4402@@ -36,6 +36,7 @@
4403 #include "pbd/stl_delete.h"
4404 #include "pbd/strsplit.h"
4405 #include "pbd/shortpath.h"
4406+#include "pbd/stacktrace.h"
4407 #include "pbd/enumwriter.h"
4408
4409 #include <sndfile.h>
4410@@ -114,6 +115,22 @@
4411 }
4412 }
4413
4414+/** Constructor used for existing internal-to-session files during crash
4415+ * recovery. File must exist
4416+ */
4417+AudioFileSource::AudioFileSource (Session& s, const string& path, Source::Flag flags, bool /* ignored-exists-for-prototype differentiation */)
4418+ : Source (s, DataType::AUDIO, path, flags)
4419+ , AudioSource (s, path)
4420+ , FileSource (s, DataType::AUDIO, path, string(), flags)
4421+{
4422+ /* note that origin remains empty */
4423+
4424+ if (init (_path, true)) {
4425+ throw failed_constructor ();
4426+ }
4427+}
4428+
4429+
4430 /** Constructor used for existing internal-to-session files via XML. File must exist. */
4431 AudioFileSource::AudioFileSource (Session& s, const XMLNode& node, bool must_exist)
4432 : Source (s, node)
4433
4434=== modified file 'libs/ardour/automation_control.cc'
4435--- libs/ardour/automation_control.cc 2013-09-21 19:05:02 +0000
4436+++ libs/ardour/automation_control.cc 2015-05-02 14:23:30 +0000
4437@@ -117,15 +117,23 @@
4438 void
4439 AutomationControl::start_touch(double when)
4440 {
4441- set_touching (true);
4442- alist()->start_touch(when);
4443- AutomationWatch::instance().add_automation_watch (shared_from_this());
4444+ if (!touching()) {
4445+ if (alist()->automation_state() == Touch) {
4446+ alist()->start_touch (when);
4447+ AutomationWatch::instance().add_automation_watch (shared_from_this());
4448+ }
4449+ set_touching (true);
4450+ }
4451 }
4452
4453 void
4454 AutomationControl::stop_touch(bool mark, double when)
4455 {
4456- set_touching (false);
4457- alist()->stop_touch (mark, when);
4458- AutomationWatch::instance().remove_automation_watch (shared_from_this());
4459+ if (touching()) {
4460+ set_touching (false);
4461+ if (alist()->automation_state() == Touch) {
4462+ alist()->stop_touch (mark, when);
4463+ AutomationWatch::instance().remove_automation_watch (shared_from_this());
4464+ }
4465+ }
4466 }
4467
4468=== modified file 'libs/ardour/automation_watch.cc'
4469--- libs/ardour/automation_watch.cc 2013-09-21 19:05:02 +0000
4470+++ libs/ardour/automation_watch.cc 2015-05-02 14:23:30 +0000
4471@@ -122,7 +122,7 @@
4472
4473 for (AutomationWatches::iterator aw = automation_watches.begin(); aw != automation_watches.end(); ++aw) {
4474 if ((*aw)->alist()->automation_write()) {
4475- (*aw)->list()->add (time, (*aw)->user_double());
4476+ (*aw)->list()->add (time, (*aw)->user_double(), true);
4477 }
4478 }
4479 }
4480
4481=== modified file 'libs/ardour/coreaudiosource.cc'
4482--- libs/ardour/coreaudiosource.cc 2013-09-21 19:05:02 +0000
4483+++ libs/ardour/coreaudiosource.cc 2015-05-02 14:23:30 +0000
4484@@ -28,6 +28,8 @@
4485 #include <appleutility/CAAudioFile.h>
4486 #include <appleutility/CAStreamBasicDescription.h>
4487
4488+#include <glibmm/fileutils.h>
4489+
4490 #include "i18n.h"
4491
4492 #include <AudioToolbox/AudioFormat.h>
4493@@ -36,21 +38,32 @@
4494 using namespace ARDOUR;
4495 using namespace PBD;
4496
4497+/** Create a new CoreAudioSource using session state, which implies that the
4498+ * file must already exist.
4499+ */
4500 CoreAudioSource::CoreAudioSource (Session& s, const XMLNode& node)
4501 : Source (s, node)
4502 , AudioFileSource (s, node)
4503 {
4504 init_cafile ();
4505+
4506+ assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
4507+ existence_check ();
4508 }
4509
4510+/** Create a new CoreAudioSource from an existing file. Sources created with this
4511+ * method are never writable or removable.
4512+ */
4513 CoreAudioSource::CoreAudioSource (Session& s, const string& path, int chn, Flag flags)
4514- /* files created this way are never writable or removable */
4515 : Source (s, DataType::AUDIO, path, Source::Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))),
4516 AudioFileSource (s, path,
4517 Source::Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
4518 {
4519 _channel = chn;
4520 init_cafile ();
4521+
4522+ assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
4523+ existence_check ();
4524 }
4525
4526 void
4527
4528=== modified file 'libs/ardour/delivery.cc'
4529--- libs/ardour/delivery.cc 2014-01-24 16:31:54 +0000
4530+++ libs/ardour/delivery.cc 2015-05-02 14:23:30 +0000
4531@@ -397,7 +397,11 @@
4532 if (panners_legal) {
4533 if (!_no_panner_reset) {
4534
4535+<<<<<<< TREE
4536 if (_panshell && _role != Insert) {
4537+=======
4538+ if (_panshell && _role != Insert && _role != Listen) {
4539+>>>>>>> MERGE-SOURCE
4540 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
4541 }
4542 }
4543
4544=== modified file 'libs/ardour/diskstream.cc'
4545--- libs/ardour/diskstream.cc 2013-09-21 19:05:02 +0000
4546+++ libs/ardour/diskstream.cc 2015-05-02 14:23:30 +0000
4547@@ -739,4 +739,3 @@
4548 {
4549 g_atomic_int_set (&_record_enabled, 0);
4550 }
4551-
4552
4553=== modified file 'libs/ardour/enums.cc'
4554--- libs/ardour/enums.cc 2013-12-23 22:07:52 +0000
4555+++ libs/ardour/enums.cc 2015-05-02 14:23:30 +0000
4556@@ -447,6 +447,7 @@
4557 REGISTER_CLASS_ENUM (Source, RemoveAtDestroy);
4558 REGISTER_CLASS_ENUM (Source, NoPeakFile);
4559 REGISTER_CLASS_ENUM (Source, Destructive);
4560+ REGISTER_CLASS_ENUM (Source, Empty);
4561 REGISTER_BITS (_Source_Flag);
4562
4563 REGISTER_ENUM (FadeLinear);
4564
4565=== modified file 'libs/ardour/export_channel.cc'
4566--- libs/ardour/export_channel.cc 2013-12-23 22:07:52 +0000
4567+++ libs/ardour/export_channel.cc 2015-05-02 14:23:30 +0000
4568@@ -239,7 +239,7 @@
4569 {
4570 assert(processor);
4571 AudioBuffer const & buffer = processor->get_capture_buffers().get_audio (channel);
4572- assert (frames <= (framecnt_t) buffer.size());
4573+ assert (frames <= (framecnt_t) buffer.capacity());
4574 data = buffer.data();
4575 }
4576
4577
4578=== modified file 'libs/ardour/file_source.cc'
4579--- libs/ardour/file_source.cc 2013-09-21 19:05:02 +0000
4580+++ libs/ardour/file_source.cc 2015-05-02 14:23:30 +0000
4581@@ -56,14 +56,12 @@
4582 FileSource::FileSource (Session& session, DataType type, const string& path, const string& origin, Source::Flag flag)
4583 : Source(session, type, path, flag)
4584 , _path (path)
4585- , _file_is_new (!origin.empty()) // origin empty => new file VS. origin !empty => new file
4586+ , _file_is_new (!origin.empty()) // if origin is left unspecified (empty string) then file must exist
4587 , _channel (0)
4588 , _origin (origin)
4589 , _open (false)
4590 {
4591 set_within_session_from_path (path);
4592-
4593- prevent_deletion ();
4594 }
4595
4596 FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist*/)
4597@@ -77,23 +75,28 @@
4598
4599 _path = _name;
4600 _within_session = true;
4601-
4602- prevent_deletion ();
4603+}
4604+
4605+FileSource::~FileSource()
4606+{
4607+}
4608+
4609+void
4610+FileSource::existence_check ()
4611+{
4612+ if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)) {
4613+ prevent_deletion ();
4614+ }
4615 }
4616
4617 void
4618 FileSource::prevent_deletion ()
4619 {
4620- /* if this file already exists, it cannot be removed, ever
4621- */
4622-
4623- if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)) {
4624- if (!(_flags & Destructive)) {
4625- mark_immutable ();
4626- } else {
4627- _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy));
4628- }
4629- }
4630+ if (!(_flags & Destructive)) {
4631+ mark_immutable ();
4632+ } else {
4633+ _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy));
4634+ }
4635 }
4636
4637 bool
4638@@ -101,7 +104,7 @@
4639 {
4640 bool r = ((_flags & Removable)
4641 && ((_flags & RemoveAtDestroy) ||
4642- ((_flags & RemovableIfEmpty) && empty() == 0)));
4643+ ((_flags & RemovableIfEmpty) && empty())));
4644
4645 return r;
4646 }
4647@@ -211,7 +214,7 @@
4648
4649 if (move_dependents_to_trash() != 0) {
4650 /* try to back out */
4651- rename (newpath.c_str(), _path.c_str());
4652+ ::rename (newpath.c_str(), _path.c_str());
4653 return -1;
4654 }
4655
4656@@ -253,8 +256,6 @@
4657
4658 split (search_path, dirs, ':');
4659
4660- hits.clear ();
4661-
4662 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4663
4664 fullpath = Glib::build_filename (*i, path);
4665@@ -309,9 +310,9 @@
4666 /* no match: error */
4667
4668 if (must_exist) {
4669- error << string_compose(
4670- _("Filesource: cannot find required file (%1): while searching %2"),
4671- path, search_path) << endmsg;
4672+ /* do not generate an error here, leave that to
4673+ whoever deals with the false return value.
4674+ */
4675 goto out;
4676 } else {
4677 isnew = true;
4678@@ -322,16 +323,17 @@
4679
4680 keeppath = de_duped_hits[0];
4681 }
4682-
4683- } else {
4684+
4685+ } else {
4686 keeppath = path;
4687 }
4688
4689 /* Current find() is unable to parse relative path names to yet non-existant
4690 sources. QuickFix(tm)
4691 */
4692- if (keeppath == "") {
4693- if (must_exist) {
4694+
4695+ if (keeppath.empty()) {
4696+ if (must_exist) {
4697 error << "FileSource::find(), keeppath = \"\", but the file must exist" << endl;
4698 } else {
4699 keeppath = path;
4700@@ -518,35 +520,6 @@
4701 return ret;
4702 }
4703
4704-int
4705-FileSource::set_source_name (const string& newname, bool destructive)
4706-{
4707- Glib::Threads::Mutex::Lock lm (_lock);
4708- string oldpath = _path;
4709- string newpath = _session.change_source_path_by_name (oldpath, _name, newname, destructive);
4710-
4711- if (newpath.empty()) {
4712- error << string_compose (_("programming error: %1"), "cannot generate a changed file path") << endmsg;
4713- return -1;
4714- }
4715-
4716- // Test whether newpath exists, if yes notify the user but continue.
4717- if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
4718- error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg;
4719- return -1;
4720- }
4721-
4722- if (::rename (oldpath.c_str(), newpath.c_str()) != 0) {
4723- error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg;
4724- return -1;
4725- }
4726-
4727- _name = Glib::path_get_basename (newpath);
4728- _path = newpath;
4729-
4730- return 0;
4731-}
4732-
4733 void
4734 FileSource::mark_immutable ()
4735 {
4736@@ -589,3 +562,46 @@
4737 Source::inc_use_count ();
4738 }
4739
4740+bool
4741+FileSource::is_stub () const
4742+{
4743+ if (!empty()) {
4744+ return false;
4745+ }
4746+
4747+ if (!removable()) {
4748+ return false;
4749+ }
4750+
4751+ if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)) {
4752+ return false;
4753+ }
4754+
4755+ return true;
4756+}
4757+
4758+int
4759+FileSource::rename (const string& newpath)
4760+{
4761+ Glib::Threads::Mutex::Lock lm (_lock);
4762+ string oldpath = _path;
4763+
4764+ // Test whether newpath exists, if yes notify the user but continue.
4765+ if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
4766+ error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg;
4767+ return -1;
4768+ }
4769+
4770+ if (Glib::file_test (oldpath.c_str(), Glib::FILE_TEST_EXISTS)) {
4771+ /* rename only needed if file exists on disk */
4772+ if (::rename (oldpath.c_str(), newpath.c_str()) != 0) {
4773+ error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg;
4774+ return -1;
4775+ }
4776+ }
4777+
4778+ _name = Glib::path_get_basename (newpath);
4779+ _path = newpath;
4780+
4781+ return 0;
4782+}
4783
4784=== modified file 'libs/ardour/filter.cc'
4785--- libs/ardour/filter.cc 2013-09-21 19:05:02 +0000
4786+++ libs/ardour/filter.cc 2015-05-02 14:23:30 +0000
4787@@ -59,10 +59,9 @@
4788 }
4789 }
4790
4791- string path = session.path_from_region_name (region->data_type(),
4792- PBD::basename_nosuffix (names[i]), string (""));
4793+ string path = session.new_audio_source_path (name, region->n_channels(), i, false, false);
4794
4795- if (path.length() == 0) {
4796+ if (path.empty()) {
4797 error << string_compose (_("filter: error creating name for new file based on %1"), region->name())
4798 << endmsg;
4799 return -1;
4800
4801=== modified file 'libs/ardour/import.cc'
4802--- libs/ardour/import.cc 2013-09-21 19:05:02 +0000
4803+++ libs/ardour/import.cc 2015-05-02 14:23:30 +0000
4804@@ -116,78 +116,31 @@
4805 }
4806 }
4807
4808-static std::string
4809-get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint channel, uint channels)
4810-{
4811- char buf[PATH_MAX+1];
4812- bool goodfile = false;
4813- string base = basename;
4814- string ext = native_header_format_extension (hf, type);
4815- uint32_t cnt = 1;
4816-
4817- do {
4818-
4819- if (type == DataType::AUDIO && channels == 2) {
4820- if (channel == 0) {
4821- if (cnt == 1) {
4822- snprintf (buf, sizeof(buf), "%s-L%s", base.c_str(), ext.c_str());
4823- } else {
4824- snprintf (buf, sizeof(buf), "%s-%d-L%s", base.c_str(), cnt, ext.c_str());
4825- }
4826- } else {
4827- if (cnt == 1) {
4828- snprintf (buf, sizeof(buf), "%s-R%s", base.c_str(), ext.c_str());
4829- } else {
4830- snprintf (buf, sizeof(buf), "%s-%d-R%s", base.c_str(), cnt, ext.c_str());
4831- }
4832- }
4833- } else if (channels > 1) {
4834- if (cnt == 1) {
4835- snprintf (buf, sizeof(buf), "%s-c%d%s", base.c_str(), channel, ext.c_str());
4836- } else {
4837- snprintf (buf, sizeof(buf), "%s-%d-c%d%s", base.c_str(), cnt, channel, ext.c_str());
4838- }
4839- } else {
4840- if (cnt == 1) {
4841- snprintf (buf, sizeof(buf), "%s%s", base.c_str(), ext.c_str());
4842- } else {
4843- snprintf (buf, sizeof(buf), "%s-%d%s", base.c_str(), cnt, ext.c_str());
4844- }
4845- }
4846-
4847- string tempname = destdir + "/" + buf;
4848-
4849- if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) {
4850-
4851- cnt++;
4852-
4853- } else {
4854-
4855- goodfile = true;
4856- }
4857-
4858- } while (!goodfile);
4859-
4860- return buf;
4861-}
4862-
4863-static vector<string>
4864-get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels)
4865+vector<string>
4866+Session::get_paths_for_new_sources (bool /*allow_replacing*/, const string& import_file_path, uint32_t channels)
4867 {
4868 vector<string> new_paths;
4869 const string basename = basename_nosuffix (import_file_path);
4870
4871- SessionDirectory sdir(session_dir);
4872-
4873 for (uint n = 0; n < channels; ++n) {
4874
4875 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
4876-
4877- std::string filepath = (type == DataType::MIDI)
4878- ? sdir.midi_path() : sdir.sound_path();
4879-
4880- filepath = Glib::build_filename (filepath,
4881- get_non_existent_filename (hf, type, allow_replacing, filepath, basename, n, channels));
4882+ string filepath;
4883+
4884+ switch (type) {
4885+ case DataType::MIDI:
4886+ filepath = new_midi_source_path (basename);
4887+ break;
4888+ case DataType::AUDIO:
4889+ filepath = new_audio_source_path (basename, channels, n, false, false);
4890+ break;
4891+ }
4892+
4893+ if (filepath.empty()) {
4894+ error << string_compose (_("Cannot find new filename for imported file %1"), import_file_path) << endmsg;
4895+ return vector<string>();
4896+ }
4897+
4898 new_paths.push_back (filepath);
4899 }
4900
4901@@ -201,7 +154,7 @@
4902 for (vector<string>::const_iterator i = new_paths.begin();
4903 i != new_paths.end(); ++i)
4904 {
4905- boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0);
4906+ boost::shared_ptr<Source> source = session->audio_source_by_path_and_channel(*i, 0);
4907
4908 if (source == 0) {
4909 error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
4910@@ -274,12 +227,12 @@
4911 {
4912 const framecnt_t nframes = ResampledImportableSource::blocksize;
4913 boost::shared_ptr<AudioFileSource> afs;
4914- uint channels = source->channels();
4915+ uint32_t channels = source->channels();
4916
4917 boost::scoped_array<float> data(new float[nframes * channels]);
4918 vector<boost::shared_array<Sample> > channel_data;
4919
4920- for (uint n = 0; n < channels; ++n) {
4921+ for (uint32_t n = 0; n < channels; ++n) {
4922 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
4923 }
4924
4925@@ -323,14 +276,14 @@
4926 progress_multiplier = 0.5;
4927 progress_base = 0.5;
4928 }
4929-
4930- uint read_count = 0;
4931+
4932+ framecnt_t read_count = 0;
4933
4934 while (!status.cancel) {
4935
4936 framecnt_t nread, nfread;
4937- uint x;
4938- uint chn;
4939+ uint32_t x;
4940+ uint32_t chn;
4941
4942 if ((nread = source->read (data.get(), nframes)) == 0) {
4943 break;
4944@@ -513,10 +466,7 @@
4945 }
4946 }
4947
4948- vector<string> new_paths = get_paths_for_new_sources (config.get_native_file_header_format(),
4949- status.replace_existing_source, *p,
4950- get_best_session_directory_for_new_source (),
4951- channels);
4952+ vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels);
4953 Sources newfiles;
4954 framepos_t natural_position = source ? source->natural_position() : 0;
4955
4956
4957=== modified file 'libs/ardour/internal_send.cc'
4958--- libs/ardour/internal_send.cc 2014-01-24 16:31:54 +0000
4959+++ libs/ardour/internal_send.cc 2015-05-02 14:23:30 +0000
4960@@ -129,7 +129,7 @@
4961 // we have to copy the input, because we may alter the buffers with the amp
4962 // in-place, which a send must never do.
4963
4964- if (_panshell && !_panshell->bypassed()) {
4965+ if (_panshell && !_panshell->bypassed() && role() != Listen) {
4966 _panshell->run (bufs, mixbufs, start_frame, end_frame, nframes);
4967 } else {
4968 if (role() == Listen) {
4969
4970=== modified file 'libs/ardour/lv2_evbuf.c'
4971--- libs/ardour/lv2_evbuf.c 2013-09-21 19:05:02 +0000
4972+++ libs/ardour/lv2_evbuf.c 2015-05-02 14:23:30 +0000
4973@@ -203,7 +203,7 @@
4974 switch (iter.evbuf->type) {
4975 case LV2_EVBUF_EVENT:
4976 ebuf = &iter.evbuf->buf.event;
4977- ev = (LV2_Event*)ebuf->data + iter.offset;
4978+ ev = (LV2_Event*)((char*)ebuf->data + iter.offset);
4979 *frames = ev->frames;
4980 *subframes = ev->subframes;
4981 *type = ev->type;
4982
4983=== modified file 'libs/ardour/lv2_plugin.cc'
4984--- libs/ardour/lv2_plugin.cc 2014-01-24 16:31:54 +0000
4985+++ libs/ardour/lv2_plugin.cc 2015-05-02 14:23:30 +0000
4986@@ -31,6 +31,7 @@
4987
4988 #include <boost/utility.hpp>
4989
4990+#include "pbd/clear_dir.h"
4991 #include "pbd/pathscanner.h"
4992 #include "pbd/compose.h"
4993 #include "pbd/error.h"
4994@@ -880,27 +881,6 @@
4995 return g_strndup(abs_path.c_str(), abs_path.length());
4996 }
4997
4998-static void
4999-remove_directory(const std::string& path)
5000-{
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: