private void CreateListEntry(MicProfile micProfile)
    {
        SongSelectMicListEntry listEntry = Instantiate(listEntryPrefab, scrollViewContent.transform);

        injector.InjectAllComponentsInChildren(listEntry);
        listEntry.Init(micProfile);
    }
示例#2
0
    public void SetMicProfileName(string deviceName)
    {
        MicProfile newMicProfile = new MicProfile(MicProfile);

        newMicProfile.Name = deviceName;
        MicProfile         = newMicProfile;
    }
示例#3
0
 public void SetColorOfMicProfile(MicProfile micProfile)
 {
     if (micProfile != null)
     {
         SetColor(micProfile.Color);
     }
 }
    private void UpdateWaveForm()
    {
        MicProfile micProfile = micPitchTracker.MicProfile;

        if (micProfile == null)
        {
            return;
        }

        float[] micData = micPitchTracker.MicSampleRecorder.MicSamples;

        // Apply noise suppression and amplification to the buffer
        float[] displayData    = new float[micData.Length];
        float   noiseThreshold = micProfile.NoiseSuppression / 100f;

        if (micData.AnyMatch(sample => sample >= noiseThreshold))
        {
            for (int i = 0; i < micData.Length; i++)
            {
                displayData[i] = NumberUtils.Limit(micData[i] * micAmplifyMultiplier, -1, 1);
            }
        }

        audioWaveFormVisualizer.DrawWaveFormValues(displayData, micData.Length - displayedSampleCount, displayedSampleCount);
    }
    private void TestPitchDetection(Func <int, IAudioSamplesAnalyzer> audioSamplesAnalyzerProvider)
    {
        MicProfile micProfile = CreateDummyMicProfile();

        string assetsPath      = Application.dataPath;
        string sineWaveToneDir = assetsPath + "/Common/Audio/SineWaveTones/";
        Dictionary <string, string> pathToExpectedMidiNoteNameMap = new();

        pathToExpectedMidiNoteNameMap.Add(sineWaveToneDir + "sine-wave-a3-220hz.ogg", "A3");
        pathToExpectedMidiNoteNameMap.Add(sineWaveToneDir + "sine-wave-a4-440hz.ogg", "A4");
        pathToExpectedMidiNoteNameMap.Add(sineWaveToneDir + "sine-wave-a5-880hz.ogg", "A5");
        pathToExpectedMidiNoteNameMap.Add(sineWaveToneDir + "sine-wave-c2-61,74hz.ogg", "C2");
        pathToExpectedMidiNoteNameMap.Add(sineWaveToneDir + "sine-wave-c4-261,64hz.ogg", "C4");
        pathToExpectedMidiNoteNameMap.Add(sineWaveToneDir + "sine-wave-c6-1046,50hz.ogg", "C6");

        foreach (KeyValuePair <string, string> pathAndNoteName in pathToExpectedMidiNoteNameMap)
        {
            // Load the audio clip
            string    uri       = "file://" + pathAndNoteName.Key;
            AudioClip audioClip = AudioUtils.GetAudioClipUncached(uri, false);
            float[]   samples   = new float[audioClip.samples];
            audioClip.GetData(samples, 0);

            // Analyze the samples
            IAudioSamplesAnalyzer audioSamplesAnalyzer = audioSamplesAnalyzerProvider(audioClip.frequency);
            PitchEvent            pitchEvent           = audioSamplesAnalyzer.ProcessAudioSamples(samples, 0, samples.Length - 1, micProfile);

            // Check result
            Assert.NotNull(pitchEvent, $"No pitch detected when analyzing audio resource {uri}");
            string expectedName = pathAndNoteName.Value;
            string analyzedName = MidiUtils.GetAbsoluteName(pitchEvent.MidiNote);
            Assert.AreEqual(expectedName, analyzedName,
                            $"Expected {expectedName} but was {analyzedName} when analyzing audio resource {uri}");
        }
    }
