[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
|
font_glyphs_dialogue 0x03E800 256 of SNESTritile length 0x1800
|
||||||
spc_note_durations 0x041D7E 14 of u8
|
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)
|
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)
|
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_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
|
bytelength_sfx_adsrs 0x041F71 u16 0x0010 = 16 bytes
|
||||||
sfx_samplerates 0x041F83 8 of u16
|
sfx_adsrs 0x041F73 8 of 4 of u4
|
||||||
sfx_data 0x041F95 Contains SPC pointers and tracks
|
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_song_pointers 0x043B97 72 of u24
|
||||||
bgm_instrument_brr_pointers 0x043C6F 35 of u24
|
bgm_instrument_brr_pointers 0x043C6F 35 of u24
|
||||||
bgm_instrument_loop_starts 0x043CD8 35 of u16
|
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_tilesets 0x070000 tilesets 0 up to 0x434
|
||||||
worldmap_compressed_tilesets2 0x080000 tilesets 0x434 up to 0x500
|
worldmap_compressed_tilesets2 0x080000 tilesets 0x434 up to 0x500
|
||||||
ptrs_jp_speech 0x082220 2160 of u16
|
ptrs_jp_speech 0x082220 2160 of u16
|
||||||
ptrs_extended_event_data 0x083320 1940 of u24
|
ptrs_event_scripts 0x083320 1940 of u24
|
||||||
extended_event_data 0x0849DC See above for addresses
|
event_scripts 0x0849DC See above for addresses
|
||||||
jp_speech 0x0A0000 See 0x082220 for offsets
|
jp_speech 0x0A0000 See 0x082220 for offsets
|
||||||
ptrs_tilemaps 0x0B0000 328 of u16
|
ptrs_tilemaps 0x0B0000 328 of u16
|
||||||
tilemaps 0x0B0290 See above for offsets
|
tilemaps 0x0B0290 See above for offsets
|
||||||
|
|
||||||
ptrs_npc_actions 0x0E0000 928 of u16
|
map_palette_animation 0x0DFA40 15 of 24 of u8 Need new struct
|
||||||
npc_actions 0x0E0740 See above for offsets
|
map_palette_animation_colors 0x0DFBA8 44 of ColorBGR555
|
||||||
ptrs_event_places 0x0E2400 512 of u16
|
|
||||||
event_places 0x0E2800 920 of EventPlace See above for offsets
|
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
|
ptrs_zone_exits 0x0E36C0 512 of u16
|
||||||
zone_exits 0x0E3AC0 See above for offsets
|
zone_exits 0x0E3AC0 See above for offsets
|
||||||
ptrs_npc_data 0x0E59C0 512 of u16
|
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
|
tile_properties 0x0FC56E See above for offsets
|
||||||
worldmap_minimap_border_tiles 0x0FD800 32 of TileSNES4bpp length 0x400
|
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
|
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_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_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
|
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
|
ptrs_battle_background_tilesets 0x184196 21 of u24 ROM addresses, subtract 0xC00000
|
||||||
lzss_battle_background_tilesets 0x1841D5 see pointers above, 4bpp
|
lzss_battle_background_tilesets 0x1841D5 see pointers above, 4bpp
|
||||||
? 0x18DE36
|
? 0x18DE36
|
||||||
ptrs_event_data 0x18E080 687 of u16
|
initial_npc_flags 0x18E000 128 of u8
|
||||||
event_data 0x18E5E0 see above, links to extended event data
|
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
|
tiles_attack_anims 0x190000
|
||||||
ptrs_anim_unk1 0x19A486 405 of u16 bank offsets to below
|
ptrs_anim_unk1 0x19A486 405 of u16 bank offsets to below
|
||||||
0x19A7B0 padding
|
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
|
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
|
font_glyphs_kanji 0x1BD000 426 of SNESTritile length of 0x27F0
|
||||||
? 0x1BF800
|
? 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
|
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 NUM_TRACKS := 8 # TODO
|
||||||
const MAX_NOTE_EVENTS := 2048
|
const MAX_NOTE_EVENTS := 2048
|
||||||
class NoteEvent:
|
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 p_end: int
|
||||||
var instrument: int
|
var instrument: int
|
||||||
var pitch: int
|
var pitch: int
|
||||||
|
@ -94,13 +95,13 @@ class TrackCurve: # built-in Curve class is too restrictive for this
|
||||||
return 0.0
|
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),
|
# 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,
|
# 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,
|
# then once all the global tracks are known, as well as the longest unlooped length,
|
||||||
# do a second pass to generate the final events
|
# do a second pass to generate the final events
|
||||||
# self.print_channel_events(inst_map)
|
# 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 all_note_events = []
|
||||||
|
|
||||||
var curve_master_volume := TrackCurve.new(100.0/255.0) # [0.0, 1.0] for now
|
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]
|
infinite_loop_target_program_counter = track[-1][1]
|
||||||
|
|
||||||
var program_counter := 0
|
var program_counter := 0
|
||||||
|
var last_note_pretransform_pitch := -2
|
||||||
|
var last_untied_note_p_start := 0
|
||||||
while true: #num_notes < MAX_NOTE_EVENTS:
|
while true: #num_notes < MAX_NOTE_EVENTS:
|
||||||
if program_counter >= l:
|
if program_counter >= l:
|
||||||
break
|
break
|
||||||
|
@ -167,8 +170,8 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
||||||
match event[0]: # Control codes
|
match event[0]: # Control codes
|
||||||
EventType.GOTO: # This is a preprocessed event list, so GOTO is a final infinite loop marker
|
EventType.GOTO: # This is a preprocessed event list, so GOTO is a final infinite loop marker
|
||||||
var note_event = NoteEvent.new()
|
var note_event = NoteEvent.new()
|
||||||
note_event.p_start = p
|
note_event.p_event_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_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
|
# 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)
|
channel_note_events.append(note_event)
|
||||||
break
|
break
|
||||||
|
@ -187,9 +190,12 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
||||||
var note = event[1]
|
var note = event[1]
|
||||||
var duration = event[2]
|
var duration = event[2]
|
||||||
if note >= 0: # Don't shift or play rests
|
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
|
note += (12 * current_octave) + current_transpose
|
||||||
var note_event = NoteEvent.new()
|
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.p_end = p + duration
|
||||||
note_event.instrument = current_instrument
|
note_event.instrument = current_instrument
|
||||||
note_event.pitch = note # pitch_idx #* curve_fine_tuning
|
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)
|
channel_note_events.append(note_event)
|
||||||
# num_notes += 1
|
# num_notes += 1
|
||||||
elif note == music.NOTE_IS_TIE:
|
elif note == music.NOTE_IS_TIE:
|
||||||
if not channel_note_events:
|
if last_note_pretransform_pitch >= 0:
|
||||||
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])
|
note = last_note_pretransform_pitch + (12 * current_octave) + current_transpose
|
||||||
else:
|
var note_event = NoteEvent.new()
|
||||||
if channel_note_events[-1].p_end != p:
|
note_event.p_event_start = 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])
|
note_event.p_note_start = last_untied_note_p_start
|
||||||
channel_note_events[-1].p_end += duration
|
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
|
p += duration
|
||||||
EventType.VOLUME:
|
EventType.VOLUME:
|
||||||
var new_velocity: float = event[1]/255.0
|
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
|
scale = fine_tune/255.0
|
||||||
curve_fine_tuning.add_point(p, scale)
|
curve_fine_tuning.add_point(p, scale)
|
||||||
EventType.PROGCHANGE:
|
EventType.PROGCHANGE:
|
||||||
var event_idx = event[1]-0x20
|
current_instrument = event[1]
|
||||||
if event_idx >= 0:
|
if current_instrument >= 0x20:
|
||||||
current_instrument = inst_map[event_idx] - 1
|
current_instrument = inst_map[current_instrument-0x20] - 1 + SoundLoader.SFX_NUM
|
||||||
if current_instrument < len(instrument_adsrs) and current_instrument > 0:
|
if current_instrument < len(sample_default_adsrs) and current_instrument > 0:
|
||||||
var adsr = instrument_adsrs[current_instrument]
|
var adsr = sample_default_adsrs[current_instrument]
|
||||||
current_adsr_attack_rate = adsr[0]
|
current_adsr_attack_rate = adsr[0]
|
||||||
current_adsr_decay_rate = adsr[1]
|
current_adsr_decay_rate = adsr[1]
|
||||||
current_adsr_sustain_level = adsr[2]
|
current_adsr_sustain_level = adsr[2]
|
||||||
current_adsr_sustain_rate = adsr[3]
|
current_adsr_sustain_rate = adsr[3]
|
||||||
EventType.ADSR_DEFAULT: # TODO - Investigate actual scaling and order
|
EventType.ADSR_DEFAULT: # TODO - Investigate actual scaling and order
|
||||||
if current_instrument < len(instrument_adsrs) and current_instrument > 0:
|
if current_instrument < len(sample_default_adsrs) and current_instrument > 0:
|
||||||
var adsr = instrument_adsrs[current_instrument]
|
var adsr = sample_default_adsrs[current_instrument]
|
||||||
current_adsr_attack_rate = adsr[0]
|
current_adsr_attack_rate = adsr[0]
|
||||||
current_adsr_decay_rate = adsr[1]
|
current_adsr_decay_rate = adsr[1]
|
||||||
current_adsr_sustain_level = adsr[2]
|
current_adsr_sustain_level = adsr[2]
|
||||||
|
@ -339,13 +353,13 @@ static func render_channels(tracks: Array, inst_map: Array, debug_name := 'none'
|
||||||
continue
|
continue
|
||||||
var note_event: NoteEvent = all_note_events[channel][-1]
|
var note_event: NoteEvent = all_note_events[channel][-1]
|
||||||
var p_end = note_event.p_end
|
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
|
# Ends on infinite loop
|
||||||
channel_loop_p_returns.append(p_end)
|
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:
|
if p_end > highest_channel_p_return:
|
||||||
highest_channel_p_return = p_end
|
highest_channel_p_return = p_end
|
||||||
p_end = note_event.p_start
|
p_end = note_event.p_event_start
|
||||||
else:
|
else:
|
||||||
channel_loop_p_returns.append(-1)
|
channel_loop_p_returns.append(-1)
|
||||||
channel_loop_p_lengths.append(0)
|
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 loop_return_p = channel_loop_p_returns[channel]
|
||||||
var curve_pan: TrackCurve = curve_channel_pans[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_bytes_t_end := StreamPeerBuffer.new()
|
||||||
var midi_events_bytes3 := StreamPeerBuffer.new()
|
var midi_events_bytes3 := StreamPeerBuffer.new()
|
||||||
var midi_events_bytes_adsr := 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
|
event_ptr = loop_return_note_event_idx
|
||||||
loop_p_offset += channel_loop_p_lengths[channel]
|
loop_p_offset += channel_loop_p_lengths[channel]
|
||||||
var event: NoteEvent = events[event_ptr]
|
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:
|
if loop_return_note_event_idx < 0 and p >= loop_return_p:
|
||||||
loop_return_note_event_idx = event_ptr
|
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_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.instrument)
|
||||||
midi_events_bytes3.put_u8(event.pitch)
|
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
|
num_notes += 1
|
||||||
# Fill up end of notes array with dummies
|
# Fill up end of notes array with dummies
|
||||||
for i in range(num_notes, MAX_NOTE_EVENTS):
|
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_bytes_t_end.put_32(0x0FFFFFFF)
|
||||||
midi_events_bytes3.put_32(0)
|
midi_events_bytes3.put_32(0)
|
||||||
midi_events_bytes_adsr.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_start = -1
|
||||||
var smp_loop_end = -1
|
var smp_loop_end = -1
|
||||||
if highest_channel_p_return > 0:
|
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)
|
output.append(print_str + print_str2)
|
||||||
p += duration
|
p += duration
|
||||||
EventType.PROGCHANGE:
|
EventType.PROGCHANGE:
|
||||||
var event_idx = event[1]-0x20
|
var event_idx = event[1]
|
||||||
if event_idx >= 0:
|
if event_idx >= 0x20:
|
||||||
output.append(print_str + 'instrument %02d'%(inst_map[event_idx] - 1))
|
output.append(print_str + '($%02x) = instrument %02d'%[event_idx, inst_map[event_idx-0x20] - 1])
|
||||||
else:
|
else:
|
||||||
output.append(print_str + print_str2)
|
output.append(print_str + 'sfx %d'%event_idx)
|
||||||
_:
|
_:
|
||||||
output.append(print_str + print_str2)
|
output.append(print_str + print_str2)
|
||||||
return output
|
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:
|
for two_of_u16 in snes_data.sfx_brr_pointers:
|
||||||
brr_spc_addrs.append(two_of_u16[0])
|
brr_spc_addrs.append(two_of_u16[0])
|
||||||
brr_spc_loop_addrs.append(two_of_u16[1])
|
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:
|
for i in SFX_NUM:
|
||||||
buffer.seek(brr_spc_addrs[i] + brr_spc_start)
|
buffer.seek(brr_spc_addrs[i] + brr_spc_start)
|
||||||
# print('Loading sfx sample #%X with BRR data offset $%06X' % [i, buffer.get_position()])
|
# 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 audio := make_sample(buffer, 900, sample_rate)
|
||||||
var loop_start_packet: int = brr_spc_loop_addrs[i] - brr_spc_addrs[i]
|
var loop_start_packet: int = brr_spc_loop_addrs[i] - brr_spc_addrs[i]
|
||||||
audio.loop_mode = AudioStreamSample.LOOP_FORWARD
|
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)
|
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
|
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)
|
emit_signal('audio_sfx_sample_loaded', i)
|
||||||
|
@ -186,14 +186,14 @@ var samples_tex: ImageTexture
|
||||||
const TEX_WIDTH := 2048
|
const TEX_WIDTH := 2048
|
||||||
const FILTER_PAD := 32
|
const FILTER_PAD := 32
|
||||||
func samples_to_texture():
|
func samples_to_texture():
|
||||||
var num_samples := INST_NUM + SFX_NUM
|
var num_samples := SFX_NUM + INST_NUM
|
||||||
var header_length := num_samples * 5
|
var header_length := num_samples * 5
|
||||||
|
|
||||||
# Create header and unwrapped payload separately first
|
# Create header and unwrapped payload separately first
|
||||||
var header_buffer := StreamPeerBuffer.new()
|
var header_buffer := StreamPeerBuffer.new()
|
||||||
var payload_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 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_begin: int = sample.loop_begin
|
||||||
var loop_length: int = sample.loop_end - 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):
|
func get_value(buffer: StreamPeer, leftover_bits: Array):
|
||||||
# Might be a bit too much branching but oh well
|
# Might be a bit too much branching but oh well
|
||||||
if self.contained_struct_type is U8:
|
if self.contained_struct_type is U8:
|
||||||
var result = PoolByteArray()
|
|
||||||
# Slight optimization over calling the method
|
# Slight optimization over calling the method
|
||||||
for i in self.count:
|
var result = buffer.get_data(self.count)
|
||||||
result.append(buffer.get_u8())
|
# result[0] is an error code
|
||||||
return result
|
return result[1]
|
||||||
|
|
||||||
var result = []
|
var result = []
|
||||||
for i in self.count:
|
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_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_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 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};
|
// 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
|
// Binary search the channels
|
||||||
for (int channel = 0; channel < NUM_CHANNELS; channel++) {
|
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 float event_idx = 0.0;
|
||||||
highp int smp_start;
|
highp int smp_start;
|
||||||
for (int i = 0; i < NUM_CHANNEL_NOTE_PROBES; i++) {
|
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))));
|
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_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 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);
|
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];
|
highp int smp_decay = DECAY_TIME_SMPS[adsr.y];
|
||||||
|
|
||||||
// For now, just branch this
|
// 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
|
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;
|
smp_overrun = (smp_overrun < 0) ? 0 : smp_overrun;
|
||||||
if (smp_overrun < 256) {
|
if (smp_overrun < 256) {
|
||||||
highp int smp_progress = smp - smp_start;
|
highp int smp_progress = smp - smp_note_start;
|
||||||
highp float t_start = float(smp_start)/output_mixrate;
|
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 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 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;
|
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:
|
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 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
|
while len(data) < target_length: # This is inefficient, but this function should be called with pre-padded data anyway
|
||||||
data.append(0)
|
data.append(0)
|
||||||
var image := Image.new()
|
var image := Image.new()
|
||||||
|
|
Loading…
Reference in New Issue