devNotes 8-17-16 Note List with Positions

Notes:

Names, Colors, Instrument – Extend to full Note List ; Dictionary

Grabbing

Repeat Button Note List

Double Hit


//=====================================================================================
//
// Purpose: Provide a mechanism for determining if a game world object is interactable
//
// This script should be attached to any object that needs touch, use or grab
//
// An optional highlight color can be set to change the object's appearance if it is
// invoked.
//
//=====================================================================================
namespace VRTK
{
    using UnityEngine;
    using System.Collections.Generic;

    public struct InteractableObjectEventArgs
    {
        public GameObject interactingObject;
    }

    public delegate void InteractableObjectEventHandler(object sender, InteractableObjectEventArgs e);

    public class VRTK_InteractableObject : MonoBehaviour
    {
        public enum GrabAttachType
        {
            Fixed_Joint,
            Spring_Joint,
            Track_Object,
            Rotator_Track,
            Child_Of_Controller
        }

        public enum AllowedController
        {
            Both,
            Left_Only,
            Right_Only
        }

        public enum ControllerHideMode
        {
            Default,
            OverrideHide,
            OverrideDontHide,
        }

        [Header("Touch Interactions", order = 1)]
        public bool highlightOnTouch = false;
        public Color touchHighlightColor = Color.clear;
        public Vector2 rumbleOnTouch = Vector2.zero;
        public AllowedController allowedTouchControllers = AllowedController.Both;
        public ControllerHideMode hideControllerOnTouch = ControllerHideMode.Default;

        [Header("Grab Interactions", order = 2)]
        public bool isGrabbable = false;
        public bool isDroppable = true;
        public bool isSwappable = true;
        public bool holdButtonToGrab = true;
        public Vector2 rumbleOnGrab = Vector2.zero;
        public AllowedController allowedGrabControllers = AllowedController.Both;
        public bool precisionSnap;
        public Transform rightSnapHandle;
        public Transform leftSnapHandle;
        public ControllerHideMode hideControllerOnGrab = ControllerHideMode.Default;

        [Header("Grab Mechanics", order = 3)]
        public GrabAttachType grabAttachMechanic = GrabAttachType.Fixed_Joint;
        public float detachThreshold = 500f;
        public float springJointStrength = 500f;
        public float springJointDamper = 50f;
        public float throwMultiplier = 1f;
        public float onGrabCollisionDelay = 0f;

        [Header("Use Interactions", order = 4)]
        public bool isUsable = false;
        public bool useOnlyIfGrabbed = false;
        public bool holdButtonToUse = true;
        public bool pointerActivatesUseAction = false;
        public Vector2 rumbleOnUse = Vector2.zero;
        public AllowedController allowedUseControllers = AllowedController.Both;
        public ControllerHideMode hideControllerOnUse = ControllerHideMode.Default;

        public event InteractableObjectEventHandler InteractableObjectTouched;
        public event InteractableObjectEventHandler InteractableObjectUntouched;
        public event InteractableObjectEventHandler InteractableObjectGrabbed;
        public event InteractableObjectEventHandler InteractableObjectUngrabbed;
        public event InteractableObjectEventHandler InteractableObjectUsed;
        public event InteractableObjectEventHandler InteractableObjectUnused;

        protected Rigidbody rb;
        protected GameObject touchingObject = null;
        protected GameObject grabbingObject = null;
        protected GameObject usingObject = null;

        private int usingState = 0;
        private Dictionary<string, Color> originalObjectColours;

        private Transform grabbedSnapHandle;
        private Transform trackPoint;
        private bool customTrackPoint = false;
        private Transform originalControllerAttachPoint;

        private Transform previousParent;
        private bool previousKinematicState;
        private bool previousIsGrabbable;
        private bool forcedDropped;

        public bool CheckHideMode(bool defaultMode, ControllerHideMode overrideMode)
        {
            switch (overrideMode)
            {
                case VRTK_InteractableObject.ControllerHideMode.OverrideDontHide:
                    return false;
                case VRTK_InteractableObject.ControllerHideMode.OverrideHide:
                    return true;
            }
            // default: do not change
            return defaultMode;
        }

        public virtual void OnInteractableObjectTouched(InteractableObjectEventArgs e)
        {
            if (InteractableObjectTouched != null)
            {
                InteractableObjectTouched(this, e);
            }
        }

        public virtual void OnInteractableObjectUntouched(InteractableObjectEventArgs e)
        {
            if (InteractableObjectUntouched != null)
            {
                InteractableObjectUntouched(this, e);
            }
        }

        public virtual void OnInteractableObjectGrabbed(InteractableObjectEventArgs e)
        {
            if (InteractableObjectGrabbed != null)
            {
                InteractableObjectGrabbed(this, e);
            }
        }

        public virtual void OnInteractableObjectUngrabbed(InteractableObjectEventArgs e)
        {
            if (InteractableObjectUngrabbed != null)
            {
                InteractableObjectUngrabbed(this, e);
            }
        }

        public virtual void OnInteractableObjectUsed(InteractableObjectEventArgs e)
        {
            if (InteractableObjectUsed != null)
            {
                InteractableObjectUsed(this, e);
            }
        }

        public virtual void OnInteractableObjectUnused(InteractableObjectEventArgs e)
        {
            if (InteractableObjectUnused != null)
            {
                InteractableObjectUnused(this, e);
            }
        }

        public InteractableObjectEventArgs SetInteractableObjectEvent(GameObject interactingObject)
        {
            InteractableObjectEventArgs e;
            e.interactingObject = interactingObject;
            return e;
        }

        public bool IsTouched()
        {
            return (touchingObject != null);
        }

        public bool IsGrabbed()
        {
            return (grabbingObject != null);
        }

        public bool IsUsing()
        {
            return (usingObject != null);
        }

        public virtual void StartTouching(GameObject currentTouchingObject)
        {
            OnInteractableObjectTouched(SetInteractableObjectEvent(currentTouchingObject));
            touchingObject = currentTouchingObject;
        }

        public virtual void StopTouching(GameObject previousTouchingObject)
        {
            OnInteractableObjectUntouched(SetInteractableObjectEvent(previousTouchingObject));
            touchingObject = null;
            StopUsingOnControllerChange(previousTouchingObject);
        }

        public virtual void Grabbed(GameObject currentGrabbingObject)
        {
            OnInteractableObjectGrabbed(SetInteractableObjectEvent(currentGrabbingObject));
            ForceReleaseGrab();
            RemoveTrackPoint();
            grabbingObject = currentGrabbingObject;
            SetTrackPoint(grabbingObject);
            if (!isSwappable)
            {
                previousIsGrabbable = isGrabbable;
                isGrabbable = false;
            }
        }

        public virtual void Ungrabbed(GameObject previousGrabbingObject)
        {
            OnInteractableObjectUngrabbed(SetInteractableObjectEvent(previousGrabbingObject));
            RemoveTrackPoint();
            grabbedSnapHandle = null;
            grabbingObject = null;
            LoadPreviousState();
            StopUsingOnControllerChange(previousGrabbingObject);
        }

        private void StopUsingOnControllerChange(GameObject previousController)
        {
            var usingObject = previousController.GetComponent<VRTK_InteractUse>();
            if (usingObject)
            {
                if (holdButtonToUse)
                {
                    usingObject.ForceStopUsing();
                }
                else
                {
                    usingObject.ForceResetUsing();
                }
            }
        }

        public virtual void StartUsing(GameObject currentUsingObject)
        {
            OnInteractableObjectUsed(SetInteractableObjectEvent(currentUsingObject));
            usingObject = currentUsingObject;
        }

        public virtual void StopUsing(GameObject previousUsingObject)
        {
            OnInteractableObjectUnused(SetInteractableObjectEvent(previousUsingObject));
            usingObject = null;
        }

        public virtual void ToggleHighlight(bool toggle)
        {
            ToggleHighlight(toggle, Color.clear);
        }