示例#6
0
    private void HandleClientConnectedEvent(ClientConnectionEvent connectionEvent)
    {
        // Find existing or create new MicProfile for the newly connected device
        MicProfile micProfile = settings.MicProfiles.FirstOrDefault(it => it.ConnectedClientId == connectionEvent.ConnectedClientHandler.ClientId);

        if (micProfile == null)
        {
            micProfile = new MicProfile(connectionEvent.ConnectedClientHandler.ClientName, connectionEvent.ConnectedClientHandler.ClientId);
            settings.MicProfiles.Add(micProfile);
        }

        SongSelectMicListEntry matchingListEntry = listEntries.FirstOrDefault(listEntry =>
                                                                              listEntry.MicProfile != null &&
                                                                              listEntry.MicProfile.ConnectedClientId == connectionEvent.ConnectedClientHandler.ClientId &&
                                                                              listEntry.MicProfile.IsEnabled);

        if (connectionEvent.IsConnected && matchingListEntry == null && micProfile.IsEnabled)
        {
            // Add to UI
            CreateListEntry(micProfile);
        }
        else if (!connectionEvent.IsConnected && matchingListEntry != null)
        {
            // Remove from UI
            RemoveListEntry(matchingListEntry);
        }
    }
    private void UseMicProfileWhereNeeded(MicProfile micProfile)
    {
        if (micProfile == null ||
            !micProfile.IsEnabled)
        {
            return;
        }

        SongSelectPlayerProfileListEntry listEntryWithMatchingMicProfile = listEntries.FirstOrDefault(it =>
                                                                                                      it.MicProfile != null &&
                                                                                                      it.MicProfile.ConnectedClientId == micProfile.ConnectedClientId);

        if (listEntryWithMatchingMicProfile != null)
        {
            // Already in use. Cannot be assign to other players.
            return;
        }

        SongSelectPlayerProfileListEntry listEntryWithMissingMicProfile = listEntries.FirstOrDefault(it => it.PlayerProfile.IsSelected && it.MicProfile == null);

        if (listEntryWithMissingMicProfile != null)
        {
            listEntryWithMissingMicProfile.MicProfile = micProfile;
        }
    }
    private void UpdateWaveForm()
    {
        if (audioWaveFormVisualization == null)
        {
            return;
        }

        MicProfile micProfile = micPitchTracker.MicProfile;

        if (micProfile == null)
        {
            return;
        }

        float[] micData = micPitchTracker.MicSampleRecorder.MicSamples;

        // Consider amplification
        AbstractAudioSamplesAnalyzer.ApplyAmplification(micData, 0, micData.Length, micProfile.AmplificationMultiplier);

        // Consider noise suppression when displaying the the buffer
        bool isAboveThreshold = AbstractAudioSamplesAnalyzer.IsAboveNoiseSuppressionThreshold(micData, 0, micData.Length, micProfile.NoiseSuppression);

        float[] displayData = isAboveThreshold
            ? micData
            : new float[micData.Length];

        audioWaveFormVisualization.DrawWaveFormMinAndMaxValues(displayData);
    }
示例#9
0
    public void Init(PlayerProfile playerProfile, MicProfile micProfile)
    {
        lineDisplayer = GetComponentInChildren <LineDisplayer>();
        lineDisplayer.Init(6);

        sentenceDisplayer = GetComponentInChildren <SentenceDisplayer>();
        sentenceDisplayer.Init(12, micProfile);

        totalScoreDisplayer = GetComponentInChildren <TotalScoreDisplayer>();

        sentenceRatingDisplayer = GetComponentInChildren <SentenceRatingDisplayer>();

        beatGridDisplayer = GetComponentInChildren <BeatGridDisplayer>();

        currentBeatGridDisplayer = GetComponentInChildren <CurrentBeatGridDisplayer>();

        PlayerNameText playerNameText = GetComponentInChildren <PlayerNameText>();

        playerNameText.SetPlayerProfile(playerProfile);

        AvatarImage avatarImage = GetComponentInChildren <AvatarImage>();

        avatarImage.SetPlayerProfile(playerProfile);

        if (micProfile != null)
        {
            totalScoreDisplayer.SetColorOfMicProfile(micProfile);
            avatarImage.SetColorOfMicProfile(micProfile);
        }
    }
示例#10
0
 public void SetMicProfile(MicProfile micProfile)
 {
     micPitchTracker.MicProfile = micProfile;
     if (!string.IsNullOrEmpty(micProfile.Name))
     {
         micPitchTracker.MicSampleRecorder.StartRecording();
     }
 }
