// ------------------------------ Private functions ------------------------------ // Recording /// <summary> /// Save data of currently one recording chord to the RECORDING-variable (start time, notes, fieldID, sequencer, quantizeOffset). /// </summary> private void SaveRecordStartData() { float sequencerPos = (float) CurSequencer.GetSequencerPosition(); // 1. Start & quantize offset if (MusicManager.inst.quantize) { float quantize = Quantize(sequencerPos); recording.start = quantize; // hack für sequencerPos bei sequencer.length: quantize 0 oder 32 (sequencer.length) if (quantize == 0 && sequencerPos > CurSequencer.length / 2) { quantize = CurSequencer.length; } recording.startQuantizeOffset = quantize - sequencerPos; } else { recording.start = sequencerPos; recording.startQuantizeOffset = 0; } // 2. End, notes, ID, sequencer recording.notes = MusicManager.inst.curChord.DeepCopy().notes; recording.fieldID = Player.inst.curField.ID; recording.sequencer = CurSequencer; recording.isRunning = true; // 3. LoopStart object? if (!Has1stRecord) { loopStart = recording.start; loopEnd_extended = loopStart + CurSequencer.length; var obj = MeshRef.inst.loopObject; var parent = MeshRef.inst.recordObj_parent; var position = Player.inst.transform.position; LoopObject.Create(obj, parent, position, loopStart, loopEnd_extended, loopObjects); } }
/// <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; }