@@ -32,18 +32,24 @@ def move(self, offset: int) -> Note:
3232 new_note .tick += offset
3333 return new_note
3434
35- def apply_layer_weight (self , layer : pynbs .Layer ) -> Note :
35+ def apply_layer_weight (
36+ self , layer : pynbs .Layer , custom_instrument : Optional [pynbs .Instrument ] = None
37+ ) -> Note :
3638 """Return a new Note object with compensated pitch, volume and panning."""
37- pitch = self ._get_pitch ()
39+ pitch = self ._get_pitch (custom_instrument )
3840 volume = self ._get_volume (layer )
3941 panning = self ._get_panning (layer )
4042 return self .__class__ (
4143 pynbs .Note (self .tick , self .layer , self .instrument , pitch , volume , panning )
4244 )
4345
44- def _get_pitch (self ) -> float :
46+ def _get_pitch (self , custom_instrument : Optional [ pynbs . Instrument ] = None ) -> float :
4547 """Return the detune-aware pitch of this note."""
46- key = self .key - 45
48+ if custom_instrument is not None :
49+ instrument_key = (45 - custom_instrument .pitch ) + 45
50+ else :
51+ instrument_key = 45 # This assumes all default instruments are pitched F#4
52+ key = self .key - instrument_key
4753 detune = self .pitch / 100
4854 pitch = key + detune
4955 return pitch
@@ -107,7 +113,14 @@ def duration(self) -> None:
107113
108114 def weighted_notes (self ) -> Iterator [Note ]:
109115 """Return all notes in this song with their layer velocity and panning applied."""
110- return (note .apply_layer_weight (self .layers [note .layer ]) for note in self .notes )
116+ for note in self .notes :
117+ layer = self .layers [note .layer ]
118+ custom_instrument_id = note .instrument - self .header .default_instruments
119+ if custom_instrument_id >= 0 :
120+ instrument = self .instruments [custom_instrument_id ]
121+ else :
122+ instrument = None
123+ yield note .apply_layer_weight (layer , instrument )
111124
112125 def layer_groups (self ) -> Dict [str , pynbs .Layer ]:
113126 """Return a dict containing each unique layer name in this song and a list
0 commit comments