Re-work layering in possibly debatable ways. Sketchy docs in doc/layering.
git-svn-id: svn://localhost/ardour2/branches/3.0@11088 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
0082e3364f
commit
6304261b98
|
@ -0,0 +1,3 @@
|
|||
*.aux
|
||||
*.pdf
|
||||
*.log
|
|
@ -0,0 +1,322 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="744.09448819"
|
||||
height="1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="basic-layering.pdf">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3618"
|
||||
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
<inkscape:perspective
|
||||
id="perspective4058"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4089"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4120"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4151"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4365"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4386"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-6"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3618-4"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
id="perspective4449"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-5"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3618-1"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
id="perspective4668"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4696"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4696-1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.633643"
|
||||
inkscape:cx="191.36241"
|
||||
inkscape:cy="685.97592"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="949"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2816"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
units="mm"
|
||||
spacingx="5mm"
|
||||
spacingy="5mm" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend);color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 88.582677,432.28344 159.448823,0"
|
||||
id="path3592" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="255.20872"
|
||||
y="435.23877"
|
||||
id="text4042"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4044"
|
||||
x="255.20872"
|
||||
y="435.23877">time</tspan></text>
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818"
|
||||
width="70.866142"
|
||||
height="35.433071"
|
||||
x="88.58268"
|
||||
y="308.2677" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2"
|
||||
width="70.86615"
|
||||
height="35.433071"
|
||||
x="124.01574"
|
||||
y="343.70078" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2-2"
|
||||
width="70.86615"
|
||||
height="35.433071"
|
||||
x="177.16534"
|
||||
y="379.13385" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2-2-4"
|
||||
width="35.433086"
|
||||
height="35.433071"
|
||||
x="265.74802"
|
||||
y="379.13385" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="119.61775"
|
||||
y="330.26825"
|
||||
id="text4320"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4322"
|
||||
x="119.61775"
|
||||
y="330.26825">A</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="155.36281"
|
||||
y="365.51532"
|
||||
id="text4324"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4326"
|
||||
x="155.36281"
|
||||
y="365.51532">B</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="208.36243"
|
||||
y="400.94839"
|
||||
id="text4328"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4330"
|
||||
x="208.36243"
|
||||
y="400.94839">C</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="279.05457"
|
||||
y="400.94839"
|
||||
id="text4332"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4334"
|
||||
x="279.05457"
|
||||
y="400.94839">D</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Lend);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 318.89764,432.28344 0,-124.01575"
|
||||
id="path3592-8"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="307.30875"
|
||||
y="301.75519"
|
||||
id="text4406"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4408"
|
||||
x="307.30875"
|
||||
y="301.75519">layer</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 311.84462,397.273 13.54507,0"
|
||||
id="path4439" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.09393"
|
||||
y="401.58279"
|
||||
id="text4656"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4658"
|
||||
x="328.09393"
|
||||
y="401.58279">0</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 312.32197,361.87109 13.54507,0"
|
||||
id="path4439-1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.02194"
|
||||
y="366.18088"
|
||||
id="text4656-0-0"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4658-6-3"
|
||||
x="328.02194"
|
||||
y="366.18088">1</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 311.84462,325.98423 13.54507,0"
|
||||
id="path4439-1-6" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.09393"
|
||||
y="329.49646"
|
||||
id="text4742"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4744"
|
||||
x="328.09393"
|
||||
y="329.49646">2</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
for f in basic-layering explicit-layering1 explicit-layering2 tricky-explicit-layering; do
|
||||
inkscape -z --export-area-drawing -f $f.svg --export-pdf $f.pdf
|
||||
done
|
||||
|
||||
pdflatex layering.tex
|
||||
pdflatex layering.tex
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="744.09448819"
|
||||
height="1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="explicit-layering.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3618"
|
||||
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
<inkscape:perspective
|
||||
id="perspective4058"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4089"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4120"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4151"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4365"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4386"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-6"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3618-4"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
id="perspective4449"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-5"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3618-1"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
id="perspective4668"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4696"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4696-1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.633643"
|
||||
inkscape:cx="191.36241"
|
||||
inkscape:cy="670.78783"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="949"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2816"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
units="mm"
|
||||
spacingx="5mm"
|
||||
spacingy="5mm" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend);color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 88.582677,432.28344 159.448823,0"
|
||||
id="path3592" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="255.20872"
|
||||
y="435.23877"
|
||||
id="text4042"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4044"
|
||||
x="255.20872"
|
||||
y="435.23877">time</tspan></text>
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818"
|
||||
width="106.29921"
|
||||
height="35.433071"
|
||||
x="88.582687"
|
||||
y="308.2677" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2"
|
||||
width="88.582687"
|
||||
height="35.433071"
|
||||
x="124.01574"
|
||||
y="343.70078" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2-2"
|
||||
width="70.86615"
|
||||
height="35.433071"
|
||||
x="177.16534"
|
||||
y="379.13385" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2-2-4"
|
||||
width="35.433086"
|
||||
height="35.433071"
|
||||
x="265.74802"
|
||||
y="379.13385" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="137.33429"
|
||||
y="330.26825"
|
||||
id="text4320"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4322"
|
||||
x="137.33429"
|
||||
y="330.26825">A</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="164.22108"
|
||||
y="365.51532"
|
||||
id="text4324"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4326"
|
||||
x="164.22108"
|
||||
y="365.51532">B</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="208.36243"
|
||||
y="400.94839"
|
||||
id="text4328"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4330"
|
||||
x="208.36243"
|
||||
y="400.94839">C</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="279.05457"
|
||||
y="400.94839"
|
||||
id="text4332"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4334"
|
||||
x="279.05457"
|
||||
y="400.94839">D</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Lend);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 318.89764,432.28344 0,-124.01575"
|
||||
id="path3592-8"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="307.30875"
|
||||
y="301.75519"
|
||||
id="text4406"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4408"
|
||||
x="307.30875"
|
||||
y="301.75519">layer</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 311.84462,397.273 13.54507,0"
|
||||
id="path4439" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.09393"
|
||||
y="401.58279"
|
||||
id="text4656"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4658"
|
||||
x="328.09393"
|
||||
y="401.58279">0</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 312.32197,361.87109 13.54507,0"
|
||||
id="path4439-1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.02194"
|
||||
y="366.18088"
|
||||
id="text4656-0-0"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4658-6-3"
|
||||
x="328.02194"
|
||||
y="366.18088">1</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 311.84462,325.98423 13.54507,0"
|
||||
id="path4439-1-6" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.09393"
|
||||
y="329.49646"
|
||||
id="text4742"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4744"
|
||||
x="328.09393"
|
||||
y="329.49646">2</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,322 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="744.09448819"
|
||||
height="1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="explicit-layering2.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3618"
|
||||
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
<inkscape:perspective
|
||||
id="perspective4058"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4089"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4120"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4151"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4365"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4386"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-6"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3618-4"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
id="perspective4449"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-5"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3618-1"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
id="perspective4668"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4696"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4696-1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.633643"
|
||||
inkscape:cx="191.36241"
|
||||
inkscape:cy="670.02843"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="949"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2816"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
units="mm"
|
||||
spacingx="5mm"
|
||||
spacingy="5mm" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend);color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 88.582677,432.28344 159.448823,0"
|
||||
id="path3592" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="255.20872"
|
||||
y="435.23877"
|
||||
id="text4042"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4044"
|
||||
x="255.20872"
|
||||
y="435.23877">time</tspan></text>
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818"
|
||||
width="106.29921"
|
||||
height="35.433071"
|
||||
x="88.58268"
|
||||
y="343.70078" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2"
|
||||
width="88.582687"
|
||||
height="35.433071"
|
||||
x="124.01575"
|
||||
y="379.13385" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2-2"
|
||||
width="70.86615"
|
||||
height="35.433071"
|
||||
x="177.16534"
|
||||
y="308.2677" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2-2-4"
|
||||
width="35.433086"
|
||||
height="35.433071"
|
||||
x="265.74802"
|
||||
y="379.13385" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="137.33429"
|
||||
y="365.70132"
|
||||
id="text4320"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4322"
|
||||
x="137.33429"
|
||||
y="365.70132">A</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="164.22108"
|
||||
y="400.94839"
|
||||
id="text4324"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4326"
|
||||
x="164.22108"
|
||||
y="400.94839">B</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="208.36243"
|
||||
y="330.08224"
|
||||
id="text4328"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4330"
|
||||
x="208.36243"
|
||||
y="330.08224">C</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="279.05457"
|
||||
y="400.94839"
|
||||
id="text4332"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4334"
|
||||
x="279.05457"
|
||||
y="400.94839">D</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Lend);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 318.89764,432.28344 0,-124.01575"
|
||||
id="path3592-8"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="307.30875"
|
||||
y="301.75519"
|
||||
id="text4406"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4408"
|
||||
x="307.30875"
|
||||
y="301.75519">layer</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 311.84462,397.273 13.54507,0"
|
||||
id="path4439" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.09393"
|
||||
y="401.58279"
|
||||
id="text4656"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4658"
|
||||
x="328.09393"
|
||||
y="401.58279">0</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 312.32197,361.87109 13.54507,0"
|
||||
id="path4439-1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.02194"
|
||||
y="366.18088"
|
||||
id="text4656-0-0"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4658-6-3"
|
||||
x="328.02194"
|
||||
y="366.18088">1</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 311.84462,325.98423 13.54507,0"
|
||||
id="path4439-1-6" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.09393"
|
||||
y="329.49646"
|
||||
id="text4742"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4744"
|
||||
x="328.09393"
|
||||
y="329.49646">2</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,150 @@
|
|||
\documentclass{article}
|
||||
\title{Region Layering}
|
||||
\author{}
|
||||
\date{}
|
||||
|
||||
\usepackage{graphicx}
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
\section{Introduction}
|
||||
|
||||
When regions overlap in time, we need to decide which one should be
|
||||
played. Ardour has a few options to set how this decision is made.
|
||||
|
||||
|
||||
\subsection{Layers}
|
||||
|
||||
Each region on a playlist is on a \emph{layer}. All overlapping regions
|
||||
are on a unique layer, and when overlaps exist the highest-layered
|
||||
region is played. This is illustrated in Figure~\ref{fig:basic-layering}.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\begin{center}
|
||||
\includegraphics{basic-layering.pdf}
|
||||
\end{center}
|
||||
\caption{Basic region layering}
|
||||
\label{fig:basic-layering}
|
||||
\end{figure}
|
||||
|
||||
Here we see that region $A$ overlaps $B$, $B$ overlaps $C$, and
|
||||
$D$ overlaps nothing. There are several ways in which these regions
|
||||
could be arranged; in the drawing, $A$ is on layer~2, $B$ on layer~1,
|
||||
$C$ and $D$ on layer~0. If this area is played back, region $A$ will
|
||||
play in its entirety, followed by the end part of region $B$, followed
|
||||
by the end part of region $C$, followed by the whole of region $D$.
|
||||
This follows the basic rule that, at any given point, the region on
|
||||
the highest layer will be played.
|
||||
|
||||
|
||||
\section{Choice of layering}
|
||||
|
||||
There are two main decisions to be made with regards to how a playlist should be layered:
|
||||
|
||||
\begin{itemize}
|
||||
\item Given overlapping regions, what order should they be layered in?
|
||||
\item When should layering be changed?
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Layering order}
|
||||
|
||||
Ardour provides three-and-a-half ways to decide on the order in which
|
||||
regions are layered. The most basic choice is:
|
||||
|
||||
\begin{itemize}
|
||||
\item \emph{Later is higher} --- regions which are later in time will
|
||||
be on higher layers.
|
||||
\item \emph{Most recently added is higher} --- regions which were more
|
||||
recently added to the playlist will be on higher layers.
|
||||
\item \emph{Most recently edited or added is higher} --- regions which
|
||||
were more recently edited or added to the playlist will be on
|
||||
higher layers.
|
||||
\end{itemize}
|
||||
|
||||
This choice can be set per-session from the \emph{Session Properties} dialogue
|
||||
box.
|
||||
|
||||
\subsubsection{Explicit ordering}
|
||||
|
||||
There are also cases when none of these rules should apply. If, for
|
||||
example, you want to put a given region at the top of the stack (on
|
||||
the highest layer), this is possible using the region `raise to top'
|
||||
command. Following such a command (called an `explicit layering'),
|
||||
the regions on the playlist may no longer obey any of the standard
|
||||
ordering rules.
|
||||
|
||||
This situation also arises when editing tracks using the `stacked' layer mode.
|
||||
In this mode, almost all layering is explicit. When starting a region drag,
|
||||
the other regions on a track spread apart vertically to allow the dragged
|
||||
region to be dropped in any position within the region stack. The normal
|
||||
layering rules will only be followed if a region is dropped on top of another;
|
||||
in all other cases, explicit layering will be used to put the region wherever
|
||||
it was dropped.
|
||||
|
||||
\subsection{When to update layering}
|
||||
|
||||
There are two distinct approaches to updating layering:
|
||||
|
||||
\begin{itemize}
|
||||
\item Update whenever any region edit is performed.
|
||||
\item Update only when a region is edited such that a new overlap has been set up.
|
||||
\end{itemize}
|
||||
|
||||
The approach to use is optional, and can be set in \emph{Session Properties}.
|
||||
|
||||
This decision only has consequences when an explicit layering command has
|
||||
been used. Consider the case in Figure~\ref{fig:explicit-layering1}.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\begin{center}
|
||||
\includegraphics{explicit-layering1.pdf}
|
||||
\end{center}
|
||||
\caption{Explicit layering: stage 1}
|
||||
\label{fig:explicit-layering1}
|
||||
\end{figure}
|
||||
|
||||
Given that arrangement, imagine that we perform a `raise to top' on region $C$.
|
||||
This results in the arrangement in Figure~\ref{fig:explicit-layering2}.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\begin{center}
|
||||
\includegraphics{explicit-layering2.pdf}
|
||||
\end{center}
|
||||
\caption{Explicit layering: stage 2}
|
||||
\label{fig:explicit-layering2}
|
||||
\end{figure}
|
||||
|
||||
Imagine now that region $C$ is moved very slightly to the left, so
|
||||
that it still overlaps both $A$ and $B$. If we are updating whenever
|
||||
any region edit is performed, this will result in a relayer; the
|
||||
regions' arrangement will go back to that in
|
||||
Figure~\ref{fig:explicit-layering1}.
|
||||
|
||||
If, on the other hand, we only relayer when a new overlap is set up,
|
||||
the region layering will remain as in
|
||||
Figure~\ref{fig:explicit-layering2}. Before the edit, regions $A$,
|
||||
$B$ and $C$ overlapped; after the edit, the situation is the same, so
|
||||
no relayering is performed.
|
||||
|
||||
Another, more complex, example is shown in Figure~\ref{fig:tricky-explicit-layering}.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\begin{center}
|
||||
\includegraphics{tricky-explicit-layering.pdf}
|
||||
\end{center}
|
||||
\caption{More complex explicit layering}
|
||||
\label{fig:tricky-explicit-layering}
|
||||
\end{figure}
|
||||
|
||||
% XXX: this makes no sense
|
||||
|
||||
Here, imagine that $C$ has been moved to the top of the stack with an explicit
|
||||
`raise to top' command. Now consider an extension of $C$ so that its
|
||||
right-hand edge overlaps $D$. If we are relayering only on new overlaps, this
|
||||
case presents one new overlap (that of $C$ with $D$). In this case, $C$ is
|
||||
moved according to the current layering rules so that it is correct with
|
||||
respect to $D$. In addition, $A$ and $B$ are re-layered so that the relation
|
||||
of $C$ to $A$ and $B$ is preserved.
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,323 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="744.09448819"
|
||||
height="1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="tricky-explicit-layering1.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3618"
|
||||
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
<inkscape:perspective
|
||||
id="perspective4058"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4089"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4120"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4151"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4365"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4386"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-6"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3618-4"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
id="perspective4449"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-5"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3618-1"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
id="perspective4668"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4696"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4696-1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.633643"
|
||||
inkscape:cx="191.36241"
|
||||
inkscape:cy="670.78783"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="949"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1"
|
||||
gridtolerance="10">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2816"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
units="mm"
|
||||
spacingx="5mm"
|
||||
spacingy="5mm" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend);color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 88.582677,432.28344 159.448823,0"
|
||||
id="path3592" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="255.20872"
|
||||
y="435.23877"
|
||||
id="text4042"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4044"
|
||||
x="255.20872"
|
||||
y="435.23877">time</tspan></text>
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818"
|
||||
width="106.29921"
|
||||
height="35.433071"
|
||||
x="88.582695"
|
||||
y="343.70078" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2"
|
||||
width="88.582687"
|
||||
height="35.433071"
|
||||
x="124.01575"
|
||||
y="379.13385" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2-2-4"
|
||||
width="70.866142"
|
||||
height="35.433071"
|
||||
x="230.31496"
|
||||
y="379.13385" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="137.33429"
|
||||
y="365.70132"
|
||||
id="text4320"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4322"
|
||||
x="137.33429"
|
||||
y="365.70132">A</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="164.22108"
|
||||
y="400.94839"
|
||||
id="text4324"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4326"
|
||||
x="164.22108"
|
||||
y="400.94839">B</tspan></text>
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2818-2-2"
|
||||
width="44.545933"
|
||||
height="35.433071"
|
||||
x="177.16534"
|
||||
y="308.2677" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="195.20232"
|
||||
y="330.08224"
|
||||
id="text4328"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4330"
|
||||
x="195.20232"
|
||||
y="330.08224">C</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="261.33801"
|
||||
y="400.94839"
|
||||
id="text4332"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4334"
|
||||
x="261.33801"
|
||||
y="400.94839">D</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Lend);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 318.89764,432.28344 0,-124.01575"
|
||||
id="path3592-8"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="307.30875"
|
||||
y="301.75519"
|
||||
id="text4406"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4408"
|
||||
x="307.30875"
|
||||
y="301.75519">layer</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.62500000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 311.84462,397.273 13.54507,0"
|
||||
id="path4439" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.09393"
|
||||
y="401.58279"
|
||||
id="text4656"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4658"
|
||||
x="328.09393"
|
||||
y="401.58279">0</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 312.32197,361.87109 13.54507,0"
|
||||
id="path4439-1" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.02194"
|
||||
y="366.18088"
|
||||
id="text4656-0-0"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4658-6-3"
|
||||
x="328.02194"
|
||||
y="366.18088">1</tspan></text>
|
||||
<path
|
||||
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.625;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 311.84462,325.98423 13.54507,0"
|
||||
id="path4439-1-6" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:LMRoman12;-inkscape-font-specification:LMRoman12"
|
||||
x="328.09393"
|
||||
y="329.49646"
|
||||
id="text4742"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4744"
|
||||
x="328.09393"
|
||||
y="329.49646">2</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -809,13 +809,14 @@ AudioStreamView::update_contents_height ()
|
|||
void
|
||||
AudioStreamView::update_content_height (CrossfadeView* cv)
|
||||
{
|
||||
if (_layer_display == Overlaid) {
|
||||
|
||||
switch (_layer_display) {
|
||||
case Overlaid:
|
||||
cv->set_y (0);
|
||||
cv->set_height (height);
|
||||
break;
|
||||
|
||||
} else {
|
||||
|
||||
case Stacked:
|
||||
case Expanded:
|
||||
layer_t const inl = cv->crossfade->in()->layer ();
|
||||
layer_t const outl = cv->crossfade->out()->layer ();
|
||||
|
||||
|
@ -824,9 +825,13 @@ AudioStreamView::update_content_height (CrossfadeView* cv)
|
|||
|
||||
const double h = child_height ();
|
||||
|
||||
cv->set_y ((_layers - high - 1) * h);
|
||||
cv->set_height ((high - low + 1) * h);
|
||||
|
||||
if (_layer_display == Stacked) {
|
||||
cv->set_y ((_layers - high - 1) * h);
|
||||
cv->set_height ((high - low + 1) * h);
|
||||
} else {
|
||||
cv->set_y (((_layers - high) * 2 - 1) * h);
|
||||
cv->set_height (((high - low) * 2 + 1) * h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,15 +87,23 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session* sess, Canvas& c
|
|||
void
|
||||
AudioTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
||||
{
|
||||
_route = rt;
|
||||
|
||||
/* RouteTimeAxisView::set_route() sets up some things in the View,
|
||||
so it must be created before RouteTimeAxis::set_route() is
|
||||
called.
|
||||
*/
|
||||
_view = new AudioStreamView (*this);
|
||||
|
||||
RouteTimeAxisView::set_route (rt);
|
||||
|
||||
_view->apply_color (color (), StreamView::RegionColor);
|
||||
|
||||
// Make sure things are sane...
|
||||
assert(!is_track() || is_audio_track());
|
||||
|
||||
subplugin_menu.set_name ("ArdourContextMenu");
|
||||
|
||||
_view = new AudioStreamView (*this);
|
||||
|
||||
ignore_toggle = false;
|
||||
|
||||
if (is_audio_track()) {
|
||||
|
|
|
@ -2477,12 +2477,12 @@ Editor::get_state ()
|
|||
* TimeAxisView may be 0. Layer index is the layer number if the TimeAxisView is valid and is
|
||||
* in stacked region display mode, otherwise 0.
|
||||
*/
|
||||
std::pair<TimeAxisView *, layer_t>
|
||||
std::pair<TimeAxisView *, double>
|
||||
Editor::trackview_by_y_position (double y)
|
||||
{
|
||||
for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
|
||||
|
||||
std::pair<TimeAxisView*, int> const r = (*iter)->covers_y_position (y);
|
||||
std::pair<TimeAxisView*, double> const r = (*iter)->covers_y_position (y);
|
||||
if (r.first) {
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -1032,7 +1032,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
|
||||
/* track views */
|
||||
TrackViewList track_views;
|
||||
std::pair<TimeAxisView*, ARDOUR::layer_t> trackview_by_y_position (double);
|
||||
std::pair<TimeAxisView*, double> trackview_by_y_position (double);
|
||||
TimeAxisView* axis_view_from_route (boost::shared_ptr<ARDOUR::Route>) const;
|
||||
|
||||
TrackViewList get_tracks_for_range_action () const;
|
||||
|
|
|
@ -485,9 +485,13 @@ RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
|||
|
||||
show_verbose_cursor_time (_last_frame_position);
|
||||
|
||||
pair<TimeAxisView*, int> const tv = _editor->trackview_by_y_position (_drags->current_pointer_y ());
|
||||
pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (_drags->current_pointer_y ());
|
||||
_last_pointer_time_axis_view = find_time_axis_view (tv.first);
|
||||
_last_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second;
|
||||
|
||||
if (tv.first->view()->layer_display() == Stacked) {
|
||||
tv.first->view()->set_layer_display (Expanded);
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -554,7 +558,7 @@ RegionMotionDrag::compute_x_delta (GdkEvent const * event, framepos_t* pending_r
|
|||
}
|
||||
|
||||
bool
|
||||
RegionMotionDrag::y_movement_allowed (int delta_track, layer_t delta_layer) const
|
||||
RegionMotionDrag::y_movement_allowed (int delta_track, double delta_layer) const
|
||||
{
|
||||
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
|
||||
int const n = i->time_axis_view + delta_track;
|
||||
|
@ -569,8 +573,13 @@ RegionMotionDrag::y_movement_allowed (int delta_track, layer_t delta_layer) cons
|
|||
return false;
|
||||
}
|
||||
|
||||
int const l = i->layer + delta_layer;
|
||||
if (delta_track == 0 && (l < 0 || l >= int (to->view()->layers()))) {
|
||||
double const l = i->layer + delta_layer;
|
||||
|
||||
/* Note that we allow layer to be up to 0.5 below zero, as this is used by `Expanded'
|
||||
mode to allow the user to place a region below another on layer 0.
|
||||
*/
|
||||
|
||||
if (delta_track == 0 && (l < -0.5 || l >= int (to->view()->layers()))) {
|
||||
/* Off the top or bottom layer; note that we only refuse if the track hasn't changed.
|
||||
If it has, the layers will be munged later anyway, so it's ok.
|
||||
*/
|
||||
|
@ -588,7 +597,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
|||
assert (!_views.empty ());
|
||||
|
||||
/* Find the TimeAxisView that the pointer is now over */
|
||||
pair<TimeAxisView*, int> const tv = _editor->trackview_by_y_position (_drags->current_pointer_y ());
|
||||
pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (_drags->current_pointer_y ());
|
||||
|
||||
/* Bail early if we're not over a track */
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv.first);
|
||||
|
@ -601,7 +610,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
|||
|
||||
/* Here's the current pointer position in terms of time axis view and layer */
|
||||
int const current_pointer_time_axis_view = find_time_axis_view (tv.first);
|
||||
layer_t const current_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second;
|
||||
double const current_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second;
|
||||
|
||||
/* Work out the change in x */
|
||||
framepos_t pending_region_position;
|
||||
|
@ -609,7 +618,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
|||
|
||||
/* Work out the change in y */
|
||||
int delta_time_axis_view = current_pointer_time_axis_view - _last_pointer_time_axis_view;
|
||||
int delta_layer = current_pointer_layer - _last_pointer_layer;
|
||||
double delta_layer = current_pointer_layer - _last_pointer_layer;
|
||||
|
||||
if (!y_movement_allowed (delta_time_axis_view, delta_layer)) {
|
||||
/* this y movement is not allowed, so do no y movement this time */
|
||||
|
@ -659,14 +668,24 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
|||
confusion when dragging regions from non-zero layers onto different
|
||||
tracks.
|
||||
*/
|
||||
int this_delta_layer = delta_layer;
|
||||
double this_delta_layer = delta_layer;
|
||||
if (delta_time_axis_view != 0) {
|
||||
this_delta_layer = - i->layer;
|
||||
}
|
||||
|
||||
/* The TimeAxisView that this region is now on */
|
||||
TimeAxisView* tv = _time_axis_views[i->time_axis_view + delta_time_axis_view];
|
||||
|
||||
/* Ensure it is moved from stacked -> expanded if appropriate */
|
||||
if (tv->view()->layer_display() == Stacked) {
|
||||
tv->view()->set_layer_display (Expanded);
|
||||
}
|
||||
|
||||
/* We're only allowed to go -ve in layer on Expanded views */
|
||||
if (tv->view()->layer_display() != Expanded && (i->layer + this_delta_layer) < 0) {
|
||||
this_delta_layer = - i->layer;
|
||||
}
|
||||
|
||||
/* Set height */
|
||||
rv->set_height (tv->view()->child_height ());
|
||||
|
||||
|
@ -695,10 +714,17 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
|||
|
||||
/* And adjust for the layer that it should be on */
|
||||
StreamView* cv = tv->view ();
|
||||
if (cv->layer_display() == Stacked) {
|
||||
switch (cv->layer_display ()) {
|
||||
case Overlaid:
|
||||
break;
|
||||
case Stacked:
|
||||
y += (cv->layers() - i->layer - 1) * cv->child_height ();
|
||||
break;
|
||||
case Expanded:
|
||||
y += (cv->layers() - i->layer - 0.5) * 2 * cv->child_height ();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Now move the region view */
|
||||
rv->move (x_delta, y - rv->get_canvas_group()->property_y());
|
||||
}
|
||||
|
@ -789,8 +815,19 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
|
|||
}
|
||||
|
||||
void
|
||||
RegionMoveDrag::finished (GdkEvent *, bool movement_occurred)
|
||||
RegionMotionDrag::finished (GdkEvent *, bool)
|
||||
{
|
||||
for (vector<TimeAxisView*>::iterator i = _time_axis_views.begin(); i != _time_axis_views.end(); ++i) {
|
||||
if ((*i)->view()->layer_display() == Expanded) {
|
||||
(*i)->view()->set_layer_display (Stacked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegionMoveDrag::finished (GdkEvent* ev, bool movement_occurred)
|
||||
{
|
||||
RegionMotionDrag::finished (ev, movement_occurred);
|
||||
if (!movement_occurred) {
|
||||
/* just a click */
|
||||
return;
|
||||
|
@ -924,6 +961,9 @@ RegionMoveDrag::finished_no_copy (
|
|||
RegionSelection new_views;
|
||||
PlaylistSet modified_playlists;
|
||||
PlaylistSet frozen_playlists;
|
||||
PlaylistSet relayer_suspended_playlists;
|
||||
|
||||
list<pair<boost::shared_ptr<Region>, double> > pending_relayers;
|
||||
|
||||
if (_brushing) {
|
||||
/* all changes were made during motion event handlers */
|
||||
|
@ -942,7 +982,7 @@ RegionMoveDrag::finished_no_copy (
|
|||
RegionView* rv = i->view;
|
||||
|
||||
RouteTimeAxisView* const dest_rtv = dynamic_cast<RouteTimeAxisView*> (_time_axis_views[i->time_axis_view]);
|
||||
layer_t const dest_layer = i->layer;
|
||||
double const dest_layer = i->layer;
|
||||
|
||||
if (rv->region()->locked()) {
|
||||
++i;
|
||||
|
@ -1002,9 +1042,10 @@ RegionMoveDrag::finished_no_copy (
|
|||
|
||||
boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
|
||||
|
||||
if (dest_rtv->view()->layer_display() == Stacked) {
|
||||
rv->region()->set_layer (dest_layer);
|
||||
rv->region()->set_pending_explicit_relayer (true);
|
||||
bool const explicit_relayer = dest_rtv->view()->layer_display() == Stacked || dest_rtv->view()->layer_display() == Expanded;
|
||||
|
||||
if (explicit_relayer) {
|
||||
pending_relayers.push_back (make_pair (rv->region (), dest_layer));
|
||||
}
|
||||
|
||||
/* freeze playlist to avoid lots of relayering in the case of a multi-region drag */
|
||||
|
@ -1024,6 +1065,9 @@ RegionMoveDrag::finished_no_copy (
|
|||
playlist->clear_changes ();
|
||||
}
|
||||
|
||||
relayer_suspended_playlists.insert (playlist);
|
||||
playlist->suspend_relayer ();
|
||||
|
||||
rv->region()->set_position (where);
|
||||
|
||||
_editor->session()->add_command (new StatefulDiffCommand (rv->region()));
|
||||
|
@ -1068,10 +1112,18 @@ RegionMoveDrag::finished_no_copy (
|
|||
_editor->selection->set (new_views);
|
||||
}
|
||||
|
||||
for (set<boost::shared_ptr<Playlist> >::iterator p = frozen_playlists.begin(); p != frozen_playlists.end(); ++p) {
|
||||
for (PlaylistSet::iterator p = frozen_playlists.begin(); p != frozen_playlists.end(); ++p) {
|
||||
(*p)->thaw();
|
||||
}
|
||||
|
||||
for (PlaylistSet::iterator p = relayer_suspended_playlists.begin(); p != relayer_suspended_playlists.end(); ++p) {
|
||||
(*p)->resume_relayer ();
|
||||
}
|
||||
|
||||
for (list<pair<boost::shared_ptr<Region>, double> >::iterator i = pending_relayers.begin(); i != pending_relayers.end(); ++i) {
|
||||
i->first->playlist()->relayer (i->first, i->second);
|
||||
}
|
||||
|
||||
/* write commands for the accumulated diffs for all our modified playlists */
|
||||
add_stateful_diff_commands_for_playlists (modified_playlists);
|
||||
|
||||
|
@ -1137,9 +1189,8 @@ RegionMoveDrag::insert_region_into_playlist (
|
|||
|
||||
dest_playlist->add_region (region, where);
|
||||
|
||||
if (dest_rtv->view()->layer_display() == Stacked) {
|
||||
region->set_layer (dest_layer);
|
||||
region->set_pending_explicit_relayer (true);
|
||||
if (dest_rtv->view()->layer_display() == Stacked || dest_rtv->view()->layer_display() == Expanded) {
|
||||
dest_playlist->relayer (region, dest_layer);
|
||||
}
|
||||
|
||||
c.disconnect ();
|
||||
|
@ -1188,6 +1239,12 @@ RegionMoveDrag::aborted (bool movement_occurred)
|
|||
void
|
||||
RegionMotionDrag::aborted (bool)
|
||||
{
|
||||
for (vector<TimeAxisView*>::iterator i = _time_axis_views.begin(); i != _time_axis_views.end(); ++i) {
|
||||
if ((*i)->view()->layer_display() == Expanded) {
|
||||
(*i)->view()->set_layer_display (Stacked);
|
||||
}
|
||||
}
|
||||
|
||||
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
|
||||
RegionView* rv = i->view;
|
||||
TimeAxisView* tv = &(rv->get_time_axis_view ());
|
||||
|
@ -1295,7 +1352,7 @@ RegionSpliceDrag::motion (GdkEvent* event, bool)
|
|||
{
|
||||
/* Which trackview is this ? */
|
||||
|
||||
pair<TimeAxisView*, int> const tvp = _editor->trackview_by_y_position (_drags->current_pointer_y ());
|
||||
pair<TimeAxisView*, double> const tvp = _editor->trackview_by_y_position (_drags->current_pointer_y ());
|
||||
RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
|
||||
|
||||
/* The region motion is only processed if the pointer is over
|
||||
|
|
|
@ -249,8 +249,11 @@ struct DraggingView
|
|||
* or -1 if it is not visible.
|
||||
*/
|
||||
int time_axis_view;
|
||||
/** layer that this region is currently being displayed on */
|
||||
ARDOUR::layer_t layer;
|
||||
/** Layer that this region is currently being displayed on. This is a double
|
||||
rather than a layer_t as we use fractional layers during drags to allow the user
|
||||
to indicate a new layer to put a region on.
|
||||
*/
|
||||
double layer;
|
||||
double initial_y; ///< the initial y position of the view before any reparenting
|
||||
framepos_t initial_position; ///< initial position of the region
|
||||
framepos_t initial_end; ///< initial end position of the region
|
||||
|
@ -295,7 +298,7 @@ public:
|
|||
|
||||
virtual void start_grab (GdkEvent *, Gdk::Cursor *);
|
||||
virtual void motion (GdkEvent *, bool);
|
||||
virtual void finished (GdkEvent *, bool) = 0;
|
||||
virtual void finished (GdkEvent *, bool);
|
||||
virtual void aborted (bool);
|
||||
|
||||
/** @return true if the regions being `moved' came from somewhere on the canvas;
|
||||
|
@ -306,13 +309,13 @@ public:
|
|||
protected:
|
||||
|
||||
double compute_x_delta (GdkEvent const *, ARDOUR::framecnt_t *);
|
||||
bool y_movement_allowed (int, ARDOUR::layer_t) const;
|
||||
bool y_movement_allowed (int, double) const;
|
||||
|
||||
bool _brushing;
|
||||
ARDOUR::framepos_t _last_frame_position; ///< last position of the thing being dragged
|
||||
double _total_x_delta;
|
||||
int _last_pointer_time_axis_view;
|
||||
ARDOUR::layer_t _last_pointer_layer;
|
||||
double _last_pointer_layer;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@ namespace Gnome {
|
|||
|
||||
enum LayerDisplay {
|
||||
Overlaid,
|
||||
Stacked
|
||||
Stacked,
|
||||
Expanded
|
||||
};
|
||||
|
||||
struct SelectionRect {
|
||||
|
|
|
@ -139,6 +139,8 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
|||
*/
|
||||
RouteTimeAxisView::set_route (rt);
|
||||
|
||||
_view->apply_color (_color, StreamView::RegionColor);
|
||||
|
||||
subplugin_menu.set_name ("ArdourContextMenu");
|
||||
|
||||
if (!gui_property ("note-range-min").empty ()) {
|
||||
|
|
|
@ -468,6 +468,7 @@ RouteTimeAxisView::build_display_menu ()
|
|||
++overlaid;
|
||||
break;
|
||||
case Stacked:
|
||||
case Expanded:
|
||||
++stacked;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -272,9 +272,17 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
|
|||
);
|
||||
|
||||
lm->add (LaterHigher, _("later is higher"));
|
||||
lm->add (MoveAddHigher, _("most recently moved or added is higher"));
|
||||
lm->add (AddOrBoundsChangeHigher, _("most recently edited or added is higher"));
|
||||
lm->add (AddHigher, _("most recently added is higher"));
|
||||
|
||||
add_option (_("Misc"), new BoolOption (
|
||||
"relayer-on-all-edits",
|
||||
_("Relayer regions after every edit"),
|
||||
sigc::mem_fun (*_session_config, &SessionConfiguration::get_relayer_on_all_edits),
|
||||
sigc::mem_fun (*_session_config, &SessionConfiguration::set_relayer_on_all_edits)
|
||||
));
|
||||
|
||||
|
||||
add_option (_("Misc"), lm);
|
||||
|
||||
add_option (_("Misc"), new OptionEditorHeading (_("MIDI Options")));
|
||||
|
|
|
@ -57,7 +57,6 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* background_g
|
|||
, _samples_per_unit (_trackview.editor().get_current_zoom ())
|
||||
, rec_updating(false)
|
||||
, rec_active(false)
|
||||
, region_color(_trackview.color())
|
||||
, stream_base_color(0xFFFFFFFF)
|
||||
, _layers (1)
|
||||
, _layer_display (Overlaid)
|
||||
|
@ -302,7 +301,7 @@ StreamView::playlist_layered (boost::weak_ptr<Track> wtr)
|
|||
_layers = tr->playlist()->top_layer() + 1;
|
||||
}
|
||||
|
||||
if (_layer_display == Stacked) {
|
||||
if (_layer_display == Stacked || _layer_display == Expanded) {
|
||||
update_contents_height ();
|
||||
update_coverage_frames ();
|
||||
} else {
|
||||
|
@ -330,8 +329,6 @@ StreamView::playlist_switched (boost::weak_ptr<Track> wtr)
|
|||
update_contents_height ();
|
||||
update_coverage_frames ();
|
||||
|
||||
tr->playlist()->set_explicit_relayering (_layer_display == Stacked);
|
||||
|
||||
/* draw it */
|
||||
|
||||
redisplay_track ();
|
||||
|
@ -569,10 +566,16 @@ StreamView::get_inverted_selectables (Selection& sel, list<Selectable*>& results
|
|||
double
|
||||
StreamView::child_height () const
|
||||
{
|
||||
if (_layer_display == Stacked) {
|
||||
switch (_layer_display) {
|
||||
case Overlaid:
|
||||
return height;
|
||||
case Stacked:
|
||||
return height / _layers;
|
||||
case Expanded:
|
||||
return height / (_layers * 2 + 1);
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
return height;
|
||||
}
|
||||
|
||||
|
@ -589,6 +592,9 @@ StreamView::update_contents_height ()
|
|||
case Stacked:
|
||||
(*i)->set_y (height - ((*i)->region()->layer() + 1) * h);
|
||||
break;
|
||||
case Expanded:
|
||||
(*i)->set_y (height - ((*i)->region()->layer() + 1) * 2 * h);
|
||||
break;
|
||||
}
|
||||
|
||||
(*i)->set_height (h);
|
||||
|
@ -600,6 +606,7 @@ StreamView::update_contents_height ()
|
|||
i->rectangle->property_y2() = height;
|
||||
break;
|
||||
case Stacked:
|
||||
case Expanded:
|
||||
/* In stacked displays, the recregion is always at the top */
|
||||
i->rectangle->property_y1() = 0;
|
||||
i->rectangle->property_y2() = h;
|
||||
|
@ -614,7 +621,6 @@ StreamView::set_layer_display (LayerDisplay d)
|
|||
_layer_display = d;
|
||||
update_contents_height ();
|
||||
update_coverage_frames ();
|
||||
_trackview.track()->playlist()->set_explicit_relayering (_layer_display == Stacked);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1195,10 +1195,10 @@ TimeAxisView::color_handler ()
|
|||
* TimeAxisView is non-0 if this object covers y, or one of its children does.
|
||||
* If the covering object is a child axis, then the child is returned.
|
||||
* TimeAxisView is 0 otherwise.
|
||||
* Layer index is the layer number if the TimeAxisView is valid and is in stacked
|
||||
* region display mode, otherwise 0.
|
||||
* Layer index is the layer number (possibly fractional) if the TimeAxisView is valid
|
||||
* and is in stacked or expanded region display mode, otherwise 0.
|
||||
*/
|
||||
std::pair<TimeAxisView*, layer_t>
|
||||
std::pair<TimeAxisView*, double>
|
||||
TimeAxisView::covers_y_position (double y)
|
||||
{
|
||||
if (hidden()) {
|
||||
|
@ -1208,15 +1208,30 @@ TimeAxisView::covers_y_position (double y)
|
|||
if (_y_position <= y && y < (_y_position + height)) {
|
||||
|
||||
/* work out the layer index if appropriate */
|
||||
layer_t l = 0;
|
||||
if (layer_display () == Stacked && view ()) {
|
||||
/* compute layer */
|
||||
l = layer_t ((_y_position + height - y) / (view()->child_height ()));
|
||||
/* clamp to max layers to be on the safe side; sometimes the above calculation
|
||||
returns a too-high value */
|
||||
if (l >= view()->layers ()) {
|
||||
l = view()->layers() - 1;
|
||||
double l = 0;
|
||||
switch (layer_display ()) {
|
||||
case Overlaid:
|
||||
break;
|
||||
case Stacked:
|
||||
if (view ()) {
|
||||
/* compute layer */
|
||||
l = floor ((_y_position + height - y) / (view()->child_height ()));
|
||||
/* clamp to max layers to be on the safe side; sometimes the above calculation
|
||||
returns a too-high value */
|
||||
if (l >= view()->layers ()) {
|
||||
l = view()->layers() - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Expanded:
|
||||
if (view ()) {
|
||||
int n = floor ((_y_position + height - y) / (view()->child_height ()));
|
||||
l = n * 0.5 - 0.5;
|
||||
if (l >= (view()->layers() - 0.5)) {
|
||||
l = view()->layers() - 0.5;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return std::make_pair (this, l);
|
||||
|
|
|
@ -146,7 +146,7 @@ class TimeAxisView : public virtual AxisView
|
|||
|
||||
virtual void reset_visual_state ();
|
||||
|
||||
std::pair<TimeAxisView*, ARDOUR::layer_t> covers_y_position (double);
|
||||
std::pair<TimeAxisView*, double> covers_y_position (double);
|
||||
|
||||
virtual void step_height (bool);
|
||||
|
||||
|
|
|
@ -63,8 +63,6 @@ namespace ARDOUR {
|
|||
std::string translation_kill_path ();
|
||||
bool translations_are_disabled ();
|
||||
|
||||
const layer_t max_layer = UCHAR_MAX;
|
||||
|
||||
static inline microseconds_t get_microseconds () {
|
||||
return (microseconds_t) jack_get_time();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
#include "ardour/session_object.h"
|
||||
#include "ardour/data_type.h"
|
||||
|
||||
class PlaylistOverlapCacheTest;
|
||||
class PlaylistLayeringTest;
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class Session;
|
||||
|
@ -215,12 +218,6 @@ public:
|
|||
|
||||
void drop_regions ();
|
||||
|
||||
bool explicit_relayering () const {
|
||||
return _explicit_relayering;
|
||||
}
|
||||
|
||||
void set_explicit_relayering (bool e);
|
||||
|
||||
virtual boost::shared_ptr<Crossfade> find_crossfade (const PBD::ID &) const {
|
||||
return boost::shared_ptr<Crossfade> ();
|
||||
}
|
||||
|
@ -228,6 +225,10 @@ public:
|
|||
framepos_t find_next_top_layer_position (framepos_t) const;
|
||||
uint32_t combine_ops() const { return _combine_ops; }
|
||||
|
||||
void relayer (boost::shared_ptr<Region>, double);
|
||||
void suspend_relayer ();
|
||||
void resume_relayer ();
|
||||
|
||||
protected:
|
||||
friend class Session;
|
||||
|
||||
|
@ -288,17 +289,10 @@ public:
|
|||
bool _frozen;
|
||||
uint32_t subcnt;
|
||||
PBD::ID _orig_track_id;
|
||||
uint64_t layer_op_counter;
|
||||
framecnt_t freeze_length;
|
||||
bool auto_partition;
|
||||
uint32_t _combine_ops;
|
||||
|
||||
/** true if relayering should be done using region's current layers and their `pending explicit relayer'
|
||||
* flags; otherwise false if relayering should be done using the layer-model (most recently moved etc.)
|
||||
* Explicit relayering is used by tracks in stacked regionview mode.
|
||||
*/
|
||||
bool _explicit_relayering;
|
||||
|
||||
void init (bool hide);
|
||||
|
||||
bool holding_state () const {
|
||||
|
@ -361,16 +355,14 @@ public:
|
|||
boost::shared_ptr<Playlist> cut (framepos_t start, framecnt_t cnt, bool result_is_hidden);
|
||||
boost::shared_ptr<Playlist> copy (framepos_t start, framecnt_t cnt, bool result_is_hidden);
|
||||
|
||||
int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir);
|
||||
void relayer ();
|
||||
void relayer (boost::shared_ptr<Region>);
|
||||
void relayer (RegionList const &);
|
||||
|
||||
void begin_undo ();
|
||||
void end_undo ();
|
||||
void unset_freeze_parent (Playlist*);
|
||||
void unset_freeze_child (Playlist*);
|
||||
|
||||
void timestamp_layer_op (boost::shared_ptr<Region>);
|
||||
|
||||
void _split_region (boost::shared_ptr<Region>, framepos_t position);
|
||||
|
||||
typedef std::pair<boost::shared_ptr<Region>, boost::shared_ptr<Region> > TwoRegions;
|
||||
|
@ -391,6 +383,71 @@ public:
|
|||
with its constituent regions
|
||||
*/
|
||||
virtual void pre_uncombine (std::vector<boost::shared_ptr<Region> >&, boost::shared_ptr<Region>) {}
|
||||
|
||||
private:
|
||||
friend class ::PlaylistOverlapCacheTest;
|
||||
friend class ::PlaylistLayeringTest;
|
||||
|
||||
/** A class which is used to store temporary (fractional)
|
||||
* layer assignments for some regions.
|
||||
*/
|
||||
class TemporaryLayers
|
||||
{
|
||||
public:
|
||||
void set (boost::shared_ptr<Region>, double);
|
||||
double get (boost::shared_ptr<Region>) const;
|
||||
|
||||
private:
|
||||
typedef std::map<boost::shared_ptr<Region>, double> Map;
|
||||
Map _map;
|
||||
};
|
||||
|
||||
/** Class to sort by temporary layer, for use with std::list<>::sort() */
|
||||
class SortByTemporaryLayer
|
||||
{
|
||||
public:
|
||||
SortByTemporaryLayer (TemporaryLayers const & t)
|
||||
: _temporary_layers (t) {}
|
||||
|
||||
bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) const {
|
||||
return _temporary_layers.get (a) < _temporary_layers.get (b);
|
||||
}
|
||||
|
||||
private:
|
||||
Playlist::TemporaryLayers const & _temporary_layers;
|
||||
};
|
||||
|
||||
/** A cache of what overlaps what, for a given playlist in a given state.
|
||||
* Divides a playlist up into time periods and notes which regions cover those
|
||||
* periods, so that get() is reasonably quick.
|
||||
*/
|
||||
class OverlapCache
|
||||
{
|
||||
public:
|
||||
OverlapCache (Playlist *);
|
||||
|
||||
RegionList get (Evoral::Range<framepos_t>) const;
|
||||
|
||||
private:
|
||||
std::pair<int, int> cache_indices (Evoral::Range<framepos_t>) const;
|
||||
|
||||
double _division_size;
|
||||
std::vector<RegionList> _cache;
|
||||
Evoral::Range<framepos_t> _range;
|
||||
|
||||
static int const _divisions;
|
||||
};
|
||||
|
||||
TemporaryLayers compute_temporary_layers (RegionList const &);
|
||||
void commit_temporary_layers (TemporaryLayers const &);
|
||||
|
||||
RegionList recursive_regions_touched (boost::shared_ptr<Region>, OverlapCache const &, boost::shared_ptr<Region>) const;
|
||||
void recursive_regions_touched_sub (boost::shared_ptr<Region>, OverlapCache const &, boost::shared_ptr<Region>, RegionList &) const;
|
||||
|
||||
void timestamp_layer_op (LayerOp, boost::shared_ptr<Region>);
|
||||
uint64_t layer_op_counter;
|
||||
|
||||
bool _relayer_suspended;
|
||||
};
|
||||
|
||||
} /* namespace ARDOUR */
|
||||
|
|
|
@ -112,6 +112,7 @@ class Region
|
|||
framepos_t start () const { return _start; }
|
||||
framecnt_t length () const { return _length; }
|
||||
layer_t layer () const { return _layer; }
|
||||
Evoral::Range<framepos_t> bounds () const;
|
||||
|
||||
framecnt_t source_length(uint32_t n) const;
|
||||
uint32_t max_source_level () const;
|
||||
|
@ -201,7 +202,7 @@ class Region
|
|||
void cut_front (framepos_t new_position);
|
||||
void cut_end (framepos_t new_position);
|
||||
|
||||
void set_layer (layer_t l); /* ONLY Playlist can call this */
|
||||
void set_layer (layer_t l); /* ONLY Playlist should call this */
|
||||
void raise ();
|
||||
void lower ();
|
||||
void raise_to_top ();
|
||||
|
@ -251,8 +252,8 @@ class Region
|
|||
|
||||
virtual boost::shared_ptr<Region> get_parent() const;
|
||||
|
||||
uint64_t last_layer_op() const { return _last_layer_op; }
|
||||
void set_last_layer_op (uint64_t when);
|
||||
uint64_t last_layer_op (LayerOp) const;
|
||||
void set_last_layer_op (LayerOp, uint64_t);
|
||||
|
||||
virtual bool is_dependent() const { return false; }
|
||||
virtual bool depends_on (boost::shared_ptr<Region> /*other*/) const { return false; }
|
||||
|
@ -293,16 +294,13 @@ class Region
|
|||
|
||||
void invalidate_transients ();
|
||||
|
||||
void set_pending_explicit_relayer (bool p) {
|
||||
_pending_explicit_relayer = p;
|
||||
}
|
||||
|
||||
bool pending_explicit_relayer () const {
|
||||
return _pending_explicit_relayer;
|
||||
}
|
||||
|
||||
void drop_sources ();
|
||||
|
||||
/** @return our bounds the last time our relayer() method was called */
|
||||
Evoral::Range<framepos_t> last_relayer_bounds () const {
|
||||
return Evoral::Range<framepos_t> (_last_relayer_bounds_from, _last_relayer_bounds_to);
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class RegionFactory;
|
||||
|
||||
|
@ -387,16 +385,17 @@ class Region
|
|||
PBD::Property<float> _shift;
|
||||
PBD::EnumProperty<PositionLockStyle> _position_lock_style;
|
||||
|
||||
/* XXX: could use a Evoral::Range<> but I'm too lazy to make PBD::Property serialize such a thing nicely */
|
||||
PBD::Property<framepos_t> _last_relayer_bounds_from; ///< from of our bounds last time relayer() was called
|
||||
PBD::Property<framepos_t> _last_relayer_bounds_to; ///< to of our bounds last time relayer() was called
|
||||
PBD::Property<uint64_t> _last_layer_op_add;
|
||||
PBD::Property<uint64_t> _last_layer_op_bounds_change;
|
||||
|
||||
framecnt_t _last_length;
|
||||
framepos_t _last_position;
|
||||
mutable RegionEditState _first_edit;
|
||||
Timecode::BBT_Time _bbt_time;
|
||||
|
||||
uint64_t _last_layer_op; ///< timestamp
|
||||
|
||||
/** true if this region has had its layer explicitly set since the playlist last relayered */
|
||||
bool _pending_explicit_relayer;
|
||||
|
||||
void register_properties ();
|
||||
|
||||
void use_sources (SourceList const &);
|
||||
|
|
|
@ -30,31 +30,24 @@ struct RegionSortByPosition {
|
|||
}
|
||||
};
|
||||
|
||||
struct RegionSortByLastLayerOp {
|
||||
bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
|
||||
return a->last_layer_op() < b->last_layer_op();
|
||||
}
|
||||
};
|
||||
|
||||
struct RegionSortByLayer {
|
||||
bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
|
||||
return a->layer() < b->layer();
|
||||
}
|
||||
};
|
||||
|
||||
struct RegionSortByLayerWithPending {
|
||||
bool operator () (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
|
||||
|
||||
double p = a->layer ();
|
||||
if (a->pending_explicit_relayer()) {
|
||||
p += 0.5;
|
||||
}
|
||||
|
||||
double q = b->layer ();
|
||||
if (b->pending_explicit_relayer()) {
|
||||
q += 0.5;
|
||||
}
|
||||
struct RegionSortByAdd {
|
||||
bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
|
||||
return (
|
||||
(a->last_layer_op (LayerOpAdd) < b->last_layer_op (LayerOpAdd))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct RegionSortByAddOrBounds {
|
||||
bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
|
||||
uint64_t const p = std::max (a->last_layer_op (LayerOpAdd), a->last_layer_op (LayerOpBoundsChange));
|
||||
uint64_t const q = std::max (b->last_layer_op (LayerOpAdd), b->last_layer_op (LayerOpBoundsChange));
|
||||
return p < q;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -47,7 +47,8 @@ CONFIG_VARIABLE_SPECIAL(std::string, audio_search_path, "audio-search-path", "",
|
|||
CONFIG_VARIABLE_SPECIAL(std::string, midi_search_path, "midi-search-path", "", search_path_expand)
|
||||
CONFIG_VARIABLE (std::string, bwf_country_code, "bwf-country-code", "US")
|
||||
CONFIG_VARIABLE (std::string, bwf_organization_code, "bwf-organization-code", "US")
|
||||
CONFIG_VARIABLE (LayerModel, layer_model, "layer-model", MoveAddHigher)
|
||||
CONFIG_VARIABLE (LayerModel, layer_model, "layer-model", AddOrBoundsChangeHigher)
|
||||
CONFIG_VARIABLE (bool, relayer_on_all_edits, "relayer-on-all-edits", true)
|
||||
CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "default")
|
||||
CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "default")
|
||||
CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", true)
|
||||
|
|
|
@ -75,6 +75,7 @@ namespace ARDOUR {
|
|||
|
||||
static const framepos_t max_framepos = INT64_MAX;
|
||||
static const framecnt_t max_framecnt = INT64_MAX;
|
||||
static const layer_t max_layer = UINT32_MAX;
|
||||
|
||||
// a set of (time) intervals: first of pair is the offset of the start within the region, second is the offset of the end
|
||||
typedef std::list<std::pair<frameoffset_t, frameoffset_t> > AudioIntervalResult;
|
||||
|
@ -410,7 +411,7 @@ namespace ARDOUR {
|
|||
|
||||
enum LayerModel {
|
||||
LaterHigher,
|
||||
MoveAddHigher,
|
||||
AddOrBoundsChangeHigher,
|
||||
AddHigher
|
||||
};
|
||||
|
||||
|
@ -591,6 +592,11 @@ namespace ARDOUR {
|
|||
FadeLogB
|
||||
};
|
||||
|
||||
enum LayerOp {
|
||||
LayerOpAdd,
|
||||
LayerOpBoundsChange
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
|
||||
|
|
|
@ -1510,15 +1510,6 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
|
|||
}
|
||||
|
||||
i_am_the_modifier++;
|
||||
|
||||
if (_playlist->explicit_relayering()) {
|
||||
/* We are in `explicit relayering' mode, so we must specify which layer this new region
|
||||
should end up on. Put it at the top.
|
||||
*/
|
||||
region->set_layer (_playlist->top_layer() + 1);
|
||||
region->set_pending_explicit_relayer (true);
|
||||
}
|
||||
|
||||
_playlist->add_region (region, (*ci)->start, 1, non_layered());
|
||||
i_am_the_modifier--;
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ setup_enum_writer ()
|
|||
REGISTER (_CrossfadeModel);
|
||||
|
||||
REGISTER_ENUM (LaterHigher);
|
||||
REGISTER_ENUM (MoveAddHigher);
|
||||
REGISTER_ENUM (AddOrBoundsChangeHigher);
|
||||
REGISTER_ENUM (AddHigher);
|
||||
REGISTER (_LayerModel);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -73,6 +73,10 @@ namespace ARDOUR {
|
|||
PBD::PropertyDescriptor<float> stretch;
|
||||
PBD::PropertyDescriptor<float> shift;
|
||||
PBD::PropertyDescriptor<PositionLockStyle> position_lock_style;
|
||||
PBD::PropertyDescriptor<framepos_t> last_relayer_bounds_from;
|
||||
PBD::PropertyDescriptor<framepos_t> last_relayer_bounds_to;
|
||||
PBD::PropertyDescriptor<uint64_t> last_layer_op_add;
|
||||
PBD::PropertyDescriptor<uint64_t> last_layer_op_bounds_change;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,6 +131,14 @@ Region::make_property_quarks ()
|
|||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for shift = %1\n", Properties::shift.property_id));
|
||||
Properties::position_lock_style.property_id = g_quark_from_static_string (X_("positional-lock-style"));
|
||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position_lock_style = %1\n", Properties::position_lock_style.property_id));
|
||||
Properties::last_relayer_bounds_from.property_id = g_quark_from_static_string (X_("last-relayer-bounds-from"));
|
||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for last_relayer_bounds_from = %1\n", Properties::last_relayer_bounds_from.property_id));
|
||||
Properties::last_relayer_bounds_to.property_id = g_quark_from_static_string (X_("last-relayer-bounds-to"));
|
||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for last_relayer_bounds_to = %1\n", Properties::last_relayer_bounds_to.property_id));
|
||||
Properties::last_layer_op_add.property_id = g_quark_from_static_string (X_("last-layer-op-add"));
|
||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for last_layer_op_add = %1\n", Properties::last_layer_op_add.property_id));
|
||||
Properties::last_layer_op_bounds_change.property_id = g_quark_from_static_string (X_("last-layer-op-bounds-change"));
|
||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for last_layer_op_bounds_change = %1\n", Properties::last_layer_op_bounds_change.property_id));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -157,6 +169,10 @@ Region::register_properties ()
|
|||
add_property (_stretch);
|
||||
add_property (_shift);
|
||||
add_property (_position_lock_style);
|
||||
add_property (_last_relayer_bounds_from);
|
||||
add_property (_last_relayer_bounds_to);
|
||||
add_property (_last_layer_op_add);
|
||||
add_property (_last_layer_op_bounds_change);
|
||||
}
|
||||
|
||||
#define REGION_DEFAULT_STATE(s,l) \
|
||||
|
@ -182,7 +198,11 @@ Region::register_properties ()
|
|||
, _ancestral_length (Properties::ancestral_length, (l)) \
|
||||
, _stretch (Properties::stretch, 1.0) \
|
||||
, _shift (Properties::shift, 1.0) \
|
||||
, _position_lock_style (Properties::position_lock_style, _type == DataType::AUDIO ? AudioTime : MusicTime)
|
||||
, _position_lock_style (Properties::position_lock_style, _type == DataType::AUDIO ? AudioTime : MusicTime) \
|
||||
, _last_relayer_bounds_from (Properties::last_relayer_bounds_from, 0) \
|
||||
, _last_relayer_bounds_to (Properties::last_relayer_bounds_to, 0) \
|
||||
, _last_layer_op_add (Properties::last_layer_op_add, 0) \
|
||||
, _last_layer_op_bounds_change (Properties::last_layer_op_bounds_change, 0)
|
||||
|
||||
#define REGION_COPY_STATE(other) \
|
||||
_sync_marked (Properties::sync_marked, other->_sync_marked) \
|
||||
|
@ -207,7 +227,11 @@ Region::register_properties ()
|
|||
, _ancestral_length (Properties::ancestral_length, other->_ancestral_length) \
|
||||
, _stretch (Properties::stretch, other->_stretch) \
|
||||
, _shift (Properties::shift, other->_shift) \
|
||||
, _position_lock_style (Properties::position_lock_style, other->_position_lock_style)
|
||||
, _position_lock_style (Properties::position_lock_style, other->_position_lock_style) \
|
||||
, _last_relayer_bounds_from (Properties::last_relayer_bounds_from, other->_last_relayer_bounds_from) \
|
||||
, _last_relayer_bounds_to (Properties::last_relayer_bounds_to, other->_last_relayer_bounds_to) \
|
||||
, _last_layer_op_add (Properties::last_layer_op_add, other->_last_layer_op_add) \
|
||||
, _last_layer_op_bounds_change (Properties::last_layer_op_bounds_change, other->_last_layer_op_bounds_change)
|
||||
|
||||
/* derived-from-derived constructor (no sources in constructor) */
|
||||
Region::Region (Session& s, framepos_t start, framecnt_t length, const string& name, DataType type)
|
||||
|
@ -217,11 +241,8 @@ Region::Region (Session& s, framepos_t start, framecnt_t length, const string& n
|
|||
, _last_length (length)
|
||||
, _last_position (0)
|
||||
, _first_edit (EditChangesNothing)
|
||||
, _last_layer_op(0)
|
||||
, _pending_explicit_relayer (false)
|
||||
{
|
||||
register_properties ();
|
||||
|
||||
/* no sources at this point */
|
||||
}
|
||||
|
||||
|
@ -233,8 +254,6 @@ Region::Region (const SourceList& srcs)
|
|||
, _last_length (0)
|
||||
, _last_position (0)
|
||||
, _first_edit (EditChangesNothing)
|
||||
, _last_layer_op (0)
|
||||
, _pending_explicit_relayer (false)
|
||||
{
|
||||
register_properties ();
|
||||
|
||||
|
@ -254,9 +273,6 @@ Region::Region (boost::shared_ptr<const Region> other)
|
|||
, _last_length (other->_last_length)
|
||||
, _last_position(other->_last_position) \
|
||||
, _first_edit (EditChangesNothing)
|
||||
, _last_layer_op (0)
|
||||
, _pending_explicit_relayer (false)
|
||||
|
||||
{
|
||||
register_properties ();
|
||||
|
||||
|
@ -326,9 +342,6 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset)
|
|||
, _last_length (other->_last_length)
|
||||
, _last_position(other->_last_position) \
|
||||
, _first_edit (EditChangesNothing)
|
||||
, _last_layer_op (0)
|
||||
, _pending_explicit_relayer (false)
|
||||
|
||||
{
|
||||
register_properties ();
|
||||
|
||||
|
@ -383,8 +396,6 @@ Region::Region (boost::shared_ptr<const Region> other, const SourceList& srcs)
|
|||
, _last_length (other->_last_length)
|
||||
, _last_position (other->_last_position)
|
||||
, _first_edit (EditChangesID)
|
||||
, _last_layer_op (other->_last_layer_op)
|
||||
, _pending_explicit_relayer (false)
|
||||
{
|
||||
register_properties ();
|
||||
|
||||
|
@ -1123,9 +1134,12 @@ Region::set_layer (layer_t l)
|
|||
{
|
||||
if (_layer != l) {
|
||||
_layer = l;
|
||||
|
||||
send_change (Properties::layer);
|
||||
}
|
||||
|
||||
Evoral::Range<framepos_t> const b = bounds ();
|
||||
_last_relayer_bounds_from = b.from;
|
||||
_last_relayer_bounds_to = b.to;
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
|
@ -1317,9 +1331,16 @@ Region::send_change (const PropertyChange& what_changed)
|
|||
}
|
||||
|
||||
void
|
||||
Region::set_last_layer_op (uint64_t when)
|
||||
Region::set_last_layer_op (LayerOp op, uint64_t when)
|
||||
{
|
||||
_last_layer_op = when;
|
||||
switch (op) {
|
||||
case LayerOpAdd:
|
||||
_last_layer_op_add = when;
|
||||
break;
|
||||
case LayerOpBoundsChange:
|
||||
_last_layer_op_bounds_change = when;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1661,3 +1682,25 @@ Region::post_set (const PropertyChange& pc)
|
|||
recompute_position_from_lock_style ();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
Region::last_layer_op (LayerOp op) const
|
||||
{
|
||||
switch (op) {
|
||||
case LayerOpAdd:
|
||||
return _last_layer_op_add;
|
||||
case LayerOpBoundsChange:
|
||||
return _last_layer_op_bounds_change;
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
Evoral::Range<framepos_t>
|
||||
Region::bounds () const
|
||||
{
|
||||
return Evoral::Range<framepos_t> (_position, _position + _length);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ export ARDOUR_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/pann
|
|||
|
||||
if [ "$1" == "--debug" ]; then
|
||||
gdb ./libs/ardour/run-tests
|
||||
elif [ "$1" == "--valgrind" ]; then
|
||||
valgrind --tool="memcheck" ./libs/ardour/run-tests
|
||||
else
|
||||
./libs/ardour/run-tests
|
||||
fi
|
||||
|
|
|
@ -974,7 +974,27 @@ int
|
|||
Session::load_options (const XMLNode& node)
|
||||
{
|
||||
LocaleGuard lg (X_("POSIX"));
|
||||
config.set_variables (node);
|
||||
|
||||
/* Copy the node */
|
||||
XMLNode node_copy = node;
|
||||
|
||||
/* XXX: evil hack: fix up sessions from before the layering alterations
|
||||
(during A3 beta)
|
||||
*/
|
||||
|
||||
XMLNodeList children = node_copy.children ();
|
||||
for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) {
|
||||
XMLProperty* p = (*i)->property (X_("name"));
|
||||
if (p && p->name() == X_("name") && p->value() == X_("layer-model") ) {
|
||||
p = (*i)->property (X_("value"));
|
||||
if (p && p->value() == X_("MoveAddHigher")) {
|
||||
(*i)->add_property (X_("value"), X_("AddOrBoundsChangeHigher"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config.set_variables (node_copy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
#include "midi++/manager.h"
|
||||
#include "pbd/textreceiver.h"
|
||||
#include "pbd/compose.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/audioengine.h"
|
||||
#include "midi++/manager.h"
|
||||
#include "ardour/playlist_factory.h"
|
||||
#include "ardour/source_factory.h"
|
||||
#include "ardour/region.h"
|
||||
#include "ardour/region_factory.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/audiosource.h"
|
||||
#include "ardour/audioengine.h"
|
||||
#include "playlist_layering_test.h"
|
||||
#include "test_receiver.h"
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION (PlaylistLayeringTest);
|
||||
|
||||
|
@ -15,68 +16,28 @@ using namespace std;
|
|||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
class TestReceiver : public Receiver
|
||||
{
|
||||
protected:
|
||||
void receive (Transmitter::Channel chn, const char * str) {
|
||||
const char *prefix = "";
|
||||
|
||||
switch (chn) {
|
||||
case Transmitter::Error:
|
||||
prefix = ": [ERROR]: ";
|
||||
break;
|
||||
case Transmitter::Info:
|
||||
/* ignore */
|
||||
return;
|
||||
case Transmitter::Warning:
|
||||
prefix = ": [WARNING]: ";
|
||||
break;
|
||||
case Transmitter::Fatal:
|
||||
prefix = ": [FATAL]: ";
|
||||
break;
|
||||
case Transmitter::Throw:
|
||||
/* this isn't supposed to happen */
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* note: iostreams are already thread-safe: no external
|
||||
lock required.
|
||||
*/
|
||||
|
||||
cout << prefix << str << endl;
|
||||
|
||||
if (chn == Transmitter::Fatal) {
|
||||
exit (9);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TestReceiver test_receiver;
|
||||
int const PlaylistLayeringTest::num_regions = 6;
|
||||
|
||||
void
|
||||
PlaylistLayeringTest::setUp ()
|
||||
{
|
||||
string const test_session_path = "libs/ardour/test/playlist_layering_test";
|
||||
string const test_wav_path = "libs/ardour/test/playlist_layering_test/playlist_layering_test.wav";
|
||||
system (string_compose ("rm -rf %1", test_session_path).c_str());
|
||||
TestNeedingSession::setUp ();
|
||||
string const test_wav_path = "libs/ardour/test/test.wav";
|
||||
|
||||
init (false, true);
|
||||
SessionEvent::create_per_thread_pool ("test", 512);
|
||||
|
||||
test_receiver.listen_to (error);
|
||||
test_receiver.listen_to (info);
|
||||
test_receiver.listen_to (fatal);
|
||||
test_receiver.listen_to (warning);
|
||||
|
||||
AudioEngine* engine = new AudioEngine ("test", "");
|
||||
MIDI::Manager::create (engine->jack ());
|
||||
CPPUNIT_ASSERT (engine->start () == 0);
|
||||
|
||||
_session = new Session (*engine, test_session_path, "playlist_layering_test");
|
||||
engine->set_session (_session);
|
||||
|
||||
_playlist = PlaylistFactory::create (DataType::AUDIO, *_session, "test");
|
||||
_source = SourceFactory::createWritable (DataType::AUDIO, *_session, test_wav_path, "", false, 44100);
|
||||
|
||||
system ("pwd");
|
||||
|
||||
/* Must write some data to our source, otherwise regions which use it will
|
||||
be limited in whether they can be trimmed or not.
|
||||
*/
|
||||
boost::shared_ptr<AudioSource> a = boost::dynamic_pointer_cast<AudioSource> (_source);
|
||||
Sample silence[512];
|
||||
memset (silence, 0, 512 * sizeof (Sample));
|
||||
a->write (silence, 512);
|
||||
|
||||
_region = new boost::shared_ptr<Region>[num_regions];
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -84,68 +45,303 @@ PlaylistLayeringTest::tearDown ()
|
|||
{
|
||||
_playlist.reset ();
|
||||
_source.reset ();
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
for (int i = 0; i < num_regions; ++i) {
|
||||
_region[i].reset ();
|
||||
}
|
||||
|
||||
AudioEngine::instance()->remove_session ();
|
||||
delete _session;
|
||||
EnumWriter::destroy ();
|
||||
MIDI::Manager::destroy ();
|
||||
AudioEngine::destroy ();
|
||||
delete[] _region;
|
||||
|
||||
TestNeedingSession::tearDown ();
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistLayeringTest::create_three_short_regions ()
|
||||
PlaylistLayeringTest::create_short_regions ()
|
||||
{
|
||||
PropertyList plist;
|
||||
plist.add (Properties::start, 0);
|
||||
plist.add (Properties::length, 100);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int i = 0; i < num_regions; ++i) {
|
||||
_region[i] = RegionFactory::create (_source, plist);
|
||||
_region[i]->set_name (string_compose ("%1", char (int ('A') + i)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistLayeringTest::addHigherTest ()
|
||||
PlaylistLayeringTest::laterHigher_relayerOnAll_Test ()
|
||||
{
|
||||
_session->config.set_layer_model (AddHigher);
|
||||
create_three_short_regions ();
|
||||
_session->config.set_layer_model (LaterHigher);
|
||||
_session->config.set_relayer_on_all_edits (true);
|
||||
|
||||
create_short_regions ();
|
||||
|
||||
_playlist->add_region (_region[0], 0);
|
||||
_playlist->add_region (_region[1], 10);
|
||||
_playlist->add_region (_region[2], 20);
|
||||
/* three overlapping regions */
|
||||
_playlist->add_region (_region[A], 0);
|
||||
_playlist->add_region (_region[B], 10);
|
||||
_playlist->add_region (_region[C], 20);
|
||||
/* and another non-overlapping one */
|
||||
_playlist->add_region (_region[D], 200);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[0]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[1]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[2]->layer ());
|
||||
/* LaterHigher means that they should be arranged thus */
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
_region[0]->set_position (5);
|
||||
_region[A]->set_position (5);
|
||||
|
||||
/* region move should have no effect */
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[0]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[1]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[2]->layer ());
|
||||
/* Region move should have no effect in LaterHigher mode */
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* C -> bottom should give C A B, not touching D */
|
||||
_region[C]->lower_to_bottom ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* C -> top should go back to A B C, not touching D */
|
||||
_region[C]->raise_to_top ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistLayeringTest::moveAddHigherTest ()
|
||||
PlaylistLayeringTest::addHigher_relayerOnAll_Test ()
|
||||
{
|
||||
_session->config.set_layer_model (MoveAddHigher);
|
||||
create_three_short_regions ();
|
||||
_session->config.set_layer_model (AddHigher);
|
||||
_session->config.set_relayer_on_all_edits (true);
|
||||
|
||||
create_short_regions ();
|
||||
|
||||
_playlist->add_region (_region[0], 0);
|
||||
_playlist->add_region (_region[1], 10);
|
||||
_playlist->add_region (_region[2], 20);
|
||||
/* three overlapping regions */
|
||||
_playlist->add_region (_region[A], 0);
|
||||
_playlist->add_region (_region[B], 10);
|
||||
_playlist->add_region (_region[C], 20);
|
||||
/* and another non-overlapping one */
|
||||
_playlist->add_region (_region[D], 200);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[0]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[1]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[2]->layer ());
|
||||
/* AddHigher means that they should be arranged thus */
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
_region[0]->set_position (5);
|
||||
_region[A]->set_position (5);
|
||||
|
||||
/* region move should have put 0 on top */
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[0]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[1]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[2]->layer ());
|
||||
/* region move should have no effect in AddHigher mode */
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* C -> bottom should give C A B, not touching D */
|
||||
_region[C]->lower_to_bottom ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* C -> top should go back to A B C, not touching D */
|
||||
_region[C]->raise_to_top ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistLayeringTest::addOrBoundsHigher_relayerOnAll_Test ()
|
||||
{
|
||||
_session->config.set_layer_model (AddOrBoundsChangeHigher);
|
||||
_session->config.set_relayer_on_all_edits (true);
|
||||
|
||||
create_short_regions ();
|
||||
|
||||
/* three overlapping regions */
|
||||
_playlist->add_region (_region[A], 0);
|
||||
_playlist->add_region (_region[B], 10);
|
||||
_playlist->add_region (_region[C], 20);
|
||||
/* and another non-overlapping one */
|
||||
_playlist->add_region (_region[D], 200);
|
||||
|
||||
/* AddOrBoundsHigher means that they should be arranged thus */
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* region move should put A on top for B C A, not touching D */
|
||||
_region[A]->set_position (5);
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* C -> bottom should give C B A, not touching D */
|
||||
_region[C]->lower_to_bottom ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* C -> top should go back to B A C, not touching D */
|
||||
_region[C]->raise_to_top ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* Put C on the bottom */
|
||||
_region[C]->lower_to_bottom ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* Now move it slightly, and it should go back to the top again */
|
||||
_region[C]->set_position (21);
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* Put C back on the bottom */
|
||||
_region[C]->lower_to_bottom ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* Trim it slightly, and it should go back to the top again */
|
||||
_region[C]->trim_front (23);
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* Same with the end */
|
||||
_region[C]->lower_to_bottom ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
_region[C]->trim_end (118);
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistLayeringTest::addOrBoundsHigher_relayerWhenNecessary_Test ()
|
||||
{
|
||||
_session->config.set_layer_model (AddOrBoundsChangeHigher);
|
||||
_session->config.set_relayer_on_all_edits (false);
|
||||
|
||||
create_short_regions ();
|
||||
|
||||
/* three overlapping regions */
|
||||
_playlist->add_region (_region[A], 0);
|
||||
_playlist->add_region (_region[B], 10);
|
||||
_playlist->add_region (_region[C], 20);
|
||||
/* and another non-overlapping one */
|
||||
_playlist->add_region (_region[D], 200);
|
||||
|
||||
/* AddOrBoundsHigher means that they should be arranged thus */
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
_region[A]->set_position (5);
|
||||
|
||||
/* region move should not have changed anything, since in
|
||||
this mode we only relayer when there is a new overlap
|
||||
*/
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* C -> bottom should give C A B, not touching D */
|
||||
_region[C]->lower_to_bottom ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* C -> top should go back to A B C, not touching D */
|
||||
_region[C]->raise_to_top ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* Put C on the bottom */
|
||||
_region[C]->lower_to_bottom ();
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
/* Now move it slightly, and it should stay where it is */
|
||||
_region[C]->set_position (21);
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistLayeringTest::lastLayerOpTest ()
|
||||
{
|
||||
create_short_regions ();
|
||||
|
||||
_playlist->add_region (_region[A], 0);
|
||||
CPPUNIT_ASSERT_EQUAL (_playlist->layer_op_counter, _region[A]->last_layer_op (LayerOpAdd));
|
||||
uint64_t const last_add = _region[A]->last_layer_op (LayerOpAdd);
|
||||
|
||||
_region[A]->set_position (42);
|
||||
CPPUNIT_ASSERT_EQUAL (_playlist->layer_op_counter, _region[A]->last_layer_op (LayerOpBoundsChange));
|
||||
CPPUNIT_ASSERT_EQUAL (last_add, _region[A]->last_layer_op (LayerOpAdd));
|
||||
|
||||
_region[A]->trim_front (46);
|
||||
CPPUNIT_ASSERT_EQUAL (_playlist->layer_op_counter, _region[A]->last_layer_op (LayerOpBoundsChange));
|
||||
CPPUNIT_ASSERT_EQUAL (last_add, _region[A]->last_layer_op (LayerOpAdd));
|
||||
|
||||
_region[A]->trim_end (102);
|
||||
CPPUNIT_ASSERT_EQUAL (_playlist->layer_op_counter, _region[A]->last_layer_op (LayerOpBoundsChange));
|
||||
CPPUNIT_ASSERT_EQUAL (last_add, _region[A]->last_layer_op (LayerOpAdd));
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistLayeringTest::recursiveRelayerTest ()
|
||||
{
|
||||
_session->config.set_layer_model (AddOrBoundsChangeHigher);
|
||||
_session->config.set_relayer_on_all_edits (false);
|
||||
|
||||
create_short_regions ();
|
||||
|
||||
_playlist->add_region (_region[A], 100);
|
||||
_playlist->add_region (_region[B], 125);
|
||||
_playlist->add_region (_region[C], 50);
|
||||
_playlist->add_region (_region[D], 250);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[C]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
|
||||
_region[A]->set_position (200);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (0), _region[D]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (1), _region[A]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (2), _region[B]->layer ());
|
||||
CPPUNIT_ASSERT_EQUAL (layer_t (3), _region[C]->layer ());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include "test_needing_session.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class Session;
|
||||
|
@ -7,25 +8,42 @@ namespace ARDOUR {
|
|||
class Source;
|
||||
}
|
||||
|
||||
class PlaylistLayeringTest : public CppUnit::TestFixture
|
||||
class PlaylistLayeringTest : public TestNeedingSession
|
||||
{
|
||||
CPPUNIT_TEST_SUITE (PlaylistLayeringTest);
|
||||
CPPUNIT_TEST (addHigherTest);
|
||||
CPPUNIT_TEST (moveAddHigherTest);
|
||||
CPPUNIT_TEST (lastLayerOpTest);
|
||||
CPPUNIT_TEST (addHigher_relayerOnAll_Test);
|
||||
CPPUNIT_TEST (addOrBoundsHigher_relayerOnAll_Test);
|
||||
CPPUNIT_TEST (laterHigher_relayerOnAll_Test);
|
||||
CPPUNIT_TEST (addOrBoundsHigher_relayerWhenNecessary_Test);
|
||||
CPPUNIT_TEST (recursiveRelayerTest);
|
||||
CPPUNIT_TEST_SUITE_END ();
|
||||
|
||||
public:
|
||||
void setUp ();
|
||||
void tearDown ();
|
||||
|
||||
void addHigherTest ();
|
||||
void moveAddHigherTest ();
|
||||
void lastLayerOpTest ();
|
||||
void addHigher_relayerOnAll_Test ();
|
||||
void addOrBoundsHigher_relayerOnAll_Test ();
|
||||
void laterHigher_relayerOnAll_Test ();
|
||||
void addOrBoundsHigher_relayerWhenNecessary_Test ();
|
||||
void recursiveRelayerTest ();
|
||||
|
||||
private:
|
||||
void create_three_short_regions ();
|
||||
void create_short_regions ();
|
||||
|
||||
static int const num_regions;
|
||||
enum {
|
||||
A = 0,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F
|
||||
};
|
||||
|
||||
ARDOUR::Session* _session;
|
||||
boost::shared_ptr<ARDOUR::Playlist> _playlist;
|
||||
boost::shared_ptr<ARDOUR::Source> _source;
|
||||
boost::shared_ptr<ARDOUR::Region> _region[16];
|
||||
boost::shared_ptr<ARDOUR::Region>* _region;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
#include "pbd/compose.h"
|
||||
#include "ardour/playlist.h"
|
||||
#include "ardour/playlist_factory.h"
|
||||
#include "ardour/source_factory.h"
|
||||
#include "ardour/region.h"
|
||||
#include "ardour/region_sorters.h"
|
||||
#include "ardour/region_factory.h"
|
||||
#include "playlist_overlap_cache_test.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION (PlaylistOverlapCacheTest);
|
||||
|
||||
void
|
||||
PlaylistOverlapCacheTest::tearDown ()
|
||||
{
|
||||
_playlist.reset ();
|
||||
_source.reset ();
|
||||
|
||||
TestNeedingSession::tearDown ();
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistOverlapCacheTest::basicTest ()
|
||||
{
|
||||
string const test_wav_path = "libs/ardour/test/test.wav";
|
||||
|
||||
_playlist = PlaylistFactory::create (DataType::AUDIO, *_session, "test");
|
||||
_source = SourceFactory::createWritable (DataType::AUDIO, *_session, test_wav_path, "", false, 44100);
|
||||
|
||||
PropertyList plist;
|
||||
plist.add (Properties::length, 256);
|
||||
|
||||
boost::shared_ptr<Region> regionA = RegionFactory::create (_source, plist);
|
||||
regionA->set_name ("A");
|
||||
_playlist->add_region (regionA, 0);
|
||||
|
||||
|
||||
{
|
||||
Playlist::OverlapCache cache (_playlist.get ());
|
||||
Playlist::RegionList rl = cache.get (Evoral::Range<framepos_t> (0, 256));
|
||||
CPPUNIT_ASSERT_EQUAL (size_t (1), rl.size ());
|
||||
CPPUNIT_ASSERT_EQUAL (regionA, rl.front ());
|
||||
|
||||
rl = cache.get (Evoral::Range<framepos_t> (-1000, 1000));
|
||||
CPPUNIT_ASSERT_EQUAL (size_t (1), rl.size ());
|
||||
CPPUNIT_ASSERT_EQUAL (regionA, rl.front ());
|
||||
}
|
||||
|
||||
boost::shared_ptr<Region> regionB = RegionFactory::create (_source, plist);
|
||||
regionA->set_name ("B");
|
||||
_playlist->add_region (regionB, 53);
|
||||
|
||||
{
|
||||
Playlist::OverlapCache cache (_playlist.get ());
|
||||
Playlist::RegionList rl = cache.get (Evoral::Range<framepos_t> (0, 256));
|
||||
CPPUNIT_ASSERT_EQUAL (size_t (2), rl.size ());
|
||||
rl.sort (RegionSortByPosition ());
|
||||
CPPUNIT_ASSERT_EQUAL (regionA, rl.front ());
|
||||
CPPUNIT_ASSERT_EQUAL (regionB, rl.back ());
|
||||
|
||||
rl = cache.get (Evoral::Range<framepos_t> (260, 274));
|
||||
CPPUNIT_ASSERT_EQUAL (size_t (1), rl.size ());
|
||||
CPPUNIT_ASSERT_EQUAL (regionB, rl.front ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PlaylistOverlapCacheTest::stressTest ()
|
||||
{
|
||||
string const test_wav_path = "libs/ardour/test/test.wav";
|
||||
|
||||
_playlist = PlaylistFactory::create (DataType::AUDIO, *_session, "test");
|
||||
_source = SourceFactory::createWritable (DataType::AUDIO, *_session, test_wav_path, "", false, 44100);
|
||||
|
||||
srand (42);
|
||||
|
||||
int const num_regions = rand () % 256;
|
||||
|
||||
for (int i = 0; i < num_regions; ++i) {
|
||||
PropertyList plist;
|
||||
plist.add (Properties::length, rand () % 32768);
|
||||
boost::shared_ptr<Region> r = RegionFactory::create (_source, plist);
|
||||
r->set_name (string_compose ("%1", i));
|
||||
_playlist->add_region (r, rand() % 32768);
|
||||
}
|
||||
|
||||
Playlist::OverlapCache cache (_playlist.get ());
|
||||
|
||||
int const tests = rand () % 256;
|
||||
|
||||
for (int i = 0; i < tests; ++i) {
|
||||
framepos_t const start = rand () % 32768;
|
||||
framepos_t const length = rand () % 32768;
|
||||
framepos_t const end = start + length;
|
||||
|
||||
Playlist::RegionList cached = cache.get (Evoral::Range<framepos_t> (start, end));
|
||||
|
||||
Playlist::RegionList actual;
|
||||
Playlist::RegionList regions = _playlist->region_list().rlist();
|
||||
for (Playlist::RegionList::iterator j = regions.begin(); j != regions.end(); ++j) {
|
||||
if ((*j)->coverage (start, end) != OverlapNone) {
|
||||
actual.push_back (*j);
|
||||
}
|
||||
}
|
||||
|
||||
cached.sort (RegionSortByPosition ());
|
||||
actual.sort (RegionSortByPosition ());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL (actual.size (), cached.size ());
|
||||
Playlist::RegionList::iterator j = actual.begin ();
|
||||
Playlist::RegionList::iterator k = cached.begin ();
|
||||
for (; j != actual.end(); ++j, ++k) {
|
||||
CPPUNIT_ASSERT_EQUAL (*j, *k);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#include "test_needing_session.h"
|
||||
|
||||
class PlaylistOverlapCacheTest : public TestNeedingSession
|
||||
{
|
||||
public:
|
||||
CPPUNIT_TEST_SUITE (PlaylistOverlapCacheTest);
|
||||
CPPUNIT_TEST (basicTest);
|
||||
CPPUNIT_TEST (stressTest);
|
||||
CPPUNIT_TEST_SUITE_END ();
|
||||
|
||||
public:
|
||||
void tearDown ();
|
||||
|
||||
void basicTest ();
|
||||
void stressTest ();
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ARDOUR::Playlist> _playlist;
|
||||
boost::shared_ptr<ARDOUR::Source> _source;
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
#include "midi++/manager.h"
|
||||
#include "pbd/textreceiver.h"
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/enumwriter.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/audioengine.h"
|
||||
#include "test_needing_session.h"
|
||||
#include "test_receiver.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
TestReceiver test_receiver;
|
||||
|
||||
void
|
||||
TestNeedingSession::setUp ()
|
||||
{
|
||||
string const test_session_path = "libs/ardour/test/test_session";
|
||||
system (string_compose ("rm -rf %1", test_session_path).c_str());
|
||||
|
||||
init (false, true);
|
||||
SessionEvent::create_per_thread_pool ("test", 512);
|
||||
|
||||
test_receiver.listen_to (error);
|
||||
test_receiver.listen_to (info);
|
||||
test_receiver.listen_to (fatal);
|
||||
test_receiver.listen_to (warning);
|
||||
|
||||
AudioEngine* engine = new AudioEngine ("test", "");
|
||||
MIDI::Manager::create (engine->jack ());
|
||||
CPPUNIT_ASSERT (engine->start () == 0);
|
||||
|
||||
_session = new Session (*engine, test_session_path, "test_session");
|
||||
engine->set_session (_session);
|
||||
}
|
||||
|
||||
void
|
||||
TestNeedingSession::tearDown ()
|
||||
{
|
||||
AudioEngine::instance()->remove_session ();
|
||||
|
||||
delete _session;
|
||||
|
||||
EnumWriter::destroy ();
|
||||
MIDI::Manager::destroy ();
|
||||
AudioEngine::destroy ();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
class Session;
|
||||
}
|
||||
|
||||
class TestNeedingSession : public CppUnit::TestFixture
|
||||
{
|
||||
public:
|
||||
void setUp ();
|
||||
void tearDown ();
|
||||
|
||||
protected:
|
||||
ARDOUR::Session* _session;
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
#include "pbd/receiver.h"
|
||||
|
||||
class TestReceiver : public Receiver
|
||||
{
|
||||
protected:
|
||||
void receive (Transmitter::Channel chn, const char * str) {
|
||||
const char *prefix = "";
|
||||
|
||||
switch (chn) {
|
||||
case Transmitter::Error:
|
||||
prefix = ": [ERROR]: ";
|
||||
break;
|
||||
case Transmitter::Info:
|
||||
/* ignore */
|
||||
return;
|
||||
case Transmitter::Warning:
|
||||
prefix = ": [WARNING]: ";
|
||||
break;
|
||||
case Transmitter::Fatal:
|
||||
prefix = ": [FATAL]: ";
|
||||
break;
|
||||
case Transmitter::Throw:
|
||||
/* this isn't supposed to happen */
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* note: iostreams are already thread-safe: no external
|
||||
lock required.
|
||||
*/
|
||||
|
||||
std::cout << prefix << str << std::endl;
|
||||
|
||||
if (chn == Transmitter::Fatal) {
|
||||
exit (9);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -431,6 +431,8 @@ def build(bld):
|
|||
test/framepos_plus_beats_test.cc
|
||||
test/framepos_minus_beats_test.cc
|
||||
test/playlist_layering_test.cc
|
||||
test/playlist_overlap_cache_test.cc
|
||||
test/test_needing_session.cc
|
||||
test/testrunner.cc
|
||||
'''.split()
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
</para>
|
||||
|
||||
<para>
|
||||
Of course, nothing in digital audio is ever quite that simple, and so of
|
||||
course there are some complications:
|
||||
Of course, nothing in digital audio is ever quite that simple, and so
|
||||
there are some complications:
|
||||
</para>
|
||||
|
||||
<section id="layers-crossfades">
|
||||
|
@ -38,14 +38,14 @@
|
|||
<section id="region-opacity">
|
||||
<title> Region Opacity </title>
|
||||
<para>
|
||||
In a perverse nod to image manipulation programs, Ardour allows you to
|
||||
With a nod to image manipulation programs, Ardour allows you to
|
||||
make regions transparent. By default, all regions are created opaque,
|
||||
which means that when they are playing, no region below them are
|
||||
audible. However, if you change the region to be transparent, the
|
||||
region will be audible together with any regions below it. This
|
||||
capability should probably not be abused - if you really want to mix
|
||||
sounds together in this way, they should probably live in their own
|
||||
tracks. Occasionally though, this can be useful trick.
|
||||
capability should probably not be abused; if you really want to mix
|
||||
sounds together in this way, they should probably be on their own
|
||||
tracks. Occasionally though, this can be a useful trick.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -55,70 +55,74 @@
|
|||
</para>
|
||||
</section>
|
||||
|
||||
<section id="layering-styles">
|
||||
<title> Layering Styles </title>
|
||||
<para>
|
||||
When you are recording new material for a track, its typical to want
|
||||
to new material recorded "over" existing material in the track to be
|
||||
what you hear on playback. For example, if you overdub part of a
|
||||
guitar solo, you normally want the overdub to be audible, not hidden
|
||||
by the old version that was already there. By contrast, when editing
|
||||
using splitting/trimming/moving of regions to create a particular
|
||||
arrangement along the timeline, many people find that they want
|
||||
regions that start later on the timeline to be the ones that are
|
||||
audible.
|
||||
</para>
|
||||
<section id="choice-of-layering">
|
||||
<title>Choice of layering</title>
|
||||
|
||||
<para>
|
||||
To facilitate these two contradictory desires, Ardour features three
|
||||
different styles for assigning regions to layers.
|
||||
There are two main decisions to be made with regard to how a playlist
|
||||
should be layered:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<title></title>
|
||||
<varlistentry>
|
||||
<term>Most recently added regions are higher</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use this style when recording/overdubbing new material. Edits of
|
||||
any kind do not modify the layering.
|
||||
</para>
|
||||
</listitem>
|
||||
Given overlapping regions, which order should they be layered in?
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Most recently added/moved/trimmed regions are higher</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use this style when recording/overdubbing new material, but you
|
||||
want basic edits to cause regions to rise to the top.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Later regions are higher</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use this style when rearranging and editing regions.
|
||||
</para>
|
||||
</listitem>
|
||||
When should layering be changed?
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<section id="layering-order">
|
||||
<title>Layering Order</title>
|
||||
<para>
|
||||
Ardour provides three-and-a-half ways to decide on the order in which regions are layered. The most basic choice is:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<title></title>
|
||||
<varlistentry>
|
||||
<term>Most recently added regions are higher</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Regions which are later in time will be on higher layers.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Most recently added or edited regions are higher</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Regions which were more recently edited or added to the playlist
|
||||
will be on higher layers.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Later regions are higher</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Regions which were more recently added to the playlist will be on higher
|
||||
layers.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</section>
|
||||
|
||||
<para>
|
||||
A new session has the layering style set to "Most recently
|
||||
added/moved/trimmed regions are higher". To change the layering style,
|
||||
open the <emphasis>options editor</emphasis> and select the
|
||||
"Layers&Fades" page. There is an option there to select the style
|
||||
you want. Layering style may be changed at any time. The existing
|
||||
layering of all playlists is not changed when changing the layering
|
||||
model.
|
||||
A new session has the layering style set to "Most recently edited or
|
||||
added regions are higher". To change the layering style, open the
|
||||
<emphasis>Session Properties</emphasis> dialogue and choose your layering
|
||||
style from the "Misc" page. Changing the layering style only affects
|
||||
future edits to the playlist; the existing layering of all playlists is
|
||||
preserved when changing the layering mode.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="modifying-layering-by-hand">
|
||||
<title> Modifying Layering By Hand </title>
|
||||
<title>Modifying Layering Explicitly</title>
|
||||
<para>
|
||||
If you want a particular region to be the uppermost when the current
|
||||
layering style has put it on a lower layer, context click on the
|
||||
|
|
Loading…
Reference in New Issue