[BGM] Rudimentary Pitch Slide

Need to dig deeper on the reset conditions, these are wrong for many songs.
Also slides in general need to have the actual end sample for slides that finish mid-note-event.
This commit is contained in:
Luke Hubmayer-Werner 2024-07-28 20:40:48 +09:30
parent c6c4a39d9c
commit e5530e1dd1
2 changed files with 26 additions and 9 deletions

View File

@ -12,10 +12,12 @@ class NoteEvent:
var p_end: int
var instrument: int
var pitch: int = 0
var pitch_slide: float
var pitch_slide_end: float
var velocity: float = 0.0
var velocity_end: float = 0.0
var pan: int
var pan_end: int
var pan: float
var pan_end: float
var adsr_attack_rate: int
var adsr_decay_rate: int
var adsr_decay_total_periods: int
@ -44,9 +46,13 @@ class TrackCurve: # built-in Curve class is too restrictive for this
self.entries.insert(i, entry)
break
func add_slide(pulse_start: int, duration: int, value: float) -> void:
func add_slide(pulse_start: int, duration: int, value: float, zero_is_256: bool = false) -> void:
if duration == 0:
duration = 256
if zero_is_256:
duration = 256
else:
self.add_point(pulse_start, value)
return
self.add_point(pulse_start, self.get_pulse(pulse_start), true)
self.add_point(pulse_start + duration, value)
@ -158,6 +164,7 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
var curve_pan_lfo_depth := TrackCurve.new()
var curve_noise_on := TrackCurve.new() # [0.0, 1.0] for now
var curve_noise_freq := TrackCurve.new()
var curve_pitch_slide := TrackCurve.new()
var curve_pitchmod_on := TrackCurve.new() # [0.0, 1.0] for now
var curve_echo_on := TrackCurve.new() # [0.0, 1.0] for now
var curve_echo_volume := TrackCurve.new()
@ -226,6 +233,8 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
note_event.instrument = current_instrument
note_event.pan = curve_pan.get_pulse(p)
note_event.pan_end = curve_pan.get_pulse(curve_p_end)
note_event.pitch_slide = curve_pitch_slide.get_pulse(p)
note_event.pitch_slide_end = curve_pitch_slide.get_pulse(curve_p_end)
note_event.adsr_attack_rate = current_adsr_attack_rate
note_event.adsr_decay_rate = current_adsr_decay_rate
note_event.adsr_decay_total_periods = current_adsr_decay_total_periods
@ -237,6 +246,7 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
note_event.pitch = note # pitch_idx #* curve_fine_tuning
note_event.velocity = curve_velocity.get_pulse(p) # current_velocity
note_event.velocity_end = curve_velocity.get_pulse(curve_p_end)
curve_pitch_slide.add_point(p, 0) # Reset pitch slide
elif note == music.NOTE_IS_TIE:
if last_note_pretransform_pitch >= 0:
note = last_note_pretransform_pitch + (12 * current_octave) + current_transpose
@ -244,25 +254,28 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
note_event.pitch = note # pitch_idx #* curve_fine_tuning
note_event.velocity = curve_velocity.get_pulse(p)
note_event.velocity_end = curve_velocity.get_pulse(curve_p_end)
else:
curve_pitch_slide.add_point(p, 0) # Reset pitch slide on rest
channel_note_events.append(note_event)
p += duration
EventType.VOLUME:
var new_velocity: float = event[1]/255.0
curve_velocity.add_point(p, new_velocity, false)
curve_velocity.add_point(p, new_velocity)
EventType.VOLUME_SLIDE:
var slide_duration: int = event[1]
var new_velocity: float = event[2]/255.0
curve_velocity.add_slide(p, slide_duration, new_velocity)
EventType.PAN:
var new_pan = 1.0 - event[1]/127.5
curve_pan.add_point(p, new_pan, false)
curve_pan.add_point(p, new_pan)
EventType.PAN_SLIDE:
var new_pan = 1.0 - event[2]/127.5
var slide_duration: int = event[1]
curve_pan.add_slide(p, slide_duration, new_pan)
EventType.PITCH_SLIDE: # TODO: implement slides
EventType.PITCH_SLIDE:
var slide_duration: int = event[1]
var target_pitch: int = event[2] # Signed
var target_pitch: int = event[2] + curve_pitch_slide.get_pulse(p) # Signed and relative
curve_pitch_slide.add_slide(p, slide_duration, target_pitch)
EventType.OCTAVE:
current_octave = event[1]
EventType.OCTAVE_UP:
@ -282,6 +295,7 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
scale = fine_tune/255.0
curve_fine_tuning.add_point(p, scale)
EventType.PROGCHANGE:
curve_pitch_slide.add_point(p, 0) # Reset pitch slide
current_instrument = event[1]
if current_instrument >= 0x20:
current_instrument = inst_map[current_instrument-0x20] - 1 + SoundLoader.SFX_NUM
@ -450,7 +464,8 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
midi_events_bytes_adsr.put_u8(event.adsr_sustain_rate)
midi_events_bytes4.put_u8(int((event.pan+1.0) * 127.5))
midi_events_bytes4.put_u8(int((event.pan_end+1.0) * 127.5))
midi_events_bytes4.put_u16(0)
midi_events_bytes4.put_u8(int((event.pitch_slide*5))+128)
midi_events_bytes4.put_u8(int((event.pitch_slide_end*5))+128)
event_ptr += 1
num_notes += 1

View File

@ -253,6 +253,8 @@ highp vec4 render_song(highp sampler2D tex, highp int smp) {
highp float pitch_idx = tex2.y * 255.0;
highp float velocity = mix(tex2.z, tex2.w, event_progress);
highp float pan = mix(tex4.x, tex4.y, event_progress);
highp float pitchslide = ((mix(tex4.z, tex4.w, event_progress)*255.0) - 128.0)/5.0;
pitch_idx += pitchslide;
highp ivec4 adsr = ivec4(tex3 * 255.0);
// ====================At some point I'll look back into packing floats====================
// TBD = note_event_supplement.zw; - tremolo/vibrato/noise/pan_lfo/pitchbend/echo remain