        public virtual void ToggleHighlight(bool toggle, Color globalHighlightColor)
        {
            if (highlightOnTouch)
            {
                if (toggle && !IsGrabbed() && !IsUsing())
                {
                    Color color = (touchHighlightColor != Color.clear ? touchHighlightColor : globalHighlightColor);
                    if (color != Color.clear)
                    {
                        var colorArray = BuildHighlightColorArray(color);
                        ChangeColor(colorArray);
                    }
                }
                else
                {
                    if (originalObjectColours == null)
                    {
                        Debug.LogError("VRTK_InteractableObject has not had the Start() method called, if you are inheriting this class then call base.Start() in your Start() method.");
                        return;
                    }
                    ChangeColor(originalObjectColours);
                }
            }
        }

        public int UsingState
        {
            get { return usingState; }
            set { usingState = value; }
        }

        public void PauseCollisions()
        {
            if (onGrabCollisionDelay > 0f)
            {
                if (GetComponent<Rigidbody>())
                {
                    GetComponent<Rigidbody>().detectCollisions = false;
                }
                foreach (Rigidbody rb in GetComponentsInChildren<Rigidbody>())
                {
                    rb.detectCollisions = false;
                }
                Invoke("UnpauseCollisions", onGrabCollisionDelay);
            }
        }

        public bool AttachIsTrackObject()
        {
            return (grabAttachMechanic == GrabAttachType.Track_Object || grabAttachMechanic == GrabAttachType.Rotator_Track);
        }

        public void ZeroVelocity()
        {
            if (GetComponent<Rigidbody>())
            {
                GetComponent<Rigidbody>().velocity = Vector3.zero;
                GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
            }
        }

        public void SaveCurrentState()
        {
            if (grabbingObject == null)
            {
                previousParent = transform.parent;
                previousKinematicState = rb.isKinematic;
            }
        }

        public void ToggleKinematic(bool state)
        {
            rb.isKinematic = state;
        }

        public GameObject GetGrabbingObject()
        {
            return grabbingObject;
        }

        public bool IsValidInteractableController(GameObject actualController, AllowedController controllerCheck)
        {
            if (controllerCheck == AllowedController.Both)
            {
                return true;
            }

            var controllerHand = VRTK_DeviceFinder.GetControllerHandType(controllerCheck.ToString().Replace("_Only", ""));
            return (VRTK_DeviceFinder.IsControllerOfHand(actualController, controllerHand));
        }

        public void ForceStopInteracting()
        {
            if (touchingObject != null && touchingObject.activeInHierarchy)
            {
                touchingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
                forcedDropped = true;
            }

            if (grabbingObject != null && grabbingObject.activeInHierarchy)
            {
                grabbingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
                grabbingObject.GetComponent<VRTK_InteractGrab>().ForceRelease();
                forcedDropped = true;
            }

            if (usingObject != null && usingObject.activeInHierarchy)
            {
                usingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
                usingObject.GetComponent<VRTK_InteractUse>().ForceStopUsing();
                forcedDropped = true;
            }
        }

        public void SetGrabbedSnapHandle(Transform handle)
        {
            grabbedSnapHandle = handle;
        }

        public void RegisterTeleporters()
        {
            foreach (var teleporter in FindObjectsOfType<VRTK_BasicTeleport>())
            {
                teleporter.Teleported += new TeleportEventHandler(OnTeleported);
            }
        }

        protected virtual void Awake()
        {
            rb = GetComponent<Rigidbody>();

            // If there is no rigid body, add one and set it to 'kinematic'.
            if (!rb)
            {
                rb = gameObject.AddComponent<Rigidbody>();
                rb.isKinematic = true;
            }
            rb.maxAngularVelocity = float.MaxValue;
            forcedDropped = false;
        }

        protected virtual void Start()
        {
            originalObjectColours = StoreOriginalColors();
            RegisterTeleporters();
        }

        protected virtual void Update()
        {
            if (!gameObject.activeInHierarchy)
            {
                ForceStopInteracting();
            }

            if (AttachIsTrackObject())
            {
                CheckBreakDistance();
            }
        }

        protected virtual void FixedUpdate()
        {
            if (trackPoint)
            {
                switch (grabAttachMechanic)
                {
                    case GrabAttachType.Rotator_Track:
                        FixedUpdateRotatorTrack();
                        break;
                    case GrabAttachType.Track_Object:
                        FixedUpdateTrackObject();
                        break;
                }
            }
        }

        protected virtual void OnDisable()
        {
            ForceStopInteracting();
        }

        protected virtual void OnEnable()
        {
            if(forcedDropped)
            {
                LoadPreviousState();
            }
        }

        protected virtual void OnJointBreak(float force)
        {
            ForceReleaseGrab();
        }

        protected virtual void LoadPreviousState()
        {
            if (gameObject.activeInHierarchy)
            {
                transform.parent = previousParent;
                forcedDropped = false;
            }
            rb.isKinematic = previousKinematicState;
            if (!isSwappable)
            {
                isGrabbable = previousIsGrabbable;
            }
        }

        private void ForceReleaseGrab()
        {
            if (grabbingObject)
            {
                grabbingObject.GetComponent<VRTK_InteractGrab>().ForceRelease();
            }
        }

        private void UnpauseCollisions()
        {
            if (GetComponent<Rigidbody>())
            {
                GetComponent<Rigidbody>().detectCollisions = true;
            }
            foreach (Rigidbody rb in GetComponentsInChildren<Rigidbody>())
            {
                rb.detectCollisions = true;
            }
        }

        private Renderer[] GetRendererArray()
        {
            return (GetComponents<Renderer>().Length > 0 ? GetComponents<Renderer>() : GetComponentsInChildren<Renderer>());
        }

        private Dictionary<string, Color> StoreOriginalColors()
        {
            Dictionary<string, Color> colors = new Dictionary<string, Color>();
            foreach (Renderer renderer in GetRendererArray())
            {
                if (renderer.material.HasProperty("_Color"))
                {
                    colors[renderer.gameObject.name] = renderer.material.color;
                }
            }
            return colors;
        }

        private Dictionary<string, Color> BuildHighlightColorArray(Color color)
        {
            Dictionary<string, Color> colors = new Dictionary<string, Color>();
            foreach (Renderer renderer in GetRendererArray())
            {
                if (renderer.material.HasProperty("_Color"))
                {
                    colors[renderer.gameObject.name] = color;
                }
            }
            return colors;
        }

        private void ChangeColor(Dictionary<string, Color> colors)
        {
            foreach (Renderer renderer in GetRendererArray())
            {
                if (renderer.material.HasProperty("_Color") && colors.ContainsKey(renderer.gameObject.name))
                {
                    renderer.material.color = colors[renderer.gameObject.name];
                }
            }
        }

        private void CheckBreakDistance()
        {
            if (trackPoint)
            {
                float distance = Vector3.Distance(trackPoint.position, transform.position);
                if (distance > (detachThreshold / 1000))
                {
                    ForceReleaseGrab();
                }
            }
        }

        private void SetTrackPoint(GameObject point)
        {
            var controllerPoint = point.transform;
            var grabScript = point.GetComponent<VRTK_InteractGrab>();

            if (grabScript && grabScript.controllerAttachPoint)
            {
                controllerPoint = grabScript.controllerAttachPoint.transform;
            }

            if (AttachIsTrackObject() && precisionSnap)
            {
                trackPoint = new GameObject(string.Format("[{0}]TrackObject_PrecisionSnap_AttachPoint", gameObject.name)).transform;
                trackPoint.parent = point.transform;
                customTrackPoint = true;
                if (grabAttachMechanic == GrabAttachType.Track_Object)
                {
                    trackPoint.position = transform.position;
                    trackPoint.rotation = transform.rotation;
                }
                else
                {
                    trackPoint.position = controllerPoint.position;
                    trackPoint.rotation = controllerPoint.rotation;
                }
            }
            else
            {
                trackPoint = controllerPoint;
                customTrackPoint = false;
            }

            originalControllerAttachPoint = new GameObject(string.Format("[{0}]Original_Controller_AttachPoint", grabbingObject.name)).transform;
            originalControllerAttachPoint.parent = transform;
            originalControllerAttachPoint.position = trackPoint.position;
            originalControllerAttachPoint.rotation = trackPoint.rotation;
        }

