[BGM] Render volume and pan slides
This commit is contained in:
parent
5fed1672c9
commit
c6c4a39d9c
|
@ -5,6 +5,7 @@ const EventType := music.EventType
|
|||
var MUSIC := music.new()
|
||||
const NUM_TRACKS := 8 # TODO
|
||||
const MAX_NOTE_EVENTS := 4096
|
||||
const CURVE_EPSILON := 0.0000001
|
||||
class NoteEvent:
|
||||
var p_event_start: int # In pulse space
|
||||
var p_note_start: int # For tied notes, this will be earlier than p_event_start and is used for envelope calculations
|
||||
|
@ -12,6 +13,9 @@ class NoteEvent:
|
|||
var instrument: int
|
||||
var pitch: int = 0
|
||||
var velocity: float = 0.0
|
||||
var velocity_end: float = 0.0
|
||||
var pan: int
|
||||
var pan_end: int
|
||||
var adsr_attack_rate: int
|
||||
var adsr_decay_rate: int
|
||||
var adsr_decay_total_periods: int
|
||||
|
@ -215,10 +219,13 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
|
|||
var note = event[1]
|
||||
var duration = event[2]
|
||||
var note_event = NoteEvent.new()
|
||||
var curve_p_end: float = p + duration - CURVE_EPSILON
|
||||
note_event.p_event_start = p
|
||||
note_event.p_note_start = p
|
||||
note_event.p_end = p + duration
|
||||
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.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
|
||||
|
@ -229,27 +236,29 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
|
|||
note += (12 * current_octave) + current_transpose
|
||||
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)
|
||||
elif note == music.NOTE_IS_TIE:
|
||||
if last_note_pretransform_pitch >= 0:
|
||||
note = last_note_pretransform_pitch + (12 * current_octave) + current_transpose
|
||||
note_event.p_note_start = last_untied_note_p_start
|
||||
note_event.pitch = note # pitch_idx #* curve_fine_tuning
|
||||
note_event.velocity = curve_velocity.get_pulse(p) # current_velocity
|
||||
note_event.velocity = curve_velocity.get_pulse(p)
|
||||
note_event.velocity_end = curve_velocity.get_pulse(curve_p_end)
|
||||
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)
|
||||
EventType.VOLUME_SLIDE: # TODO: implement slides
|
||||
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)
|
||||
EventType.PAN_SLIDE: # TODO: implement slides
|
||||
EventType.PAN_SLIDE:
|
||||
var new_pan = 1.0 - event[2]/127.5
|
||||
var slide_duration: int = event[1] # TODO: work out how slides are scaled
|
||||
var slide_duration: int = event[1]
|
||||
curve_pan.add_slide(p, slide_duration, new_pan)
|
||||
EventType.PITCH_SLIDE: # TODO: implement slides
|
||||
var slide_duration: int = event[1]
|
||||
|
@ -334,7 +343,7 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
|
|||
EventType.ECHO_VOLUME:
|
||||
curve_echo_volume.add_point(p, event[1])
|
||||
EventType.ECHO_VOLUME_SLIDE:
|
||||
var slide_duration: int = event[1] # TODO: work out how slides are scaled
|
||||
var slide_duration: int = event[1]
|
||||
var new_echo_volume = event[2]
|
||||
curve_echo_volume.add_slide(p, slide_duration, new_echo_volume)
|
||||
EventType.ECHO_FEEDBACK_FIR: # TODO
|
||||
|
@ -410,10 +419,9 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
|
|||
|
||||
var midi_events_bytes_t_event_start := StreamPeerBuffer.new()
|
||||
var midi_events_bytes_t_note_start := StreamPeerBuffer.new()
|
||||
# var midi_events_bytes_t_end := StreamPeerBuffer.new()
|
||||
var midi_events_bytes2 := StreamPeerBuffer.new()
|
||||
var midi_events_bytes_adsr := StreamPeerBuffer.new()
|
||||
var midi_events_bytes_adsr2 := StreamPeerBuffer.new()
|
||||
var midi_events_bytes4 := StreamPeerBuffer.new()
|
||||
|
||||
var num_notes: int = 0
|
||||
var event_ptr := 0
|
||||
|
@ -434,13 +442,15 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
|
|||
# midi_events_bytes_t_end.put_32(int(curve_master_tempo.get_integral(event.p_end + loop_p_offset) * 32000)) # t_end
|
||||
midi_events_bytes2.put_u8(event.instrument)
|
||||
midi_events_bytes2.put_u8(event.pitch)
|
||||
midi_events_bytes2.put_u8(int(event.velocity * curve_master_volume.get_pulse(p) * 255.0)) # velocity
|
||||
midi_events_bytes2.put_u8(int((curve_pan.get_pulse(p)+1.0) * 127.5)) # pan
|
||||
midi_events_bytes2.put_u8(int(event.velocity * curve_master_volume.get_pulse(p) * 255.0))
|
||||
midi_events_bytes2.put_u8(int(event.velocity_end * curve_master_volume.get_pulse(p) * 255.0))
|
||||
midi_events_bytes_adsr.put_u8(event.adsr_attack_rate)
|
||||
midi_events_bytes_adsr.put_u8(event.adsr_decay_rate)
|
||||
midi_events_bytes_adsr.put_u8(event.adsr_decay_total_periods)
|
||||
midi_events_bytes_adsr.put_u8(event.adsr_sustain_rate)
|
||||
midi_events_bytes_adsr2.put_32(0)
|
||||
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)
|
||||
|
||||
event_ptr += 1
|
||||
num_notes += 1
|
||||
|
@ -454,9 +464,9 @@ static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none
|
|||
# midi_events_bytes_t_end.put_32(0x0FFFFFFF)
|
||||
midi_events_bytes2.put_32(0)
|
||||
midi_events_bytes_adsr.put_32(0)
|
||||
midi_events_bytes_adsr2.put_32(0)
|
||||
midi_events_bytes4.put_32(0)
|
||||
# data += midi_events_bytes_t_event_start.data_array + midi_events_bytes_t_end.data_array + midi_events_bytes2.data_array + midi_events_bytes_adsr.data_array + midi_events_bytes_t_note_start.data_array
|
||||
data += midi_events_bytes_t_event_start.data_array + midi_events_bytes_t_note_start.data_array + midi_events_bytes2.data_array + midi_events_bytes_adsr.data_array + midi_events_bytes_adsr2.data_array
|
||||
data += midi_events_bytes_t_event_start.data_array + midi_events_bytes_t_note_start.data_array + midi_events_bytes2.data_array + midi_events_bytes_adsr.data_array + midi_events_bytes4.data_array
|
||||
var t_loop_endpoints := Vector2(-1, -1)
|
||||
if highest_channel_p_return >= 0:
|
||||
t_loop_endpoints = Vector2(curve_master_tempo.get_integral(highest_channel_p_return + 100), curve_master_tempo.get_integral(longest_channel_p_end + 100))
|
||||
|
|
|
@ -237,19 +237,22 @@ highp vec4 render_song(highp sampler2D tex, highp int smp) {
|
|||
highp vec4 tex2 = get_midi_texel(tex, event_idx, row+2.0);
|
||||
highp vec4 tex3 = get_midi_texel(tex, event_idx, row+3.0);
|
||||
highp vec4 tex4 = get_midi_texel(tex, event_idx, row+4.0);
|
||||
highp vec4 next_tex0 = get_midi_texel(tex, event_idx+1.0, row);
|
||||
highp vec4 next_tex1 = get_midi_texel(tex, event_idx+1.0, row+1.0);
|
||||
smp_event_start = retime_smp(unpack_int32(tex0));
|
||||
highp int smp_note_start = retime_smp(unpack_int32(tex1));
|
||||
highp int next_smp_event_start = retime_smp(unpack_int32(next_tex0));
|
||||
highp int next_smp_note_start = retime_smp(unpack_int32(next_tex1));
|
||||
|
||||
// For now, just branch this
|
||||
if (smp_note_start < smp) { // First sample may not start at zero!
|
||||
highp int smp_release_overrun = (smp_note_start == next_smp_note_start) ? 0 : max(smp - next_smp_note_start + 256, 0); // 256 samples of linear decay to 0 before next non-tie event
|
||||
if (smp_release_overrun < 256) {
|
||||
highp float event_progress = float(smp - smp_event_start)/float(next_smp_event_start - smp_event_start);
|
||||
highp float instrument_idx = trunc(tex2.x * 255.0);
|
||||
highp float pitch_idx = tex2.y * 255.0;
|
||||
highp float velocity = tex2.z;
|
||||
highp float pan = tex2.w;
|
||||
highp float velocity = mix(tex2.z, tex2.w, event_progress);
|
||||
highp float pan = mix(tex4.x, tex4.y, event_progress);
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue