Beispiel #1
0
    private void OnBeatAnalyzed(PlayerPitchTracker.BeatAnalyzedEvent beatAnalyzedEvent)
    {
        // Check if pitch was detected where a note is expected in the song
        if (beatAnalyzedEvent.PitchEvent == null ||
            beatAnalyzedEvent.NoteAtBeat == null)
        {
            return;
        }

        if (beatAnalyzedEvent.Beat < NextBeatToScore)
        {
            return;
        }

        Note analyzedNote = beatAnalyzedEvent.NoteAtBeat;

        // Check if note was hit
        if (MidiUtils.GetRelativePitch(beatAnalyzedEvent.RoundedMidiNote) != MidiUtils.GetRelativePitch(analyzedNote.MidiNote))
        {
            return;
        }

        // The beat was sung correctly.
        if (!ScoreData.NoteToNoteScoreMap.TryGetValue(analyzedNote, out NoteScore noteScore))
        {
            noteScore = new NoteScore(analyzedNote);
            ScoreData.NoteToNoteScoreMap.Add(analyzedNote, noteScore);
        }
        noteScore.CorrectlySungBeats++;

        Sentence analyzedSentence = beatAnalyzedEvent.NoteAtBeat.Sentence;

        if (!ScoreData.SentenceToSentenceScoreMap.TryGetValue(analyzedSentence, out SentenceScore sentenceScore))
        {
            sentenceScore = new SentenceScore(analyzedSentence);
            ScoreData.SentenceToSentenceScoreMap.Add(analyzedSentence, sentenceScore);
        }

        if (analyzedNote.IsNormal)
        {
            ScoreData.CorrectNormalNoteLengthTotal++;
            sentenceScore.CorrectlySungNormalBeats++;
        }
        else if (analyzedNote.IsGolden)
        {
            ScoreData.CorrectGoldenNoteLengthTotal++;
            sentenceScore.CorrectlySungGoldenBeats++;
        }
    }
    private void OnBeatAnalyzed(PlayerPitchTracker.BeatAnalyzedEvent beatAnalyzedEvent)
    {
        // Check if pitch was detected where a note is expected in the song
        if (beatAnalyzedEvent.PitchEvent == null ||
            beatAnalyzedEvent.NoteAtBeat == null)
        {
            return;
        }

        if (beatAnalyzedEvent.Beat < NextBeatToScore)
        {
            return;
        }

        Note analyzedNote = beatAnalyzedEvent.NoteAtBeat;

        // Check if note was hit
        if (MidiUtils.GetRelativePitch(beatAnalyzedEvent.RoundedRecordedMidiNote) != MidiUtils.GetRelativePitch(analyzedNote.MidiNote))
        {
            return;
        }

        // The beat was sung correctly.
        if (!ScoreData.NoteToNoteScoreMap.TryGetValue(analyzedNote, out NoteScore noteScore))
        {
            noteScore = new NoteScore(analyzedNote);
            ScoreData.NoteToNoteScoreMap.Add(analyzedNote, noteScore);
        }
        noteScore.CorrectlySungBeats++;

        Sentence analyzedSentence = beatAnalyzedEvent.NoteAtBeat.Sentence;

        if (!ScoreData.SentenceToSentenceScoreMap.TryGetValue(analyzedSentence, out SentenceScore sentenceScore))
        {
            sentenceScore = CreateSentenceScore(analyzedSentence);
            ScoreData.SentenceToSentenceScoreMap.Add(analyzedSentence, sentenceScore);
        }

        if (IsPerfectHit(beatAnalyzedEvent))
        {
            ScoreData.GetBeatData(analyzedNote).IfNotNull(it => it.PerfectBeats++);
            sentenceScore.GetBeatData(analyzedNote).IfNotNull(it => it.PerfectBeats++);
        }
        else if (IsGoodHit(beatAnalyzedEvent))
        {
            ScoreData.GetBeatData(analyzedNote).IfNotNull(it => it.GoodBeats++);
            sentenceScore.GetBeatData(analyzedNote).IfNotNull(it => it.GoodBeats++);
        }
    }
Beispiel #3
0
    private int GetCorrectlySungNoteLength(RecordedNote recordedNote)
    {
        if (recordedNote.TargetNote == null)
        {
            return(0);
        }

        if (MidiUtils.GetRelativePitch(recordedNote.TargetNote.MidiNote) != MidiUtils.GetRelativePitch(recordedNote.RoundedMidiNote))
        {
            return(0);
        }

        int correctlySungNoteLength = (int)(recordedNote.EndBeat - recordedNote.StartBeat);

        return(correctlySungNoteLength);
    }
