[BGM] Fix incorrect SFX data, change tie handling to accomodate weird edge cases
This commit is contained in:
parent
38a822362a
commit
59de8aa820
|
@ -11,12 +11,16 @@ locations_bg_palettes 0x03BB00 /nar/ff5_binx.bin 0x03BF80 43 of 128 of ColorBGR5
|
|||
font_glyphs_dialogue 0x03E800 256 of SNESTritile length 0x1800
|
||||
spc_note_durations 0x041D7E 14 of u8
|
||||
bytelength_sfx_brr_data 0x041E3F u16 Used by the memcpy routine that copies the below data to the SPC (0x010E = 270 bytes = 16 BRR packets = 480 samples)
|
||||
sfx_brr_data 0x041E41 Use the below SPC pointers
|
||||
sfx_brr_data 0x041E41 270 of u8 Use the below SPC pointers
|
||||
bytelength_sfx_brr_pointers 0x041F4F u16 Used by the memcpy routine that copies the below data to the SPC (0x0020 = 32 bytes)
|
||||
sfx_brr_pointers 0x041F51 8 of 2 of u16 SPC memory addresses not ROM. Start address followed by loop address.
|
||||
sfx_adsrs 0x041F71 8 of 4 of u4
|
||||
sfx_samplerates 0x041F83 8 of u16
|
||||
sfx_data 0x041F95 Contains SPC pointers and tracks
|
||||
bytelength_sfx_adsrs 0x041F71 u16 0x0010 = 16 bytes
|
||||
sfx_adsrs 0x041F73 8 of 4 of u4
|
||||
bytelength_sfx_samplerates 0x041F83 u16 0x0010 = 16 bytes
|
||||
sfx_samplerates 0x041F85 8 of u16
|
||||
bytelength_sfx_data 0x041F95 u16 0x1C00 = 7168 bytes
|
||||
sfx_sequence_pointers 0x041F97 256 of 2 of u16 Contains SPC pointers. Subtract 0x3000 to get position within next block. Each SFX sequence has two channels.
|
||||
sfx_sequences 0x042397 6144 of u8 0x1800 = 6144 bytes
|
||||
bgm_song_pointers 0x043B97 72 of u24
|
||||
bgm_instrument_brr_pointers 0x043C6F 35 of u24
|
||||
bgm_instrument_loop_starts 0x043CD8 35 of u16
|
||||
|
@ -27,16 +31,19 @@ bgm_instrument_indices 0x043DAA 72 of 16 of u16 length 0x900
|
|||
worldmap_compressed_tilesets 0x070000 tilesets 0 up to 0x434
|
||||
worldmap_compressed_tilesets2 0x080000 tilesets 0x434 up to 0x500
|
||||
ptrs_jp_speech 0x082220 2160 of u16
|
||||
ptrs_extended_event_data 0x083320 1940 of u24
|
||||
extended_event_data 0x0849DC See above for addresses
|
||||
ptrs_event_scripts 0x083320 1940 of u24
|
||||
event_scripts 0x0849DC See above for addresses
|
||||
jp_speech 0x0A0000 See 0x082220 for offsets
|
||||
ptrs_tilemaps 0x0B0000 328 of u16
|
||||
tilemaps 0x0B0290 See above for offsets
|
||||
|
||||
ptrs_npc_actions 0x0E0000 928 of u16
|
||||
npc_actions 0x0E0740 See above for offsets
|
||||
ptrs_event_places 0x0E2400 512 of u16
|
||||
event_places 0x0E2800 920 of EventPlace See above for offsets
|
||||
map_palette_animation 0x0DFA40 15 of 24 of u8 Need new struct
|
||||
map_palette_animation_colors 0x0DFBA8 44 of ColorBGR555
|
||||
|
||||
ptrs_npc_scripts 0x0E0000 928 of u16
|
||||
npc_scripts 0x0E0740 See above for offsets
|
||||
ptrs_event_triggers 0x0E2400 512 of u16
|
||||
event_triggers 0x0E2800 920 of EventPlace See above for offsets
|
||||
ptrs_zone_exits 0x0E36C0 512 of u16
|
||||
zone_exits 0x0E3AC0 See above for offsets
|
||||
ptrs_npc_data 0x0E59C0 512 of u16
|
||||
|
@ -50,7 +57,7 @@ ptrs_tile_properties 0x0FC540 23 of u16
|
|||
tile_properties 0x0FC56E See above for offsets
|
||||
worldmap_minimap_border_tiles 0x0FD800 32 of TileSNES4bpp length 0x400
|
||||
ptrs_worldmap_tilesets 0x0FE000 5 of 256 of u16 Every offset points to a horizontal line of 256 tiles stored in banks C7 and C8
|
||||
worldmap_block_properties 0x0FEA00 3 of 192 of WorldMapBlockProperties
|
||||
worldmap_block_properties 0x0FEA00 3 of 192 of WorldMapBlockProperties
|
||||
worldmap_blocks 0x0FF0C0 /nar/ff5_binx.bin 0x040300 3 of 4 of 192 of u8 # Top-left corners, top-right corners, bottom-left corners, bottom-right corners
|
||||
worldmap_tiles.bias 0x0FF9C0 /nar/ff5_bin3.bin 0x03FB00 3 of 256 of u8 Add to each pixel of the mode7c tiles
|
||||
worldmap_palettes 0x0FFCC0 /nar/ff5_binx.bin 0x040000 3 of 128 of ColorBGR555
|
||||
|
@ -125,8 +132,9 @@ ptrs_battle_background_tileset_skips 0x184157 21 of u24 RAM addresses, subtrac
|
|||
ptrs_battle_background_tilesets 0x184196 21 of u24 ROM addresses, subtract 0xC00000
|
||||
lzss_battle_background_tilesets 0x1841D5 see pointers above, 4bpp
|
||||
? 0x18DE36
|
||||
ptrs_event_data 0x18E080 687 of u16
|
||||
event_data 0x18E5E0 see above, links to extended event data
|
||||
initial_npc_flags 0x18E000 128 of u8
|
||||
ptrs_trigger_scripts 0x18E080 704 of u16 offset from this same address
|
||||
trigger_scripts 0x18E600 see above, links to event scripts too
|
||||
tiles_attack_anims 0x190000
|
||||
ptrs_anim_unk1 0x19A486 405 of u16 bank offsets to below
|
||||
0x19A7B0 padding
|
||||
|
@ -139,4 +147,11 @@ worldmap_tiles.1 0x1BA000 /nar/ff5_bin3.bin 0x039B00 256 of TileSNESMode7c Add t
|
|||
worldmap_tiles.2 0x1BC000 /nar/ff5_bin3.bin 0x039B00 128 of TileSNESMode7c Add the biases
|
||||
font_glyphs_kanji 0x1BD000 426 of SNESTritile length of 0x27F0
|
||||
? 0x1BF800
|
||||
ptrs_map_bg3_graphics 0x1C0000 18 of u16 From start of region (0x1C0024)
|
||||
map_bg3_graphics 0x1C0024 2bpp
|
||||
ptrs_map_graphics 0x1C2D84 40 of u32 From start of region (0x1C2E24)
|
||||
map_graphics 0x1C2E24 4bpp
|
||||
map_animation_graphics 0x1F9B00
|
||||
map_palettes 0x1FFC00 32 of 16 of ColorBGR555
|
||||
|
||||
RPGe_font_character_widths 0x203225 512 of u8 RPGe only, Includes the 1px spacing
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 53.
|
|
@ -6,7 +6,8 @@ var MUSIC := music.new()
|
|||
const NUM_TRACKS := 8 # TODO
|
||||
const MAX_NOTE_EVENTS := 2048
|
||||
class NoteEvent:
|
||||
var p_start: int # In pulse space
|
||||
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
|
||||
var p_end: int
|
||||
var instrument: int
|
||||
var pitch: int
|
||||
|
@ -94,13 +95,13 @@ class TrackCurve: # built-in Curve class is too restrictive for this
|
|||
return 0.0
|
||||
|
||||
|
||||
static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none') -> Array: # [data: PoolByteArray, target_time_length: float in seconds]
|
||||
static func render_channels(tracks: Array, inst_map: Array, _debug_name := 'none') -> Array: # [data: PoolByteArray, target_time_length: float in seconds]
|
||||
# Since some channels contain global events (tempo and global volume for now),
|
||||
# the strategy will be to preprocess each channel in a global-state-agnostic way,
|
||||
# then once all the global tracks are known, as well as the longest unlooped length,
|
||||
# do a second pass to generate the final events
|
||||
# self.print_channel_events(inst_map)
|
||||
var instrument_adsrs = RomLoader.snes_data.bgm_instrument_adsrs # TODO: UNHARDCODE THIS
|
||||
var sample_default_adsrs = RomLoader.snes_data.sfx_adsrs + RomLoader.snes_data.bgm_instrument_adsrs # TODO: UNHARDCODE THIS
|
||||
var all_note_events = []
|
||||
|
||||
var curve_master_volume := TrackCurve.new(100.0/255.0) # [0.0, 1.0] for now
|
||||
|
@ -157,6 +158,8 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
|||
infinite_loop_target_program_counter = track[-1][1]
|
||||
|
||||
var program_counter := 0
|
||||
var last_note_pretransform_pitch := -2
|
||||
var last_untied_note_p_start := 0
|
||||
while true: #num_notes < MAX_NOTE_EVENTS:
|
||||
if program_counter >= l:
|
||||
break
|
||||
|
@ -167,8 +170,8 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
|||
match event[0]: # Control codes
|
||||
EventType.GOTO: # This is a preprocessed event list, so GOTO is a final infinite loop marker
|
||||
var note_event = NoteEvent.new()
|
||||
note_event.p_start = p
|
||||
note_event.p_end = infinite_loop_target_pulse # Fake final note event using p_start > p_end to encode the infinite jump back loop.
|
||||
note_event.p_event_start = p
|
||||
note_event.p_end = infinite_loop_target_pulse # Fake final note event using p_event_start > p_end to encode the infinite jump back loop.
|
||||
# Note that event[1] points to an Event, not a NoteEvent, not a Pulse, so we looked it up earlier
|
||||
channel_note_events.append(note_event)
|
||||
break
|
||||
|
@ -187,9 +190,12 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
|||
var note = event[1]
|
||||
var duration = event[2]
|
||||
if note >= 0: # Don't shift or play rests
|
||||
last_note_pretransform_pitch = note # Ties reuse this
|
||||
last_untied_note_p_start = p
|
||||
note += (12 * current_octave) + current_transpose
|
||||
var note_event = NoteEvent.new()
|
||||
note_event.p_start = p
|
||||
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.pitch = note # pitch_idx #* curve_fine_tuning
|
||||
|
@ -201,12 +207,20 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
|||
channel_note_events.append(note_event)
|
||||
# num_notes += 1
|
||||
elif note == music.NOTE_IS_TIE:
|
||||
if not channel_note_events:
|
||||
print('Encountered a tie with no preceeding note! %s channel %d pulse %d (loop return is %d)' % [debug_name, channel, p, infinite_loop_target_pulse])
|
||||
else:
|
||||
if channel_note_events[-1].p_end != p:
|
||||
print('Encountered a tie with preceeding rest! %s channel %d pulse %d (loop return is %d)' % [debug_name, channel, p, infinite_loop_target_pulse])
|
||||
channel_note_events[-1].p_end += duration
|
||||
if last_note_pretransform_pitch >= 0:
|
||||
note = last_note_pretransform_pitch + (12 * current_octave) + current_transpose
|
||||
var note_event = NoteEvent.new()
|
||||
note_event.p_event_start = p
|
||||
note_event.p_note_start = last_untied_note_p_start
|
||||
note_event.p_end = p + duration
|
||||
note_event.instrument = current_instrument
|
||||
note_event.pitch = note # pitch_idx #* curve_fine_tuning
|
||||
note_event.velocity = curve_velocity.get_pulse(p) # current_velocity
|
||||
note_event.adsr_attack_rate = current_adsr_attack_rate
|
||||
note_event.adsr_decay_rate = current_adsr_decay_rate
|
||||
note_event.adsr_sustain_level = current_adsr_sustain_level
|
||||
note_event.adsr_sustain_rate = current_adsr_sustain_rate
|
||||
channel_note_events.append(note_event)
|
||||
p += duration
|
||||
EventType.VOLUME:
|
||||
var new_velocity: float = event[1]/255.0
|
||||
|
@ -248,18 +262,18 @@ 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:
|
||||
var event_idx = event[1]-0x20
|
||||
if event_idx >= 0:
|
||||
current_instrument = inst_map[event_idx] - 1
|
||||
if current_instrument < len(instrument_adsrs) and current_instrument > 0:
|
||||
var adsr = instrument_adsrs[current_instrument]
|
||||
current_adsr_attack_rate = adsr[0]
|
||||
current_adsr_decay_rate = adsr[1]
|
||||
current_adsr_sustain_level = adsr[2]
|
||||
current_adsr_sustain_rate = adsr[3]
|
||||
current_instrument = event[1]
|
||||
if current_instrument >= 0x20:
|
||||
current_instrument = inst_map[current_instrument-0x20] - 1 + SoundLoader.SFX_NUM
|
||||
if current_instrument < len(sample_default_adsrs) and current_instrument > 0:
|
||||
var adsr = sample_default_adsrs[current_instrument]
|
||||
current_adsr_attack_rate = adsr[0]
|
||||
current_adsr_decay_rate = adsr[1]
|
||||
current_adsr_sustain_level = adsr[2]
|
||||
current_adsr_sustain_rate = adsr[3]
|
||||
EventType.ADSR_DEFAULT: # TODO - Investigate actual scaling and order
|
||||
if current_instrument < len(instrument_adsrs) and current_instrument > 0:
|
||||
var adsr = instrument_adsrs[current_instrument]
|
||||
if current_instrument < len(sample_default_adsrs) and current_instrument > 0:
|
||||
var adsr = sample_default_adsrs[current_instrument]
|
||||
current_adsr_attack_rate = adsr[0]
|
||||
current_adsr_decay_rate = adsr[1]
|
||||
current_adsr_sustain_level = adsr[2]
|
||||
|
@ -339,13 +353,13 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
|||
continue
|
||||
var note_event: NoteEvent = all_note_events[channel][-1]
|
||||
var p_end = note_event.p_end
|
||||
if p_end < note_event.p_start:
|
||||
if p_end < note_event.p_event_start:
|
||||
# Ends on infinite loop
|
||||
channel_loop_p_returns.append(p_end)
|
||||
channel_loop_p_lengths.append(note_event.p_start - p_end)
|
||||
channel_loop_p_lengths.append(note_event.p_event_start - p_end)
|
||||
if p_end > highest_channel_p_return:
|
||||
highest_channel_p_return = p_end
|
||||
p_end = note_event.p_start
|
||||
p_end = note_event.p_event_start
|
||||
else:
|
||||
channel_loop_p_returns.append(-1)
|
||||
channel_loop_p_lengths.append(0)
|
||||
|
@ -365,7 +379,8 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
|||
var loop_return_p = channel_loop_p_returns[channel]
|
||||
var curve_pan: TrackCurve = curve_channel_pans[channel]
|
||||
|
||||
var midi_events_bytes_t_start := StreamPeerBuffer.new()
|
||||
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_bytes3 := StreamPeerBuffer.new()
|
||||
var midi_events_bytes_adsr := StreamPeerBuffer.new()
|
||||
|
@ -381,10 +396,11 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
|||
event_ptr = loop_return_note_event_idx
|
||||
loop_p_offset += channel_loop_p_lengths[channel]
|
||||
var event: NoteEvent = events[event_ptr]
|
||||
var p = event.p_start
|
||||
var p = event.p_event_start
|
||||
if loop_return_note_event_idx < 0 and p >= loop_return_p:
|
||||
loop_return_note_event_idx = event_ptr
|
||||
midi_events_bytes_t_start.put_32(int(curve_master_tempo.get_integral(p + loop_p_offset) * 32000))
|
||||
midi_events_bytes_t_event_start.put_32(int(curve_master_tempo.get_integral(p + loop_p_offset) * 32000))
|
||||
midi_events_bytes_t_note_start.put_32(int(curve_master_tempo.get_integral(event.p_note_start + loop_p_offset) * 32000))
|
||||
midi_events_bytes_t_end.put_32(int(curve_master_tempo.get_integral(event.p_end + loop_p_offset) * 32000)) # t_end
|
||||
midi_events_bytes3.put_u8(event.instrument)
|
||||
midi_events_bytes3.put_u8(event.pitch)
|
||||
|
@ -399,11 +415,12 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
|||
num_notes += 1
|
||||
# Fill up end of notes array with dummies
|
||||
for i in range(num_notes, MAX_NOTE_EVENTS):
|
||||
midi_events_bytes_t_start.put_32(0x0FFFFFFF)
|
||||
midi_events_bytes_t_event_start.put_32(0x0FFFFFFF)
|
||||
midi_events_bytes_t_note_start.put_32(0x0FFFFFFF)
|
||||
midi_events_bytes_t_end.put_32(0x0FFFFFFF)
|
||||
midi_events_bytes3.put_32(0)
|
||||
midi_events_bytes_adsr.put_32(0)
|
||||
data += midi_events_bytes_t_start.data_array + midi_events_bytes_t_end.data_array + midi_events_bytes3.data_array + midi_events_bytes_adsr.data_array
|
||||
data += midi_events_bytes_t_event_start.data_array + midi_events_bytes_t_end.data_array + midi_events_bytes3.data_array + midi_events_bytes_adsr.data_array + midi_events_bytes_t_note_start.data_array
|
||||
var smp_loop_start = -1
|
||||
var smp_loop_end = -1
|
||||
if highest_channel_p_return > 0:
|
||||
|
@ -431,11 +448,11 @@ static func disassemble_channel_events(channel_events: Array, inst_map: Array) -
|
|||
output.append(print_str + print_str2)
|
||||
p += duration
|
||||
EventType.PROGCHANGE:
|
||||
var event_idx = event[1]-0x20
|
||||
if event_idx >= 0:
|
||||
output.append(print_str + 'instrument %02d'%(inst_map[event_idx] - 1))
|
||||
var event_idx = event[1]
|
||||
if event_idx >= 0x20:
|
||||
output.append(print_str + '($%02x) = instrument %02d'%[event_idx, inst_map[event_idx-0x20] - 1])
|
||||
else:
|
||||
output.append(print_str + print_str2)
|
||||
output.append(print_str + 'sfx %d'%event_idx)
|
||||
_:
|
||||
output.append(print_str + print_str2)
|
||||
return output
|
||||
|
|
|
@ -148,7 +148,7 @@ func load_sfx_samples_data(snes_data: Dictionary, buffer: StreamPeerBuffer):
|
|||
for two_of_u16 in snes_data.sfx_brr_pointers:
|
||||
brr_spc_addrs.append(two_of_u16[0])
|
||||
brr_spc_loop_addrs.append(two_of_u16[1])
|
||||
var brr_spc_start = Common.SNES_PSX_addresses.sfx_brr_data.SNES - brr_spc_addrs[0] # Refactor this later
|
||||
var brr_spc_start = Common.SNES_PSX_addresses.sfx_brr_data.SNES - brr_spc_addrs[0] # Refactor this later - SFX samples start at $4800 in ARAM, right after the SFX tracks
|
||||
for i in SFX_NUM:
|
||||
buffer.seek(brr_spc_addrs[i] + brr_spc_start)
|
||||
# print('Loading sfx sample #%X with BRR data offset $%06X' % [i, buffer.get_position()])
|
||||
|
@ -156,7 +156,7 @@ func load_sfx_samples_data(snes_data: Dictionary, buffer: StreamPeerBuffer):
|
|||
var audio := make_sample(buffer, 900, sample_rate)
|
||||
var loop_start_packet: int = brr_spc_loop_addrs[i] - brr_spc_addrs[i]
|
||||
audio.loop_mode = AudioStreamSample.LOOP_FORWARD
|
||||
audio.loop_begin = loop_start_packet * 16 # Each 9byte packet is 16 samples
|
||||
audio.loop_begin = (loop_start_packet/9) * 16 # Each 9byte packet is 16 samples
|
||||
audio.loop_end = (len(audio.data)/2)
|
||||
sfx_samples.append(audio) # Use 900 as a limit, it won't be hit, parser stops after End packet anyway
|
||||
emit_signal('audio_sfx_sample_loaded', i)
|
||||
|
@ -186,14 +186,14 @@ var samples_tex: ImageTexture
|
|||
const TEX_WIDTH := 2048
|
||||
const FILTER_PAD := 32
|
||||
func samples_to_texture():
|
||||
var num_samples := INST_NUM + SFX_NUM
|
||||
var num_samples := SFX_NUM + INST_NUM
|
||||
var header_length := num_samples * 5
|
||||
|
||||
# Create header and unwrapped payload separately first
|
||||
var header_buffer := StreamPeerBuffer.new()
|
||||
var payload_buffer := StreamPeerBuffer.new()
|
||||
|
||||
for sample in instrument_samples + sfx_samples:
|
||||
for sample in sfx_samples + instrument_samples:
|
||||
var sample_data_start: int = header_length + (payload_buffer.get_position()/2) + FILTER_PAD # After the prepended silence, in texels (2bytes)
|
||||
var loop_begin: int = sample.loop_begin
|
||||
var loop_length: int = sample.loop_end - loop_begin
|
||||
|
|
|
@ -118,11 +118,10 @@ class StructArrayType extends StructType:
|
|||
func get_value(buffer: StreamPeer, leftover_bits: Array):
|
||||
# Might be a bit too much branching but oh well
|
||||
if self.contained_struct_type is U8:
|
||||
var result = PoolByteArray()
|
||||
# Slight optimization over calling the method
|
||||
for i in self.count:
|
||||
result.append(buffer.get_u8())
|
||||
return result
|
||||
var result = buffer.get_data(self.count)
|
||||
# result[0] is an error code
|
||||
return result[1]
|
||||
|
||||
var result = []
|
||||
for i in self.count:
|
||||
|
|
|
@ -172,7 +172,7 @@ highp float get_instrument_sample(highp float instrument_index, highp float note
|
|||
}
|
||||
|
||||
// const int ATTACK_TIME_MS[16] = {4100, 2600, 1500, 1000, 640, 380, 260, 160, 96, 64, 40, 24, 16, 10, 6, 0};
|
||||
const int ATTACK_TIME_SMPS[16] = {131200, 83200, 48000, 32000, 20480, 12160, 8320, 5120, 3072, 2048, 1280, 768, 512, 320, 192, 1};
|
||||
const int ATTACK_TIME_SMPS[16] = {131200, 83200, 48000, 32000, 20480, 12160, 8320, 5120, 3072, 2048, 1280, 768, 512, 320, 192, 0};
|
||||
// const int DECAY_TIME_MS[8] = {1200, 740, 440, 290, 180, 110, 74, 37};
|
||||
const int DECAY_TIME_SMPS[8] = {38400, 23680, 14080, 9280, 5760, 3520, 2368, 1184};
|
||||
// const int SUSTAIN_DECAY_TIME_MS[32] = {Infinite, 38000, 28000, 24000, 19000, 14000, 12000, 9400, 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500, 1200, 880, 740, 590, 440, 370, 290, 220, 180, 150, 110, 92, 74, 55, 37, 18};
|
||||
|
@ -202,7 +202,7 @@ highp vec4 render_song(highp sampler2D tex, highp int smp) {
|
|||
|
||||
// Binary search the channels
|
||||
for (int channel = 0; channel < NUM_CHANNELS; channel++) {
|
||||
highp float row = float(channel * 4);
|
||||
highp float row = float(channel * 5);
|
||||
highp float event_idx = 0.0;
|
||||
highp int smp_start;
|
||||
for (int i = 0; i < NUM_CHANNEL_NOTE_PROBES; i++) {
|
||||
|
@ -212,6 +212,7 @@ highp vec4 render_song(highp sampler2D tex, highp int smp) {
|
|||
}
|
||||
smp_start = retime_smp(int(unpack_int32(get_midi_texel(tex, event_idx, row))));
|
||||
highp int smp_end = retime_smp(int(unpack_int32(get_midi_texel(tex, event_idx, row+1.0))));
|
||||
highp int smp_note_start = retime_smp(int(unpack_int32(get_midi_texel(tex, event_idx, row+4.0))));
|
||||
|
||||
highp vec4 note_event_supplement = get_midi_texel(tex, event_idx, row+2.0); // left as [0.0, 1.0]
|
||||
highp float instrument_idx = trunc(note_event_supplement.x * 255.0);
|
||||
|
@ -228,12 +229,12 @@ highp vec4 render_song(highp sampler2D tex, highp int smp) {
|
|||
highp int smp_decay = DECAY_TIME_SMPS[adsr.y];
|
||||
|
||||
// For now, just branch this
|
||||
if (smp_start < smp) { // First sample may not start at zero!
|
||||
if (smp_note_start < smp) { // First sample may not start at zero!
|
||||
highp int smp_overrun = smp - smp_end; // 256 samples of linear decay to 0 after note_off
|
||||
smp_overrun = (smp_overrun < 0) ? 0 : smp_overrun;
|
||||
if (smp_overrun < 256) {
|
||||
highp int smp_progress = smp - smp_start;
|
||||
highp float t_start = float(smp_start)/output_mixrate;
|
||||
highp int smp_progress = smp - smp_note_start;
|
||||
highp float t_start = float(smp_note_start)/output_mixrate;
|
||||
highp float attack_factor = clamp(float(smp_progress)/float(smp_attack), 0.0, 1.0);
|
||||
highp float decay_factor = mix(1.0, sustain_level, clamp(float(smp_progress - smp_attack)/float(smp_decay), 0.0, 1.0));
|
||||
highp float sustain_decay_factor = 1.0;
|
||||
|
|
|
@ -161,7 +161,7 @@ func push_image(image: Image, target_samples: int, key: String, enqueue: bool =
|
|||
|
||||
func push_bytes(data: PoolByteArray, target_samples: int, key: String, enqueue: bool = true) -> void:
|
||||
var rows = int(pow(2, ceil(log((len(data)/INPUT_BYTES_PER_TEXEL) / INPUT_TEX_WIDTH)/log(2))))
|
||||
var target_length = rows * INPUT_BYTES_PER_TEXEL * INPUT_FORMAT
|
||||
var target_length = rows * INPUT_BYTES_PER_TEXEL * INPUT_TEX_WIDTH
|
||||
while len(data) < target_length: # This is inefficient, but this function should be called with pre-padded data anyway
|
||||
data.append(0)
|
||||
var image := Image.new()
|
||||
|
|
Loading…
Reference in New Issue