示例#11
0
 public void SetMicProfile(MicProfile micProfile)
 {
     microphonePitchTracker.MicProfile = micProfile;
     if (!string.IsNullOrEmpty(micProfile.Name))
     {
         microphonePitchTracker.StartPitchDetection();
     }
 }
示例#12
0
    public void SetColorOfMicProfile(MicProfile micProfile)
    {
        float r = micProfile.Color.r * colorFactor;
        float g = micProfile.Color.g * colorFactor;
        float b = micProfile.Color.b * colorFactor;

        image.color = new Color(r, g, b, 1);
    }
示例#13
0
 private void OnDropdownValueChanged(int index)
 {
     if (index > 0 && index < micProfilesInDropdown.Count)
     {
         MicProfile selectedMicProfile = micProfilesInDropdown[index];
         micPitchTracker.MicProfile = selectedMicProfile;
     }
 }
 public void SetMicProfile(MicProfile micProfile)
 {
     micPitchTracker.MicProfile = micProfile;
     if (!micProfile.Name.IsNullOrEmpty() &&
         !micProfile.IsInputFromConnectedClient)
     {
         micPitchTracker.MicSampleRecorder.StartRecording();
     }
 }
示例#15
0
    public void Init(MicProfile micProfile)
    {
        micPitchTracker         = GetComponentInChildren <MicPitchTracker>();
        audioWaveFormVisualizer = GetComponentInChildren <AudioWaveFormVisualizer>();

        micImage.color             = micProfile.Color;
        micPitchTracker.MicProfile = micProfile;
        micPitchTracker.MicSampleRecorder.StartRecording();
    }
示例#16
0
    private void CreatePlayerController(PlayerProfile playerProfile, MicProfile micProfile)
    {
        string           voiceIdentifier  = GetVoiceIdentifier(playerProfile);
        PlayerController playerController = GameObject.Instantiate <PlayerController>(playerControllerPrefab);

        playerController.Init(sceneData.SelectedSongMeta, playerProfile, voiceIdentifier, micProfile);

        PlayerControllers.Add(playerController);
    }
示例#17
0
    public void Init(MicProfile micProfile)
    {
        microphonePitchTracker  = GetComponentInChildren <MicrophonePitchTracker>();
        audioWaveFormVisualizer = GetComponentInChildren <AudioWaveFormVisualizer>();

        micImage.color = micProfile.Color;
        microphonePitchTracker.MicProfile = micProfile;
        microphonePitchTracker.StartPitchDetection();
    }
示例#18
0
    public void SetMicProfile(MicProfile micProfile)
    {
        if (disposable != null)
        {
            disposable.Dispose();
        }

        SelectedValue = micProfile.DelayInMillis;
        disposable    = SelectedValueStream.Subscribe(newValue => micProfile.DelayInMillis = (int)newValue);
    }
示例#19
0
    public void SetMicProfile(MicProfile micProfile)
    {
        if (disposable != null)
        {
            disposable.Dispose();
        }

        Selection.Value = Items.Where(it => it == micProfile.NoiseSuppression).First();
        disposable      = Selection.Subscribe(newValue => micProfile.NoiseSuppression = newValue);
    }
示例#20
0
    private static MicProfile CreateDummyMicProfile()
    {
        MicProfile result = new MicProfile("Dummy Mic");

        result.Amplification    = 0;
        result.NoiseSuppression = 0;
        result.IsEnabled        = true;
        result.Color            = Colors.indigo;
        return(result);
    }
示例#21
0
    public void SetMicProfile(MicProfile micProfile)
    {
        if (disposable != null)
        {
            disposable.Dispose();
        }

        Selection.Value = Items.Where(it => it == micProfile.DelayInMillis).FirstOrDefault().OrIfNull(140);
        disposable      = Selection.Subscribe(newValue => micProfile.DelayInMillis = newValue);
    }
示例#22
0
    private void CreatePlayerController(PlayerProfile playerProfile, MicProfile micProfile)
    {
        string           voiceName        = GetVoiceName(playerProfile);
        PlayerController playerController = GameObject.Instantiate <PlayerController>(playerControllerPrefab);

        sceneInjector.Inject(playerController);
        playerController.Init(playerProfile, voiceName, micProfile);

        PlayerControllers.Add(playerController);
    }
