I am trying to play a sound generated from script and want to use OnAudioFilterRead.
I made some test and it seem that it is not called costantly at 23ms or whatever the samplerate needs.
In my tests I see it’s often called two times consecutively, one at the correct time, and one immediately after that…
So do I need to keep track myself of the buffer playback? If so, how?
public void OnAudioFilterRead(float[] data, int channels) {
print("Elapsed: " + (DateTime.Now - OldTime).TotalMilliseconds.ToString());
OldTime = DateTime.Now;
;
const int RESCALE_FACTOR = 128;
if (Player == null) {
print("no player, returning");
return;
}
int read = 0;
/
read = Player.GetBytes(buffer, data.Length);
for (int i = 0; i < read; i++) {
data[i] = (float)buffer[i] / RESCALE_FACTOR;
}
}
The player is set to work at whatever Sample rate unity report, but it seem that OnAudioFilterRead is being called to match a samplerate of 48khz no matter what the AudioSettings.outputSampleRate report, the only difference is that if for example i set it at 24khz it will get called every 46ms roughly plus another time immediately after, while at 48khz it’s more spread out evenly.
Sorry for my stupid question (totally newbie to C# programming & Unity), but I couldn’t help but wondering how could it be safe if you set items to array ‘data’ without checking boundaries of it? Could it be just a standard way to using it like that in this context?
for (int i = 0; i < read; i++) {
data[i] = (float)buffer[i];
}
I also met the similar problem as we need to decode AAC fragment to PCM from a RTMP stream, and feed it to Unity. I think OnAudioFilterRead() could be the solution to keep audio playback continuously while downloading & decoding are happened in the background (in a plugin DLL). But feeding data like this (without checking boundaries) looks not right to me.
I don’t check in that particular code because the buffer is being fed from a method that accept data.length as a parameter so read bytes is always less of data.length.
Be careful that there is still a bug of onAudioFilterRead that continuosly allocate memory on the garbage collection( although it’s not reported in the profiler) causing the garbage collection to fire continuously and resulting in frame rate spikes. https://issuetracker.unity3d.com/issues/onaudiofilterread-allocates-memory-every-frame-instead-of-reusing-the-same-buffer
Christian, do you know if that garbage collection issue is iOS only or if it is applicable to all platforms? The issue itself only mentions iOS, but it seems to me like it should specifically say iOS only if that was the case.
It should be for all platforms. I had reported that on iOS it was easier to verify due to XCode tools that let you check the Unity Garbage collector thread, but was definitively something in Unity core code common to all platforms.