@@ -56,15 +56,15 @@ func loadfile(filepath):
5656 return AudioStreamSample .new ()
5757
5858 var bytes = file .get_buffer (file .get_len ())
59-
6059 # if File is wav
6160 if filepath .ends_with (".wav" ):
62-
6361 var newstream = AudioStreamSample .new ()
6462
6563 # ---------------------------
6664 # parrrrseeeeee!!! :D
67-
65+
66+ var bits_per_sample = 0
67+
6868 for i in range (0 , 100 ):
6969 var those4bytes = str (char (bytes [i ])+ char (bytes [i + 1 ])+ char (bytes [i + 2 ])+ char (bytes [i + 3 ]))
7070
@@ -90,6 +90,9 @@ func loadfile(filepath):
9090 if format_code == 0 : format_name = "8_BITS"
9191 elif format_code == 1 : format_name = "16_BITS"
9292 elif format_code == 2 : format_name = "IMA_ADPCM"
93+ else :
94+ format_name = "UNKNOWN (trying to interpret as 16_BITS)"
95+ format_code = 1
9396 print ("Format: " + str (format_code ) + " " + format_name )
9497 # assign format to our AudioStreamSample
9598 newstream .format = format_code
@@ -114,20 +117,25 @@ func loadfile(filepath):
114117 var bits_sample_channel = bytes [fsc0 + 12 ] + (bytes [fsc0 + 13 ] << 8 )
115118 print ("BitsPerSample * Channel / 8: " + str (bits_sample_channel ))
116119
117- # aaaand bits per sample/bitrate [Bytes 14-15] - TODO: Handle different bitrates
118- var bits_per_sample = bytes [fsc0 + 14 ] + (bytes [fsc0 + 15 ] << 8 )
120+ # aaaand bits per sample/bitrate [Bytes 14-15]
121+ bits_per_sample = bytes [fsc0 + 14 ] + (bytes [fsc0 + 15 ] << 8 )
119122 print ("Bits per sample: " + str (bits_per_sample ))
120123
121-
122124 if those4bytes == "data" :
125+ assert (bits_per_sample != 0 )
126+
123127 var audio_data_size = bytes [i + 4 ] + (bytes [i + 5 ] << 8 ) + (bytes [i + 6 ] << 16 ) + (bytes [i + 7 ] << 24 )
124128 print ("Audio data/stream size is " + str (audio_data_size ) + " bytes" )
125129
126130 var data_entry_point = (i + 8 )
127131 print ("Audio data starts at byte " + str (data_entry_point ))
128132
129- newstream . data = bytes .subarray (data_entry_point , data_entry_point + audio_data_size - 1 )
133+ var data = bytes .subarray (data_entry_point , data_entry_point + audio_data_size - 1 )
130134
135+ if bits_per_sample in [24 , 32 ]:
136+ newstream .data = convert_to_16bit (data , bits_per_sample )
137+ else :
138+ newstream .data = data
131139 # end of parsing
132140 # ---------------------------
133141
@@ -155,6 +163,44 @@ func loadfile(filepath):
155163 print ("ERROR: Wrong filetype or format" )
156164 file .close ()
157165
166+ # Converts .wav data from 24 or 32 bits to 16
167+ #
168+ # These conversions are SLOW in GDScript
169+ # on my one test song, 32 -> 16 was around 3x slower than 24 -> 16
170+ #
171+ # I couldn't get threads to help very much
172+ # They made the 24bit case about 2x faster in my test file
173+ # And the 32bit case abour 50% slower
174+ # I don't wanna risk it always being slower on other files
175+ # And really, the solution would be to handle it in a low-level language
176+ func convert_to_16bit (data : PoolByteArray , from : int ) -> PoolByteArray :
177+ print ("converting to 16-bit from %d " % from )
178+ var time = OS .get_ticks_msec ()
179+ # 24 bit .wav's are typically stored as integers
180+ # so we just grab the 2 most significant bytes and ignore the other
181+ if from == 24 :
182+ var j = 0
183+ for i in range (0 , data .size (), 3 ):
184+ data [j ] = data [i + 1 ]
185+ data [j + 1 ] = data [i + 2 ]
186+ j += 2
187+ data .resize (data .size () * 2 / 3 )
188+ # 32 bit .wav's are typically stored as floating point numbers
189+ # so we need to grab all 4 bytes and interpret them as a float first
190+ if from == 32 :
191+ var spb := StreamPeerBuffer .new ()
192+ var single_float : float
193+ var value : int
194+ for i in range (0 , data .size (), 4 ):
195+ spb .data_array = data .subarray (i , i + 3 )
196+ single_float = spb .get_float ()
197+ value = single_float * 32768
198+ data [i / 2 ] = value
199+ data [i / 2 + 1 ] = value >> 8
200+ data .resize (data .size () / 2 )
201+ print ("Took %f seconds for slow conversion" % ((OS .get_ticks_msec () - time ) / 1000.0 ))
202+ return data
203+
158204
159205# ---------- REFERENCE ---------------
160206# note: typical values doesn't always match
0 commit comments