示例#23
0
 private void CreateRectangles(SongMeta songMeta, PlayerControl playerControl, double durationOfSongInMillis)
 {
     foreach (Sentence sentence in playerControl.Voice.Sentences)
     {
         double     startPosInMillis = BpmUtils.BeatToMillisecondsInSong(songMeta, sentence.MinBeat);
         double     endPosInMillis   = BpmUtils.BeatToMillisecondsInSong(songMeta, sentence.MaxBeat);
         MicProfile micProfile       = playerControl.MicProfile;
         CreateRectangle(micProfile, startPosInMillis, endPosInMillis, durationOfSongInMillis);
     }
 }
示例#24
0
    public void SetMicProfile(MicProfile micProfile)
    {
        if (disposable != null)
        {
            disposable.Dispose();
        }

        Selection.Value = micProfile.Color;
        disposable      = Selection.Subscribe(newValue => micProfile.Color = newValue);
    }
示例#25
0
 private void CreateTimeLineRects(SongMeta songMeta, PlayerController playerController, double durationOfSongInMillis)
 {
     foreach (Sentence sentence in playerController.Voice.Sentences)
     {
         double        startPosInMillis = BpmUtils.BeatToMillisecondsInSong(songMeta, sentence.MinBeat);
         double        endPosInMillis   = BpmUtils.BeatToMillisecondsInSong(songMeta, sentence.MaxBeat);
         PlayerProfile playerProfile    = playerController.PlayerProfile;
         MicProfile    micProfile       = playerController.MicProfile;
         CreateTimeLineRect(playerProfile, micProfile, startPosInMillis, endPosInMillis, durationOfSongInMillis);
     }
 }
示例#26
0
 public void Init(int noteRowCount, MicProfile micProfile)
 {
     this.micProfile = micProfile;
     // Notes can be placed on and between the drawn lines.
     this.noteRowCount = noteRowCount;
     // Check that there is at least one row for every possible note in an octave.
     if (this.noteRowCount < 12)
     {
         throw new UnityException("SentenceDisplayer must be initialized with a row count >= 12 (one row for each note in an octave)");
     }
 }
 private void RemoveMicProfileFromListEntries(MicProfile micProfile)
 {
     foreach (SongSelectPlayerProfileListEntry listEntry in listEntries)
     {
         if (listEntry.MicProfile != null &&
             listEntry.MicProfile.ConnectedClientId == micProfile.ConnectedClientId)
         {
             listEntry.MicProfile = null;
         }
     }
 }
    private void SetStyleByMicProfile(MicProfile micProfile)
    {
        // If no target note, then remove saturation from color and make transparent
        Color color      = micProfile.Color;
        Color finalColor = (RecordedNote != null && RecordedNote.TargetNote == null)
            ? color.RgbToHsv().WithGreen(0).HsvToRgb().WithAlpha(0.25f)
            : color;

        image.style.unityBackgroundImageTintColor = finalColor;
        image.style.backgroundColor = finalColor;
    }
示例#29
0
    private void CreateListEntry(MicProfile micProfile)
    {
        SongSelectMicListEntry listEntry = Instantiate(listEntryPrefab, scrollViewContent.transform);

        injector.InjectAllComponentsInChildren(listEntry);
        listEntry.MicProfile = micProfile;

        listEntries.Add(listEntry);

        emptyListLabel.SetActive(false);
    }
示例#30
0
 public void Init(int playerProfileIndex,
                  PlayerProfile playerProfile,
                  SingingResultsSceneData.PlayerScoreData playerScoreData,
                  MicProfile micProfile)
 {
     SetPlayerProfile(playerProfileIndex, playerProfile, micProfile);
     SetNormalNotesScore(playerScoreData.NormalNotesScore);
     SetGoldenNotesScore(playerScoreData.GoldenNotesScore);
     SetPerfectSentenceBonusScore(playerScoreData.PerfectSentenceBonusScore);
     SetTotalScore(playerScoreData.TotalScore);
 }