Skip to content

Commit

Permalink
ppsf (nt): support pitch generation
Browse files Browse the repository at this point in the history
  • Loading branch information
SoulMelody committed Jan 18, 2025
1 parent 02697d8 commit feaf80f
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 3 deletions.
4 changes: 2 additions & 2 deletions libresvip/plugins/ppsf/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class PpsfParamPoint(BaseModel):
region_index: Optional[int] = Field(None, alias="region-index")
border_type: Optional[int] = Field(None, alias="border-type")
note_index: Optional[int] = Field(None, alias="note-index")
edited_by_user: Optional[bool] = Field(False, alias="edited-by-user")
edited_by_user: Optional[bool] = Field(None, alias="edited-by-user")
seg_array_id: Optional[int] = Field(None, alias="seg-array-id")


Expand Down Expand Up @@ -318,7 +318,7 @@ class PpsfEnvelope(BaseModel):


def default_portamento_envelope() -> PpsfEnvelope:
return PpsfEnvelope(length=161, offset=-107)
return PpsfEnvelope(length=0, offset=0)


class PpsfDvlTrackEvent(BaseModel):
Expand Down
100 changes: 99 additions & 1 deletion libresvip/plugins/ppsf/piapro_studio_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,27 @@
legato_chars,
romaji2xsampa,
)
from libresvip.core.time_interval import PiecewiseIntervalDict
from libresvip.core.time_sync import TimeSynchronizer
from libresvip.model.base import (
InstrumentalTrack,
Note,
ParamCurve,
Project,
SingingTrack,
SongTempo,
TimeSignature,
Track,
)
from libresvip.utils.audio import audio_track_info
from libresvip.utils.search import find_index

from .model import (
PpsfAudioTrackEvent,
PpsfAudioTrackItem,
PpsfBaseSequence,
PpsfCurvePoint,
PpsfCurvePointSeq,
PpsfCurveType,
PpsfDvlTrackEvent,
PpsfDvlTrackItem,
Expand All @@ -28,13 +34,16 @@
PpsfMeter,
PpsfMeters,
PpsfNote,
PpsfParamPoint,
PpsfProject,
PpsfRegion,
PpsfSeqParam,
PpsfSyllable,
PpsfTempo,
PpsfTempos,
)
from .options import OutputOptions
from .ppsf_interval_dict import ppsf_key_interval_dict


@dataclasses.dataclass
Expand Down Expand Up @@ -129,10 +138,99 @@ def generate_singing_tracks(
else 0,
)
)
dvl_tracks.append(PpsfDvlTrackItem(name=track.title, events=track_events))
key_interval_dict = ppsf_key_interval_dict(track_events, event_track.notes)
pitch_param, pitch_curve_point = self.generate_pitch(
track.edited_params.pitch, key_interval_dict, track.note_list
)
event_track.curve_points.append(pitch_curve_point)
dvl_track = PpsfDvlTrackItem(
name=track.title, events=track_events, parameters=[pitch_param]
)
dvl_tracks.append(dvl_track)
event_tracks.append(event_track)
return dvl_tracks

def generate_pitch(
self, pitch: ParamCurve, key_interval_dict: PiecewiseIntervalDict, notes: list[Note]
) -> tuple[PpsfSeqParam, PpsfCurvePoint]:
pitch_param = PpsfSeqParam()
curve_point = PpsfCurvePoint(
sub_track_category=7,
sub_track_id=2,
)
pitch_param.base_sequence = PpsfBaseSequence(
constant=0,
name="pitch_bend",
use_sequence=True,
)
in_pitch_part = False
for point in pitch.points.root:
pos = point.x - self.first_bar_length
if point.y == -100:
if (
point.x not in [-192000, 1073741823]
and in_pitch_part
and len(pitch_param.base_sequence.sequence)
):
pitch_param.base_sequence.sequence.append(
PpsfParamPoint(
curve_type=PpsfCurveType.BORDER,
pos=pitch_param.base_sequence.sequence[-1].pos,
value=pitch_param.base_sequence.sequence[-1].value,
)
)
curve_point.sequence.append(
PpsfCurvePointSeq(
border_type=7,
abs_value=-1,
edited_by_user=True,
region_index=-1,
note_index=-1,
seg_array_id=-1,
)
)
in_pitch_part = False
elif (base_key := key_interval_dict.get(pos)) is not None:
if not in_pitch_part:
pitch_param.base_sequence.sequence.append(
PpsfParamPoint(
curve_type=PpsfCurveType.BORDER,
pos=pos - 1,
value=0,
)
)
curve_point.sequence.append(
PpsfCurvePointSeq(
border_type=6,
abs_value=-1,
edited_by_user=True,
region_index=-1,
note_index=-1,
seg_array_id=-1,
)
)
in_pitch_part = True
pitch_param.base_sequence.sequence.append(
PpsfParamPoint(
curve_type=PpsfCurveType.NORMAL,
pos=pos,
value=point.y - round(base_key * 100),
)
)
curve_point.sequence.append(
PpsfCurvePointSeq(
border_type=1,
abs_value=point.y,
edited_by_user=True,
region_index=-1,
note_index=find_index(
notes, lambda note: note.start_pos <= pos <= note.end_pos
),
seg_array_id=-1,
)
)
return pitch_param, curve_point

def generate_instrumental_tracks(
self, tracks: list[Track], event_tracks: list[PpsfEventTrack]
) -> list[PpsfAudioTrackItem]:
Expand Down

0 comments on commit feaf80f

Please sign in to comment.