diff --git a/shaders/audio_renderer.gdshader b/shaders/audio_renderer.gdshader index 9754508..7e3f648 100644 --- a/shaders/audio_renderer.gdshader +++ b/shaders/audio_renderer.gdshader @@ -3,9 +3,8 @@ // Unfortunately, this loses type-checking on [0.0, 1.0] vs [0,255] etc. so a lot of this will involve comments declaring ranges. shader_type canvas_item; render_mode blend_premul_alpha; -const int INT_TEX_SIZE = 4096; -const float TEX_SIZE = 4096.0; -const float UV_QUANTIZE = TEX_SIZE; +uniform int INT_TEX_WIDTH = 4096; +uniform vec2 TEX_SIZE = vec2(4096.0, 4096.0); // I feel like these magic numbers are a bit more intuitive in hex const float x00FF = float(0x00FF); // 255.0 const float x0100 = float(0x0100); // 256.0 @@ -60,16 +59,16 @@ vec2 pack_float_to_int16(float value) { return vec2(LSB, MSB); } -vec4 test_writeback(sampler2D tex, vec2 uv) { - // Test importing and exporting the samples, - // and exporting a value derived from the UV - vec4 output; - float sample_1 = rescale_int16(unpack_int16(texture(tex, uv).xw)); - float sample_2 = rescale_int16(dot(trunc(uv*TEX_SIZE), vec2(1.0, TEX_SIZE))); - output.xy = pack_float_to_int16(sample_1); - output.zw = pack_float_to_int16(sample_2); - return output; -} +// vec4 test_writeback(sampler2D tex, vec2 uv) { +// // Test importing and exporting the samples, +// // and exporting a value derived from the UV +// vec4 output; +// float sample_1 = rescale_int16(unpack_int16(texture(tex, uv).xw)); +// float sample_2 = rescale_int16(dot(trunc(uv*TEX_SIZE), vec2(1.0, TEX_SIZE))); +// output.xy = pack_float_to_int16(sample_1); +// output.zw = pack_float_to_int16(sample_2); +// return output; +// } // ============================================================= LOGIC ============================================================= @@ -153,7 +152,6 @@ float get_instrument_sample(float instrument_index, float note, float t) { const int NUM_CHANNELS = 8; const int MAX_CHANNEL_NOTE_EVENTS = 2048; const int NUM_CHANNEL_NOTE_PROBES = 11; // log2(MAX_CHANNEL_NOTE_EVENTS) -// uniform sampler2D midi_events : hint_normal; uniform vec2 midi_events_size = vec2(2048.0, 32.0); vec4 get_midi_texel(sampler2D tex, float x, float y) { return texture(tex, vec2(x, y)/midi_events_size).xyzw; @@ -211,8 +209,8 @@ vec4 render_song(sampler2D tex, int smp) { void fragment() { // GLES2 vec2 uv = vec2(UV.x, 1.0-UV.y); - // uv = (trunc(uv*UV_QUANTIZE)+0.5)/UV_QUANTIZE; + // uv = (trunc(uv*TEX_SIZE)+0.5)/TEX_SIZE; // COLOR.xyzw = test_writeback(TEXTURE, uv); ivec2 xy = ivec2(trunc(uv*TEX_SIZE)); - COLOR.xyzw = render_song(TEXTURE, xy.x + (xy.y*INT_TEX_SIZE)); + COLOR.xyzw = render_song(TEXTURE, xy.x + (xy.y*INT_TEX_WIDTH)); } diff --git a/test/audio_renderer.gd b/test/audio_renderer.gd index 0dd51cc..6144411 100644 --- a/test/audio_renderer.gd +++ b/test/audio_renderer.gd @@ -4,8 +4,9 @@ const INPUT_TEX_WIDTH := 2048 const INPUT_FORMAT := Image.FORMAT_RGBA8 # Image.FORMAT_LA8 const INPUT_BYTES_PER_TEXEL := 4 # 2 const OUTPUT_BYTES_PER_TEXEL := 4 -const OUTPUT_WIDTH := 4096 -const OUTPUT_HEIGHT := 4096 +const OUTPUT_FRAMEBUFFER_SIZE := Vector2(4096, 4096) +const OUTPUT_WIDTH := int(OUTPUT_FRAMEBUFFER_SIZE.x) +const OUTPUT_HEIGHT := int(OUTPUT_FRAMEBUFFER_SIZE.y) const QUAD_COLOR := PoolColorArray([Color.white, Color.white, Color.white, Color.white]) var viewport: Viewport var render_queue: Array # of Images @@ -21,19 +22,27 @@ func _ready() -> void: self.waiting_for_viewport = [] self.done_first_draw = false self.current_textures = [] + self.get_parent().size = OUTPUT_FRAMEBUFFER_SIZE + self.material.set_shader_param('OUTPUT_FRAMEBUFFER_SIZE', OUTPUT_FRAMEBUFFER_SIZE) + self.material.set_shader_param('INT_OUTPUT_WIDTH', OUTPUT_WIDTH) -func push_image(img: Image, uv_rows: int = 4096, desc: String = '') -> void: - self.render_queue.append([img, uv_rows, desc]) +func push_image(img: Image, target_samples: int = -1, desc: String = '') -> void: + var target_rows = ceil(target_samples/float(OUTPUT_WIDTH)) + if target_samples <= 0: + target_rows = int(img.get_size().y) + self.render_queue.append([img, target_rows, desc]) -func push_bytes(data: PoolByteArray, uv_rows: int = 4096, desc: String = '') -> void: - # print(data.subarray(0, 15)) +func push_bytes(data: PoolByteArray, target_samples: int = -1, desc: String = '') -> 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 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() image.create_from_data(INPUT_TEX_WIDTH, rows, false, INPUT_FORMAT, data) - self.render_queue.append([image, uv_rows, desc]) + var target_rows = ceil(target_samples/float(OUTPUT_WIDTH)) + if target_samples <= 0: + target_rows = rows + self.render_queue.append([image, target_rows, desc]) func _process(_delta) -> void: update() @@ -67,11 +76,10 @@ func _draw() -> void: self.current_textures.append(ImageTexture.new()) var tex: ImageTexture = self.current_textures[i] tex.create_from_image(image_and_uv_rows_and_desc[0], 0) - # self.material.set_shader_param('midi_events', tex) self.material.set_shader_param('midi_events_size', tex.get_size()) var y_top: int = OUTPUT_HEIGHT - rows_drawn var y_bot: int = y_top + draw_rows - var uv_inv_v: float = 1 - (draw_rows / float(OUTPUT_WIDTH)) + var uv_inv_v: float = 1 - (draw_rows / OUTPUT_FRAMEBUFFER_SIZE.y) var uvs := PoolVector2Array([Vector2(0, uv_inv_v), Vector2(1, uv_inv_v), Vector2(1, 1), Vector2(0, 1)]) var points := PoolVector2Array([Vector2(0, y_top), Vector2(OUTPUT_WIDTH, y_top), Vector2(OUTPUT_WIDTH, y_bot), Vector2(0, y_bot)]) draw_primitive(points, QUAD_COLOR, uvs, tex) diff --git a/test/audio_system.gd b/test/audio_system.gd index 6898853..1927f48 100644 --- a/test/audio_system.gd +++ b/test/audio_system.gd @@ -180,14 +180,13 @@ func queue_prerender_bgm(bgm_id: int) -> void: var data = data_and_target_time_and_loops[0] var target_time = data_and_target_time_and_loops[1] var target_samples = target_time * 32000 - var target_rows = ceil(target_samples/4096.0) var bgm_key := 'BGM%02d'%bgm_id - audio_renderer.push_bytes(data, target_rows, bgm_key) + audio_renderer.push_bytes(data, target_samples, bgm_key) self.prerendered_bgm_start_and_end_loops[bgm_key] = data_and_target_time_and_loops[2] -func render_all_bgm(bgms_to_render: int = 64) -> void: +func render_all_bgm(bgms_to_render: int = 70) -> void: self.initialize_instrument_texture() for bgm_id in bgms_to_render: self.queue_prerender_bgm(bgm_id) @@ -199,6 +198,7 @@ func render_all_bgm(bgms_to_render: int = 64) -> void: const save_prerendered_audio := false func _get_prerendered_audio(): audio_renderer.get_result() + var tracks_rendered := '' while audio_renderer.result_queue: var result = audio_renderer.result_queue.pop_front() var desc = result[0] @@ -216,11 +216,13 @@ func _get_prerendered_audio(): var error = rendered_audio.save_to_wav('output/rendered_%s.wav'%desc) print('@%dms - Saved render of %s (error code %s)' % [get_ms(), desc, globals.ERROR_CODE_STRINGS[error]]) else: - print('@%dms - Rendered %s without saving' % [get_ms(), desc]) + # print('@%dms - Rendered %s without saving' % [get_ms(), desc]) + tracks_rendered = '%s, %s'%[tracks_rendered, desc] if self.queued_bgm_playback == desc: self.audio_player.stream = rendered_audio self.audio_player.play() self.queued_bgm_playback = '' + print('@%dms - Rendered %s without saving' % [get_ms(), tracks_rendered.right(2)]) func get_shader_test_pattern() -> PoolByteArray: diff --git a/test/audio_system.tscn b/test/audio_system.tscn index f54c51c..ac65bff 100644 --- a/test/audio_system.tscn +++ b/test/audio_system.tscn @@ -6,6 +6,8 @@ [sub_resource type="ShaderMaterial" id=2] shader = ExtResource( 4 ) +shader_param/INT_TEX_WIDTH = 4096 +shader_param/TEX_SIZE = Vector2( 4096, 4096 ) shader_param/instrument_samples_size = Vector2( 2048, 128 ) shader_param/reference_note = 71.0 shader_param/output_mixrate = 32000.0