void Awake() { microphoneUI = transform.GetComponent <MicrophoneUI>(); if (microphoneUI != null) { prewarned = !microphoneUI.AskPermission(); } else { LogMT.Log("No UI detected, defulting to skip permission step"); prewarned = true; } /*if (FindObjectOfType<AudioListener>() == null) * { * LogMT.LogWarning("MicrophoneController: No AudioListener found, creating one"); * GameObject audioListener = new GameObject(); * audioListener.name = "AudioListener"; * audioListener.AddComponent<AudioListener>(); * } * * AudioMixer audioMixer = Resources.Load("MicrophoneToolsMixer") as AudioMixer; * if (audioMixer == null) * LogMT.LogError("MicrophoneController: Could not find Audio Mixer");*/ }
/// <summary> /// Track where we should consider the current position in the AudioClip for accessing samples. /// </summary> private void BufferTrackingUpdate() { deltaDSPTime = (AudioSettings.dspTime - previousDSPTime); if (waitingForAudio) { float[] newData = new float[audioClip.samples]; audioClip.GetData(newData, 0); for (int i = newData.Length - 1; i >= 0; i--) // going backwards find end //for (int i=0;i<buffer.Length;i++) // going forwards, find beginning { if (newData[i] != 0) { bufferPos = 0; waitingForAudio = false; gameObject.SendMessage("OnSoundEvent", SoundEvent.BufferReady, SendMessageOptions.DontRequireReceiver); break; } } } else { int samplesPassed = (int)Math.Ceiling(deltaDSPTime * audioClip.frequency); bufferPos = (bufferPos + samplesPassed) % audioClip.samples; if (logAudioData) { float[] newData = new float[samplesPassed]; audioClip.GetData(newData, bufferPos); LogMT.SendByteDataBase64("MTaudio", EncodeFloatBlockTo16BitPCM(newData)); } } }
void Update() { if (microphoneDeviceSet) { if (microphoneActive) { MicrophoneUpdate(); } else if (listening) // If we're listening, but the microphone shouldn't be active { StopListening(); } } else if (microphoneActive) // If the microphone should be active, but it is not configured { LogMT.LogWarning("MicrophoneController: Microphone active yet no microphone device set!"); //microphoneActive = false; } if (listening) { BufferTrackingUpdate(); } else { MicrophoneConfigurationUpdate(); } previousDSPTime = AudioSettings.dspTime; }
void OnSoundEvent(SoundEvent soundEvent) { LogMT.Log(soundEvent.ToString()); switch (soundEvent) { case SoundEvent.PermissionGranted: prewarned = true; break; } }
/// <summary> /// Watch for changes in microphone configuration status, possibly due to user interaction, and /// configure appropriately /// </summary> private void MicrophoneConfigurationUpdate() { if (microphoneAvailable) { if (!microphoneChoiceSent) { if (!prewarned) { if (!prewarningSent) { gameObject.SendMessage("OnSoundEvent", SoundEvent.PermissionRequired, SendMessageOptions.DontRequireReceiver); prewarningSent = true; } } else if (Application.HasUserAuthorization(UserAuthorization.Microphone)) { if (Microphone.devices.Length > 0) { if (microphoneUI != null) { if (microphoneUI.UseDefaultMic()) { UseDefaultDevice(); } else { microphoneUI.ChooseDevice(Microphone.devices); } } else { UseDefaultDevice(); } microphoneChoiceSent = true; } else { if (microphoneUI != null) { microphoneUI.NoMicrophonesFound(); } LogMT.LogWarning("MicrophoneController: No microphones found"); microphoneAvailable = false; } } else if (!authorizationRequestSent) { Application.RequestUserAuthorization(UserAuthorization.Microphone); LogMT.Log("MicrophoneController: User authorization requested for microphone"); authorizationRequestSent = true; } } } }
public void OnSoundEvent(SoundEvent e) { switch (e) { case SoundEvent.BufferReady: yin = new Yin(microphoneController.SampleRate, SyllableDetectionAlgorithm.windowSize); LogMT.Log("Window Size for Algorithm: " + SyllableDetectionAlgorithm.windowSize); syllableDetectionAlgorithm = new SyllableDetectionAlgorithm(microphoneController.SampleRate); break; } }
public bool Run(float[] data, float deltaTime) { syllableDetected = false; float sumIntensity = 0; if (!SinglePolaity(data)) // Here to easily take out artifacts found on my poor desktop mic { sumIntensity = SumAbsIntensity(data); level = sumIntensity / data.Length; float mean = SumIntensity(data) / data.Length; int sampleOffsetHigh; int sampleOffsetLow; FrequencyBandToSampleOffsets(data.Length, sampleRate, 80, 300, out sampleOffsetHigh, out sampleOffsetLow); // was 80,900 float newNPA = DoNormalisedPeakAutocorrelation(data, mean, sampleOffsetHigh, sampleOffsetLow); normalisedPeakAutocorrelation += (newNPA - normalisedPeakAutocorrelation) * deltaTime * 10; DipTracking(); // If we're using the periodicity, check that the normalised value is high before // considering it if (normalisedPeakAutocorrelation > npaThreshold) { peak = Math.Max(peak, level); PeakPicking(); } } else { level = 0; } if (syllableDetected) { totalSyllables++; } LogMT.SendStreamValue("MTdt", deltaTime); LogMT.SendStreamValue("MTnpa", normalisedPeakAutocorrelation); LogMT.SendStreamValue("MTlvl", level); LogMT.SendStreamValue("MTpek", peak); LogMT.SendStreamValue("MTdip", dip); LogMT.SendStreamValue("MTdpd", Convert.ToInt32(dipped)); LogMT.SendStreamValue("MTsbs", totalSyllables); return(syllableDetected); }
/// <summary> /// Will set the sampling rate to the default, or the highest available from the microphone if /// this is lower than the default /// </summary> private void SetSamplingRate() { int min, max; Microphone.GetDeviceCaps(microphoneDeviceName, out min, out max); if (max == 0) { sampleRate = defaultSampleRate; } else if (defaultSampleRate > max) { sampleRate = max; } LogMT.Log("MicrophoneController: Sampling rate: " + sampleRate); }
/// <summary> /// Calculates the peak of the normalised autocorrelation of a window of samples, /// with an offset within a given band. /// </summary> private static float DoNormalisedPeakAutocorrelation(float[] window, float mean, int sampleOffsetHigh, int sampleOffsetLow) { float highest = 0; float[] gammaA = new float[sampleOffsetHigh - sampleOffsetLow + 1]; float sumZero = 0; for (int t = 0; t < window.Length - 0; t++) { sumZero += window[t + 0] * window[t]; } float gammaZero = sumZero / window.Length; for (int h = sampleOffsetHigh; h >= sampleOffsetLow; h--) { float sum = 0; for (int t = 0; t < window.Length - h; t++) { sum += (window[t + h] - mean) * (window[t] - mean); } float gamma = (sum / window.Length) / (window.Length - h); if (gamma > highest) { highest = gamma; } float norm = highest / (gammaZero / window.Length); gammaA[h - sampleOffsetLow] = norm; } // Here we normalise the peak value so it is between 0 and 1 float normalised = highest / (gammaZero / window.Length); LogMT.SendStreamValue("MTsoL", sampleOffsetLow); LogMT.SendStreamValue("MTsoH", sampleOffsetHigh); LogMT.SendStreamValueBlock("MTatc", gammaA); return(normalised); }
void initialize(float yinSampleRate, int yinBufferSize) { bufferSize = yinBufferSize; sampleRate = yinSampleRate; halfBufferSize = bufferSize / 2; threshold = 0.6; //was 0.15 probability = 0.0f; //initialize array and set it to zero yinBuffer = new float[halfBufferSize]; for (int i = 0; i < halfBufferSize; i++) { yinBuffer[i] = 0; } LogMT.Log("Yin sample rate: " + yinSampleRate); LogMT.Log("Yin buffer size: " + yinBufferSize); LogMT.Log("Yin threshold: " + threshold); }
/// <summary> /// Change the microphone to the default microphone. Will fail if user authorisation has not /// been obtained or there are no microphones. /// </summary> public void UseDefaultDevice() { if (Application.HasUserAuthorization(UserAuthorization.Microphone)) { if (Microphone.devices.Length > 0) { microphoneDeviceName = ""; microphoneDeviceSet = true; SetSamplingRate(); LogMT.Log("MicrophoneController: Using default microphone"); } else { LogMT.LogError("MicrophoneController: Cannot set device: No devices available", this); } } else { LogMT.LogError("MicrophoneController: Cannot set device: User Authorization required", this); } }
/// <summary> /// Change the microphone to the given ID. Will fail if user authorisation has not been obtained /// or device doesn't exist. /// </summary> public void SetDevice(int id) { if (Application.HasUserAuthorization(UserAuthorization.Microphone)) { if ((id >= 0) && (Microphone.devices.Length > 0)) { microphoneDeviceName = Microphone.devices[id]; LogMT.Log("MicrophoneController: Using microphone: " + microphoneDeviceName); microphoneDeviceSet = true; SetSamplingRate(); } else { LogMT.LogError("MicrophoneController: Cannot set device: Device not available", this); } } else { LogMT.LogError("MicrophoneController: Cannot set device: User Authorization required", this); } }
/// <summary> /// Start microphone access and collecting samples. Wait for a SoundEvent.BufferReady signal /// through OnSoundEvent() before attempting to access sample data. /// </summary> private void StartListening() { if (testClip != null) { audioClip = testClip; channels = audioClip.channels; sampleRate = audioClip.frequency; } else { audioClip = Microphone.Start(microphoneDeviceName, true, 1, sampleRate); channels = 1; // Fetching the number of channels from the audio clip gives incorrect // results, possibly due to a Unity bug } LogMT.Log("Audio Channels: " + channels); listening = true; waitingForAudio = true; gameObject.SendMessage("OnSoundEvent", SoundEvent.AudioStart, SendMessageOptions.DontRequireReceiver); }