deadlyfingers/UnityWav

created audioclips having the wrong time length.

TheFitzyG opened this issue · 3 comments

audio clips created using this are filled with a long period of silence in the file. silence can sometimes be longer that the original audio. this is persistent with many .wav files i have tried. Looking into it further. the file seems to be doubling in length with half being silence. e.g. the first half of the audio clip is the full audio and the second half is just silence.

I think I know what the issue is here... When recording you set the time, but if the record audio clip is shorter then the full audio gets converted including the empty space. This should be timed so only the recorded time gets processed.

I have some newer revisions of the code in another library which rectify this issue, but need to include changes back here #5

https://github.com/Unity3dAzure/UnityWebSocketDemo/blob/master/Assets/BingSpeech/MicRecorder.cs
https://github.com/Unity3dAzure/UnityWebSocketDemo/blob/master/Assets/BingSpeech/WavDataUtility.cs

I'm not sure if this is related, but I ran into an issue where stereo wav files were twice the number of samples they should be once the AudioClip is created. I tracked it down to the offending line:

AudioClip audioClip = AudioClip.Create (name, data.Length, (int)channels, sampleRate, false);

For stereo files data.length will contain the total length of all samples left + right, and yet AudioClip.Create() is only asking for the data length in samples regardless of channels.

In other words let's say you have a file that is 1000 samples in duration. In a stereo file you will have 2000 total samples (1000 left, 1000 right). AudioClip.Create() wants just the duration in samples (1000), but the code is passing in data.length which will be 2000 samples, which is why extra silence is being created. You can verify this by checking AudioClip.samples after creation and comparing to the original wav file's sample length in an audio editor.

I replaced it with this line that takes the number of channels into account and allocates the correct number of samples in the AudioClip regardless of channel count:

AudioClip audioClip = AudioClip.Create (name, data.Length / channels, (int)channels, sampleRate, false);

Not sure if this is related to this issue, but it is an issue nonetheless and an easy fix. Hope this helps.

Thank you @CymaticLabs for pointing out this issue, this really saved me a lot of time spent looking.
Once you make the adjustment that is mentioned above, you will be able to correctly load multichannel Wav files. But when saving the audioclip again to a wav file you need two additional changes:

int fileSize = audioClip.samples * BlockSize_16Bit + headerSize; // BlockSize (bitDepth)

should be changed to:

int fileSize = audioClip.samples * BlockSize_16Bit * audioClip.channels + headerSize; // BlockSize (bitDepth) 

int subchunk2Size = Convert.ToInt32 (audioClip.samples * BlockSize_16Bit); // BlockSize (bitDepth)

should be changed to:

int subchunk2Size = Convert.ToInt32 (audioClip.samples * BlockSize_16Bit * audioClip.channels); // BlockSize (bitDepth)

This makes the data writer keep the amount of channels in account and makes sure that all data is written to a bite stream.