Loading wav files into an AudioClip without using WWW or Resources.Load???

Hello,
I was able to load images from a local directory on my computer, into an array of Texture2Ds without using WWW (which will not work properly when trying to load files from a local drive, even when using ‘File:///c:/…’), or Resources.Load (which will not allow a published game’s ‘experience’ to change based on files that are placed in or taken away from a subfolder that sits right outside the published .exe file’s directory). Here is the code that works with loading images that sit in a sub folder that sits outside the published game’s directory, and I see that the data from the published game changes based on what images sit in the folder…

            if (System.IO.Directory.Exists(settings.data_directory_s+"textures/"))
            {
                Rect rect = new Rect();
                DirectoryInfo dir = new DirectoryInfo(settings.data_directory_s+"textures/");
                FileInfo[] info = dir.GetFiles("*.*");
                int cnt = 0;
                foreach (FileInfo f in info)
                {
 
                    Texture2D tex = null;
                    byte[] fileData;

                    if (File.Exists(f.FullName))
                    {
                        if (f.FullName.IndexOf(".jpg") == f.FullName.Length - 4 || f.FullName.IndexOf(".bmp") == f.FullName.Length - 4 || f.FullName.IndexOf(".gif") == f.FullName.Length - 4)
                        {
                            fileData = File.ReadAllBytes(f.FullName);
                            tex = new Texture2D(2, 2);
                            tex.LoadImage(fileData);
                            textureList.Add(tex);
                      }
                    }

                    cnt++;
                }
            }

As you can see, I did the image-loading by loading everything bitwise, but I am wondering how to convert an array of bytes into an array of floats that would then go into an audio clip (through AudioClip.SetData()).

What I am looking for is something like …

if (System.IO.Directory.Exists(settings.data_directory_s+"sounds/"))
            {
                Rect rect = new Rect();
                DirectoryInfo dir = new DirectoryInfo(settings.data_directory_s+"sounds/");
                FileInfo[] info = dir.GetFiles("*.*");
                int cnt = 0;
                foreach (FileInfo f in info)
                {

                    AudioClip aud = null;
                    byte[] fileData;
                    if (File.Exists(f.FullName))
                    {
                        if (f.FullName.IndexOf(".wav") == f.FullName.Length - 4 || f.FullName.IndexOf(".mp3") == f.FullName.Length - 4 || f.FullName.IndexOf(".raw") == f.FullName.Length - 4)
                        {
                            fileData = File.ReadAllBytes(f.FullName);
                            aud = new AudioClip();
                            aud.LoadSound(fileData);
                            soundList.Add(aud);
                      }
                    }
                    cnt++;
                }

… but there is no ‘AudioClip.LoadSound’, YET. Maybe that is a good idea for a new feature that would automatically convert the raw bytes read from a .wav file, into floats that would go into the data of an AudioClip through the proper format and algorithm that would leave the sound unaltered.

This should work just fine, per the documentation:

If you’re having a problem with it… instead of trying to hack around what might just be a syntactical error, why not try to figure out why it’s failing.

With that said, I agree, it’d be nice to be able to load audio files on the fly like that.

With some googling I was able to find this person demonstrating how they were able to parse wav files to sample data that could be loaded into an AudioClip:

Thank you. Actually, I already TRIED loading .wav files using both WWW and File:///c:/… They load fine into an empty AudioClip that would have no name. When I loaded them into a variable in the inspector, they show up as a “blank” AudioClip variable in my inspector, and they will not play in my game but will play in the inspector. When I print var.clip.length, it also comes out as 0, which is very strange. That does not happen when I use http://

Thanks for the reply.

In my case, I can’t use WWW, because it forces you to use coroutines, which we are avoiding for all client-server communications.
We are using a custom native Network library (with cache) and proper async Tasks instead. So, the second link is actually useful.

It doesn’t. If you keep WWW around and check it’s progress every frame it works fine. Same with UnityWebRequest, which also has an advantage since 2017.2 that you can connect an event for completion.

1 Like

WWW does not seem to allow loading from local persistent path. Nor does UnityWebRequest…

They do, you just have to provide URI, not path. Pass the absolute path to System.Uri and pass created URI to UnityWebRequest, it should load the file.

In 2021.3.0f1, using UnityWebRequestMultimedia.GetAudioClip sometimes returns garbage. That is, it does return the data from the website, but converting to an AudioClip results in exceptions thrown, either in audioClip = DownloadHandlerAudioClip.GetContent(uwr) or other access to the audio clip after that.

Are you checking for errors?
If your HTTP request end in errors, likely the received content is not an audio content, but something that tells you a reason for failure.

1 Like

Yes, return code is Success. I can see the data in the download handler, it reports the correct length and the values it contains look like a RIFF WAVE stream. However, the audio clip has zero length after GetContent(uwr) is called.
For the time being, I’ve implemented my own wav parser and am using a generic UnityWebRequest to get the data. Not optimal or desired, but it seems the only thing that works ATM. Thankfully I can AudioClip.Create and SetData that into existence OK.

Ok, that sounds strange. I’m glad you cleared that up. Most people try to load unsupported formats or have issues with their hoster and not getting the actual data. However, I’m not sure how “sensitive” Unity is when it comes to mime types of HTTP reponses. Is the mime type / content type actually reported as “audio/x-wav” by your server? Maybe Unity refuses your content based on that.

Try creating DownloadHandlerAudioClip manually and pass the type as a parameter: