// 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); } } }
// 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); }