public void OnRecordedNoteContinued(RecordedNote recordedNote, bool updateUi) { if (updateUi) { DisplayRecordedNote(recordedNote); } }
public void DisplayRecordedNote(RecordedNote recordedNote) { if (recordedNote.TargetNote.Sentence != displayedSentence) { // This is probably a recorded note from the previous sentence that is still continued because of the mic delay. // Do not draw the recorded note, it is not in the displayed sentence. return; } // Freestyle notes are not drawn if (recordedNote.TargetNote.IsFreestyle) { return; } // Try to update existing recorded notes. if (recordedNoteToUiRecordedNotesMap.TryGetValue(recordedNote, out List <UiRecordedNote> uiRecordedNotes)) { foreach (UiRecordedNote uiRecordedNote in uiRecordedNotes) { uiRecordedNote.TargetEndBeat = recordedNote.EndBeat; } return; } // Draw the bar for the rounded note // and draw the bar for the actually recorded pitch if needed. CreateUiRecordedNote(recordedNote, true); if (displayRoundedAndActualRecordedNotes && (recordedNote.RecordedMidiNote != recordedNote.RoundedMidiNote)) { CreateUiRecordedNote(recordedNote, false); } }
private int GetCorrectlySungGoldenNoteLength(RecordedNote recordedNote) { if (recordedNote.TargetNote == null || !recordedNote.TargetNote.IsGolden) { return(0); } return(GetCorrectlySungNoteLength(recordedNote)); }
protected void CreateUiRecordedNote(RecordedNote recordedNote, bool useRoundedMidiNote) { if (recordedNote.StartBeat == recordedNote.EndBeat) { return; } // Pitch detection algorithms often have issues finding the correct octave. However, the octave is irrelevant for scores. // When notes are drawn far away from the target note because the pitch detection got the wrong octave then it looks wrong. // Thus, only the relative pitch of the roundedMidiNote is used and drawn on the octave of the target note. int midiNote; if (useRoundedMidiNote && recordedNote.TargetNote != null) { midiNote = MidiUtils.GetMidiNoteOnOctaveOfTargetMidiNote(recordedNote.RoundedMidiNote, recordedNote.TargetNote.MidiNote); } else { midiNote = recordedNote.RecordedMidiNote; } UiRecordedNote uiNote = Instantiate(uiRecordedNotePrefab, uiRecordedNotesContainer); uiNote.RecordedNote = recordedNote; uiNote.StartBeat = recordedNote.StartBeat; uiNote.TargetEndBeat = recordedNote.EndBeat; // Draw already a portion of the note uiNote.LifeTimeInSeconds = Time.deltaTime; uiNote.EndBeat = recordedNote.StartBeat + (uiNote.LifeTimeInSeconds * beatsPerSecond); uiNote.MidiNote = midiNote; if (micProfile != null) { uiNote.SetColorOfMicProfile(micProfile); } Text uiNoteText = uiNote.lyricsUiText; if (showPitchOfNotes) { string pitchName = MidiUtils.GetAbsoluteName(midiNote); uiNoteText.text = " (" + pitchName + ")"; } else { uiNoteText.text = ""; } RectTransform uiNoteRectTransform = uiNote.RectTransform; PositionUiNote(uiNoteRectTransform, midiNote, uiNote.StartBeat, uiNote.EndBeat); uiRecordedNotes.Add(uiNote); recordedNoteToUiRecordedNotesMap.AddInsideList(recordedNote, uiNote); }
public override void DisplayRecordedNote(RecordedNote recordedNote) { if (recordedNote.TargetNote.Sentence != currentSentence) { // This is probably a recorded note from the previous sentence that is still continued because of the mic delay. // Do not draw the recorded note, it is not in the displayed sentence. return; } base.DisplayRecordedNote(recordedNote); }
private void OnContinuedNote(RecordedNote recordedNote, double currentBeat) { if (playerController == null) { lastRecordedNote = null; return; } Sentence currentSentence = playerController.CurrentSentence; if (currentSentence == null) { lastRecordedNote = null; return; } // Only accept recorded notes where a note is expected in the song Note noteAtCurrentBeat = GetNoteAtBeat(currentSentence, currentBeat); if (noteAtCurrentBeat == null) { lastRecordedNote = null; return; } // Limit recorded note bounds to target note bounds if (recordedNote.StartBeat < noteAtCurrentBeat.StartBeat) { recordedNote.StartBeat = noteAtCurrentBeat.StartBeat; } if (recordedNote.EndBeat > noteAtCurrentBeat.EndBeat) { recordedNote.EndBeat = noteAtCurrentBeat.EndBeat; } // Round pitch of recorded note to pitch of note in song if (noteAtCurrentBeat.Type == ENoteType.Rap || noteAtCurrentBeat.Type == ENoteType.RapGolden) { // Rap notes accept any noise as correct note. recordedNote.RoundedMidiNote = noteAtCurrentBeat.MidiNote; } else { // Round recorded note if it is close to the target note. recordedNote.RoundedMidiNote = GetRoundedMidiNote(recordedNote.RecordedMidiNote, noteAtCurrentBeat.MidiNote, RoundingDistance); } // Remember this note and show it in the UI AddRecordedNote(lastRecordedNote, currentSentence); playerController.DisplayRecordedNotes(GetRecordedNotes(currentSentence)); }
private void CheckPerfectlySungNote(Sentence sentence, RecordedNote lastRecordedNote) { if (sentence == null || lastRecordedNote == null) { return; } Note perfectlySungNote = sentence.Notes.Where(note => note.MidiNote == lastRecordedNote.RoundedMidiNote && note.StartBeat >= lastRecordedNote.StartBeat && note.EndBeat <= lastRecordedNote.EndBeat).FirstOrDefault(); if (perfectlySungNote != null) { playerUiController.CreatePerfectNoteEffect(perfectlySungNote); } }
private void DisplayRecordedNote(RecordedNote recordedNote, bool useRoundedNote = true) { int midiNote = (useRoundedNote) ? recordedNote.RoundedMidiNote : recordedNote.RecordedMidiNote; UiRecordedNote uiNote = Instantiate(uiRecordedNotePrefab); uiNote.transform.SetParent(transform); Text uiNoteText = uiNote.GetComponentInChildren <Text>(); uiNoteText.text = (useRoundedNote) ? MidiUtils.GetAbsoluteName(recordedNote.RoundedMidiNote) : MidiUtils.GetAbsoluteName(recordedNote.RecordedMidiNote); RectTransform uiNoteRectTransform = uiNote.GetComponent <RectTransform>(); PositionUiNote(uiNoteRectTransform, midiNote, recordedNote.StartBeat, recordedNote.EndBeat); }
private void CheckPerfectlySungNote(RecordedNote lastRecordedNote) { if (lastRecordedNote == null || lastRecordedNote.TargetNote == null) { return; } Note targetNote = lastRecordedNote.TargetNote; int targetMidiNoteRelative = MidiUtils.GetRelativePitch(targetNote.MidiNote); int recordedMidiNoteRelative = MidiUtils.GetRelativePitch(lastRecordedNote.RoundedMidiNote); bool isPerfect = ((targetMidiNoteRelative == recordedMidiNoteRelative) && (targetNote.StartBeat >= lastRecordedNote.StartBeat) && (targetNote.EndBeat <= lastRecordedNote.EndBeat)); if (isPerfect) { playerUiController.CreatePerfectNoteEffect(targetNote); } }
private void HandleRecordedNoteContinued(int midiNote, double currentBeat, bool updateUi) { lastRecordedNote.EndBeat = currentBeat; bool targetNoteIsDone = (lastRecordedNote.TargetNote != null && lastRecordedNote.EndBeat >= lastRecordedNote.TargetNote.EndBeat); if (targetNoteIsDone) { lastRecordedNote.EndBeat = lastRecordedNote.TargetNote.EndBeat; playerController.OnRecordedNoteEnded(lastRecordedNote); lastRecordedNote = null; HandleRecordedNoteStarted(midiNote, currentBeat, updateUi); } else { playerController.OnRecordedNoteContinued(lastRecordedNote, updateUi); } }
public void OnPitchDetected(int midiNote) { double currentBeat = singSceneController.CurrentBeat; if (midiNote <= 0) { if (lastRecordedNote != null) { // End singing of last recorded note. // Do this seamlessly, i.e., continue the last recorded note until now. lastRecordedNote.EndBeat = currentBeat; OnContinuedNote(lastRecordedNote, currentBeat); lastRecordedNote = null; // Debug.Log("Ended singing"); } } else { if (lastRecordedNote != null && lastRecordedNote.RecordedMidiNote == midiNote) { // Continue singing on same pitch lastRecordedNote.EndBeat = currentBeat; OnContinuedNote(lastRecordedNote, currentBeat); // Debug.Log("Continued note"); } else { playerController.OnRecordedNoteEnded(lastRecordedNote); // Start new note. // Do this seamlessly, i.e., start the new note at the time the last note was recorded. lastRecordedNote = new RecordedNote(midiNote, lastPitchDetectedBeat, currentBeat); // Debug.Log("Start new note"); } } lastPitchDetectedBeat = currentBeat; }
public void DisplayRecordedNote(RecordedNote recordedNote) { playerUiController.DisplayRecordedNote(recordedNote); }
public void OnRecordedNoteContinued(RecordedNote recordedNote) { DisplayRecordedNote(recordedNote); }
public void OnRecordedNoteEnded(RecordedNote recordedNote) { CheckPerfectlySungNote(recordedNote); DisplayRecordedNote(recordedNote); }
private bool IsTargetNoteHit(RecordedNote recordedNote) { return(recordedNote.TargetNote != null && recordedNote.TargetNote.MidiNote == recordedNote.RoundedMidiNote); }