Skip to main content
Search our knowledge base

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

Comments

12 comments

  • 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();
    }

     

    1
  • 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.

    0
  • 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..."

    -1
  • 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

    3
  • 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 )

    0
  • Arnas Cibulskis

    Hi, this doesn't seem to be working in 2018, any suggestions?

    1
  • axi zapantis

    This script used to work in unity 5.6 for my gearvr app.I updated to unity 2018.1.0f2 and the gearvr app freezes on a frame but headtracking continues to work.I know this script is the problem because when i uncheck it the app is working fine...Is there an alternative way to playback a mic in realtime in unity 2018?Thanks.

    0
  • UncleChris

    I just tried this script in 2018.3.0b5 Personal and it is working for me.  I hear the slightly delayed sound in my headphones, so it works. 

    Some slight adjustments:
    I didn't need to include any namespace - it just worked with Microphone,

    Had to use Microphone.devices to get the name of my microphone (since Built-in Microphone didn't exist for my machine).

    0
  • axi zapantis

    The problem in my occassion was caused by the permission request "Record audio" .Even if i had the reference UnityEngine.Microphone in my script it didnt ask for this permission when i was starting my app.I created a new project and copy pasted everything and now it asks for the permission "record audio" and everything works fine like before...

    0
  • rahul patil

    when first microphone is start how to stop for the 5 seconds

    StartCoroutine(RecordVoice());

    IEnumerator RecordVoice()
    {
    yield return new WaitForSeconds(5);
    //Microphone.End(null);
    }

    0
  • wsdfz

    @Megan I tested the codes on Mac and android platforms, there was a little latency on MAC which can satisfy my requirement, but on android platform the latency was longer, and the experience was bad,how to solve this?

    1
  • Paulo Renan

    A slightly more flexible implementation could be like that

    (just save the code below as AudioSourceAssigner.cs and drag it into an empty gameobject)

    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;

    [RequireComponent(typeof(AudioSource))]
    public class AudioSourceAssigner : MonoBehaviour
    {
        [SerializeField] private string useSpecificDevice = "";

        [SerializeField] private int refreshMicEveryNSeconds = 5;

        IEnumerator Start()
        {
            var audio = GetComponent<AudioSource>();

            if (audio == null || Microphone.devices == null || Microphone.devices.Length == 0) yield break;

            string deviceName = Microphone.devices.FirstOrDefault(x =>
                !string.IsNullOrEmpty(x) &&
                (string.IsNullOrEmpty(useSpecificDevice) ? true : x.Contains(useSpecificDevice))
            );
            if (string.IsNullOrEmpty(deviceName)) yield break;

            int minFreq, maxFreq;
            Microphone.GetDeviceCaps(deviceName, out minFreq, out maxFreq);
            int freq = maxFreq;

            foreach (var item in Microphone.devices)
                Debug.Log("Microphone device: " + item);
            Debug.Log("Using: " + deviceName);

            audio.loop = false;
            audio.clip = Microphone.Start(deviceName, true, 10, freq);

            while (Microphone.devices.Any(x => x == deviceName))
            {
                while (!Microphone.IsRecording(deviceName) || !audio.isPlaying)
                {

                    refreshMicEveryNSeconds = Mathf.Clamp(refreshMicEveryNSeconds, 1, 60 * 60); // unity requires this to be between 1 second and an hour
                    audio.clip = Microphone.Start(deviceName, true, refreshMicEveryNSeconds, freq);

                    while (Microphone.GetPosition(deviceName) == 0)
                        yield return null;

                    audio.Play();
                    yield return null;
                }
                yield return null;
            }
            yield return null;

        }
    }

    0

Please sign in to leave a comment.