DaveTheCoder i think i know the problem, i forgot im in the process thread.. i will have to try to move it into a separate thread... this way the while loop can parse faster

Also, as i tried to use an array of bytes and then parse the array, it seems to not function like the get_buffer method.. idk why.. i tripple checked the code.. it executes differently, like reading wrong bytes..

Maybe there is a limit on how much can you fit into array.. and 18MB of bytes is just one too many..?

Yes, putting a time-consuming operation in _process is bad.

Parsing bytes in a packed array should work. 18MB shouldn't be a problem. Something else is wrong.

This looks suspicious:
var r_size = r_buff.slice(0,4).to_int32_array()
If that's intended to get an int value, shouldn't it be:
var r_size = r_buff.decode_u32(0)

Depending on how the file was created, you may need to rearrange the byte order when converting to an int.

I strongly recommend using static typing and declaring the type of each variable. That will often tell you about problems.

    • Edited

    DaveTheCoder the thread only saved me half of the time.. still takes 9.7s to process 18MB file 🙁...

    As for the decode, im not sure what type it is.. the to_int32 worked so i used it.. whats the difference?

    Tested with decode, the time didnt improve...
    Added types to vars, ddint improve nothing..

    Any other suggestions?

    func read_wav_decode(wav_file_path:String):
    	var start_time = Time.get_unix_time_from_system()
    	var sfx_file = FileAccess.open(wav_file_path,FileAccess.READ)
    	print("---START---")
    	print("file_start: ",wav_file_path)
    	while sfx_file.get_position() < sfx_file.get_length():
    		# Read data
    		var buff_bytes:PackedByteArray = sfx_file.get_buffer(4)
    		var id_tag:String = sfx_file.get_buffer(4).get_string_from_ascii()
    		match id_tag:
    			"RIFF":
    				var r_buff:PackedByteArray = sfx_file.get_buffer(8)
    				var r_size:int = r_buff.decode_u32(0)
    				var r_format:String = r_buff.slice(4,8).get_string_from_ascii()
    				print("---")
    				print(id_tag)
    				print("size: ",r_size)
    				print("format: ",r_format)
    			"fmt ":
    				var f_buff:PackedByteArray = sfx_file.get_buffer(20)
    				var f_size:int = f_buff.decode_u32(0)
    				var f_format:int = f_buff.slice(4,6)[0]
    				var f_num_channels:int = f_buff.slice(6,8)[0]
    				var f_sample_rate:int = f_buff.slice(8,12).decode_u32(0)
    				var f_byte_rate:int = f_buff.slice(12,16).decode_u32(0)
    				var f_block_align:int = f_buff.slice(16,18).[0]
    				var f_bits_per_sample:int = f_buff.slice(18,20).[0]
    				print("---")
    				print(id_tag)
    				print("f_size: ",f_size)
    				print("f_format: ",f_format)
    				print("f_num_channels: ",f_num_channels)
    				print("f_sample_rate: ",f_sample_rate)
    				print("f_byte_rate: ",f_byte_rate)
    				print("f_block_align: ",f_block_align)
    				print("f_bits_per_sample: ",f_bits_per_sample)
    			"data":
    				var d_buff:PackedByteArray = sfx_file.get_buffer(4)
    				var d_size:int = d_buff.decode_u32(0)
    				print("---")
    				print(id_tag)
    				print("d_size: ",d_size)
    			"bext":
    				var b_buff:PackedByteArray = sfx_file.get_buffer(4)
    				var b_size:int = b_buff.decode_u32(0)
    				var b_data:String = sfx_file.get_buffer(4+b_size).get_string_from_ascii()
    				print("---")
    				print(id_tag)
    				print("b_size: ",b_size)
    				print("b_data: ",b_data)
    			"iXML":
    				var i_buff:PackedByteArray = sfx_file.get_buffer(4)
    				var i_size:int = i_buff.decode_u32(0)
    				var i_data:String = sfx_file.get_buffer(4+i_size).get_string_from_ascii()
    				print("---")
    				print(id_tag)
    				print("i_size: ",i_size)
    				print("i_data: ",i_data)
    			"LIST":
    				var l_buff:PackedByteArray = sfx_file.get_buffer(8)
    				var l_size:int = l_buff.decode_u32(0)
    				var l_type:String = l_buff.slice(4,8).get_string_from_ascii()
    				var l_data_buff:PackedByteArray = sfx_file.get_buffer(l_size)
    				print("---")
    				print(id_tag)
    				print("l_size: ",l_size)
    				print("l_type: ",l_type)
    				
    				match l_type:
    					"INFO":
    						var inf_type:String = l_data_buff.slice(0,4).get_string_from_ascii()
    						var inf_size:int = l_data_buff.slice(4,8).decode_u32(0)
    						var inf_data:String = l_data_buff.slice(8,l_data_buff.size()-1).get_string_from_ascii()
    						print("---SUB---")
    						print("inf_type: ",inf_type)
    						print("inf_size: ",inf_size)
    						print("inf_data: ",inf_data)
    	var end_time = Time.get_unix_time_from_system()
    	var time_diff = end_time - start_time
    	
    	print("---END---")
    	print("---Elapsed time---: ",time_diff,"s")

    Full code with decode and types

    TEST

    Test with my old method without types and decode

    ---START---
    file_start: res://Test_files/sfx/01 - Title Theme (Main Menu).wav
    ---
    fmt 
    f_size: [18]
    f_format: [1, 0]
    f_num_channels: [2, 0]
    f_sample_rate: [44100]
    f_byte_rate: [176400]
    f_block_align: [4, 0]
    f_bits_per_sample: [16, 0]
    ---
    bext
    b_size: [602]
    b_data: 
    ---
    LIST
    l_size: [66]
    l_type: INFO
    ---SUB---
    inf_type: IART
    inf_size: [11]
    inf_data: David Wise
    ---END---
    ---Elapsed time---: 9.79999995231628s

    The new: decode method

    ---START---
    file_start: res://Test_files/sfx/01 - Title Theme (Main Menu).wav
    ---
    fmt 
    f_size: 18
    f_format: 1
    f_num_channels: 2
    f_sample_rate: 44100
    f_byte_rate: 176400
    f_block_align: 4
    f_bits_per_sample: 16
    ---
    bext
    b_size: 602
    b_data: 
    ---
    LIST
    l_size: 66
    l_type: INFO
    ---SUB---
    inf_type: IART
    inf_size: 11
    inf_data: David Wise
    ---END---
    ---Elapsed time---: 9.76999998092651s

    I run this from:

    func thread_func():
    	var t_wav = "res://Test_files/sfx/01 - Title Theme (Main Menu).wav"
    	read_wav(t_wav)
    	read_wav_decode(t_wav)

    That gets started with button press:

    	thread.start(thread_func)
    	thread.wait_to_finish()

    RIFF spec for reference
    http://soundfile.sapp.org/doc/WaveFormat/

      kuligs2 As for the decode, im not sure what type it is.. the to_int32 worked so i used it.. whats the difference?

      to_int32_array returns a PackedInt32Array, not an int.

      kuligs2 Added types to vars, ddint improve nothing..

      I didn't expect that to change the speed. It makes the code more reliable by warning you about problems.

      I thought of something.

      Measure how long it takes to read the file into memory, without doing any parsing or processing of the data.

      Try both methods (reading a few bytes at a time, and using a large buffer) that you used above.

      If it's the parsing, rather than the file I/O, that's consuming the time, then a significant speed-up could be achieved by writing a GDExtension in C or C++, or using .NET Godot with C#.

      By the way, what's the purpose of doing this? Maybe there's a better approach.

        DaveTheCoder By the way, what's the purpose of doing this? Maybe there's a better approach.

        audio sfx browser app.. search via metadata. i need to parse audio files for metadata.. the godot has few PRs that deal with mp3 and ogg, but they went lazy on wav.. so im trying to make a proof of concept, clean it up and maybe suggest they include it into the engine, or maybe not..

        DaveTheCoder If it's the parsing, rather than the file I/O, that's consuming the time, then a significant speed-up could be achieved by writing a GDExtension in C or C++, or using .NET Godot with C#.

        Its not IO, file gets read instantly. Its the for loop.. it iterates every byte, but in reality i dont need to do that, because when i read byte length and process the data, i need the iterator to be at the last read byte value to continue the next loop.. and that value is dependant on the data size and is variable..

        What i need is recursive something.. somehow where i can set the cursor position to the byte index where the next loop needs to start..

        So far with updated method i get nice gains.. from 18s to 4s 🙂

        Results:

        Old meth:

        ---START---read_wav_decode---
        file_start: res://Test_files/sfx/01 - Title Theme (Main Menu).wav
        ---
        RIFF
        size: 22557324
        format: WAVE
        ---
        fmt 
        f_size: 18
        f_format: 1
        f_num_channels: 2
        f_sample_rate: 44100
        f_byte_rate: 176400
        f_block_align: 4
        f_bits_per_sample: 16
        ---
        bext
        b_size: 602
        b_data: 
        ---
        LIST
        l_size: 66
        l_type: INFO
        ---SUB---
        inf_type: IART
        inf_size: 11
        inf_data: David Wise
        ---END---
        ---Elapsed time---: 18.6229999065399s

        Improved meth

        ---START---read_wav_decode_new---
        file_start: res://Test_files/sfx/01 - Title Theme (Main Menu).wav
        ---
        RIFF
        size: 22557324
        format: WAVE
        ---
        fmt 
        f_size: 18
        f_format: 1
        f_num_channels: 2
        f_sample_rate: 44100
        f_byte_rate: 176400
        f_block_align: 4
        f_bits_per_sample: 16
        ---
        bext
        b_size: 602
        b_data: 
        ---
        LIST
        l_size: 66
        l_type: INFO
        ---SUB---
        inf_type: IART
        inf_size: 11
        inf_data: David Wise
        ---END---
        ---Elapsed time---: 4.02900004386902s

        Code:

        func read_wav_decode(wav_file_path:String):
        	var start_time = Time.get_unix_time_from_system()
        	var sfx_file = FileAccess.open(wav_file_path,FileAccess.READ)
        	print("---START---read_wav_decode---")
        	print("file_start: ",wav_file_path)
        	while sfx_file.get_position() < sfx_file.get_length():
        		# Read data
        		
        		var id_tag:String = sfx_file.get_buffer(4).get_string_from_ascii()
        		match id_tag:
        			"RIFF":
        				var r_buff:PackedByteArray = sfx_file.get_buffer(8)
        				var r_size:int = r_buff.slice(0,4).decode_u32(0)
        				var r_format:String = r_buff.slice(4,8).get_string_from_ascii()
        				print("---")
        				print(id_tag)
        				print("size: ",r_size)
        				print("format: ",r_format)
        			"fmt ":
        				var f_buff:PackedByteArray = sfx_file.get_buffer(20)
        				var f_size:int = f_buff.slice(0,4).decode_u32(0)
        				var f_format:int = f_buff.slice(4,6)[0]
        				var f_num_channels:int = f_buff.slice(6,8)[0]
        				var f_sample_rate:int = f_buff.slice(8,12).decode_u32(0)
        				var f_byte_rate:int = f_buff.slice(12,16).decode_u32(0)
        				var f_block_align:int = f_buff.slice(16,18)[0]
        				var f_bits_per_sample:int = f_buff.slice(18,20)[0]
        				print("---")
        				print(id_tag)
        				print("f_size: ",f_size)
        				print("f_format: ",f_format)
        				print("f_num_channels: ",f_num_channels)
        				print("f_sample_rate: ",f_sample_rate)
        				print("f_byte_rate: ",f_byte_rate)
        				print("f_block_align: ",f_block_align)
        				print("f_bits_per_sample: ",f_bits_per_sample)
        			"data":
        				var d_buff:PackedByteArray = sfx_file.get_buffer(4)
        				var d_size:int = d_buff.slice(0,4).decode_u32(0)
        				print("---")
        				print(id_tag)
        				print("d_size: ",d_size)
        			"bext":
        				var b_buff:PackedByteArray = sfx_file.get_buffer(4)
        				var b_size:int = b_buff.slice(0,4).decode_u32(0)
        				var b_data:String = sfx_file.get_buffer(4+b_size).get_string_from_ascii()
        				print("---")
        				print(id_tag)
        				print("b_size: ",b_size)
        				print("b_data: ",b_data)
        			"iXML":
        				var i_buff:PackedByteArray = sfx_file.get_buffer(4)
        				var i_size:int = i_buff.slice(0,4).decode_u32(0)
        				var i_data:String = sfx_file.get_buffer(4+i_size).get_string_from_ascii()
        				print("---")
        				print(id_tag)
        				print("i_size: ",i_size)
        				print("i_data: ",i_data)
        			"LIST":
        				var l_buff:PackedByteArray = sfx_file.get_buffer(8)
        				var l_size:int = l_buff.slice(0,4).decode_u32(0)
        				var l_type:String = l_buff.slice(4,8).get_string_from_ascii()
        				var l_data_buff:PackedByteArray = sfx_file.get_buffer(l_size)
        				print("---")
        				print(id_tag)
        				print("l_size: ",l_size)
        				print("l_type: ",l_type)
        				
        				match l_type:
        					"INFO":
        						var inf_type:String = l_data_buff.slice(0,4).get_string_from_ascii()
        						var inf_size:int = l_data_buff.slice(4,8).decode_u32(0)
        						var inf_data:String = l_data_buff.slice(8,l_data_buff.size()).get_string_from_ascii()
        						print("---SUB---")
        						print("inf_type: ",inf_type)
        						print("inf_size: ",inf_size)
        						print("inf_data: ",inf_data)
        	var end_time = Time.get_unix_time_from_system()
        	var time_diff = end_time - start_time
        	
        	print("---END---")
        	print("---Elapsed time---: ",time_diff,"s")
        	
        func read_wav_decode_new(wav_file_path:String):
        	var start_time = Time.get_unix_time_from_system()
        	var sfx_file = FileAccess.open(wav_file_path,FileAccess.READ)
        	var buff_file:PackedByteArray  = sfx_file.get_buffer(sfx_file.get_length())
        	var offset:int = 0
        	
        	print("---START---read_wav_decode_new---")
        	print("file_start: ",wav_file_path)
        	for i in range(0,buff_file.size()):
        		# Read data
        		if i < offset:
        			continue
        		offset+=4
        		var id_tag:String =buff_file.slice(i,offset).get_string_from_ascii()
        		match id_tag:
        			"RIFF":
        				var r_buff:PackedByteArray = buff_file.slice(offset,offset+8)
        				var r_size:int = r_buff.slice(0,4).decode_u32(0)
        				var r_format:String = r_buff.slice(4,8).get_string_from_ascii()
        				print("---")
        				print(id_tag)
        				print("size: ",r_size)
        				print("format: ",r_format)
        				offset+=8
        			"fmt ":
        				var f_buff:PackedByteArray = buff_file.slice(offset,offset+20)
        				var f_size:int = f_buff.slice(0,4).decode_u32(0)
        				var f_format:int = f_buff.slice(4,6)[0]
        				var f_num_channels:int = f_buff.slice(6,8)[0]
        				var f_sample_rate:int = f_buff.slice(8,12).decode_u32(0)
        				var f_byte_rate:int = f_buff.slice(12,16).decode_u32(0)
        				var f_block_align:int = f_buff.slice(16,18)[0]
        				var f_bits_per_sample:int = f_buff.slice(18,20)[0]
        				print("---")
        				print(id_tag)
        				print("f_size: ",f_size)
        				print("f_format: ",f_format)
        				print("f_num_channels: ",f_num_channels)
        				print("f_sample_rate: ",f_sample_rate)
        				print("f_byte_rate: ",f_byte_rate)
        				print("f_block_align: ",f_block_align)
        				print("f_bits_per_sample: ",f_bits_per_sample)
        				offset+=20
        			"data":
        				var d_buff:PackedByteArray = buff_file.slice(offset,offset+4)
        				var d_size:int = d_buff.decode_u32(0)
        				print("---")
        				print(id_tag)
        				print("d_size: ",d_size)
        				offset+=4
        			"bext":
        				var b_buff:PackedByteArray = buff_file.slice(offset,offset+4)
        				var b_size:int = b_buff.decode_u32(0)
        				var b_data:String = buff_file.slice(offset+4,offset+4+b_size).get_string_from_ascii()
        				print("---")
        				print(id_tag)
        				print("b_size: ",b_size)
        				print("b_data: ",b_data)
        				offset+=4+b_size
        			"iXML":
        				var i_buff:PackedByteArray = buff_file.slice(offset,offset+4)
        				var i_size:int = i_buff.decode_u32(0)
        				var i_data:String = buff_file.slice(offset+4,offset+4+i_size).get_string_from_ascii()
        				print("---")
        				print(id_tag)
        				print("i_size: ",i_size)
        				print("i_data: ",i_data)
        				offset+=4+i_size
        			"LIST":
        				var l_buff:PackedByteArray = buff_file.slice(offset,offset+8)
        				var l_size:int = l_buff.slice(0,4).decode_u32(0)
        				var l_type:String = l_buff.slice(4,8).get_string_from_ascii()
        				var l_data_buff:PackedByteArray = buff_file.slice(offset+8,offset+8+l_size)
        				print("---")
        				print(id_tag)
        				print("l_size: ",l_size)
        				print("l_type: ",l_type)
        				offset+=8+l_size
        				match l_type:
        					"INFO":
        						var inf_type:String = l_data_buff.slice(0,4).get_string_from_ascii()
        						var inf_size:int = l_data_buff.slice(4,8).decode_u32(0)
        						var inf_data:String = l_data_buff.slice(8,l_data_buff.size()).get_string_from_ascii()
        						print("---SUB---")
        						print("inf_type: ",inf_type)
        						print("inf_size: ",inf_size)
        						print("inf_data: ",inf_data)
        	var end_time = Time.get_unix_time_from_system()
        	var time_diff = end_time - start_time
        	
        	print("---END---")
        	print("---Elapsed time---: ",time_diff,"s")

        Note here:
        As you can see below here i wait for the iterator to catch up with the desired offset to continue.

        	for i in range(0,buff_file.size()):
        		# Read data
        		if i < offset:
        			continue

        I havent come up with a better way to loop with given position..

        For your second version you should use a while loop instead of the for loop. This allows you to manually control the loop variable (i) without the continue hack. Also, you may want to consider assigning the value of buff_file.size() to a variable outside of the loop and use that variable for comparison instead. GDScirpt may be able to optimise out these function calls. Or it may not. Only testing will answer that question.

        One thing I notice is that you have a lot of print statements inside the loop. I am not sure if that is the case for Godot. But on many platforms print-style output is very slow. I suggest to comment out all the print statements inside the loop to ensure that you are actually measuring the time of the algorithm and not the debug-printing instead.

          Zini One thing I notice is that you have a lot of print statements inside the loop. I am not sure if that is the case for Godot. But on many platforms print-style output is very slow. I suggest to comment out all the print statements inside the loop to ensure that you are actually measuring the time of the algorithm and not the debug-printing instead.

          Didnt help much commenting out print statements, maybe 0.3s faster.. still i think file parsing on byte level should be much faster..

          Zini For your second version you should use a while loop instead of the for loop. This allows you to manually control the loop variable (i) without the continue hack. Also, you may want to consider assigning the value of buff_file.size() to a variable outside of the loop and use that variable for comparison instead. GDScirpt may be able to optimise out these function calls. Or it may not. Only testing will answer that question.

          Didnt do diddly squat. Negligible improvements...

          added at the top

          var i = 0 # <---
          	while offset < buff_len: # <---

          And at the bottom:

          		i = offset # <-------------
          	var end_time = Time.get_unix_time_from_system()
          	var time_diff = end_time - start_time
          func read_wav_decode_new(wav_file_path:String):
          	var start_time = Time.get_unix_time_from_system()
          	var sfx_file = FileAccess.open(wav_file_path,FileAccess.READ)
          	var buff_file:PackedByteArray  = sfx_file.get_buffer(sfx_file.get_length())
          	var offset:int = 0
          	
          	print("---START---read_wav_decode_new---")
          	print("file_start: ",wav_file_path)
          	var buff_len = buff_file.size()
          	var i = 0
          	#for i in range(0,buff_file.size()):
          		## Read data
          		#if i < offset:
          			#continue
          	while offset < buff_len:
          		offset+=4
          		var id_tag:String =buff_file.slice(i,offset).get_string_from_ascii()
          		match id_tag:
          			"RIFF":
          				var r_buff:PackedByteArray = buff_file.slice(offset,offset+8)
          				var r_size:int = r_buff.slice(0,4).decode_u32(0)
          				var r_format:String = r_buff.slice(4,8).get_string_from_ascii()
          				print("---")
          				print(id_tag)
          				print("size: ",r_size)
          				print("format: ",r_format)
          				offset+=8
          			"fmt ":
          				var f_buff:PackedByteArray = buff_file.slice(offset,offset+20)
          				var f_size:int = f_buff.slice(0,4).decode_u32(0)
          				var f_format:int = f_buff.slice(4,6)[0]
          				var f_num_channels:int = f_buff.slice(6,8)[0]
          				var f_sample_rate:int = f_buff.slice(8,12).decode_u32(0)
          				var f_byte_rate:int = f_buff.slice(12,16).decode_u32(0)
          				var f_block_align:int = f_buff.slice(16,18)[0]
          				var f_bits_per_sample:int = f_buff.slice(18,20)[0]
          				print("---")
          				print(id_tag)
          				print("f_size: ",f_size)
          				print("f_format: ",f_format)
          				print("f_num_channels: ",f_num_channels)
          				print("f_sample_rate: ",f_sample_rate)
          				print("f_byte_rate: ",f_byte_rate)
          				print("f_block_align: ",f_block_align)
          				print("f_bits_per_sample: ",f_bits_per_sample)
          				offset+=20
          			"data":
          				var d_buff:PackedByteArray = buff_file.slice(offset,offset+4)
          				var d_size:int = d_buff.decode_u32(0)
          				print("---")
          				print(id_tag)
          				print("d_size: ",d_size)
          				offset+=4
          			"bext":
          				var b_buff:PackedByteArray = buff_file.slice(offset,offset+4)
          				var b_size:int = b_buff.decode_u32(0)
          				var b_data:String = buff_file.slice(offset+4,offset+4+b_size).get_string_from_ascii()
          				print("---")
          				print(id_tag)
          				print("b_size: ",b_size)
          				print("b_data: ",b_data)
          				offset+=4+b_size
          			"iXML":
          				var i_buff:PackedByteArray = buff_file.slice(offset,offset+4)
          				var i_size:int = i_buff.decode_u32(0)
          				var i_data:String = buff_file.slice(offset+4,offset+4+i_size).get_string_from_ascii()
          				print("---")
          				print(id_tag)
          				print("i_size: ",i_size)
          				print("i_data: ",i_data)
          				offset+=4+i_size
          			"LIST":
          				var l_buff:PackedByteArray = buff_file.slice(offset,offset+8)
          				var l_size:int = l_buff.slice(0,4).decode_u32(0)
          				var l_type:String = l_buff.slice(4,8).get_string_from_ascii()
          				var l_data_buff:PackedByteArray = buff_file.slice(offset+8,offset+8+l_size)
          				print("---")
          				print(id_tag)
          				print("l_size: ",l_size)
          				print("l_type: ",l_type)
          				offset+=8+l_size
          				match l_type:
          					"INFO":
          						var inf_type:String = l_data_buff.slice(0,4).get_string_from_ascii()
          						var inf_size:int = l_data_buff.slice(4,8).decode_u32(0)
          						var inf_data:String = l_data_buff.slice(8,l_data_buff.size()).get_string_from_ascii()
          						print("---SUB---")
          						print("inf_type: ",inf_type)
          						print("inf_size: ",inf_size)
          						print("inf_data: ",inf_data)
          		i = offset
          	var end_time = Time.get_unix_time_from_system()
          	var time_diff = end_time - start_time
          	
          	print("---END---")
          	print("---Elapsed time---: ",time_diff,"s")

          Output

          ---Elapsed time---: 3.28799986839294s
          • Edited

          Another idea: Maybe the slice function is responsible for some of the slowdown? It created a new PackedArray every time. This might be expensive.

          Potential improvements:

          • remove the initial slice for each tag and read each element of the tag from the main buffer directly
          • r_buff.slice(0,4).decode_u32(0): The slice here is clearly redundant because decode_u32 only grabs 4 bytes anyway
          • All the strings seem to be 4 characters long. You could try to read them as an integer (32 bit) instead and compare them to an int value that matches the bit pattern of the desired string. This would only work for strings that you want to compare against fixed values and that don't require further processing as strings.

            Zini well maybe i got few 0.2s improvement..

            This is what AI said too.. gave me broken code because of outdated godot docs, but fixing it manually i have this:

            func read_wav_decode_new_ai(wav_file_path: String):
            	var start_time = Time.get_unix_time_from_system()
            	var sfx_file = FileAccess.open(wav_file_path, FileAccess.READ)
            	var buff_file: PackedByteArray = sfx_file.get_buffer(sfx_file.get_length())
            	var offset: int = 0
            	print("---START---read_wav_decode_new---")
            	print("file_start: ", wav_file_path)
            	var buff_len = buff_file.size()
            
            	while offset < buff_len:
            		var id_tag: String = buff_file.slice(offset, offset + 4).get_string_from_ascii()
            		offset += 4
            		match id_tag:
            			"RIFF":
            				var r_size: int = buff_file.decode_u32(offset)
            				offset += 4
            				var r_format: String = buff_file.slice(offset, offset + 4).get_string_from_ascii()
            				offset += 4
            				print("---")
            				print(id_tag)
            				print("size: ", r_size)
            				print("format: ", r_format)
            
            			"fmt ":
            				offset += 4  # Skip chunk size field
            				var f_format: int = buff_file.decode_u16(offset)
            				offset += 2
            				var f_num_channels: int = buff_file.decode_u16(offset)
            				offset += 2
            				var f_sample_rate: int = buff_file.decode_u32(offset)
            				offset += 4
            				offset += 4  # Skip byte rate field
            				var f_block_align: int = buff_file.decode_u16(offset)
            				offset += 2
            				var f_bits_per_sample: int = buff_file.decode_u16(offset)
            				offset += 2
            				print("---")
            				print(id_tag)
            				print("f_format: ", f_format)
            				print("f_num_channels: ", f_num_channels)
            				print("f_sample_rate: ", f_sample_rate)
            				print("f_block_align: ", f_block_align)
            				print("f_bits_per_sample: ", f_bits_per_sample)
            
            			"data":
            				var d_size: int = buff_file.decode_u32(offset)
            				offset += 4+d_size
            				print("---")
            				print(id_tag)
            				print("d_size: ", d_size)
            
            			"bext":
            				var b_size: int = buff_file.decode_u32(offset)
            				offset += 4
            				var b_data: String = buff_file.slice(offset, offset + b_size).get_string_from_ascii()
            				offset += b_size
            				print("---")
            				print(id_tag)
            				print("b_size: ", b_size)
            				print("b_data: ", b_data)
            
            			"iXML":
            				var i_size: int = buff_file.decode_u32(offset)
            				offset += 4
            				var i_data: String = buff_file.slice(offset, offset + i_size).get_string_from_ascii()
            				offset += i_size
            				print("---")
            				print(id_tag)
            				print("i_size: ", i_size)
            				print("i_data: ", i_data)
            
            			"LIST":
            				var l_size: int = buff_file.decode_u32(offset)
            				offset += 4
            				var l_type: String = buff_file.slice(offset, offset + 4).get_string_from_ascii()
            				offset += 4
            				print("---")
            				print(id_tag)
            				print("l_size: ", l_size)
            				print("l_type: ", l_type)
            
            				match l_type:
            					"INFO":
            						var inf_type: String = buff_file.slice(offset, offset + 4).get_string_from_ascii()
            						offset += 4
            						var inf_size: int = buff_file.decode_u32(offset)
            						offset += 4
            						var inf_data: String = buff_file.slice(offset, offset + inf_size).get_string_from_ascii()
            						offset += inf_size
            						print("---SUB---")
            						print("inf_type: ", inf_type)
            						print("inf_size: ", inf_size)
            						print("inf_data: ", inf_data)
            
            	var end_time = Time.get_unix_time_from_system()
            	var time_diff = end_time - start_time
            	print("---END---")
            	print("---Elapsed Time: ", time_diff, " seconds---")

            Output:

            ---START---read_wav_decode_new---
            file_start: res://Test_files/sfx/01 - Title Theme (Main Menu).wav
            ---
            RIFF
            size: 22557324
            format: WAVE
            ---
            fmt 
            f_format: 1
            f_num_channels: 2
            f_sample_rate: 44100
            f_block_align: 4
            f_bits_per_sample: 16
            ---
            bext
            b_size: 602
            b_data: 
            ---
            LIST
            l_size: 66
            l_type: INFO
            ---SUB---
            inf_type: IART
            inf_size: 11
            inf_data: David Wise
            ---END---
            ---Elapsed Time: 3.07799983024597 seconds---

            I dont understand how else to improve it..

            • Edited

            Zini All the strings seem to be 4 characters long. You could try to read them as an integer (32 bit) instead and compare them to an int value that matches the bit pattern of the desired string. This would only work for strings that you want to compare against fixed values and that don't require further processing as strings.

            hmm maybe i should try this.. need to see how to encode string into int

            EDIT:

            Seems i dont understand how to make int from either string or buffer..

            --TEST--
            r_s: 1380533830
            r_d: 1179011410

            As you can see the values dont match..

            var r_s = string_to_int(id_tag)
            var r_d = buff_file.slice(offset, offset + 4).decode_u32(0)

            where

            func string_to_int(s: String) -> int:
            	var result: int = 0
            	for i in range(4):
            		if i >= s.length():
            			break
            		var char_value: int = s[i].to_ascii_buffer()[0]
            		result |= (char_value << ((3 - i) * 8))
            	return result

            EDIT2:
            Ah, the joys of precision when doing meths:

            func string_to_int(s: String) -> int:
            	var result: int = 0
            	#for i in range(4):
            		#if i >= s.length():
            			#break
            		#var char_value: int = s[i].to_ascii_buffer()[0]
            		#result |= (char_value << ((3 - i) * 8))
            	result = s.to_ascii_buffer().decode_u32(0)
            	return result

            output:

            --TEST--
            r_s: 1179011410
            r_d: 1179011410

            Now need to make this into a whole function

            EDIT:3
            Hardcoded ints:

            RIFF 1179011410
            fmt  544501094
            data 1635017060
            bext 1954047330
            iXML 1280137321
            LIST 1414744396
            INFO 1330007625

            EDIT:4

            Well, got maybe 1s improvement, but still takes more than 2s to parse.. also it throws me this error:

            E 0:00:03:354   file_ops.gd:749 @ read_wav_decode_new_2(): Condition "p_offset < 0 || p_offset > (int64_t(size) - 4)" is true. Returning: 0
              <C++ Source>  core\variant\variant_call.cpp:824 @ func_PackedByteArray_decode_u32()
              <Stack Trace> file_ops.gd:749 @ read_wav_decode_new_2()
                            file_ops.gd:931 @ thread_func()

            ---START---read_wav_decode_new---
            file_start: res://Test_files/sfx/01 - Title Theme (Main Menu).wav
            ---
            
            size: 22557324
            format: WAVE
            ---
            
            f_format: 1
            f_num_channels: 2
            f_sample_rate: 44100
            f_block_align: 4
            f_bits_per_sample: 16
            ---
            
            b_size: 602
            b_data: 
            ---
            
            l_size: 66
            l_type: INFO
            ---END---
            ---Elapsed Time: 2.19700002670288 seconds---