devNotes 8-14-16 Multi Voice – Persistent Filtering

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;

[RequireComponent(typeof(AudioSource))]
public class Argos_Sound_Gen : MonoBehaviour
{
    AudioSource audioSource;

    public float estimatedLatency { get; protected set; }

    //public Texture2D textureSamps;
    //public int width;
    //public int height;

    public int globalSampleRate;

    [Range(0.002f, 0.005f)]
    public float dTime = 0.005f;

    [Range(0, 5)]
    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;

    public bool bMicOn = false;

    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 int accent;
    private bool running = false;

    private float[] _freqs = { 249.66f, 264.505f, 280.235f, 296.9f, 314.55f, 333.255f, 353.075f, 374.07f, 396.31f, 419.875f, 444.845f, 471.295f, 499.32f };
    private float[] _dtime = { 0.004124562f, 0.00389302f, 0.003674579f, 0.003468248f, 0.003273644f, 0.003089948f, 0.002916472f,
                                0.002752773f, 0.00259828f, 0.002452483f, 0.002314815f, 0.002184885f, 0.002062281f};


    [Range(0.0f, 1.0f)]
    public float echoGain;

    [Range(0.001f, 3.0f)]
    public float echoTime;

    [Range(-1.5f, 0f)]
    public float delayTime = 0f;

    [Range(0f, 1f)]
    public float echoAttenuation;

    private float[] echoBuffer = new float[(int)(48000 * 2 * 6.0f)];

    public float[] EchoBuffer
    {
        get { return echoBuffer; }
    }
    private int _record_Head = 0;
    private int _play_head = 0;
    private int _delay_head = 0;

    public int Record_Head
    {
        get { return _record_Head; }
    }

    public int Play_Head
    {
        get { return _play_head; }
    }

    public int Delay_Head
    {
        get { return _delay_head; }
    }

    public void playNote(int idx)
    {
        time1 = accumTime;//Attack
        phasemult1 = idx;
        dTIME = _dtime[(int)phasemult1];
    }


    void Awake()
    {
        // Create an audio source.
        audioSource = gameObject.GetComponent<AudioSource>();
        audioSource.playOnAwake = false;
        audioSource.loop = true;

        //width = textureSamps.width;
        //height = textureSamps.height;

        //684,2048
        //Color col = new Color(1, 1, 1, 1);

        //for (int i = 20; i < height - 20; i++)
        //{
        //    for (int j = -15; j < 15; j++)
        //    {
        //        textureSamps.SetPixel(j + width / 2, i, col);
        //    }
        //}
        //textureSamps.Apply();

        //for(int i = 0; i)

        //textureSamps

        //StartInput();
    }

    void OnApplicationPause(bool paused)
    {
        if (paused)
        {
            audioSource.Stop();
            Microphone.End(null);
            audioSource.clip = null;
        }
        else
            StartInput();
    }

    public void OnMicOn(bool micOn)
    {
        bMicOn = micOn;
        if (!bMicOn)
        {
            audioSource.Stop();
            Microphone.End(null);
            audioSource.clip = null;

            //clear echo buff
            for (int i = 0; i < echoBuffer.Length; i++)
            {
                echoBuffer[i] = 0f;
            }
        }
        else
            StartInput();
    }

    //void WriteEchoBuff()
    //{
    //    Color col1 = new Color(1, 1, 1, 1);
    //    Color col2 = new Color(.3f, .3f, 1, 1);
    //    Color colBlack = new Color(0, 0, 0, 0);

    //    int displZoneX = width - 40;
    //    int displZoneY = height - 40;

    //    int peak = displZoneX / 2;
    //    float levSum;
    //    float avgLev;

    //    int bucketLen = echoBuffer.Length / displZoneY;
    //    int n = 0;
    //    int walker = 0;

    //    for (int i = 20; i < displZoneY; i++)
    //    {
    //        levSum = 0;
    //        for(int k = 0; k<bucketLen;k++)
    //        {
    //            levSum += echoBuffer[k + walker];
    //        }
    //        walker += bucketLen;
    //        avgLev = levSum / bucketLen;

    //        n = 0;
    //        for (int j = 20; j < displZoneX/2; j++)
    //        {
    //            if ((float)(peak - n)/peak > avgLev)
    //                textureSamps.SetPixel(j, i, colBlack);
    //            else
    //                textureSamps.SetPixel(j, i, col2);
    //            n++;
    //        }
    //    }

    //    for (int i = 20; i < height - 20; i++)
    //    {
    //        for (int j = -4; j < 4; j++)
    //        {
    //            textureSamps.SetPixel(j + width / 2, i, col1);
    //        }
    //    }
    //    textureSamps.Apply();

    //}


    void Update()
    {
        //WriteEchoBuff();
    }



