Beispiel #1
0
    // Update is called once per frame
    void Update()
    {
        Debug.Log("Running");
        // Check if the volume is above threshold
        src.GetOutputData(volSamples, 0);
        float avg = 0;

        for (int i = 0; i < volSamples.Length; i++)
        {
            avg += Mathf.Abs(volSamples[i]);
        }
        avg = avg / volSamples.Length;
        if (avg * 100 < volThreshold)
        {
            MainNote = "";
            return;
        }

        // Get frequency information
        src.GetSpectrumData(freqSamples, 0, FFTWindow.BlackmanHarris);

        float[] hpsFreqSamples = new float[freqSamples.Length / 5];
        for (int i = 1; i < hpsFreqSamples.Length; i++)
        {
            hpsFreqSamples[i] = freqSamples[i] * freqSamples[i * 2] * freqSamples[i * 3] * freqSamples[i * 4] * freqSamples[i * 5];
        }

        if (Input.GetKeyDown(KeyCode.D))
        {
            Debug.Log("Break");
        }


        // Loop over frequency bins within human range:
        //   - Calculate spectral flatness to determine if sound is noise/tone
        //   - Find out which frequency bin, within desired range, has the strongest signal
        int minBin = minFreq * (2 * bins) / samplerate;
        int maxBin = maxFreq * (2 * bins) / samplerate;

        double geometricMean  = 0;
        float  arithmeticMean = 0;
        int    maxIndex       = 0;
        float  maxVal         = 0.0f;

        for (int i = minBin; i < maxBin && i < hpsFreqSamples.Length; i++)
        {
            // Update sums
            if (hpsFreqSamples[i] != 0)
            {
                geometricMean  += Mathf.Log(hpsFreqSamples[i]);
                arithmeticMean += hpsFreqSamples[i];
            }

            // Update max frequency
            if (hpsFreqSamples[i] >= maxVal)
            {
                maxIndex = i;
                maxVal   = hpsFreqSamples[i];
            }
        }

        arithmeticMean /= (maxBin - minBin);
        geometricMean  /= (maxBin - minBin);
        geometricMean   = Math.Exp(geometricMean);

        // Exclude audio that's too noisy (i.e., if the player isn't singing)
        if (maxIndex == 0 || (geometricMean / arithmeticMean > specFlatnessThreshold))
        {
            MainNote = "";
            return;
        }

        // Log frequency
        float frequency = (float)maxIndex * samplerate / (2 * bins);

        frequencyHistory.Enqueue(frequency);
        if (frequencyHistory.Count >= queueHistorySize)
        {
            frequencyHistory.Dequeue();
        }
        float freqSum = 0;

        foreach (float freq in frequencyHistory)
        {
            freqSum += freq;
        }
        // Log note
        MainNote = guide.GetClosestNote(freqSum / frequencyHistory.Count);


        /*
         * - - - - - - - GRAPH RESULTS OF FFT - - - - - - - - - - -
         */

        // Wipe previous graph contents
        foreach (LineRenderer l in lines)
        {
            if (l != null)
            {
                Destroy(l.gameObject);
            }
        }
        foreach (TextMesh label in labels)
        {
            if (label != null)
            {
                Destroy(label.gameObject);
            }
        }
        lines.Clear();
        labels.Clear();


        // Figure out spacing for notches along the x-axis
        minBin = minGraphedFreq * (2 * bins) / samplerate;
        maxBin = maxGraphedFreq * (2 * bins) / samplerate;
        float notchInterval = maxX / (maxBin - minBin);

        // Loop over frequency bins within graphable range
        for (int i = minBin; i < maxBin && i < hpsFreqSamples.Length; i++)
        {
            float binVal = hpsFreqSamples[i];

            if (binVal != 0)
            {
                // Scale the y-axis so that the maximum value reaches the top
                float yPos = (binVal / maxVal) * maxY;
                //   float yPos = binVal * graphingMult * maxY;

                LineRenderer line = Instantiate <LineRenderer>(linePrefab);
                line.SetPosition(0, new Vector3(notchInterval * i, 0));
                line.SetPosition(1, new Vector3(notchInterval * i, yPos));
                lines.Add(line);
            }

            if (i % labelSpacing == 0)
            {
                TextMesh label = Instantiate <TextMesh>(labelPrefab);
                label.transform.position = new Vector3(notchInterval * i, -1);
                label.text = (i * samplerate / (2 * bins)).ToString();
                labels.Add(label);
            }
        }
    }
Beispiel #2
0
    // Update is called once per frame
    void Update()
    {
        // Check if the volume is above threshold
        src.GetOutputData(volSamples, 0);
        float avg = 0;

        for (int i = 0; i < volSamples.Length; i++)
        {
            avg += Mathf.Abs(volSamples[i]);
        }
        avg = avg / volSamples.Length;

        //
        if (avg * 100 < volThreshold)
        {
            MainNote = "";
            return;
        }

        // Get frequency information
        src.GetSpectrumData(freqSamples, 0, FFTWindow.BlackmanHarris);

        float[] hpsFreqSamples = new float[freqSamples.Length / 5];
        for (int i = 1; i < hpsFreqSamples.Length; i++)
        {
            hpsFreqSamples[i] = freqSamples[i] * freqSamples[i * 2] * freqSamples[i * 3] * freqSamples[i * 4] * freqSamples[i * 5];
        }

        if (Input.GetKeyDown(KeyCode.D))
        {
            Debug.Log("Break");
        }

        // Loop over frequency bins within human range:
        //   - Calculate spectral flatness to determine if sound is noise/tone
        //   - Find out which frequency bin, within desired range, has the strongest signal
        int minBin = minFreq * (2 * bins) / samplerate;
        int maxBin = maxFreq * (2 * bins) / samplerate;

        double geometricMean  = 0;
        float  arithmeticMean = 0;
        int    maxIndex       = 0;
        float  maxVal         = 0.0f;

        for (int i = minBin; i < maxBin && i < hpsFreqSamples.Length; i++)
        {
            // Update sums
            if (hpsFreqSamples[i] != 0)
            {
                geometricMean  += Mathf.Log(hpsFreqSamples[i]);
                arithmeticMean += hpsFreqSamples[i];
            }

            // Update max frequency
            if (hpsFreqSamples[i] >= maxVal)
            {
                maxIndex = i;
                maxVal   = hpsFreqSamples[i];
            }
        }

        arithmeticMean /= (maxBin - minBin);
        geometricMean  /= (maxBin - minBin);
        geometricMean   = Math.Exp(geometricMean);

        // Exclude audio that's too noisy (i.e., if the player isn't singing)
        if (maxIndex == 0 || (geometricMean / arithmeticMean > specFlatnessThreshold))
        {
            MainNote = "";
            return;
        }

        // Log frequency
        float frequency = (float)maxIndex * samplerate / (2 * bins);

        // Compare with previous frequencies to get rid of outliers
        frequencyHistory.Enqueue(frequency);
        if (frequencyHistory.Count >= queueHistorySize)
        {
            frequencyHistory.Dequeue();
        }
        float freqSum = 0;

        foreach (float freq in frequencyHistory)
        {
            freqSum += freq;
        }

        // Log note
        MainNote = guide.GetClosestNote(freqSum / frequencyHistory.Count);
    }