Hello everyone!
1 . For my project I want to use voice recognition with input from the microphone, for this I need raw sound data (pcm). Using the Unity Audio system, I used the AudioClip.GetData() method I received float numbers and converted them to pcm and everything worked as expected.
The problem arose when I needed to change the audio system to fmod. After searching through a bunch of forum articles and trying thousands of lines of code, I got nothing. So just for testing I decided to try to just get the data from a pre-recorded audio file (I used a microphone before) and test everything on it.
To check the reliability of the received data, I decided to create a unity audio clip with the data (bytes) that I received from the fmod, but instead of my recorded sound I got a crackling sound.
Sound that i used: record.wav - Google Drive
For this experiment I used the code written from this topic (AudioClip.GetData Equivalent in FMOD?) and and at the end got this code:
public class Test: MonoBehaviour
{
public string FilePath;
public byte[] Bytes;
public float[] Floats;
public AudioSource Source;
public AudioClip Clip;
[ContextMenu("Play")]
public void CreateAudioClipFromBytesAndPlay()
{
Bytes = GetSampleData(FilePath);
Floats = ConvertByteToFloat(Bytes);
Clip = AudioClip.Create("testSound", Floats.Length, 1, 44100, false);
Clip.SetData(Floats, 0);
Source.clip = Clip;
Source.Play();
}
private float[] ConvertByteToFloat(byte[] bytes)
{
float[] samples = new float[bytes.Length / 4];
Buffer.BlockCopy(bytes, 0, samples, 0, bytes.Length);
return samples;
}
/// <summary>
/// Return sample data in a byte array from an audio source using its file path
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private byte[] GetSampleData(string filePath)
{
// Very useful tool for debugging FMOD function calls
FMOD.RESULT result;
// Sound variable to retrieve the sample data from
FMOD.Sound sound;
// Creating the sound using the file path of the audio source
// Make sure to create the sound using the MODE.CREATESAMEPLE | MDOE.OPENONLY so the sample data can be retrieved
result = FMODUnity.RuntimeManager.CoreSystem.createSound(filePath, FMOD.MODE.CREATESAMPLE | FMOD.MODE.OPENONLY, out sound);
// Debug the results of the FMOD function call to make sure it got called properly
if (result != FMOD.RESULT.OK)
{
Debug.Log("Failed to create sound with the result of: " + result);
return null;
}
// Retrieving the length of the sound in milliseconds to size the arrays correctly
result = sound.getLength(out uint length, FMOD.TIMEUNIT.MS);
if (result != FMOD.RESULT.OK)
{
Debug.Log("Failed to retrieve the length of the sound with result: " + result);
return null;
}
// Buffer which the sample data will be copied too
System.IntPtr buffer;
// Creating a pointer to newly allocated memory
// This pointer must be released at the end of the function!
buffer = Marshal.AllocHGlobal((int)length * sizeof(byte));
// Creating the return array which will have the sample data is a readable variable type
// Using the length of the sound to create it to the right size
byte[] byteArray = new byte[(int)length];
// Retrieving the sample data to the pointer using the full length of the sound
result = sound.readData(buffer, length, out uint read);
if (result != FMOD.RESULT.OK)
{
Debug.Log("Failed to retrieve data from sound: " + result);
return null;
}
// Make sure the pointer has been populated
if (_buffer != System.IntPtr.Zero)
{
// Coping the data from our pointer to our usable array
Marshal.Copy(buffer, byteArray, 0, (int)length);
}
//Releasing the pointer
Marshal.FreeHGlobal(buffer);
//Returning the array populated with the sample data to be used
return byteArray;
}
}
2 . If I uncheck the “Use Unity Audio System” checkbox in project settings to use exclusively the Microphone class in Unity to record data to audioclip, will I not break anything in the fmod system?
2 . 1 . If this is possible, then can I then process the raw data from audio clip using fmod?
Thanks