How to load a wav file at runtime?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By zinc29

in the data section of AudioStreamMP3 it gives instructions to access and use an mp3 file in an audiostreamplayer:

func load_mp3(path):
    var file = FileAccess.open(path, FileAccess.READ)
    var sound = AudioStreamMP3.new()
    sound.data = file.get_buffer(file.get_length())
    return sound

this works fine, but trying to replace AudioStreamMP3 with AudioStreamWav (and changing the file type to wav obviously) it just sounds like a bunch of static. any clue how to fix this? and no, i can’t just use load() because these are files created during runtime

:bust_in_silhouette: Reply From: DevBadger10

3rd edit, hope this helps.
This code should solve the issue:

func toSigned(file):
        var bytes = to_int64_array(PackedByteArray(file))
        for i in bytes:
                bytes[i] = bytes[i] - 128
        return to_byte_array(bytes)

Basically, “bytes” are a series of 8 0’s or 1’s, and is used in files. These store the Audio Data. This iterates through each bbyte and subtracts 128 from it.

Note: This only works in theory, and may not even work. If this works, then good! But it ONLY WORKS IN THEORY. If you have trouble, first thing I’d suggest is changing to_int64_array(PackedByteArray(file)) to to_int32_array(PackedByteArray(file)). Anything further than this is outside of my Godot documentation-reading abilites.

did you even read my question? i literally included a disclaimer at the end for this exact answer

zinc29 | 2023-03-28 00:57

Sorry, I didn’t read the entire thing. I just read “I can’t use load”. My apologies. I will edit my answer in order to reflect this change.

DevBadger10 | 2023-03-28 02:56

Okay, I’ve fixed it.

DevBadger10 | 2023-03-28 03:00

that just doesn’t really help in my scenario, sorry for my original impatient response. my problem isn’t with accessing the files, it’s that AudioStreamWav produces a strange, static filled mess rather than anything audible like AudioStreamMP3. one possible source ive found was in the wiki, where it says “Note: This property expects signed PCM8 data. To convert unsigned PCM8 to signed PCM8, subtract 128 from each byte.” but i have no clue how to “subtract 128 from each byte”

zinc29 | 2023-03-28 04:04

I know how I just don’t know how in Godot. I’ll do some research on my computer just not at it rn. This is sent from my phone

DevBadger10 | 2023-03-28 04:20

alright well i figured out how to loop through the data and subtract 128 from each byte, was easier than i expected. it made the static somewhat better but its still nowhere near where it should be

zinc29 | 2023-03-28 04:30

It’s always better when you figure it out yourself. I don’t know anything beyond that, let’s hope someone finds this. Maybe ask in the Godot discord?

DevBadger10 | 2023-03-28 04:48

i already have 5-7 times and it always just gets ignored

zinc29 | 2023-03-28 04:51

Okay. How about you try changing between Int64 and Int32? Or changing the subtraction number? I’m really not sure, music files are not my area of expertise.

DevBadger10 | 2023-03-28 04:53

That’s annoying, i hate it when people do that. Maybe, if al else fails, you could try with ChatGPT? It normally gets things wrong tho

DevBadger10 | 2023-03-28 04:54

ive tried changing the format if thats what you mean, ive messed with pretty much every option in AudioStreamWav. currently, this is my code:

var sound = AudioStreamWAV.new()
var bytes = FileAccess.get_file_as_bytes("res://test.wav")
sound.data = bytes
audio.stream = sound
audio.playing = true

which just results in static. changing the format just speeds it up, and subtracting 128 from each byte barely does anything.

zinc29 | 2023-03-28 05:07

I’m sorry I don’t know what to do. Maybe try with the code I wrote? It might work? Probably not. May I ask why you need to use music generated at runtime? As the music may be being saved incorrectly.

DevBadger10 | 2023-03-28 05:11

youre code doesn’t actually function, but changing it to

var bytes = FileAccess.get_file_as_bytes("res://test.wav")
bytes = bytes.to_int64_array()
for i in bytes.size():
	bytes[i] = bytes[i] - 128
bytes = bytes.to_byte_array()

does what you intended. sadly, this doesn’t work either and it still sounds staticky, both with to_int64_array() and to_int32_array()

zinc29 | 2023-03-28 21:59

ah shame the code didnt work I coudnlt test it

DevBadger10 | 2023-03-28 23:49

it’s alright, i finally found a fix!
GitHub - Gianclgar/GDScriptAudioImport: A script in GDScript for importing .wav and .ogg audio files at runtime
apparently it was an issue with the wave header. thanks for your time and sorry for being so rude yesterday, had gotten like 3 hours of sleep the night before. have a good day

zinc29 | 2023-03-29 02:18

It’s okay,if I’d put a lot of work in to type a question then someone comes up and says something not reading the entire thing Id have the same reaction :stuck_out_tongue:

Also I’m glad you found a fix! What project are you making?

DevBadger10 | 2023-03-29 04:39

when i asked this i was working on a dectalk implementation for a larger project

zinc29 | 2023-04-01 02:26

Hi! For anyone needing this for godot 4, there is a pull request to port it but Ogg Vorbis support had been taken out, I just commented a fix on the PR to put it back in: