Discrete Fourier Transform:
Music DSP Source Code Archive
MIC Latency Unity
Mic Input with processing – Initial:
using UnityEngine; using System.Collections; using UnityEngine.UI; using System; [RequireComponent(typeof(AudioSource))] public class MicrophoneInput : MonoBehaviour { public TestAudioSource tAS; [Range(0, 2)] public double gain = 1; [Range(0, 1)] public double gain1 = 1; [Range(0, 1)] public double gain2 = 1; [Range(0, 1)] public double gain3 = 1; [Range(0.00f, 20f)] public double multInterval1 = 1; [Range(0.00f, 20f)] public double multInterval2 = 1; [Range(0.00f, 20f)] public double multInterval3 = 1; [Range(0.01f, 0.02f)] public double phase1base = 0.01; [Range(0.01f, 0.02f)] public double phase2base = 0.01; [Range(0.01f, 0.02f)] public double phase3base = 0.01; [Range(0.0f, 1f)] public double attack1 = 0.01; [Range(0.0f, 1f)] public double decay1 = 0.01; [Range(0.0f, 1f)] public double attack2 = 0.01; [Range(0.0f, 1f)] public double decay2 = 0.01; [Range(0.0f, 1f)] public double attack3 = 0.01; [Range(0.0f, 1f)] public double decay3 = 0.01f; public bool bVoiceHigh = true; public bool bVoiceMid = true; public bool bVoiceLow = true; double phase1; double phase2; double phase3; double amp1; double amp2; double amp3; private double nextTick = 0.0F; private double amp = 0.0F; private double phase = 0.0F; private double sampleRate = 0.0F; private int accent; private bool running = false; void Start() { sampleRate = AudioSettings.outputSampleRate; AudioSource As = new AudioSource(); AudioClip aC = new AudioClip(); As.clip = aC; tAS.aSource = As; //As.clip.SetData() } int count1 = 0; int count2 = 0; int count3 = 0; double phasemult1 = 6.0f; double phasemult2 = 4.0f; double phasemult3 = 2.0f; bool switch1 = true; bool switch2 = true; bool switch3 = true; double time1; double time2; double time3; double accumTime; bool aOn = true; double ampSamp(int voice, double sampTime) { amp = 0; if (voice == 1) { if (sampTime - time1 < attack1) { amp = CubicEaseIn(sampTime - time1, 0, 1, attack1); } else if (accumTime - time1 < attack1 + decay1) { amp = CubicEaseOut((sampTime - time1 - attack1), 1, -1, decay1); } else { amp = 0; } } if (voice == 2) { if (sampTime - time2 < attack2) { amp = CubicEaseIn(sampTime - time2, 0, 1, attack2); } else if (accumTime - time2 < attack2 + decay2) { amp = CubicEaseOut((sampTime - time2 - attack2), 1, -1, decay2); } else { amp = 0; } } if (voice == 3) { if (sampTime - time3 < attack3) { amp = CubicEaseIn(sampTime - time3, 0, 1, attack3); } else if (accumTime - time3 < attack3 + decay3) { amp = CubicEaseOut((sampTime - time3 - attack3), 1, -1, decay3); } else { amp = 0; } } return amp; } double WDT = 0.1; //Why Do This? void OnAudioFilterRead(float[] data, int channels) { accumTime = (double)AudioSettings.dspTime; if (count1++ > 10*multInterval1) { time1 = accumTime;//Attack if (switch1) { if (++phasemult1 > 6) { switch1 = false; } } else { if (--phasemult1 < 6) { switch1 = true; } } count1 = 0; } if (count2++ > 10* multInterval2) { time2 = accumTime;//Attack if (switch2) { if (++phasemult2 > 4) { switch2= false; } } else { if (--phasemult2 < 4) { switch2 = true; } } count2 = 0; } if (count3++ > 10*multInterval3) { time3 = accumTime;//Attack if (switch3) { if (++phasemult3 > 2) { switch3 = false; } } else { if (--phasemult3 < 2) { switch3 = true; } } count3 = 0; } double samples = AudioSettings.dspTime * sampleRate; int dataLen = data.Length / channels; double deltTime = (AudioSettings.dspTime / samples); int n = 0; double a, b, c; double sanpTime = accumTime; while (n < dataLen) { sanpTime += deltTime; if (bVoiceHigh) a = WDT * gain * ampSamp(1, sanpTime) * Math.Sin(phase1); else a = 0;//ampSamp(1,sanpTime) if (bVoiceMid) b = WDT * gain * ampSamp(2, sanpTime) * Math.Sin(phase2); else b = 0; if (bVoiceLow) c = WDT * gain * ampSamp(3, sanpTime) * Math.Sin(phase3); else c = 0; float x = (float)(gain1*a + gain2*b + gain3*c); int i = 0; while (i < channels) { data[n * channels + i] += x; i++; } phase1 += phase1base * phasemult1; if (phase1 > Math.PI * 2f) phase1 = 0f; phase2 += phase2base * phasemult2; if (phase2 > Math.PI * 2f) phase2 = 0f; phase3 += phase3base * phasemult3; if (phase3 > Math.PI * 2f) phase3 = 0f; n++; } } /// </summary> /// <param name= t "current">how long into the ease are we</param> /// <param name= b "initialValue">starting value if current were 0</param> /// <param name= c "totalChange">total change in the value (not the end value, but the end - start)</param> /// <param name= d "duration">the total amount of time (when current == duration, the returned value will == initial + totalChange)</param> /// <returns></returns> public static double CubicEaseOut(double t, double b, double c, double d) { if (t < d) { return c * ((t = t / d - 1) * t * t + 1) + b; } else { return b + c; } } public static double CubicEaseIn(double t, double b, double c, double d) { if (t < d) { return c * (t /= d) * t * t + b; } else { return b + c; } } } //public class MicrophoneInput : MonoBehaviour //{ // public double sensitivity = 100; // public double loudness = 0; // public Text dbg_Text; // string micName; // AudioSource audioSource; // void Start() // { // audioSource = GetComponent<AudioSource>(); // foreach (string device in Microphone.devices) // { // Debug.Log("Name: " + device); // } // micName = Microphone.devices[0]; // audioSource.clip = Microphone.Start(null, true, 10, 44100); // audioSource.loop = true; // Set the AudioClip to loop // //audioSource.mute = true; // Mute the sound, we don't want the player to hear it // while (!(Microphone.GetPosition(micName) > 0)) { } // Wait until the recording has started // audioSource.Play(); // Play the audio source! // } // void Update() // { // //if (audioSource.isPlaying == false && Microphone.GetPosition(micName) > 1) // //{ // // audioSource.Play(); // //} // loudness = GetAveragedVolume() * sensitivity; // dbg_Text.text = "Loudness = " + loudness.ToString("F8"); // } // double GetAveragedVolume() // { // double[] data = new double[256]; // double a = 0; // GetComponent<AudioSource>().GetOutputData(data, 0); // foreach (double s in data) // { // a += Mathf.Abs(s); // } // return a / 256; // } //}