-
Notifications
You must be signed in to change notification settings - Fork 691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add fade_in_length() and fade_out_length() methods to audioregion #592
base: master
Are you sure you want to change the base?
Changes from all commits
3986f5d
fb9e890
f71043f
a39fe31
69d9b8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1243,6 +1243,20 @@ AudioRegion::fade_out_is_default () const | |
return _fade_out->size() == 2 && _fade_out->when(true) == 0 && _fade_out->when(false) == 64; | ||
} | ||
|
||
samplecnt_t | ||
AudioRegion::fade_in_length () | ||
{ | ||
samplecnt_t fade_in_length = (samplecnt_t) _fade_in->when(false); | ||
return fade_in_length; | ||
} | ||
|
||
samplecnt_t | ||
AudioRegion::fade_out_length () | ||
{ | ||
samplecnt_t fade_out_length = (samplecnt_t) _fade_out->when(false); | ||
return fade_out_length; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see above comment for |
||
} | ||
|
||
void | ||
AudioRegion::set_default_fade_in () | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
ardour { ["type"] = "EditorAction", name = "New clean playlists", | ||
license = "MIT", | ||
author = "Mathieu Picot (Houston4444)", | ||
description = [[Copy the current playlist of selected tracks to a new playlist with audible regions only.]] | ||
} | ||
|
||
function factory (params) return function () | ||
|
||
-- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:Selection | ||
local sel = Editor:get_selection () | ||
|
||
-- Track/Bus Selection -- iterate over all Editor-GUI selected tracks | ||
-- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:TrackSelection | ||
for route in sel.tracks:routelist():iter() do | ||
|
||
-- each of the items 'route' is-a | ||
-- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Route | ||
local track = route:to_track() -- see if it's a track | ||
if track:isnil() then | ||
-- if not, skip it | ||
goto next_route | ||
end | ||
|
||
local is_audio = false | ||
if track:data_type():to_string() == "audio" then | ||
is_audio = true | ||
end | ||
|
||
local main_pl_name = track:name() .. "._MAIN_" | ||
local main_pl_ex_name = track:name() .. "_ExMAIN_" | ||
|
||
-- find the playlist name track_name._MAIN_ | ||
for pl in Session:playlists():playlists_for_track (track):iter() do | ||
if pl:name() == main_pl_name then | ||
pl:set_name(main_pl_ex_name) | ||
break | ||
end | ||
end | ||
|
||
-- copy current playlist, get new playlist and rename it | ||
-- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Playlist | ||
track:use_copy_playlist() | ||
local playlist = track:playlist() | ||
playlist:set_name(track:name() .. "._MAIN_") | ||
|
||
-- we will stock here the values needed to modify/remove regions | ||
local regions_to_modify = {} | ||
|
||
for r in playlist:region_list():iter() do | ||
local r_front = r:position() | ||
local r_end = r_front + r:length() | ||
|
||
-- region can be finally splited into many segments | ||
-- 'segments' is a table containing segments with the form | ||
-- {{seg1_start, seg1_end}, {seg2_start, seg2_finish}...} | ||
-- segments will finally be regions | ||
local segments = {{r_front, r_end}} | ||
|
||
-- values used for audio tracks to prevent cut during an audible fade | ||
local r_no_cut_before = r_front | ||
local r_no_cut_after = r_end | ||
|
||
if is_audio then | ||
local ra = r:to_audioregion() | ||
|
||
if ra:fade_in_active() then | ||
r_no_cut_before = r_front + ra:fade_in_length() + 64 | ||
end | ||
|
||
if ra:fade_out_active() then | ||
r_no_cut_after = r_end - ra:fade_out_length() - 64 | ||
end | ||
Comment on lines
+66
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if the region is shorter than 128 samples? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. regions shorter than 128 samples are not copied to the new playlist, because an isolated region with a such length could only be noise. But at this point of the script we just check from when we could cut the compared regions. |
||
end | ||
|
||
for rg in playlist:region_list():iter() do | ||
-- ignore regions equal or above this one | ||
if rg:layer() <= r:layer() then | ||
goto next_rg | ||
end | ||
|
||
-- get points between which lower regions can be cut | ||
local cut_point_left = rg:position() | ||
local cut_point_right = cut_point_left + rg:length() | ||
|
||
if is_audio then | ||
rga = rg:to_audioregion() | ||
|
||
cut_point_left = cut_point_left + 64 | ||
cut_point_right = cut_point_right - 64 | ||
|
||
if rga:fade_in_active() then | ||
cut_point_left = cut_point_left + rga:fade_in_length() | ||
end | ||
|
||
if rga:fade_out_active() then | ||
cut_point_right = cut_point_right - rga:fade_out_length() | ||
end | ||
end | ||
|
||
-- ignore regions with no overlap with this one | ||
if cut_point_left >= segments[#segments][2] | ||
or cut_point_right <= segments[1][1] then | ||
goto next_rg | ||
end | ||
|
||
-- stock here the segments ids we should remove | ||
local remove_id_list = {} | ||
|
||
-- iterate segments | ||
for i, s in pairs(segments) do | ||
if cut_point_right <= s[1] or cut_point_left >= s[2] then | ||
-- rg: ___ or ____ | ||
-- s : ___ ____ | ||
|
||
-- compared region doesn't overlap this segment | ||
goto next_segment | ||
|
||
elseif cut_point_left <= s[1] and cut_point_right >= s[2] then | ||
-- rg: ________ | ||
-- s : ____ | ||
|
||
-- compared region exceed both front and end | ||
-- this segment will be removed | ||
table.insert(remove_id_list, i) | ||
goto next_segment | ||
|
||
elseif cut_point_left <= s[1] then | ||
-- rg: ____ | ||
-- s : _____ | ||
|
||
if is_audio then | ||
-- audio segment is cut 64 samples before compared region fade out | ||
-- in the limit of the original segment | ||
-- it also do not cut during the region fades | ||
if cut_point_right > r_no_cut_before then | ||
s[1] = math.min(cut_point_right, | ||
r_no_cut_after) | ||
end | ||
else | ||
s[1] = cut_point_right | ||
end | ||
|
||
elseif cut_point_right >= s[2] then | ||
-- rg: _____ | ||
-- s : _____ | ||
|
||
if is_audio then | ||
-- audio segment is cut 64 samples after compared region fade in | ||
-- in the limit of the original segment | ||
if cut_point_left < r_no_cut_after then | ||
s[2] = math.max(cut_point_left, | ||
r_no_cut_before) | ||
end | ||
else | ||
s[2] = cut_point_left | ||
end | ||
|
||
else | ||
-- rg: B___C | ||
-- s : A___________D | ||
|
||
-- worst case, compared region rg is above r, | ||
-- rg starts after and finish before r. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. whitespace (should use tabs for indent) |
||
|
||
point_b = cut_point_left | ||
point_c = cut_point_right | ||
|
||
if is_audio then | ||
point_b = math.max(point_b, r_no_cut_before) | ||
point_c = math.min(point_c, r_no_cut_after) | ||
|
||
if point_b > r_no_cut_after or point_c < r_no_cut_before then | ||
-- we must keep the fade integrity | ||
goto next_segment | ||
end | ||
end | ||
|
||
-- we can modify the table now because | ||
-- we break the iteration loop just after. | ||
-- add the new segment C->D | ||
table.insert(segments, i + 1, {point_c, s[2]}) | ||
|
||
-- reduce the original segment (from A->D to A->B) | ||
s[2] = point_b | ||
break | ||
end | ||
::next_segment:: | ||
end | ||
|
||
-- remove segments that need to be removed | ||
for i=1, #remove_id_list do | ||
table.remove( | ||
segments, remove_id_list[#remove_id_list +1 -i]) | ||
end | ||
|
||
-- if all segments are removed, region will be deleted | ||
if segments[1] == nil then break end | ||
|
||
::next_rg:: | ||
end | ||
|
||
-- security check | ||
-- prevent segments and gaps shorter than 128 | ||
-- and overlap segments from the same region | ||
local last_end = -1 | ||
local new_segments = {} | ||
|
||
for i, s in pairs(segments) do | ||
if s[2] - s[1] > 128 then | ||
if s[1] > last_end + 128 then | ||
table.insert(new_segments, s) | ||
else | ||
new_segments[#new_segments][2] = s[2] | ||
end | ||
end | ||
last_end = s[2] | ||
end | ||
|
||
-- remember the regions we have to delete or modify | ||
table.insert(regions_to_modify, {r, new_segments}) | ||
end | ||
|
||
-- Remove, split or cut needed regions | ||
for i=1, #regions_to_modify do | ||
r = regions_to_modify[i][1] | ||
segments = regions_to_modify[i][2] | ||
|
||
if #segments == 0 then | ||
playlist:remove_region(r) | ||
else | ||
for j=1, #segments do | ||
if j == #segments then | ||
-- last segment, cut directly this region | ||
rg = r | ||
else | ||
-- 2 segments or more for this region | ||
-- So we need to clone the region before to cut it | ||
rg = ARDOUR.RegionFactory.clone_region(r, true, false) | ||
playlist:add_region(rg, rg:position(), 1, false, 0, 0, false) | ||
|
||
while rg:layer() > r:layer() | ||
do | ||
rg:lower() | ||
end | ||
end | ||
|
||
-- finally cut the region if needed | ||
if segments[j][1] ~= rg:position() then | ||
rg:cut_front(segments[j][1], 0) | ||
end | ||
|
||
if segments[j][2] ~= rg:position() + rg:length() then | ||
rg:cut_end(segments[j][2], 0) | ||
end | ||
end | ||
end | ||
end | ||
::next_route:: | ||
end | ||
end end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use a temporary variable instead of
return _fade_in->when(false)
?ControlList::when (false) returns the position of the last point, which is only the length if
ControlList::when(true) == 0
.Either name the function
fade_in_end_position()
, or subtract_fader_in->when(true)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, I can't remember, indeed it's useless.
I didn't know it is possible that fade in could start before or after the region start. Is it really possible ? I don't see how to do it in the GUI. The script doesn't manage this possibility.