void FixedUpdate()
    {
        float indexIncrements      = ((indexRangeEnd - indexRangeStart) / numberOfLines);
        float multiplierIncrements = ((multiplierRangeEnd - multiplierRangeStart) / numberOfLines);
        float rangeIncrements      = ((rangeRangeStart - rangeRangeEnd) / numberOfLines);

        for (int i = 0; i < linePositions.Length; i++)
        {
            if (!inProgress[i])
            {
                int   index = indexRangeStart + (int)(indexIncrements * i);
                int   range = rangeRangeStart + (int)(rangeIncrements * i);
                float raw   = AudioResponseSystem.GetData(audioSource,
                                                          index,
                                                          range,
                                                          AudioResponseSystem.RangeType.MAX);
                float multiplier = multiplierRangeStart + multiplierIncrements * i;
                if (raw * multiplier > triggerVolume)
                {
                    StartCoroutine(StartLine(i, index, range, multiplier, lineLifetime, colorRange.Evaluate((float)i / numberOfLines)));
                    inProgress[i] = true;
                }
            }
        }
    }
    IEnumerator StartLine(int lineNumber, int index, int range, float multiplier, float time, Color color)
    {
        float      timer = 0;
        GameObject cube  = GameObject.CreatePrimitive(PrimitiveType.Cube);

        cube.transform.parent = linePositions[lineNumber].transform;

        cube.transform.localPosition = Vector3.zero;
        cube.transform.localRotation = Quaternion.identity;
        Renderer cubeRenderer = cube.GetComponent <Renderer>();

        cubeRenderer.material       = cubeMaterial;
        cubeRenderer.material.color = color;

        bool expand = true;

        while (true)
        {
            timer += Time.deltaTime;
            float raw = AudioResponseSystem.GetData(audioSource,
                                                    index,
                                                    range,
                                                    AudioResponseSystem.RangeType.MAX);
            if (expand)
            {
                if (raw * multiplier <= triggerVolume)
                {
                    inProgress[lineNumber] = false;
                    expand = false;
                }
                cube.transform.localScale    = new Vector3(1, cube.transform.localScale.y + (Time.deltaTime * lineSpeed), 1);
                cube.transform.localPosition = new Vector3(0, cube.transform.localScale.y / 2, 0);
            }
            else
            {
                cube.transform.localPosition = new Vector3(0, cube.transform.localPosition.y + (Time.deltaTime * lineSpeed), 0);
            }
            cubeRenderer.material.color = color * Mathf.Clamp((raw * multiplier) / triggerVolume, 0.5f, 1);

            if (timer > time)
            {
                Destroy(cube);
                yield break;
            }
            yield return(null);
        }
    }
    /// <summary>
    /// Returns the raw amplitude of the target frequency range.
    /// </summary>
    public float GetResponseValue()
    {
        float rawValue = AudioResponseSystem.GetData(audioSource, frequencyIndex, range, AudioResponseSystem.rangeType[rangeType]);

        currentResponseValue = Mathf.Lerp(currentResponseValue,
                                          rawValue * multiplier,
                                          Time.deltaTime * damping);

        if (triggerVolume < rawValue * 6000)
        {
            isTriggered = true;
            OnTriggered();
        }
        else
        {
            isTriggered = false;
        }

        return(currentResponseValue);
    }