Get the FULL version

Unity: Capturing audio from a microphone

Unity: Capturing audio from a microphone thumbnail

This Unity programming tutorial explains how to create a Unity script to capture the audio from a microphone. It also shows how to playback the captured audio and the necessary steps to check if there is a microphone present and its recording capabilities. The code featured in this post has been developed and tested using Unity 3.5.4f1 at the editor and a as a standalone Windows application. A sample project with all the code discussed in this tutorial is available for download at the end of the post.

To capture the audio input from a microphone in Unity, one can simply call the static Start() method from the Microphone class to start recording. This method returns an AudioClip that can be played back using an AudioSource. And that’s exactly what the script explained in this post will do. However, to avoid exceptions from being thrown, there is a simple verification to detect if there’s a microphone present prior to calling this method, and also, the mic audio capture capabilities are checked. Luckily, the same Microphone class also offers public members and methods that aid in accomplishing the two aforementioned tasks.

So, here’s the script:

using UnityEngine;
using System.Collections;

[RequireComponent (typeof (AudioSource))]

public class SingleMicrophoneCapture : MonoBehaviour 
{
	//A boolean that flags whether there's a connected microphone
	private bool micConnected = false;

	//The maximum and minimum available recording frequencies
	private int minFreq;
	private int maxFreq;

	//A handle to the attached AudioSource
	private AudioSource goAudioSource;

	//Use this for initialization
	void Start() 
	{
		//Check if there is at least one microphone connected
		if(Microphone.devices.Length <= 0)
		{
			//Throw a warning message at the console if there isn't
			Debug.LogWarning("Microphone not connected!");
		}
		else //At least one microphone is present
		{
			//Set 'micConnected' to true
			micConnected = true;

			//Get the default microphone recording capabilities
			Microphone.GetDeviceCaps(null, out minFreq, out maxFreq);

			//According to the documentation, if minFreq and maxFreq are zero, the microphone supports any frequency...
			if(minFreq == 0 && maxFreq == 0)
			{
				//...meaning 44100 Hz can be used as the recording sampling rate
				maxFreq = 44100;
			}

			//Get the attached AudioSource component
			goAudioSource = this.GetComponent<AudioSource>();
		}
	}

	void OnGUI() 
	{
		//If there is a microphone
		if(micConnected)
		{
			//If the audio from any microphone isn't being captured
			if(!Microphone.IsRecording(null))
			{
				//Case the 'Record' button gets pressed
				if(GUI.Button(new Rect(Screen.width/2-100, Screen.height/2-25, 200, 50), "Record"))
				{
					//Start recording and store the audio captured from the microphone at the AudioClip in the AudioSource
					goAudioSource.clip = Microphone.Start(null, true, 20, maxFreq);
				}
			}
			else //Recording is in progress
			{
				//Case the 'Stop and Play' button gets pressed
				if(GUI.Button(new Rect(Screen.width/2-100, Screen.height/2-25, 200, 50), "Stop and Play!"))
				{
					Microphone.End(null); //Stop the audio recording
					goAudioSource.Play(); //Playback the recorded audio
				}

				GUI.Label(new Rect(Screen.width/2-100, Screen.height/2+25, 200, 50), "Recording in progress...");
			}
		}
		else // No microphone
		{
			//Print a red "Microphone not connected!" message at the center of the screen
			GUI.contentColor = Color.red;
			GUI.Label(new Rect(Screen.width/2-100, Screen.height/2-25, 200, 50), "Microphone not connected!");
		}

	}
}

At the beginning of this script, four, member variables are being declared: a boolean, a pair of integers and an AudioSource. The boolean flag is set to tell whether there’s a microphone attached or not. The two integers will later in the code store the maximum and minimum available sampling frequencies for audio recording with the default microphone. Lastly, the AudioSource object is going to be the one responsible for playing back the recorded audio (lines 9 through 16).

The Start() method is basically composed of a single if statement, that tests whether the string static array named devices at the Microphone class has a length greater than zero (line 22). A length equal to zero means that there is no connected microphone. In this case, a warning message is printed at the console (line 25). Otherwise, if the length of the devices array is greater than one, the audio recording and playback variables are initialized.

This is done by first assigning true to micConnected (line 30). Then calling the static method GetDeviceCaps() from the Microphone class (line 33). This method gets the audio recording capabilities of the device’s microphone. It receives three parameters: a string with the microphone name and two integers for the maximum and minimum frequencies. In the above script, null has been passed as the first parameter and according to the documentation; “[…] Passing null or an empty string will pick the default device“. If there’s just a single microphone attached to the computer, this won’t be a problem. Nevertheless, to target a specific microphone, you just need to pass its name to this first parameter.

