Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Help me understand how use onAudioFilterRead to generate audio

Discussion in 'Audio & Video' started by 00christian00, Mar 3, 2016.

  1. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    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?

    Code (CSharp):
    1.  
    2. public void OnAudioFilterRead(float[] data, int channels) {
    3.  
    4.          
    5.             print("Elapsed: " + (DateTime.Now - OldTime).TotalMilliseconds.ToString());
    6.             OldTime = DateTime.Now;
    7.            
    8. ;
    9.             const int RESCALE_FACTOR = 128;
    10.             if (Player == null) {
    11.              
    12.                 print("no player, returning");
    13.                 return;
    14.             }
    15.             int read = 0;
    16.             /
    17.             read = Player.GetBytes(buffer, data.Length);
    18.  
    19.             for (int i = 0; i < read; i++) {
    20.                 data[i] = (float)buffer[i] / RESCALE_FACTOR;
    21.             }
    22.            
    23.             }
    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.
     
    Last edited: Mar 3, 2016
  2. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    Seem I got it working by making the tracker render the audio at 16 bit, instead of 8.
    Is there no way to make unity expect 8 bit sounds?
     
  3. zhengshencn

    zhengshencn

    Joined:
    Sep 8, 2016
    Posts:
    1
    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?

    Code (csharp):
    1. for (int i = 0; i < read; i++) {
    2.     data[i] = (float)buffer[i];
    3. }
    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.

    Looking forward to your reply.

    Thanks!
     
  4. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    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/is...very-frame-instead-of-reusing-the-same-buffer
     
  5. maxmalmgren

    maxmalmgren

    Joined:
    Sep 14, 2016
    Posts:
    1
    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.
     
  6. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    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.
     
  7. laggyluk

    laggyluk

    Joined:
    Oct 7, 2011
    Posts:
    32
    did you check with empty method to make sure it's not your code?
     
  8. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032