Beispiel #4
0
    public static int GetRelativePitchDistanceSigned(int fromMidiNote, int toMidiNote)
    {
        int toRelativeMidiNote   = MidiUtils.GetRelativePitch(toMidiNote);
        int fromRelativeMidiNote = MidiUtils.GetRelativePitch(fromMidiNote);
        // Distance when going from 2 to 10 via 3, 4, 5... -> (8)
        // Distance when going from 10 to 2 via 9, 8, 7... -> (-8)
        int distanceUnwrapped = toRelativeMidiNote - fromRelativeMidiNote;
        // Distance when going from 2 to 10 via 1, 0, 11, 10 -> (-4)
        // Distance when going from 10 to 2 via 11, 0, 1, 2 -> (4)
        int distanceWrapped = distanceUnwrapped >= 0
            ? distanceUnwrapped - 12
            : distanceUnwrapped + 12;
        int distance = Math.Abs(distanceUnwrapped) < Math.Abs(distanceWrapped)
            ? distanceUnwrapped
            : distanceWrapped;

        return(distance);
    }
Beispiel #5
0
    void Update()
    {
        if (songAudioPlayer.PositionInSongInMillis <= 0)
        {
            return;
        }

        PitchEvent pitchEvent = playerPitchTracker.GetPitchEventOfSamples(micSampleRecorder.MicSamples.Length - 1 - samplesPerBeat, micSampleRecorder.MicSamples.Length - 1);

        if (pitchEvent != null)
        {
            // Shift midi note to octave of last recorded midi note (can be different because PlayerPitchTracker is rounding towards the target note)
            int midiNote = lastRecordedRoundedMidiNote > 0
                ? MidiUtils.GetRelativePitch(pitchEvent.MidiNote) + (12 * (MidiUtils.GetOctave(lastRecordedRoundedMidiNote) + 1))
                : pitchEvent.MidiNote;
            UpdatePosition(midiNote);
        }
    }
Beispiel #6
0
    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);
        }
    }
Beispiel #7
0
    private void UpdateMidiNoteLines()
    {
        horizontalGridImage.ClearTexture();

        int minMidiNote = noteArea.MinMidiNoteInViewport;
        int maxMidiNote = noteArea.MaxMidiNoteInViewport;

        for (int midiNote = minMidiNote; midiNote <= maxMidiNote; midiNote++)
        {
            // Notes are drawn on lines and between lines alternatingly.
            bool hasLine = (midiNote % 2 == 0);
            if (hasLine)
            {
                Color color = (MidiUtils.GetRelativePitch(midiNote) == 0) ? lineHighlightColor : lineNormalColor;
                DrawHorizontalGridLine(midiNote, color);
            }
        }

        horizontalGridImage.ApplyTexture();
    }
    private void UpdateMidiNoteLines()
    {
        dynamicTexture.ClearTexture();

        int minMidiNote = noteAreaControl.MinMidiNoteInCurrentViewport;
        int maxMidiNote = noteAreaControl.MaxMidiNoteInCurrentViewport;

        for (int midiNote = minMidiNote; midiNote <= maxMidiNote; midiNote++)
        {
            // Notes are drawn on lines and between lines alternatingly.
            bool hasLine = (midiNote % 2 == 0);
            if (hasLine)
            {
                Color color = (MidiUtils.GetRelativePitch(midiNote) == 0)
                    ? NoteAreaHorizontalRulerControl.highlightLineColor
                    : NoteAreaHorizontalRulerControl.normalLineColor;
                DrawHorizontalGridLine(midiNote, color);
            }
        }

        dynamicTexture.ApplyTexture();
    }
 private bool IsPerfectHit(PlayerPitchTracker.BeatAnalyzedEvent beatAnalyzedEvent)
 {
     return(MidiUtils.GetRelativePitch(beatAnalyzedEvent.NoteAtBeat.MidiNote) == MidiUtils.GetRelativePitch(beatAnalyzedEvent.RecordedMidiNote));
 }
Beispiel #10
0
    private 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)
        {
            int relativeSignedDistance = MidiUtils.GetRelativePitchDistanceSigned(recordedNote.TargetNote.MidiNote, recordedNote.RoundedMidiNote);
            int roundedMidiNoteOnOctaveOfTargetNote = recordedNote.TargetNote.MidiNote + relativeSignedDistance;
            if (MidiUtils.GetRelativePitch(recordedNote.RoundedMidiNote) != MidiUtils.GetRelativePitch(roundedMidiNoteOnOctaveOfTargetNote))
            {
                // Should never happen
                Debug.LogError($"The displayed midi note does not correspond to the rounded recorded midi note:"
                               + $"recorded {recordedNote.RoundedMidiNote}, target: {recordedNote.TargetNote.MidiNote}, displayed: {roundedMidiNoteOnOctaveOfTargetNote}");
            }
            midiNote = roundedMidiNoteOnOctaveOfTargetNote;
        }
        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);
    }