From e5530e1dd1ec03cf9df10a91c5d3d3d7f16ab3e9 Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Sun, 28 Jul 2024 20:40:48 +0930 Subject: [PATCH] [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. --- scripts/MusicRenderer.gd | 33 ++++++++++++++++++++++++--------- shaders/audio_renderer.gdshader | 2 ++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/scripts/MusicRenderer.gd b/scripts/MusicRenderer.gd index 249cbdd..373728f 100644 --- a/scripts/MusicRenderer.gd +++ b/scripts/MusicRenderer.gd @@ -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 diff --git a/shaders/audio_renderer.gdshader b/shaders/audio_renderer.gdshader index 72b09e4..3d7a2c5 100644 --- a/shaders/audio_renderer.gdshader +++ b/shaders/audio_renderer.gdshader @@ -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