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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Bug OnAudioFilter and samples rate

Discussion in 'Audio & Video' started by Davide, May 12, 2020.

  1. Davide

    Davide

    Joined:
    Sep 19, 2012
    Posts:
    13
    Hi,
    i'm developing a real time streaming chat and stumbled upon this problem.

    The code is much more complex but for the sake of simplicity i'll summarize what i'm doing and expose just what is giving me the problem.

    If i record the mic like this, on the client side:

    Code (CSharp):
    1.  void Init_Mic()
    2.     {
    3.         audioSource.clip = Microphone.Start(null, true, 120, 44100);
    4.         audioSource.loop = true;
    5.         audioSource.Play();
    6.     }
    7.  
    8. void OnAudioFilterRead(float[] data, int channels)
    9.     {
    10.  
    11.         samples = new float[data.Length];
    12.  
    13.         for (int x = 0; x < data.Length; x++)
    14.         {
    15.             samples[x] = data[x];
    16.         }
    17.  
    18.         client.ReceiveData(samples);
    19.     }
    20.  
    It works GREAT. Minimum delay and no artifacts. But of course i need to compress the data through an encoder before sending the packets to the network socket. To do such a thing, i need to resample my microphone input to 8000hz, or 16000hz for example (Speex or Opus encoders i.e.) and here come the problems.

    If i simply change the microphone clip samplerate from 44100hz to 8000hz (or any other sampling rate for that matter), onaudiofilterread completely breaks and doesn't give me the resulting data correctly (the input audio is glitchy like some data is missing).

    The only way to get correct samples from a 8000hz mic input is to do something like this:

    Code (CSharp):
    1.   if (Microphone.GetPosition(null) >= last_pos + mic_samples_buffer)
    2.         {
    3.  
    4.             float[] samples = new float[mic_samples_buffer];
    5.             goAudioSource.clip.GetData(samples, last_pos);
    6.  
    7.             bufferHandler.AddArrayToBuffer(samples);
    8.  
    9.             last_pos = Microphone.GetPosition(null);
    10.         }
    Getting samples through GetData() function of the audioclip is not the solution tho because is slow and can only run on the main thread (i.e. Update()).

    Also, i tried to change the global outputSampleRate of the project (and tried various dsp sizes) but the problem persists. The samplerate that works is 44100.

    It looks like OnAudioFilter doesn't adapts anymore to the samplingRate changes.
    I'm absolutely sure it was POSSIBLE, previously (i've been working as an audio designer / coder for years in a commercial company) just by settings an empty clip with different samplingRate on the audiosource on the same object where the onAudioFilter code runs.

    Can anybody confirm this is a bug?
    In case, can anybody point me to an older Unity version where this was used to work?

    I've been pulling my hair on this for days... :)
     
    Last edited: May 13, 2020
  2. marc_tanenbaum

    marc_tanenbaum

    Unity Technologies

    Joined:
    Oct 22, 2014
    Posts:
    637
    Looks suspicious. One of our engineers said this:

    So maybe check the drivers to be sure that the frequency you've picked is supported. If that checks out, would you mind filing a bug report by following the instructions here?
     
  3. Davide

    Davide

    Joined:
    Sep 19, 2012
    Posts:
    13
    Hello, thanks so much for your reply! Yes, microphone should support the frequency indeed if i use GetData() to get the samples from a null microphone audioclip at 8khz, it works good (Microphone is a Blue Yeti studio professional USB mic) I'll also try to check my drivers and i'll export the project on another computer (Dell notebook). If it reproduces everywhere i'm gonna report the bug for sure. Happy to help.
     
  4. Davide

    Davide

    Joined:
    Sep 19, 2012
    Posts:
    13
    Ok sooooo i digged more and more into the problem.

    Bad news and good news.

    The bad news: my microphone has no problems to record at 8000hz if i set this sample rate on Windows 10.
    I've also bought a new cheap mic to try, and i got the same result.

    The good news: i built the project to try it on another machine and... MAGIC. IT WORKS GREAT!
    The issue is present only in the editor but not in the build.
    I've been banging the head in the wall for a whole week and the thing was working since the beginning but i didn't think to make a build... shame on me.

    Anyways, i wrote a new project from scratch containing just the minimum to reproduce the bug and sent it to the bug tracker. I can always reproduce the issue on my machine, i hope you can do the same.

    Regards.

    Davide C.
     
    marc_tanenbaum likes this.
  5. marc_tanenbaum

    marc_tanenbaum

    Unity Technologies

    Joined:
    Oct 22, 2014
    Posts:
    637
    Great! Thanks for filing the report, and glad to hear you have a (bit of a) workaround.
     
  6. Davide

    Davide

    Joined:
    Sep 19, 2012
    Posts:
    13
    More on this:

    Setting the entire output sample rate of the project to 8000hz / 16000hz (Project settings --> audio) and leaving the microphone input at 44.1khz like this:

    Code (CSharp):
    1. audioSource.clip = Microphone.Start(null, true, 120, 44100);
    2.         audioSource.loop = true;
    3.         audioSource.Play();
    Works. The microphone input is correctly downsampled (along with the entire project).
    I'm sure because i'm passing the data to an encoder which expect a certain rate and it goes very well (i'm so F***in happy about it!)

    But if i also set the mic input to the project samplerate (8000 or 16000), that makes the onAudioFilter go nuts. :)
     
    WendelinReich likes this.