        private void RemoveTrackPoint()
        {
            if (customTrackPoint && trackPoint)
            {
                Destroy(trackPoint.gameObject);
            }
            else
            {
                trackPoint = null;
            }
            if (originalControllerAttachPoint)
            {
                Destroy(originalControllerAttachPoint.gameObject);
            }
        }

        private void FixedUpdateRotatorTrack()
        {
            var rotateForce = trackPoint.position - originalControllerAttachPoint.position;
            rb.AddForceAtPosition(rotateForce, originalControllerAttachPoint.position, ForceMode.VelocityChange);
        }

        private void FixedUpdateTrackObject()
        {
            float maxDistanceDelta = 10f;

            Quaternion rotationDelta;
            Vector3 positionDelta;

            float angle;
            Vector3 axis;

            if (grabbedSnapHandle != null)
            {
                rotationDelta = trackPoint.rotation * Quaternion.Inverse(grabbedSnapHandle.rotation);
                positionDelta = trackPoint.position - grabbedSnapHandle.position;
            }
            else
            {
                rotationDelta = trackPoint.rotation * Quaternion.Inverse(transform.rotation);
                positionDelta = trackPoint.position - transform.position;
            }

            rotationDelta.ToAngleAxis(out angle, out axis);

            angle = (angle > 180 ? angle -= 360 : angle);

            if (angle != 0)
            {
                Vector3 angularTarget = angle * axis;
                rb.angularVelocity = Vector3.MoveTowards(rb.angularVelocity, angularTarget, maxDistanceDelta);
            }

            Vector3 velocityTarget = positionDelta / Time.fixedDeltaTime;
            rb.velocity = Vector3.MoveTowards(rb.velocity, velocityTarget, maxDistanceDelta);
        }

        private void OnTeleported(object sender, DestinationMarkerEventArgs e)
        {
            if (AttachIsTrackObject() && trackPoint)
            {
                transform.position = grabbingObject.transform.position;
            }
        }
    }
}

rbrbrb

head

vcbnvbn

vbcnbvn

dfgngfnfg

https://github.com/TomorrowTodayLabs/NewtonVR/


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using System;
using VRTK;

public class Argos_Note
{
    public int nIdx;
    public double startTime;
    public float phaseBase;
    public double phase;
    public double attack;
    public double decay;
    public double amplitude;
    public bool isPlaying = false;

