// ------------------------------ Private functions ------------------------------



    private void PlayField()
    {
        // 1. Get field type
        lastChord = curChord;
        curChord  = GetChord();

        int ID        = Player.curField.ID;
        var fieldType = Player.curFieldSet[ID].type;

        if (Player.inst.curFieldSet[ID].isNotSpawning)
        {
            // nur wenn sich feld nicht aufbaut
            switch (fieldType)
            {
            case MusicField.Type.Chord:
                MyAudioHelmHelper.PlayChord(curChord, controller, velocity);
                break;

            case MusicField.Type.Modulation:
                //MusicFieldSet.SwitchEdgeParts();
                break;

            case MusicField.Type.Pitch:
                break;
            }
        }
        // 2. Event
        GameEvents.inst.onPlayField?.Invoke();
    }
    // ------------------------------ Public functions ------------------------------



    /// <summary>
    /// Change controller channel and sequencer reference.
    /// </summary>
    /// <param name="layer"></param>
    public void ChangeLayer(int layer)
    {
        bool isPlaying      = Player.inst.actionState == Player.ActionState.Play;
        var  sequencerPos   = (float)curSequencer.GetSequencerPosition();
        var  sequencerNotes = MyAudioHelmHelper.GetCurrentNotes(curSequencer, sequencerPos);

        // 1. Stop curChord (if not being played in the sequencer)
        if (isPlaying)
        {
            foreach (int curNote in curChord.notes)
            {
                bool isPlayedInSequencer = false;
                foreach (Note seqNote in sequencerNotes)
                {
                    if (curNote == seqNote.note)
                    {
                        isPlayedInSequencer = true;
                        break;
                    }
                }

                if (!isPlayedInSequencer)
                {
                    controller.NoteOff(curNote);
                }
            }
        }

        // 2. Change sequencer & controller reference
        curSequencer       = Recorder.inst.sequencers[layer];
        controller.channel = layer;
    }
    private void StopField()
    {
        // 1. Get field type
        int ID        = Player.curField.ID;
        var fieldType = Player.curFieldSet[ID].type;            // TO DO: ID und fieldType sind glaube ich das aktuell anvisierte feld und nicht das letzte (noch spielende) feld

        switch (fieldType)
        {
        case MusicField.Type.Chord:
            MyAudioHelmHelper.StopChord(curChord, controller, curSequencer);
            break;

        case MusicField.Type.Modulation:
            break;

        case MusicField.Type.Pitch:
            break;
        }

        // 2. Event
        GameEvents.inst.onStopField?.Invoke();
    }
