Converting AudioListener.GetOutputData to a wav file
Hello @aldonaletto,
I've read your helpful forum posts about audio in Unity, and I'm wondering if you might be able to help me. (Anything would be appreciated!)
Not for lack of googling I am tearing my hair out trying to understand how GetOutputData works, and how to transform that data into a file. This is my first attempt wrangling with audio, so I might get some terminology wrong. Bear with me...
My task is to use the AudioListener as a simulated microphone in a simulated 3D environment, and then export the "recorded" audio as a wav file (or similar uncompressed audio format). My AudioSource clip is playing a 10 second wav file at 44100hz.
I imagined that if I capture the right number of samples for each frame and store them in a list, then that list should translate into the recorded audio. Instead it's... something else (sounds like the clicks of a record player stuck at the end of the record).
I'm obviously missing something about how GetOutputData() works; there is surprisingly little documentation / forum posts I can find that explain what that gets and how to use it. (Most of them are of the sort "GetOutputData() gets your output data and stores them in a float array based on how many samples you want", which might make sense to somebody who understands what that data is in the first place, but it does not make sense to me.)
This is the code attached to my main camera, which has the AudioListener as well as its own AudioSource component for capturing the "recorded" clip. The other AudioSource clip is playing on an empty object nearby.
private float[] outputData;
private List<float> outputValues;
private float[] outputValuesFloat;
public AudioClip thisAudio;
// Use this for initialization
void Start () {
outputData = new float[512];
Invoke("PlayData", 5);
outputValues = new List<float>();
thisAudio = AudioClip.Create("thisAudio", 110592, 1, 44000, false);
}
// Update is called once per frame
void Update () {
AudioListener.GetOutputData(outputData, 0);
for (int i = 0; i < outputData.Length; i++)
{
outputValues.Add(outputData[i]);
}
}
void PlayData()
{
outputValuesFloat = new float[outputValues.Count];
int j = 0;
foreach (float thisFloat in outputValues)
{
outputValuesFloat[j] = thisFloat;
j++;
}
thisAudio.SetData(outputValuesFloat, 0);
this.GetComponent<AudioSource>().clip = thisAudio;
this.GetComponent<AudioSource>().Play();
Answer by JasonBennett · Jul 24, 2018 at 02:26 PM
Hey Towerss,
I did end up solving it, by bypassing the AudioListener and doing a basic calculation of spatial audio myself. Then I just calculated the distance from my "listener" to the AudioSource, and used the AudioSource.GetOutputData with my custom spatial audio calculation applied.
In terms of writing the data to a WAV file, I used this script: https://gist.github.com/darktable/2317063
Shoutout to darktable for writing it :)
-Jason
Thanks Jason for your reply. $$anonymous$$y issue was that the gameobject and the component AudioListener were hidden with a combination of a combination of [HideInInspector], HideFlags.HideInHierarchy, and HideFlags.HideInInspector. Once I figured out where to find them all good. Thanks :)
Hey Jason! Im in the exact same situation. Im trying to make sense on how to record the mixed audio through audio listener. At the moment i get sound data that resembles the audio but its very weird and garbled. I understand that you instead took the audio data from all audiosources playing and mixed them programmatically to get the audio data? Would you $$anonymous$$d sharing how? I agree that its weird that this function is not very well documented with and example. And i cant either seem to find someone explaining how its supposed to be used.
@Lautaro-Arino This post in SO might be handy: https://stackoverflow.com/questions/50302315/save-audio-stream-float-frames-as-wav-with-c-sharp I do not have the source code I used, because it was a contract project, but I used that answer to actually save the audio file. hope it helps.
Thanks! But I'm looking to get the audio data out of the audio listener and play it back. I think I have the save to file covered. Do you have any other tip?
Your answer