    public Argos_Note(int nI, double sT, float pB, double aT, double dC, double amp)
    {
        nIdx = nI;
        startTime = sT;
        phaseBase = pB;
        attack = aT;
        decay = dC;
        amplitude = amp;

        phase = 0;
    }
}

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

    public List<Argos_Note> noteList = new List<Argos_Note>();
    private int noteCount = 0;
    public Argos_Note[] voiceArray = new Argos_Note[10];

    public Text dbg_Text;

    public float estimatedLatency { get; protected set; }

    public int globalSampleRate;

    [Range(0, 5)]
    public double gain = 1;

    [Range(0.01f, 0.02f)]
    public double phase1base = 0.01;

    [Range(0.0f, 1f)]
    public double attack = 0.01;

    [Range(0.0f, 5f)]
    public double decay = 0.01;

    public VRTK_Control attack_Slider;
    public VRTK_Control decay_Slider;
    public VRTK_Control echo_Delay_Slider;
    public VRTK_Control echo_Decay_Slider;
    public VRTK_Control echo_WetMix_Slider;
    public VRTK_Control echo_DryMix_Slider;

    private double amp = 0.0F;
    private double phase = 0.0F;

    private int accent;
    private bool running = false;

    private bool seqOn = false;
    int noteIDX = 0;

    private AudioEchoFilter aEchoFilter;


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


    private float[] _dtime = {

                                0.015571473f, //C2  0
                                0.014697237f, //Db2 1
                                0.013873474f, //D2  2
                                0.013094147f, //Eb2 3                                  
        #region Note_Periods                               
                                0.012359412f, //E2  4
                                0.011665889f, //F2  5
                                0.011010791f, //F#2 6
                                0.01039285f,  //G2  7
                                0.009809692f, //Ab2 8
                                0.009259259f, //A2  9
                                0.008739731f, //Bb2 10
                                0.008248783f, //B2  11
                                0.007786343f, //C3  12
                                0.007349159f, //Db3 13
                                0.006936737f, //D3  14
                                0.006547073f, //Eb3 15
                                0.006179706f, //E3  16
                                0.005832944f, //F3  17
                                0.005505698f, //F#3 18
                                0.005196695f, //G3  19
                                0.004904846f, //Ab3 20
                                0.00462963f,  //A3  21
                                0.004369865f, //Bb3 22
                                0.004124562f, //B3  23
                                0.00389302f,  //C4  24
                                0.003674579f, //Db4 25
                                0.003468248f, //D4  26
                                0.003273644f, //Eb4 27
                                0.003089948f, //E4  28
                                0.002916472f, //F4  29
                                0.002752773f, //F#4 30
                                0.00259828f,  //G4  31
                                0.002452483f, //Ab4 32
                                0.002314815f, //A4  33 --- A 432
                                0.002184885f, //Bb4 34
                                0.002062281f, //B4  35
                                0.00194651f,  //C4  36
                                0.001837256f,
                                0.001734154f,
                                0.001636822f,
                                0.00154495f,
                                0.001458236f,
                                0.001376406f,
                                0.00129914f,
                                0.001226227f,
                                0.001157407f,
                                0.001092442f,
                                0.00103113f,
                                0.000973264f,
                                0.000918636f,
                                0.000867077f,
                                0.000818411f,
                                0.000772475f,
                                0.000729123f,
                                0.000688198f,
                                0.000649574f,
                                0.000613117f,
                                0.000578704f,
                                0.000546224f,
                                0.000515568f,
                                0.00048663f,
                                0.000459318f,
                                0.000433539f,
                                0.000409205f,
                                0.000386239f,
                                0.00036456f,
                                0.000344099f,
                                0.000324786f,
                                0.000306558f,
                                0.000289352f,
                                0.000273112f,
                                0.000257783f,
                                0.000243315f,
                                0.000229659f,
                                0.000216769f,
                                0.000204603f,
                                0.000193119f,
                                0.00018228f,
                                0.00017205f,
                                0.000162393f,
                                0.000153279f,
                                0.000144676f,
                                0.000136556f,
                                0.000128892f };
    #endregion


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

    void Start()
    {
        globalSampleRate = AudioSettings.outputSampleRate;

        for(int i = 0; i<10; i++)
        {
            voiceArray[i] = null;
        }

        if(attack_Slider)
        {
            attack_Slider.defaultEvents.OnValueChanged.AddListener(AttackSlider_Change);

        }
        if (decay_Slider)
        {
            decay_Slider.defaultEvents.OnValueChanged.AddListener(DecaySlider_Change);

        }

        aEchoFilter = GetComponent<AudioEchoFilter>();

        if (echo_Delay_Slider)
        {
            echo_Delay_Slider.defaultEvents.OnValueChanged.AddListener(Echo_Delay_Slider_Change);

        }

        if (echo_Decay_Slider)
        {
            echo_Decay_Slider.defaultEvents.OnValueChanged.AddListener(Echo_Decay_Slider_Change);

        }

        if (echo_WetMix_Slider)
        {
            echo_WetMix_Slider.defaultEvents.OnValueChanged.AddListener(Echo_WetMix_Slider_Change);

        }

        if (echo_DryMix_Slider)
        {
            echo_WetMix_Slider.defaultEvents.OnValueChanged.AddListener(Echo_DryMix_Slider_Change);

        }



    }

    private void AttackSlider_Change(float value)
    {
        attack = value;
    }

    private void DecaySlider_Change(float value)
    {
        decay = value;
    }

    private void Echo_Delay_Slider_Change(float value)
    {
        aEchoFilter.delay = value;
    }

    private void Echo_Decay_Slider_Change(float value)
    {
        aEchoFilter.decayRatio = value;
    }

    private void Echo_WetMix_Slider_Change(float value)
    {
        aEchoFilter.wetMix = value;
    }

    private void Echo_DryMix_Slider_Change(float value)
    {
        aEchoFilter.dryMix = value;
    }


    void OnApplicationPause(bool paused)
    {

    }

    float accum = 0.0f;
    void Update()
    {
        //if (seqOn) test
        //{
        //    accum += Time.deltaTime;

        //    if(accum > 1.7f)
        //    {
        //        playNote(noteIDX, 0.8f);
        //        if (++noteIDX > _dtime.Length - 1)
        //        {
        //            seqOn = false;
        //            noteIDX = 0;
        //        }
        //        accum = 0f;
        //    }
        //}
    }




    public void playNote(int idx, float amp)
    {

            Argos_Note aN = new Argos_Note(idx, (double)AudioSettings.dspTime, _dtime[idx], attack, decay, amp);

            aN.isPlaying = true;

            if (noteList.Count < 500)
            {
                noteList.Add(aN);
            } 
            StartNewNote(aN);
    }

    public void StartNewNote(Argos_Note aN)
    {
        for(int i = 0; i<10; i++)
        {
            if(voiceArray[i] == null || !voiceArray[i].isPlaying)
            {
                voiceArray[i] = aN;
                return;
            }
        }

        //else replace oldest
        double minStartTime = double.MaxValue;
        int repIdx = 0;
        for(int j = 0; j < 10; j++)
        {
            if(voiceArray[j].startTime < minStartTime)
            {
                minStartTime = voiceArray[j].startTime;
                repIdx = j;
            }
        }
        voiceArray[repIdx] = aN;
    }


    double EnvelopShaper(Argos_Note aN, double sampTime)
    {
        amp = 0;

        if (sampTime - aN.startTime < aN.attack)
        {
            amp = CubicEaseIn(sampTime - aN.startTime, 0, 1, aN.attack);
        }
        else if (accumTime - aN.startTime < aN.attack + aN.decay)
        {
            amp = CubicEaseOut((sampTime - aN.startTime - aN.attack), 1, -1, aN.decay);
        }
        else
        {
            amp = 0;
            aN.isPlaying = false;
        }
        return amp;
    }

    float dTIME = 0f;
    double dt;
    int testCount = 0;
    double accumTime;

    void OnAudioFilterRead(float[] data, int channels)
    {

        //TESTER ACTIVE VOICE COUNT
        if (++testCount > 10)
        {
            int active = 0;
            for(int po = 0; po<10; po++)
            {
                if (voiceArray[po] != null)
                {
                    if (voiceArray[po].isPlaying) active++;
                }   
            }
            dbg_Text.text = "active Voices = " + active.ToString();
            testCount = 0;
        }

        accumTime = (double)AudioSettings.dspTime;

        double samples = AudioSettings.dspTime * globalSampleRate;
        int dataLen = data.Length / channels;
        double deltTime = (AudioSettings.dspTime / samples);//HIGHLY REDUNDANT - FIX
        int n = 0;

        double a;

        double sampTime = accumTime;

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

        while (n < dataLen)
        {
            sampTime += deltTime;
            //do 10 voices
            a = 0;
            for (int v = 0; v<10; v++)
            {
                if (voiceArray[v] != null)
                {
                    if (voiceArray[v].isPlaying)
                    {
                        a += voiceArray[v].amplitude * EnvelopShaper(voiceArray[v], sampTime) * Math.Sin(voiceArray[v].phase);
                    }
                }   
           }
 
           float x = (float)(a);
           int i = 0;

            while (i < channels)
            {
                data[n * channels + i] = x;
                i++;
            }

            for (int u = 0; u < 10; u++)
            {
                if (voiceArray[u] != null)
                {
                    if (voiceArray[u].isPlaying)
                    {
                        dt = deltTime / voiceArray[u].phaseBase * 2f * Mathf.PI;

                        voiceArray[u].phase += dt;
                        if (voiceArray[u].phase > Math.PI * 2f) voiceArray[u].phase = 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;
        }
    }
}

Three Instruments – Sliding Helices

To record Media – Track Both Hands – Two Channels MIDI – Start With Arms in View – Poss Astral Proj

Capture Artist Moves and And Midi Events are Placed at the location of the associated Controller.

To play back in time – The movement must follow what was recorded in Time.

voices