static void ControlerInput()
    {
        // generate new data
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // set new gamedata
            // TODO: automate this
            testCycles[0].parametersToAdapt[1].value = MockGameData();
            testCycles[0].parametersToAdapt[3].value = MockGameData();
            testCycles[0].parametersToAdapt[4].value = MockGameData();

            // call cycles
            foreach (PAdaptionMoment adaptMoment in adaptionMoments)
            {
                foreach (PCycle cycle in adaptMoment.cycles)
                {
                    PAudioDataSystem.CallCycle(cycle);
                }
            }
        }

        // toggle first 5 layers with keyinput for testing
        var layers = ProceduralAudio.layers;

        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            layers[0].layerOn = !layers[0].layerOn;
        }
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            layers[1].layerOn = !layers[1].layerOn;
        }
        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            layers[2].layerOn = !layers[2].layerOn;
        }
        if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            layers[3].layerOn = !layers[3].layerOn;
        }
        if (Input.GetKeyDown(KeyCode.Alpha5))
        {
            layers[4].layerOn = !layers[4].layerOn;
        }

        // call oneshots for testing
        if (Input.GetKeyDown(KeyCode.A))
        {
            POneshots.playOneShot(0, Random.Range(0, ProceduralAudio.entryListOS[0].Count));
        }
    }
    public static void Start()
    {
        // create cycles and parameters
        testCycles.Add(new PCycle(new List <PParameter>()));

        testCycles[0].parametersToAdapt.Add(new PParameter(AdaptableParametersCycle.chordsAndScale));
        testCycles[0].parametersToAdapt.Add(new PParameter(AdaptableParametersCycle.layerdata, MockGameData(), new List <int> {
            1
        }));
        testCycles[0].parametersToAdapt.Add(new PParameter(AdaptableParametersCycle.rythmAndMelody, null, new List <int> {
            0, 1, 2, 3, 4, 5
        }));
        testCycles[0].parametersToAdapt.Add(new PParameter(AdaptableParametersCycle.bpm, MockGameData()));
        testCycles[0].parametersToAdapt.Add(new PParameter(AdaptableParametersCycle.dynamicCycleLayerAmount, MockGameData()));

        testCycles.Add(new PCycle(new List <PParameter> {
            new PParameter(AdaptableParametersCycle.rythmAndMelody, null, new List <int> {
                1
            })
        }));

        // init dynamic cycle
        dynamicCycle = new PDynamicCycle(new List <int> {
            0, 1, 2, 3, 4, 5
        }, true);

        // set a timer on the second cycle and the dynamic cycle
        cycleTimers.Add(new PCycleTimer(testCycles[1], null));
        cycleTimers.Add(new PCycleTimer(null, dynamicCycle));

        // create adaptionmoments
        adaptionMoments.Add(new PAdaptionMoment(testCycles));

        // call dataa
        PAudioDataSystem.CallCycle(testCycles[0]);
    }
    public static void Sequencer()
    {
        if (PClock.nextTick)
        {
            ProceduralAudio.print("tick");

            foreach (PCycleTimer cycleTimer in PParameterLinker.cycleTimers)
            {
                // check trigger timed cycle
                if (cycleTimer.currentTick % cycleTimer.lengthInTicks == cycleTimer.lengthInTicks - 1)
                {
                    if (cycleTimer.cycle != null)
                    {
                        PAudioDataSystem.CallCycle(cycleTimer.cycle);
                    }
                    else
                    {
                        PAudioDataSystem.callDynamicCycle(cycleTimer.dynamicCycle);
                    }
                }

                cycleTimer.currentTick += 1;
            }

            // for every layer
            for (int layer = 0; layer < ProceduralAudio.amountOfLayers; layer++)
            {
                var currentLayer = ProceduralAudio.layers[layer];

                // convert tick number into measure
                currentLayer.currentTick %= currentLayer.rythm.Count;

                // check if layer is active
                if (currentLayer.layerOn)
                {
                    // check rythm
                    if (currentLayer.rythm[currentLayer.currentTick] == 1)
                    {
                        // TODO: set scale for all layers here instead of only the melody
                        // check if audio needs to adapt to another layer and play audio TODO: set a layer parameter to see if it needs to adapt instead of just checking if its the melody
                        if (currentLayer.layerType == ProceduralAudio.LayerType.melody)
                        {
                            // account for scale having switches
                            int chordBaseScaleIndex = (PAudioDataSystem.currentScale.IndexOf(currentChordBase) == -1) ? PAudioDataSystem.previousScale.IndexOf(currentChordBase) : PAudioDataSystem.currentScale.IndexOf(currentChordBase);
                            PAudioPlayer.PlayFile(layer, PAudioDataSystem.currentScale[(chordBaseScaleIndex + currentLayer.melody[currentLayer.currentTick]) % PAudioDataSystem.currentScale.Count]);
                        }
                        else
                        {
                            PAudioPlayer.PlayFile(layer, currentLayer.melody[currentLayer.currentTick]);
                        }

                        // set currentChord when chordlayer changes
                        if (currentLayer.layerType == ProceduralAudio.LayerType.chords)
                        {
                            currentChordBase = currentLayer.melody[currentLayer.currentTick];
                        }
                    }
                }

                // next tick
                currentLayer.currentTick += 1;
            }
        }
    }