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}");
        }
    }
Esempio n. 2
0
    private void OnRecordingEvent(RecordingEvent recordingEvent)
    {
        // Detect the pitch of the sample
        int newSampleLength = recordingEvent.NewSamplesEndIndex - recordingEvent.NewSamplesStartIndex;

        bufferedNotAnalyzedSampleCount += newSampleLength;

        // Wait until enough new samples are buffered
        if (bufferedNotAnalyzedSampleCount < MinSampleCountToUse)
        {
            return;
        }

        // Do not analyze more than necessary
        if (bufferedNotAnalyzedSampleCount > MaxSampleCountToUse)
        {
            bufferedNotAnalyzedSampleCount = MaxSampleCountToUse;
        }

        // Analyze the newest portion of the not-yet-analyzed MicSamples
        int        startIndex = recordingEvent.MicSamples.Length - bufferedNotAnalyzedSampleCount;
        int        endIndex   = recordingEvent.MicSamples.Length;
        PitchEvent pitchEvent = audioSamplesAnalyzer.ProcessAudioSamples(recordingEvent.MicSamples, startIndex, endIndex, MicProfile);

        bufferedNotAnalyzedSampleCount = 0;

        // Notify listeners
        pitchEventStream.OnNext(pitchEvent);
    }