예제 #1
0
        public void ProcessAudio(float[] AudioData, int SampleRate)
        {
            Debug.Assert(AudioData.Length == m_FFTSize);

            if (SampleRate != m_SampleRate)
            {
                SetSampleRate(SampleRate);
            }

            m_FFT.Add(AudioData, AudioData.Length);
            m_FFT.GetFftData(m_FFTResult);

            // Calculate Band Levels.  Band Levels are much more useful
            // For visualization / system feedback.  Raw FFT is mostly useless.
            ConvertRawSpectrumToBandLevels();

            // Fill the buffers full
            for (int i = 0; i < m_FFTSize; ++i)
            {
                float fLChannel = AudioData[i];
                m_AudioSamples[i] = fLChannel;
                // m_RChannelTempBuffer[i] = fRChannel;
                m_LChannelWeird[i] = Mathf.Lerp(fLChannel, m_LChannelWeird[i], m_WeirdWaveformLerp);
                m_PeakFFTResult[i] = Mathf.Max(m_PeakFFTResult[i] * m_FFTPeakDecay, m_FFTResult[i]);
            }

            m_AudioSamples.CopyTo(m_LChannelLowPass, 0);
            m_AudioSamples.CopyTo(m_LChannelHighPass, 0);

            m_LowPassFilter.Frequency  = m_LowPassFreq;
            m_HighPassFilter.Frequency = m_HighPassFreq;
            m_LowPassFilter.Process(m_LChannelLowPass);
            m_HighPassFilter.Process(m_LChannelHighPass);

            // Pipe waveform values in to texture.
            for (int i = 0; i < m_FFTSize; ++i)
            {
                m_WaveFormRow[i].r = m_AudioSamples[i] * 0.5f + 0.5f;
                m_WaveFormRow[i].g = m_LChannelWeird[i] * 0.5f + 0.5f;

                m_WaveFormRow[i].b = m_LChannelLowPass[i] * 0.5f + 0.5f;
                m_WaveFormRow[i].a = m_LChannelHighPass[i] * 0.5f + 0.5f;
            }
            // Pipe FFT values in to texture.
            // Only use the first half of the FFT. Second half is boring.
            for (int i = 0; i < m_FFTTextureSize; ++i)
            {
                // Mirrored index
                int fMirroredIndex = 128 - Mathf.Abs(i - 128);
                m_FFTRow[i].r = m_FFTResult[fMirroredIndex] * m_FFTScale;
                m_FFTRow[i].g = m_FFTResult[fMirroredIndex] * Mathf.Pow((fMirroredIndex / 512.0f), m_FFTPower) * m_FFTPowerScale;
                m_FFTRow[i].b = m_PeakFFTResult[fMirroredIndex] * Mathf.Pow((fMirroredIndex / 512.0f), m_FFTPower) * m_FFTPowerScale;
            }

            for (int i = 0; i < m_FFTTextureSize; ++i)
            {
                int band_levels_index = (int)(i * ((float)m_BandLevels.Length / (float)m_FFTTextureSize));
                m_FFTRow[i].a = m_BandNormalizedLevels[band_levels_index];
            }

            // Pipe values into the Audio Injector for beat detection, if the component exists.
            if (m_SystemAudioInjector)
            {
                m_SystemAudioInjector.ProcessAudio(m_AudioSamples);
            }
            if (m_SystemAudioInjectorAlt)
            {
                m_SystemAudioInjectorAlt.ProcessAudio(m_AudioSamples);
            }
            if (m_SystemAudioInjectorLowPass)
            {
                m_SystemAudioInjectorLowPass.ProcessAudio(m_AudioSamples);
            }
            if (m_SystemAudioInjectorHighPass)
            {
                m_SystemAudioInjectorHighPass.ProcessAudio(m_AudioSamples);
            }

            //
            // Update Shaders
            //
            Shader.SetGlobalTexture("_WaveFormTex", m_WaveFormTexture);
            Shader.SetGlobalVector("_PeakBandLevels", m_BandPeakLevelsOutput);
            Shader.SetGlobalTexture("_FFTTex", m_FFTTexture);
            Shader.SetGlobalVector("_BeatOutput", m_BeatOutput);
            Shader.SetGlobalVector("_BeatOutputAccum", m_BeatOutputAccum);
            Shader.SetGlobalVector("_AudioVolume", m_AudioVolume);

            m_BandPeakLevelsOutput = new Vector4(m_BandPeakLevels[0], m_BandPeakLevels[1], m_BandPeakLevels[2], m_BandPeakLevels[3]);

            m_WaveFormTexture.SetPixels(0, 0, m_FFTSize, 1, m_WaveFormRow);
            m_WaveFormTexture.Apply();
            m_FFTTexture.SetPixels(0, 0, m_FFTTextureSize, 1, m_FFTRow);
            m_FFTTexture.Apply();

            m_BeatOutput = new Vector4(m_Reaktor.output, m_ReaktorAlt.output, m_ReaktorLowPass.output, m_ReaktorHighPass.output);
            //Scale the accumulated output to a value more usable in shaders (saves us a multiply)
            m_BeatOutputAccum = new Vector4(m_Reaktor.outputAccumulated, m_ReaktorAlt.outputAccumulated, m_ReaktorLowPass.outputAccumulated, m_ReaktorHighPass.outputAccumulated) * .02f;

            // XXX TO DO: Better and more useful conversion from DB to a useful 0:1 range.
            float val1 = (60.0f + m_Reaktor.outputDb) / 60.0f;

            val1 = Mathf.Clamp(val1, 0.0f, 1.0f);
            float val2 = (60.0f + m_ReaktorAlt.outputDb) / 60.0f;

            val2 = Mathf.Clamp(val2, 0.0f, 1.0f);
            float val3 = (60.0f + m_ReaktorLowPass.outputDb) / 60.0f;

            val3 = Mathf.Clamp(val3, 0.0f, 1.0f);
            float val4 = (60.0f + m_ReaktorHighPass.outputDb) / 60.0f;

            val4          = Mathf.Clamp(val3, 0.0f, 1.0f);
            m_AudioVolume = new Vector4(val1, val2, val3, val4);
        }