public void Awake() { SpectrumData = new float[SpectrumSize]; PostScaledSpectrumData = new float[SpectrumSize]; PostScaledMinMaxSpectrumData = new float[SpectrumSize]; // Used for post scaling float postScaleStep = 1.0f / SpectrumSize; // Setup loopback audio and start listening _realtimeAudio = new RealtimeAudio(SpectrumSize, ScalingStrategy, (spectrumData) => { // Raw SpectrumData = spectrumData; float postScaledMax = 0.0f; float postScaleAverage = 0.0f; float totalPostScaledValue = 0.0f; bool isIdle = true; // Pass 1: Scaled. Scales progressively as moving up the spectrum for (int i = 0; i < SpectrumSize; i++) { float postScaleValue = PostScaleCurve.Evaluate(postScaleStep * i) * SpectrumData[i] * PostScaleMultiplier; PostScaledSpectrumData[i] = Mathf.Clamp(postScaleValue, 0, RealtimeAudio.MaxAudioValue); if (PostScaledSpectrumData[i] > postScaledMax) { postScaledMax = PostScaledSpectrumData[i]; } totalPostScaledValue += PostScaledSpectrumData[i]; if (spectrumData[i] > 0) { isIdle = false; } } PostScaledMax = postScaledMax; // Calculate "energy" using the post scale average postScaleAverage = totalPostScaledValue / SpectrumSize; _postScaleAverages.Add(postScaleAverage); // We only want to track EnergyAverageCount averages. // With a value of 1000, this will happen every couple seconds if (_postScaleAverages.Count == EnergyAverageCount) { _postScaleAverages.RemoveAt(0); } // Average the averages to get the energy. PostScaledEnergy = _postScaleAverages.Average(); // Pass 2: MinMax spectrum. Here we use the average. // If a given band falls below the average, reduce it 50% // otherwise boost it 50% for (int i = 0; i < SpectrumSize; i++) { float minMaxed = PostScaledSpectrumData[i]; if (minMaxed <= postScaleAverage * ThresholdToMin) { minMaxed *= MinAmount; } else if (minMaxed >= postScaleAverage * ThresholdToMax) { minMaxed *= MaxAmount; } PostScaledMinMaxSpectrumData[i] = minMaxed; } IsIdle = isIdle; }); _realtimeAudio.StartListen(); }