I’m doing some Fourier transform work that manipulates the sound data that enters Unity’s OnAudioFilterRead method. When I try to re-fill the buffer with the modified data, it simply doesn’t produce any sound.
I’ve checked that there is actually numerical data being passed into the buffer. However, I’m just not getting any playback. I’ve attached the script that contains the OnAudioFilterRead method to an object in the scene that is also an AudioSource (without a clip attached). Am I doing something else wrong?
I’m not completely sure how it all works I’m about to figure it out but this should produce something.
AudioClip myClip = AudioClip.Create("MySound", 44100, 1, 44100, false, false, OnAudioRead);
//Set the data of the clip
myClip.SetData(dataArray, 0);
audio.clip = myClip;
audio.Play
Btw for as far I’ve seen, if you set your data this way you don’t have to put any code in the OnAudioRead function (although you could). I assume the function get its data from SetData and puts it back into the data array that OnAudioRead uses.
So basically what I’m doing in the OnAudioFilterRead method is passing the float[ ] data variable to a method that does some processing on it and returns a new 1D array. I then set data equal to this newly created array. The problem is, no matter what I do to change the values, the sound output is the same. I’ve even tried multiplying all of the values in data by ridiculously high numbers, but it has no effect on the sound that plays.
EDIT: To clarify my scene setup: the script with OnAudioFilterRead implemented is attached to a “target” object that is also an AudioListener. The AudioSource comes from a different object.
I guess I’m just confused by the mechanics of the OnAudioFilterRead function. Does it collect all of the sound data from the scene? And if so, how do you go about applying effects to the data that “passes through” OnAudioFilterRead? I know that ‘data’ is passing through because when I print out all of the values in the float[ ] data array, it certainly contains many non-zero values. My problem is how to alter and then output only the altered version of the sound.
I’m not completely sure which of the two functions you should use to play back samples, but I’m using OnAudioRead and it does the trick. I first create a new audioclip, an array of floats, and set the floatdata with audio.SetDeta(). Actual playback of the created sound I do with audio.Play
Btw my OnAudioRead function looks like this. As you can see it’s empty and that’s alright to just try this out and make it work.
void OnAudioRead(float[] data)
{
//this is just empty
}
I used OnAudioFilterRead in the past and never had any issues. I just copyied, again, the example provided in the documentation and slapped it onto a gameobject with an AudioSource component, hit play and I can hear the generated beat. So I have no idea what your issue is. Maybe you don’t have an AudioSource on your object. Though, if you copied the whole example script, let it compile and then put the script onto a gameobject, it should have added an AudioSource automatically since it has a RequireComponent attribute. However attaching the script before the attribute was added to the class, had no effect. RequireComponent is a pure editor attribute which only take effect when you actively attach a script in the editor.
It definitely works. Check the “Mute Audio” button in your Game window. Check the master volume settings in PlayerSettings. Check your computer’s volume control. Check the audio output device routing. Put a WAV file in your project and preview it in the inspector, etc.
This thing is completely random. Somehow a button to play audio in inspector fixes it (same method call from code in Update doesn’t work). Hopefully it’s only so bugged in editor.
edit
If float[ ] data isn’t change at all and audio clip is over audio source will stop playing. Simply set [0] = 0.001 to prevent it.