using UnityEngine;
using System.Collections.Generic;

public class Microphoner : MonoBehaviour {

    public const int minfreq = 40;
    public const int maxfreq = 400;
    public const int freqsamples = 4096;

    public float[] allpitches;

    public static float threshold = 0.002f;
    public static float origthreshold = 0.002f;
    public const float threshold_change = 1.04f;

    public float pitch;
    public float amplitude;
    public float[] li;


    // Use this for initialization
    void Awake () {
        li = new float[freqsamples];
        allpitches = new float[] { };
        
    }

    public void InitMike() {
        foreach (string device in Microphone.devices) {
            Debug.Log("Name: " + device);
        }
        //Microphone.devices;
        GetComponent<AudioSource>().clip = Microphone.Start(null, true, 1, 44100);
        GetComponent<AudioSource>().loop = true;
        //GetComponent<AudioSource>().mute = true;
        while (!(Microphone.GetPosition(null) > 0)) { } // Wait until the recording has started
        GetComponent<AudioSource>().Play();
    }

    

    void Update() {
        List<float> piitches = new List<float>();
        li = new float[freqsamples];
        GetComponent<AudioSource>().GetSpectrumData(li, 0, FFTWindow.Hamming);

        float maxV = 0;
        int maxN = 0;
        
        for (int i = minfreq; i < maxfreq; i++) { // find max 
            bool locma = true;
            if (li[i] < li[i + 1]) locma = false;
            if (li[i] < li[i - 1]) locma = false;
            if (li[i] > threshold && locma) {
                maxV = li[i];
                maxN = i; // maxN is the index of max

                float ff = i;
                //float ddL = Mathf.Min(1, li[i - 1] / li[i]);
                //float ddR = Mathf.Min(1, li[i + 1] / li[i]);

                piitches.Add(Idx_To_Pitch(i /*+ 0.5f * (ddR * ddR - ddL * ddL)*/) );
                
                //if (Mathf.Abs(piitches[piitches.Count - 1] - 430) < 1) print(Random.Range(0,1000));
            }
        }
        float freqN = maxN; // pass the index to a float variable
        if (maxN > 0 && maxN < freqsamples - 1) { // interpolate index using neighbours
            float dL = li[maxN - 1] / li[maxN];
            float dR = li[maxN + 1] / li[maxN];
            freqN += 0.5f * (dR * dR - dL * dL);
        }

        float pitchValue = Idx_To_Pitch(freqN); // convert index to frequency
        
        pitch = pitchValue;
        amplitude = 0;
        if (maxN > 0) amplitude = 1;
        //print(pitch);

        //print (li[0]);
        
        allpitches = piitches.ToArray();
        //print(allpitches.Length);
        if (allpitches.Length > 7) {
            threshold *= threshold_change;
            //print("omg");
        }
        else {
            threshold = Mathf.Max(origthreshold, threshold / threshold_change );
        }
        //print(allpitches.Length);
        
    }

    public static float Idx_To_Pitch(float idx) {
        return idx * (44100f / 2) / freqsamples;
    }

    public static int Pitch_To_Idx(float pitch) {
        return (int)(pitch * freqsamples / (44100f / 2));
    }

    // Update is called once per frame
    void OnAudioFilterRead(float[] dada, int channels) {
        //print(dada[0]);

        for (int i = 0; i < dada.Length; i++) {
            dada[i] *= 0f;
        }
    }
}