Esempio n. 4
0
    /// <summary>
    /// Write into recording (end-time of the currently played chord), recalculate notes to prevent weird stuff and set notes to sequencer.
    /// </summary>
    private IEnumerator WriteToSequencer_delayed()
    {
        float curPos = (float)CurSequencer.GetSequencerPosition();
        float velocity = MusicManager.inst.velocity;
        var curNotes = MyAudioHelmHelper.GetCurrentNotes(CurSequencer, curPos);
        var doubleNotes = MyAudioHelmHelper.DoubleNotes(recording.notes, curNotes);

        // 1. Write to recording
        // 2. Quantize?
        if (MusicManager.inst.quantize)
        {
            // Legato: quantize recording.end, too
            if (Player.inst.actionState == Player.ActionState.Play)
            {
                float quantize = Quantize(curPos);

                recording.end = quantize;
                recording.endQuantizeOffset = quantize - curPos;

                // Special case: very short notes
                if (recording.end == recording.start)
                {
                    recording.end = (recording.end + MusicManager.inst.quantizeStep) % recording.sequencer.length;
                }
            }
            // Staccato: Dont quantize recording.end
            else
            {
                // get the time the chord was pressed
                recording.end = (curPos + recording.startQuantizeOffset).Modulo(recording.sequencer.length);
                recording.endQuantizeOffset = recording.startQuantizeOffset;
            }
        }
        else
        {
            recording.end = curPos;
        }


        // Special case: recording exceeds self
        if (recording.endExceedsStart)
        {
            recording.end = (recording.start - 0.01f).Modulo(recording.sequencer.length);
            recording.endExceedsStart = false;

            foreach (int note in recording.notes)
            {
                recording.sequencer.NoteOn(note, velocity);
            }
        }



        // 3. IF THERE ARE CURRENTLY EXISTING NOTES: Calc additional notes, to prevent breaking notes
        var usualNotes = new List<NoteContainer>();
        var remainingNotes = new List<NoteContainer>();
        foreach (Note doubleNote in doubleNotes)
        {
            // #1: Existing note within bounds (Sequencer note.start < note.end), curNote plays within sequencer.chord (curNote > start); would disrupt and delete remaining note
            if (recording.end > doubleNote.start && recording.end < doubleNote.end)
            {
                int note = doubleNote.note;
                float start = recording.end + noteAdd; // note add == 0 currently
                float end = doubleNote.end;

                // 1.1. Shorten existing note (1/3)
                if (recording.start != doubleNote.start)    // sonst macht das keinen sinn
                {
                    doubleNote.end = recording.start;
                }

                // Note on
                MusicManager.inst.controller.NoteOn(note, velocity, end - start);

                // 1.2. Add new note for remaining part (== 3/3; recording == 2/3, existing note == 1/3)
                usualNotes.Add(new NoteContainer(note, start, end, velocity));

                //print("existing note, case #1; remaining usual note gets added (3/3)");
            }

            // #2 Existing note extends over the sequencer bounds, would disrupt and stop playing the remaining note
            else if (doubleNote.start > doubleNote.end)
            {
                float oldEnd = doubleNote.end;

                // 2.1. Shorten existing sequencer note
                if (recording.start != doubleNote.start)    // sonst macht das keinen sinn
                {
                    if (recording.start != 0)
                        doubleNote.end = recording.start;
                    else
                        doubleNote.end = recording.sequencer.length - 0.01f;
                }

                // 2.2. Add note for remaining sequencer note?
                //float oldEndPercentage = SequencerPositionPercentage(recording.sequencer, oldEnd, recording.loopStart);
                //float curPosPercentage = SequencerPositionPercentage(recording.sequencer, recording.end, recording.loopStart);
                int note = doubleNote.note;
                float start = recording.end;
                float end = oldEnd;

                var temp = new NoteContainer(note, start, end, velocity);
                remainingNotes.Add(temp); // dont add now because it would be overwritten by usual notes; has to be added at last
                MusicManager.inst.controller.NoteOn(note, velocity, end - start);

                //print("existing note, case #2; remaining undefined note gets added (3/3)");
            }
        }


        var recordCopy = recording.DeepCopy(); // DeepCopy, because otherwise wrong data at later point



        // WAIT to add notes; otherwise notes will disrupt unintendedly
        if (recordCopy.endQuantizeOffset > 0)
        {
            float delay = recordCopy.endQuantizeOffset * LoopData.timePerSixteenth;

            isWaitingToWrite = true;

            yield return new WaitForSeconds(delay);
        }
        isWaitingToWrite = false;



        // #3 Get bridges notes that are NOT being played
        curPos = (float)recordCopy.sequencer.GetSequencerPosition();
        var unplayedBridgeNotes = MyAudioHelmHelper.UnplayedBridgeNotes(CurSequencer, curPos);

        // cur douplicate notes, at the time of the start
        var curNotes_quantize = MyAudioHelmHelper.GetCurrentNotes(recordCopy.sequencer, recordCopy.start);
        var curDoubleNotes_quantize = MyAudioHelmHelper.DoubleNotes(recordCopy.notes, curNotes_quantize);


        // 5. Add remaining usual notes (#1; 3/3)
        foreach (NoteContainer note in usualNotes)
        {
            MyAudioHelmHelper.RemoveIdenticalStartNotes(note, curDoubleNotes_quantize, recordCopy.sequencer);

            recordCopy.sequencer.AddNote(note.note, note.start, note.end, velocity);
        }


        // 4. Write CURRENTLY RECORDED notes
        foreach (int noteNote in recordCopy.notes)
        {
            var note = new Note { note = noteNote, start = recordCopy.start, end = recordCopy.end, velocity = velocity, parent = null };
            //note.parent = null;

            if (note.IsUnplayedBridgeNote(curPos))
            {
                unplayedBridgeNotes.Add(note);
            }
            else
            {
                MyAudioHelmHelper.RemoveIdenticalStartNotes(note, curDoubleNotes_quantize, recordCopy.sequencer);

                // add to sequencer
                recordCopy.sequencer.AddNote(noteNote, recordCopy.start, recordCopy.end, velocity);
            }
        }



        // 5. Add bridge notes again
        foreach (NoteContainer note in remainingNotes) // #2: remaining notes of case #2
        {
            if (note.IsUnplayedBridgeNote(curPos))
            {
                var helmNote = new Note { note = note.note, start = note.start, end = note.end };
                unplayedBridgeNotes.Add(helmNote);
            }
            else
            {
                MyAudioHelmHelper.RemoveIdenticalStartNotes(note, curDoubleNotes_quantize, recordCopy.sequencer);

                recordCopy.sequencer.AddNote(note.note, note.start, note.end, velocity);
            }
        }
        foreach (Note note in unplayedBridgeNotes)  // #3: unplayed bridge notes
        {
            MyAudioHelmHelper.RemoveIdenticalStartNotes(note, curDoubleNotes_quantize, recordCopy.sequencer);

            recordCopy.sequencer.AddNote(note.note, note.start, note.end, velocity);
        }

        yield return null;
        yield return null;
    }