Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

IOS and Android Frequency detection

Discussion in 'Scripting' started by Tongie, Jul 28, 2014.

  1. Tongie

    Tongie

    Joined:
    Sep 19, 2012
    Posts:
    90
    Hi guys, I am trying to achieve frequency detection of 15k, 17k and19k but there will always be noise and distance problem which distort the frequency received how can i improve it. The scripts actually works but i want to further improve the detection.

    Really need help on this... Thanks guys!

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class FrequencyDetector : MonoBehaviour
    5. {
    6.     private GameObject _gameObject;
    7.     public FrequencyMenu frequencyMenu;
    8.  
    9.     private int _samplingCount = 2048;
    10.     private float _frequency;
    11.     private int _samplerate;
    12.     private float[] _data;
    13.  
    14.     public tk2dTextMesh freqText;
    15.  
    16.     void Awake ()
    17.     {
    18.         _gameObject = gameObject;
    19.         Application.targetFrameRate = 60;
    20.         AudioSettings.outputSampleRate = 44100;
    21.         _data = new float[_samplingCount];
    22.         _samplerate = AudioSettings.outputSampleRate;
    23.     }
    24.  
    25.     void Start ()
    26.     {
    27.         initMic();
    28.     }
    29.  
    30.     void Update ()
    31.     {
    32.         analyzeSound();
    33.         findRange();
    34.         setFreqText();
    35.     }
    36.  
    37.     private void setFreqText()
    38.     {
    39.         freqText.text = _frequency.ToString();
    40.         freqText.Commit();
    41.     }
    42.  
    43.     public void initMic()
    44.     {
    45.         Application.RequestUserAuthorization (UserAuthorization.Microphone);
    46.         if (Application.HasUserAuthorization (UserAuthorization.Microphone))
    47.         {
    48.             audio.loop = true;
    49.             audio.mute = true;
    50.             audio.clip = Microphone.Start(null, true, 1, _samplerate);
    51.             while (!(Microphone.GetPosition(null) > 0))
    52.                 audio.Play();
    53.         }
    54.     }
    55.  
    56.     public void StartMic()
    57.     {  
    58.         _gameObject.SetActive(true);
    59.         audio.clip = Microphone.Start(null, true, 1, _samplerate);
    60.         while (!(Microphone.GetPosition(null) > 0))
    61.             audio.Play();
    62.     }
    63.  
    64.     public void StopMic()
    65.     {
    66.         Microphone.End(null);
    67.         _gameObject.SetActive(false);
    68.     }
    69.  
    70.     private void analyzeSound()
    71.     {
    72.         audio.GetSpectrumData(_data, 0, FFTWindow.BlackmanHarris);
    73.         float max = 0f;
    74.         int maxN  = 0;
    75.         for (int i = 0; i < _samplingCount; ++i)
    76.         {
    77.             if (_data[i] > max)
    78.             {
    79.                 max = _data[i];
    80.                 maxN = i;
    81.             }
    82.         }
    83.         _frequency = maxN * (_samplerate / 2) / _samplingCount;
    84.     }
    85.  
    86.     private void findRange()
    87.     {
    88.         if ((_frequency > 18970 && _frequency < 19030) ||
    89.             (_frequency > 16970 && _frequency < 17030) ||
    90.             (_frequency > 14970 && _frequency < 15030))
    91.         {
    92.                     // Do something
    93.         }
    94.         else if ((_frequency > 19070 && _frequency < 19130) ||
    95.                  (_frequency > 17070 && _frequency < 17130) ||
    96.                  (_frequency > 15070 && _frequency < 15130))
    97.         {
    98.                   // Do something
    99.         }
    100.         else if ((_frequency > 19170 && _frequency < 19230) ||
    101.                  (_frequency > 17170 && _frequency < 17230) ||
    102.                  (_frequency > 15170 && _frequency < 15230))
    103.         {
    104.                      // Do something
    105.         }
    106.         else if ((_frequency > 19570 && _frequency < 19630) ||
    107.                  (_frequency > 17570 && _frequency < 17630) ||
    108.                  (_frequency > 15570 && _frequency < 15630))
    109.         {
    110.                      // Do something  
    111.         }
    112.         else if ((_frequency > 19670 && _frequency < 19730) ||
    113.                  (_frequency > 17670 && _frequency < 17730) ||
    114.                  (_frequency > 15370 && _frequency < 15430))
    115.         {
    116.                    // Do something  
    117.         }
    118.         else if ((_frequency > 19770 && _frequency < 19830) ||
    119.                  (_frequency > 17770 && _frequency < 17830) ||
    120.                  (_frequency > 15270 && _frequency < 15330))
    121.         {
    122.                   // Do something
    123.         }
    124.     }
    125. }
    126.  
     
    Last edited: Jul 28, 2014
  2. MakeCodeNow

    MakeCodeNow

    Joined:
    Feb 14, 2014
    Posts:
    1,246
    My guess is that the mic has a different sample rate than the input, so that could be one problem. I'd also say check your fft to freq math. I don't remember it off the top of my head so maybe there is a bug there.
     
  3. Tongie

    Tongie

    Joined:
    Sep 19, 2012
    Posts:
    90
    Hi makecodenow thanks for the reply, the code does read the correct frequency but when the frequency is played together with alot of noise it cant accurately detect the high frequency or doesnt read the high frequency at all.
     
  4. Tongie

    Tongie

    Joined:
    Sep 19, 2012
    Posts:
    90
    Anyone able to help?
     
  5. MakeCodeNow

    MakeCodeNow

    Joined:
    Feb 14, 2014
    Posts:
    1,246
    Easy does it with the aggressive bumps. It discourages people from responding to you...

    In short, what you are trying to do is hard in general, especially on crappy phone mics even more so in noisy environments. You're going to just have to try lots of stuff, but here are some ideas:

    Have fewer fft buckets if you can. Bigger bucks may have a better chance of catching the freq you want. Alternatively, keep the same number of buckets but look at adjacent frequencies to select the dominant tone.

    If you are worried about noise, try to persistently record and estimate the ambient noise floor. Ignore sounds below this.

    Filter over multiple frames not just instantaneously. Noise moves around over time but signals stay put. Basically, look for signals in time domain not just freq domain.

    If you have pro, try to create a noise reduction DSP, maybe out of a lowpass and high pass filter. Can work especially well if you are listening in a specific range.

    Take time to make debug drawing of your data. Pictures may reveal patterns and bugs that are hard too see in code.

    Consider detecting harmonics of the dominant pitch. May be another way to separate signal from noise.
     
  6. Tongie

    Tongie

    Joined:
    Sep 19, 2012
    Posts:
    90
    Thanks for the advice on the bumps...! Sound like it will take some time haha.

    Thanks makecodenow. Really appreciate!