Audio frequency sample on Android (479354)

Hi!
I’m new into unity and i’m trying to build an application that get information from the microphone and show the main frequency of the signal on the screen. I will use this to create an application that do some stuff when a tone in a specific frequency is detected (something like audio augmented reality). Looking in Unity community I found this pos which I found really useful (thank you all who helped with that topic): http://forum.unity3d.com/threads/118215-Blow-detection-(Using-iOS-Microphone)

I’m working now with this code

      private const int SAMPLECOUNT = 1024;
      private const float REFVALUE = 0.1f; 
      private const float THRESHOLD = 0.02f;
     
      private float rmsValue; 
      private float dbValue;   
     
      private float[] samples;         
      private float[] spectrum;        

      public void Start () {
		Application.RequestUserAuthorization (UserAuthorization.Microphone);
		if (Application.HasUserAuthorization (UserAuthorization.Microphone)) {
          samples = new float[SAMPLECOUNT];
          spectrum = new float[SAMPLECOUNT];
          StartMicListener();
		}
      }
     
      public void Update () {
        if (Application.HasUserAuthorization (UserAuthorization.Microphone)) {
          if (!audio.isPlaying) {
            StartMicListener();
          }
     
          AnalyzeSound();
	}
      }
     
      private void StartMicListener() {
        audio.clip = Microphone.Start(null, true, 1, AudioSettings.outputSampleRate);
		audio.loop = true;
		audio.mute = true;
		audio.Play();
      }
     
      private void AnalyzeSound() {
     
        // Get samples from microphone
        audio.GetOutputData(samples, 0);
     
        // Sums squared samples
        float sum = 0;
        for (int i = 0; i < SAMPLECOUNT; i++){
          sum += samples[i] * samples[i];
        }
     
        rmsValue = Mathf.Sqrt(sum / SAMPLECOUNT);
        dbValue = 20 * Mathf.Log10(rmsValue / REFVALUE);
     
        if (dbValue < -160) {
          dbValue = -160;
        }
     
        // Gets the sound spectrum.
        audio.GetSpectrumData(spectrum, 0, FFTWindow.BlackmanHarris);
        float maxV = 0;
        int maxN = 0;
     
        // Find the highest sample.
        for (int i = 0; i < SAMPLECOUNT; i++){
          if (spectrum[i] > maxV  spectrum[i] > THRESHOLD){
            maxV = spectrum[i];
            maxN = i; // maxN is the index of max
          }
        }
     
		float freq = maxN * 24000 / SAMPLECOUNT;
		gameObject.guiText.text = freq.ToString ();
      }

I’ve run the application on a Macbook, and it works fine, I generate tones of several frequencies and it shows correctly. However, if I run on an Android device, the frequency shown is incorrect (it’s value seems to be halved in most cases, although in some frequencies it keeps another proportion). I tested a native android application which shows audio spectrum and it works fine, so I don’t think it’s a hardware problem of my device. Is this a Unity bug compiling into Android? I’m using Unity 3.5.1.

Thank you

Not sure if you’ve solved your problem but , have you tried using Microphone.GetDeviceCaps, instead of using output.samplerate ?

I have the same problem, I described it here: Frequency spectrum on android to the one on my mac - Unity Engine - Unity Discussions

Can anybody help?

It is a real late answer but I will share my thoughts if anyone else is looking for answer. (I am basically enhancing james’s answer.)

Before using Unity’s default audio settings, you need to check for the hardware capabilities and set your values according to it:

Microphone.GetDeviceCaps(null,out minFrequency,out maxFrequency);

For my case AudioSettings.outputSampleRate was 48000 but my microphone’s max frequency capability was 44100. I have set that value and everything works fine.