2

I'm making a cross platform application, with the game engine Unity, that simply takes images and audio files (.ogg) from a bucket made with the Amazon Simple Storage Service (Amazon S3). I'm having a problem converting audio files, represented in bytes, to AudioClips.

I have already tried the solutions from both links:

create AudioClip from byte

Noisy audio clip after decoding from base64

But both solutions doesn't resolve my problem, there is still the static sound after the conversion process from bytes to array.

Another solution I tried is to use the UnityWebRequestMultimedia and taking the audio from the url that every single object has in the bucket. This solution works only on the standalone version of the application (PC,Linux,Mac OS). When I try my application on an smartphone, with Android as OS, the UnityWebRequestMultimedia doesn't send the request and that's why I'm trying again to convert the bytes of the object taken from S3 to audioclip.

Every Audio file on S3 is an .ogg file with the following properties:

Properties of every file audio file

//Method that takes the bytes of the audioclip
    private AudioClip GetMediaBytesFromS3 (Amazon.Runtime.AmazonServiceResult<GetObjectRequest,GetObjectResponse> ServiceResult,string nameOfAudio)
        {
            //Take the bytes of the audio
            byte[] mediaBytes = GetBytesFromMultimediaObject(ServiceResult);

            //Make a float array
            float[] floatMediaBytes = new float[mediaBytes.Length / 4];



            for(int i=0;i<floatMediaBytes.Length; i++)
            {
                //Check if the architecture use the LittleEndian ordering of Bytes
                if(BitConverter.IsLittleEndian)
                {
                    Array.Reverse(mediaBytes,i*4,4);
                }

                floatMediaBytes[i] = ((float) BitConverter.ToInt16(mediaBytes,i*4)) / 0x80000000;
            }

            //Make a new audioclip
            AudioClip clipAudio = AudioClip.Create(nameOfAudio,floatMediaBytes.Length,1,16000,false);
            //See if the data are set
            if(clipAudio.SetData(floatMediaBytes,28))
            {

                return clipAudio;
            }

            return null;
        }

I simply want the audio be played correctly without the static noise.

Simone
  • 146
  • 2
  • 13
  • if you manually attach the .ogg file does it work? does it sound right? – BugFinder Apr 09 '19 at 14:07
  • 1
    If the bytes represent an ogg format file (complete with headers and compressed using an audio codec) you can't simply read them and convert them to audio sample values. You need to load the ogg file into AudioClip in such a way that it knows it's an ogg file and can decompress the audio samples, or you need to decompress the ogg file to a stream of values and then work with them. – Ian Mercer Apr 09 '19 at 14:21
  • @BugFinder No you can't simply give the array of byte to an object of type AudioClip. In the [Unity Manual](https://docs.unity3d.com/ScriptReference/AudioClip.SetData.html) to set the data of an audioclip you must have an array of float and give the array to the audio clip. – Simone Apr 09 '19 at 15:53
  • @IanMercer Unfortunately I'm not an expert of decompressing files or conversion because I never did projects about this kind of stuff. The files on the bucket are .ogg files without any compression and with headers so this must be the problem. I have tried a different approach by writing all the bytes, not the ones converted in float, in a temporary folder using the **File.WriteAllBytes** and I got the .ogg file but the problem of using this method is the slowness and also I had to save it until the user stops using the app which is not what I really want. – Simone Apr 09 '19 at 18:57

1 Answers1

0

What you are doing looks quite all right - that has all the reasons to work fine - as long as data is in stored in the raw, uncompressed PCM stream. If its not - well its kind of the same as reading bytes from a JPG file and expect to find colors there. You will need to feed the data into an apropriate decoder first

quick google allowed me to find this link https://archive.codeplex.com/?p=nvorbis

I have not used it myself but it seems to fit the bill. Alternatively you could link to a .dll and do the decoding on the unmanaged side using some PInvokes

zambari
  • 4,797
  • 1
  • 12
  • 22
  • Thank you for answering me @zambari. The .ogg files aren't compressed but yesterday I tried to write all the bytes, without doing the conversion to float, in a temporary folder and I got the audio correctly. The problem is the method of the **AudioClip** class that asks a float array. I can't use the software from the link you provided because I'm working on a *non commercial project* where I can only use free/freeware softwares. Even if **Unity Personal Edition** it's free my application is *non commercial* so I don't have problems to use it. – Simone Apr 10 '19 at 18:57