Still on the GetDeviceCaps() method, the second and third parameters are respectively, the maximum and minimum recording frequencies supported by the device. This method take these two parameters with an out modifier, meaning that any value alteration made to the minFreq and maxFreq inside the method will be maintained after the method has finished its execution. It’s roughly similar as passing a reference parameter to a function in C++. Again, quoting the documentation, if the maximum and minimum frequencies values are zero, the microphone supports any recording sampling frequency.

This test is done on the following if statement (lines 36 to 40), and being true, the maxFreq value is set to 44100. The last member variable to be initialized is the goAudioSource by obtaining a reference to the attached AudioSource on the same Game Object the script is linked to.

The OnGUI() method is responsible for rendering the controls to start recording, stop and playback the recorded audio. As the Start() method, this one is composed basically of a single if statement that checks the value of the micConnected boolean (line 53). If that’s false, no microphone is connected, so a red “Microphone not connected!” message is rendered at the middle of the screen (lines 74 through 79).

When a microphone is connected, the other block of code is executed, which checks if any microphone audio input isn’t being recorded (line 53). Case that’s true, the ‘Record‘ button is rendered to the user and by clicking on it, the audio from the microphone will get recorded (line 56).

As previously mentioned, the Microphone.Start() method will be the one responsible for capturing the audio from the microphone (line 59). The first parameter it takes is a string with the name of the microphone we wish to record from. Again, passing null will make Unity pick up the default microphone. The second parameter takes a boolean that indicates whether the recording should continue if the length defined on the third parameter is reached. Passing true as in the above script makes the audio recording wrap around the length of the audio clip and record from the beginning. And the third parameter, as explained, is the length of the AudioClip this method returns. To put in a simplified manner, in this script, if an audio recorded from a microphone has 23 seconds, the final 3 seconds will be recorded over the initial 3 seconds. So, the maximum recording time is 20 seconds in this script. The AudioClip returned by this method is assigned as the AudioClip of the goAudioSource.

And, if there’s at least one microphone and the audio from one of them is being recorded, the ‘Stop and Play‘ button is rendered (line 65). Pressing it will stop the audio recording and play it back (lines 67 and 68). Just like the other static methods from the microphone class, the End() method takes a string that tells Unity which microphone the recording should be stopped. It also accepts null as a parameter to select the default microphone.

And that’s it! Here are some screenshots of the application in action:

Record Button

If there were no microphones connected, a red text label stating that no microphones were found would have been rendered, instead of the ‘Record’ button.

Stop And Play Button

Press this button to stop the recording and start the audio playback.

Final Thoughts

As stated in the beginning of the post, this code has only been tested on the editor and as a Windows standalone application, on a computer. It should work without much changes on the web player, by setting the necessary permissions. I’m not sure it will work when targeting mobile platforms, even if the correct permissions are set. It works on iOS devices, as pointed out by Scottie (thanks!). I’m not sure whether it works on Android. Also, this script requires an attached AudioSource to the same game object it has been linked to. But don’t worry, attaching this script will automatically add the necessary component, because of the RequireComponent directive.

Downloads

Please share your thoughts in the comments!

11 Comments to “Unity: Capturing audio from a microphone”

  1. Benoit Dupuis says:

    Exactly what I needed and works perfectly. Thanks a lot!

  2. Prabhu says:

    Hi, I tried this, its very nice.I got one doubt , when we are recording it is recording every audio which of low freq.But can we record only our voice without all other small sounds.

    And, is there any way to store our recorded sound to word format.like If I am speaking “Hi”

    it should store in some variable x=”Hi”;. Thanks.

  3. Prabhu says:

    Hi, I tried this, its very nice.I got one doubt , when we are recording it is recording every audio which of low freq.But can we record only our voice without all other small sounds.

    And, is there any way to store our recorded sound to word format.like If I am speaking “Hi”

    it should store in some variable x=”Hi”

  4. Scottie says:

    Just thought I’d let you know that the microphone works perfectly on the iOS devices, no changes were needed whatsoever. This is a brilliant tutorial and I hope you do more Unity tutorials in the future. Well done!

  5. rafiq says:

    wow , thx

  6. izzoell says:

    Is it work on android too?

  7. Krodil says:

    hey,
    Great work!
    How can this be used to also save a wav file?
    Best

  8. Rhenns says:

    i can´t do it work in android..anyone can help me?
    thanks a lot
    great tutorial.

  9. Abhiansh says:

    Hi,
    i want to save the audio clip in memory onces i record it how can i do that

Leave a Reply to Benoit Dupuis

Post Comments RSS