Skip to content

Commit

Permalink
s5p: refactor vibrato layer
Browse files Browse the repository at this point in the history
  • Loading branch information
SoulMelody committed Aug 15, 2024
1 parent 981c944 commit 12a07ed
Showing 1 changed file with 27 additions and 40 deletions.
67 changes: 27 additions & 40 deletions libresvip/plugins/s5p/synthv_editor_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,59 +228,46 @@ def parse_params(self, parameters: S5pParameters, note_list: list[Note]) -> Para
def parse_pitch_curve(
self, pitch_delta: S5pPoints, interval: int, note_list: list[Note]
) -> list[Point]:
points = sortedcontainers.SortedList(key=operator.attrgetter("x"))
note_start_positions = [note.start_pos for note in note_list]
pitch_intervals = portion.empty()
pitch_raw_data = sortedcontainers.SortedList(key=operator.attrgetter("x"))
for s5p_point_group in more_itertools.split_when(
pitch_delta.root, lambda p1, p2: p2.offset > p1.offset + 1
):
pitch_start = None
for is_first, is_last, s5p_point in more_itertools.mark_ends(s5p_point_group):
if is_first and is_last:
continue
point_ticks = round(s5p_point.offset * (interval / TICK_RATE))
point_secs = self.synchronizer.get_actual_secs_from_ticks(point_ticks)
if is_first:
pitch_start = point_secs
elif is_last:
pitch_intervals |= portion.closed(pitch_start, point_secs)
point_value = s5p_point.value
if (vibrato_value := self.vibrato_value_interval_dict.get(point_secs)) is not None:
point_value += (
vibrato_value * self.vibrato_coef_interval_dict[point_secs] * 2000
)
points.add(
pitch_raw_data.add(
Point(
x=point_ticks,
y=round(point_value),
)
)
auto_pitch_intervals = self.vibrato_value_interval_dict.domain() - pitch_intervals
self.vibrato_value_interval_dict._last_index = 0
self.vibrato_coef_interval_dict._last_index = 0
for sub_interval in auto_pitch_intervals:
start_tick = round(self.synchronizer.get_actual_ticks_from_secs(sub_interval.lower))

step_secs = self.synchronizer.get_duration_secs_from_ticks(
start_tick, int(start_tick + interval / TICK_RATE)
)
for is_first, is_last, vibrato_secs in more_itertools.mark_ends(
portion.iterate(
sub_interval,
step_secs,
)
):
vibrato_ticks = int(self.synchronizer.get_actual_ticks_from_secs(vibrato_secs))
if (
vibrato_ticks not in note_start_positions
and (vibrato_value := self.vibrato_value_interval_dict.get(vibrato_secs))
is not None
):
vibrato_value *= self.vibrato_coef_interval_dict[vibrato_secs] * 2000
points.add(
points = []
prev_pos = None
value = None
for pos, value in pitch_raw_data:
pos_secs = self.synchronizer.get_actual_secs_from_ticks(pos)
if prev_pos is not None:
for interp_pos in range(prev_pos + 5, pos, 5):
interp_pos_secs = self.synchronizer.get_actual_secs_from_ticks(interp_pos)
if interp_value_diff := self.vibrato_value_interval_dict.get(
interp_pos_secs, 0
):
interp_value_diff *= self.vibrato_coef_interval_dict[interp_pos_secs] * 2000
points.append(
Point(
x=vibrato_ticks,
y=round(vibrato_value),
x=interp_pos,
y=value + round(interp_value_diff),
)
)
return list(points)
if value_diff := self.vibrato_value_interval_dict.get(pos_secs, 0):
value_diff *= self.vibrato_coef_interval_dict[pos_secs] * 2000
points.append(
Point(
x=pos,
y=value + round(value_diff),
)
)
prev_pos = pos
return points

0 comments on commit 12a07ed

Please sign in to comment.