    void StartInput()
        {
            globalSampleRate = AudioSettings.outputSampleRate;

            // Create a clip which is assigned to the default microphone.
            audioSource.clip = Microphone.Start(null, true, 10, globalSampleRate);

            if (audioSource.clip != null)
            {
                // Wait until the microphone gets initialized.
                int delay = 0;
                while (delay <= 0) delay = Microphone.GetPosition(null);

                // Start playing.
                audioSource.Play();

                // Estimate the latency.
                estimatedLatency = (float)delay / globalSampleRate;
            }
            else
                Debug.LogWarning("GenericAudioInput: Initialization failed.");
        }

    int count1 = 0;
    int count2 = 0;
    int count3 = 0;

    double phasemult1 = 3.0f;
    double phasemult2 = 2.0f;
    double phasemult3 = 1.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;
    }


    float dTIME = 0f;
    double dt;
    void OnAudioFilterRead(float[] data, int channels)
    {
        accumTime = (double)AudioSettings.dspTime;

        //private float[] _freqs = { 249.66f, 264.505f, 280.235f, 296.9f, 314.55f, 333.255f, 353.075f, 374.07f, 396.31f, 419.875f, 444.845f, 471.295f,499.32f };
        //   private float[] _dtime = { 0.004124562f, 0.00389302f, 0.003674579f, 0.003468248f, 0.003273644f, 0.003089948f, 0.002916472f,
        //                               0.002752773f, 0.00259828f, 0.002452483f, 0.002314815f, 0.002184885f, 0.002062281f};

        //float dTIME = dTime;
        //for (int i = 0; i < 12; i++)
        //{
        //    if (freq > 2 * _freqs[i] && freq < 2 * _freqs[i + 1])
        //    {
        //        dTIME = _dtime[i + 1];
        //    }
        //}
        //phase1 = dTime * 2f * Mathf.PI / globalSampleRate;

        //if (count1++ > 10 * multInterval1)
        //{
        //    time1 = accumTime;//Attack
        //    if (switch1)
        //    {
        //        if (++phasemult1 > 11)
        //        {
        //            switch1 = false;
        //        }
        //    }
        //    else
        //    {
        //        if (--phasemult1 < 2)
        //        {
        //            switch1 = true;
        //        }
        //    }
        //    count1 = 0;
        //    dTIME = _dtime[(int)phasemult1];
        //}

        //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 * globalSampleRate;
        int dataLen = data.Length / channels;
        double deltTime = (AudioSettings.dspTime / samples);
        int n = 0;

        double a, b, c;

        double sampTime = accumTime;

        dt = deltTime / dTIME * 2f * Mathf.PI;

        while (n < dataLen)
        {
            sampTime += deltTime;

            if (bVoiceHigh) a =  gain * ampSamp(1, sampTime)* Math.Sin(phase1); else a = 0;//ampSamp(1,sampTime) 
            //if (bVoiceMid) b  = gain * ampSamp(2, sampTime) * Math.Sin(phase2); else b = 0;
            //if (bVoiceLow) c  = gain * ampSamp(3, sampTime) * 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;


                //if (bMicOn)
                //{
                //    record(data[n * channels + i] + playback(delayTime) /*+ x*/);
                //    //data[n * channels + i] = (float)a;
                //    data[n * channels + i] = echoGain * playback();
                //}
                //else
                //{
                //    data[n * channels + i] = 0f;
                //}

                i++;
            }

            phase1 += dt;
            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>

    private void record(float samp)
    {
        if (++_record_Head > echoBuffer.Length - 1) _record_Head = 0;

        echoBuffer[_record_Head] = samp;
    }

    private float playback()
    {
        _play_head = (int)(_record_Head - (echoTime * globalSampleRate * 2f));
        if (_play_head < 0) _play_head = (int)(6.0f * globalSampleRate * 2f) + _play_head;

        return echoBuffer[_play_head] * echoAttenuation;

    }

    private float playback(float delay)
    {
        _delay_head = (int)(_record_Head + (delayTime * globalSampleRate * 2f));
        if (_delay_head < 0) _delay_head = (int)(6.0f * globalSampleRate * 2f) + _delay_head;
        if (_delay_head > echoBuffer.Length - 1) _delay_head = _delay_head - (echoBuffer.Length - 1);


        _delay_head = (int)(_delay_head - (echoTime * globalSampleRate * 2f));
        if (_delay_head < 0) _delay_head = (int)(6.0f * globalSampleRate * 2f) + _delay_head;

        return echoBuffer[_delay_head] * echoAttenuation;
    }

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

 

 

https://www.msi.com/Laptop/support/GS60-6QE-Ghost-Pro.html#down-bios

——————————————————————————————————————————————————

Screenshot_194.6111_