Follow

How do I get Unity to playback a Microphone input in real time?

Symptoms

  • I want to develop an application with my Microphone device
  • I cannot get real time audio playback from my Microphone input without latency occurring

Cause

You are unable to play back audio from a Microphone source in real time. You may be experiencing one of the following issues:

  • During playback you can hear an inaudible chopped noise
  • The audio recorded continues to play in an infinite feedback loop
  • The audio heard during playback has a fair amount of latency and does not sound immediately.

Resolution

To ensure your Microphone audio plays back in real time:

  1. Firstly, you will need to set the microphone as an AudioClip and attach this AudioClip onto an Audio Source. You will need to set the audio to loop by checking the loop tick box in your Audio Source component in the Inspector. You will then be able to use the spectrum data off the Audio Source, rather than the Audio Listener.
  2. Secondly, you will need to attach a script to the Audio Source which tells Unity that the Microphone device to start recording an AudioClip. For this you will need to call Microphone.Start();

To control latency you will also need to call Microphone.GetPosition(); and choose your desired latency sample rate. If you want no latency you can set this to “0” samples before the audio starts to play. See the below script to see how this script is executed.

Please note that you need to add the permissions to the app (iOS, Android, Windows Phone, Web Player), to use the microphone. The permissions are added if you have a reference to UnityEngine.Microphone in your script.

However, on Android specifically this feature is not strictly required as it breaks compatibility with Android TV.

More Information

For scripting reference to calling Microphone.Start(); then see this document here

For scripting reference to calling Microphone.GetPosition(); then see this document here

 

Was this article helpful?
1 out of 1 found this helpful
Have more questions? Submit a request

5 Comments

  • 1
    Avatar
    Ted Barnett

    Following the instructions above, I still see latency of over 220 msec using the Microphone on Windows, Unity 5.4.1 (see image).  Is that the expected minimum?  I've tried disabling all effects, using both USB and line-in mics, and varying the sample size without success.  

    I'm trying to build a Unity app that allows users to sing through the speakers, but this delay makes singing impossible.  

    Any hints/samples/suggestions appreciated!

     

     My code is as follows:

    using UnityEngine;
    using System.Collections;
    [RequireComponent (typeof(AudioSource))]

    public class MicrophoneOn : MonoBehaviour {

    void Start ()
    {
    AudioSource audio = GetComponent<AudioSource>();
    audio.clip = Microphone.Start(null, true, 100, 44100);
    audio.loop = true;
    while (!(Microphone.GetPosition(null) > 0)){}
    Debug.Log("start playing... position is " + Microphone.GetPosition(null));
    audio.Play();
    }

     

  • 0
    Avatar
    Pino De Francesco

    Unity is not designed for real time mic management, so if you want to create a Karaoke game you can't use Unity internal microphone management.

    Edited by Pino De Francesco
  • 0
    Avatar
    Ted Barnett

    Thanks, Pino.  I thought so, though the text above (from Unity!) deceptively suggests that it CAN work:

    "To ensure your Microphone audio plays back in real time..."

  • 0
    Avatar
    Andy

    Hi Ted,

    There will always be some inherent latency when processing audio. Depending on the platform(s) you are targeting this audio latency will occur at different rates.

    Something you can do if you haven’t yet done so to improve audio latency is by reducing the DSP buffer size: 

    • Edit -> Project Settings -> Audio

           Set DSP Buffer Size to ‘Best Latency’

    Hope this helps.

    Andy

  • 0
    Avatar
    Max Aigner

    Hi Ted,

    If you change your code to that, it is a lot faster and really great:

     

    Snippet

    AudioSource audio = GetComponent<AudioSource>();
           audio.clip = Microphone.Start(null, true, 1, 22050);
           audio.loop = true;
           while (!(Microphone.GetPosition(null) > 0)) { }
           Debug.Log("start playing... position is " + Microphone.GetPosition(null));
           audio.Play();

     

    ( a Pity we cannot change the Microphone LengthSec to 0.1 something or another float, but it's quite nice already.)

     

    yours

     

    Max Aigner

    (Signature: www.maxaigner.de )

    Edited by Max Aigner
Please sign in to leave a comment.