void DetectJump(float value) { buffer.Add(value); // calculate fft PrepareBuffer(); FFT.CalculateFFT(fftBuffer, false); // check frequency band var amp = (float)fftBuffer[frequencyBand].magnitude * 2; // show debug info var scoreText = (GameObject.Find("DebugText").GetComponent("GUIText") as GUIText); scoreText.text = "Input: " + input.Value + "\nFFT: " + amp + "\nMax: " + maxAmp; if (maxAmp < amp) { maxAmp = amp; } if (c == 100) { c = 0; maxAmp = 0; } // jump if (amp >= threshold) { jump.Jump(); } c++; }
// Update is called once per frame void Update() { // Unity's FFT function AudioListener.GetSpectrumData(spec, 0, FFTWindow.BlackmanHarris); for (int i = 0; i < spec.Length; i++) { Debug.DrawLine(new Vector3(i, 0, 0), new Vector3(i, spec[i] * 18000), Color.black); } // My FFT based on the output samples. AudioListener.GetOutputData(tmp, 0); // copy the output data into the complex array for (int i = 0; i < tmp.Length; i++) { spec2[i] = new Complex(tmp[i], 0); } // calculate the FFT FFT.CalculateFFT(spec2, false); for (int i = 0; i < spec2.Length / 2; i++) // plot only the first half { // multiply the magnitude of each value by 2 Debug.DrawLine(new Vector3(i, 0, 40), new Vector3(i, (float)spec2[i].magnitude * 36000, 40), Color.white); if (spec2 [i].magnitude * 18000 > 300) { Debug.Log(i); } } }
public static float[] GetFrequencySpectrum(float[] soundData) { int grainSize = soundData.Length; if (!Mathf.IsPowerOfTwo(grainSize)) { throw new System.ArgumentException("Grain Size needs to be a power of 2"); } Complex[] complexData = new Complex[grainSize]; for (int i = 0; i < grainSize; i++) { complexData[i] = new Complex(soundData[i], 0); } FFT.CalculateFFT(complexData, false); for (int i = 0; i < grainSize; i++) { soundData[i] = (float)complexData[i].magnitude; } return(soundData); }
// Update is called once per frame void Update() { for (int i = 1024, j = 0; i < fakeSize; i++, j++) { lastsamples[j] = lastsamples[i]; } for (int i = 0, j = fakeSize - 1024; j < fakeSize; i++, j++) { lastsamples[j] = samples[i]; } MasterInput.RetrieveWaveform(FilterType.Bypass, samples); for (int i = 0; i < lastsamples.Length; i++) { freq[i] = new Complex(lastsamples[i], 0); } for (int i = 0; i < samples.Length; i++) { freq[lastsamples.Length + i] = new Complex(samples[i], 0); } for (int i = 0; i < samples.Length; i++) { Debug.DrawLine(new Vector3(i, 0), new Vector3(i, samples[i] * 20), Color.cyan); } FFT.CalculateFFT(freq, false); for (int i = 0; i < freq.Length / 2; i++) // plot only the first half { // multiply the magnitude of each value by 2 Debug.DrawLine(new Vector3(i, 200), new Vector3(i, 200 + (float)freq[i].magnitude * 200), Color.white); } List <FreqData> maximas = new List <FreqData>(); for (int i = imin; i < imax; i++) { if (freq[i].magnitude > noteThreshold) { if (freq[i].magnitude > freq[i - 1].magnitude && freq[i].magnitude > freq[i + 1].magnitude) { FreqData temp = new FreqData(); temp.location = i; temp.mag = freq[i].magnitude; maximas.Add(temp); } } } if (maximas.Count > 0) { maximas.Sort((s1, s2) => s1.mag.CompareTo(s2.mag)); float maxFreq = maximas[0].location * freqStep; int closest = (int)FreqToNumber(maxFreq); float closestFreq = NumberToFreq(closest); ColorHSV colorA = Colors[closest % 12], colorB; if (maxFreq - closestFreq > 0) { colorB = Colors[(closest + 1) % 12]; } else { colorB = Colors[(closest - 1) % 12]; } var mainModule = objectToColorChange.main; Color x = ColorHSV.Lerp(colorA, colorB, Mathf.Abs(maxFreq - closestFreq) / maxFreq).ToColor(); mainModule.startColor = x; } }
void Start() { AudioClip clip; float[] data; double[] data2; double sampleRate; int channels; using (var stream = System.IO.File.OpenRead(filePath)) { var waveFile = new WaveFile(stream); clip = AudioClip.Create("test", waveFile.Samples.Length / waveFile.Channels, channels = waveFile.Channels, (int)waveFile.SamplePerSec, false); songLength = (float)waveFile.Samples.Length / waveFile.SamplePerSec / waveFile.Channels; data = new float[waveFile.Samples.Length]; data2 = new double[waveFile.Samples.Length / waveFile.Channels]; sampleRate = waveFile.SamplePerSec; for (int i = 0; i < data.Length; i++) { data[i] = (float)waveFile.Samples[i]; } for (int i = 0; i < data2.Length; i++) { data2[i] = waveFile.Samples[i * waveFile.Channels]; } clip.SetData(data, 0); } const int length = 2048; const int skip = 512; const int width = length >> 3; var com = new Complex[length]; var texture = new Texture2D(width, data.Length / channels / skip, TextureFormat.RGB24, false); texture.filterMode = FilterMode.Point; Debug.Log(texture.height); Debug.Log(texture.width); if (System.IO.File.Exists(filePath + ".png")) { texture.LoadImage(System.IO.File.ReadAllBytes(filePath + ".png")); } else { for (int i = 0; i < data.Length / channels / skip; i++) { if (i * skip * channels + length * channels >= data.Length) { break; } for (int j = 0; j < length; j++) { com[j].real = data[i * skip * channels + j * channels]; com[j].img = 0; } com = FFT.CalculateFFT(com, false); for (int j = 0; j < width; j++) { texture.SetPixel(width - j - 1, i, gradient.Evaluate(com[j].fMagnitude * 5)); } } } texture.Apply(); uiRawImage.texture = texture; // uiRawImage.SetNativeSize(); beatmapEditor.Init(clip.length, 2, 0); System.IO.File.WriteAllBytes(filePath + ".png", texture.EncodeToPNG()); source.clip = clip; }
public void calcSpectrum() { //8192 per 4s, spt pake 2048 di fungsi unity biasa // print(spectrumDom.Length); int currentSample = 0; //sample sudah sampe mana for (int d = 0; d < 4; d++) { bands [d] = 0; } int c = 0; for (int a = 0; a < spectrumDom.Length; a++) { c = 0; spec = new Complex[8192]; for (int b = currentSample; b < (samplerate * 4) + currentSample && b < totalsample && c < 8192; b += samplerate * 4 / 8192) { spec [c] = new Complex(samples [b], 0); c++; //TODO: cek getoutputdata itu bener skip2 ato ngambil sample terakhir } currentSample += ((samplerate * 4)); FFT.CalculateFFT(spec, false); // utk array size 8192, per index=2.93 // each element represent amplitude of freq N*24000/(arrsize) hz float [] tmpmag = new float[spec.Length / 2]; for (int d = 0; d < tmpmag.Length; d++) { tmpmag [d] = spec [d].fMagnitude; } // int samplerate = tempAC.samples / songDur; int skip = samplerate / 8192; //5.85 - > skip for (int d = 0; d < spec.Length / 2; d++) { if (spec [d].fMagnitude > Mathf.Max(tmpmag) / 10) // 10% max magnitude buat eliminasi { if (d * skip < 4000) { bands [0] += spec [d].fMagnitude * 1000; //print ("band1 " + d); } else if (d * skip < 8000) { bands [1] += spec [d].fMagnitude * 1000; //print ("band2 " + d); } else if (d * skip < 12000) { bands [2] += spec [d].fMagnitude * 1000; //print ("band3 " + d); } else if (d * skip < 16000) { bands [3] += spec [d].fMagnitude * 1000; //print ("band4 " + d); //print(d*skip); } } //print (spec [d].magnitude + " " + spec [d].fMagnitude); } // spectrumDom [a] = Mathf.Max (band1, band2, band3, band4); for (int d = 0; d < 4; d++) { // print (bands [d] + " " + d); } if (Mathf.Max(bands) == bands[0]) { spectrumDom [a] = 1; } else if (Mathf.Max(bands) == bands[1]) { spectrumDom [a] = 2; } else if (Mathf.Max(bands) == bands[2]) { spectrumDom [a] = 3; } else if (Mathf.Max(bands) == bands[3]) { spectrumDom [a] = 4; } // print(Mathf.Max(bands) + " " + bands[0] + " " + bands[1] + " " + bands[2] + " " + bands[3]); } //dapetin band terkuat var fileName = "spectrumDom.txt"; var sr = File.CreateText(fileName); for (int a = 0; a < spectrumDom.Length; a++) { sr.Write((int)spectrumDom [a]); } sr.Close(); }
/// <summary> /// Gibt die stärkste Frequenz aus, bis die Funktion wieder deaktiviert wird /// </summary> /// <param name="freq"></param> /// <param name="sampleRate"></param> /// <param name="minFreq"></param> /// <param name="maxFreq"></param> /// <returns></returns> public static IEnumerator ReportFrequencies(int freq = 8000, float sampleRate = 0.05f, string minTone = "C1", string maxTone = "C8", float thres = 1e-6f) { if (runFetch) { runFetch = false; yield return(new WaitWhile(() => fetching)); } runFetch = true; float[] sample = new float[freq * sampleLength]; Complex[] spec = new Complex[2048]; float maxAmp, sample_val, maxFreqPower, freqPower; float activeFrequency, stepFrequency = freq / (float)spec.Length; float sum; int ptr = 0; int activeTone, startTone = ToneLookUp.NameToIndex[minTone], maxFrequency; int minFreqIndex = (int)(ToneLookUp.IndexToRange[startTone] / stepFrequency); int maxFreqIndex = (int)(ToneLookUp.IndexToRange[ToneLookUp.NameToIndex[maxTone]] / stepFrequency); if (maxFreqIndex > freq / 2) { maxFreqIndex = freq / 2; } //Create Hamming: float[] hamming = CreateHamming(spec.Length); AudioClip myClip = Microphone.Start(null, true, sampleLength, freq); fetching = true; while (runFetch) { yield return(new WaitForSeconds(sampleRate)); myClip.GetData(sample, ptr); ptr = Microphone.GetPosition(null); //copy input data into array maxAmp = 0; for (int i = spec.Length - 1; i >= 0; i--) { sample_val = ptr - i < 0? sample[ptr - i + sample.Length] : sample[ptr - i]; maxAmp = maxAmp < Mathf.Abs(sample_val) ? Mathf.Abs(sample_val) : maxAmp; spec[spec.Length - 1 - i] = new Complex(sample_val * hamming[i], 0); } sum = 0; maxFreqPower = 0; maxFrequency = -1; //Get spectrum: FFT.CalculateFFT(spec, false); activeTone = startTone; activeFrequency = ToneLookUp.IndexToRange[startTone]; for (int i = 0; i < Signal.frequency.Length; i++) { Signal.frequency[i] = 0; } for (int i = minFreqIndex; i < maxFreqIndex; i++) { freqPower = spec[i].fSqrMagnitude; sum += freqPower; if (activeFrequency > ToneLookUp.IndexToRange[activeTone + 1]) { if (maxFreqPower == 0 && Signal.frequency[activeTone] > thres) { maxFreqPower = Signal.frequency[activeTone]; maxFrequency = activeTone; } activeTone++; } Signal.frequency[activeTone] += freqPower; activeFrequency += stepFrequency; } //Auswertung: Signal.power = sum; Signal.dominantFrequency = maxFrequency != -1 ? ToneLookUp.IndexToName[maxFrequency] : ""; Signal.amplitude = maxAmp; Signal.length = maxFrequency != -1 ? Signal.length + sampleRate : 0; //if(maxFrequency != -1) Debug.Log("freq: " + Signal.dominantFrequency + ", freqrange: " + ToneLookUp.IndexToRange[ToneLookUp.NameToIndex[Signal.dominantFrequency]]); } Microphone.End(null); fetching = false; runFetch = false; yield break; }
/// <summary> /// Nimmt den Sound auf bis ein Soundsample erkannt wird. Schneidet die Tonspur zurecht /// </summary> /// <param name="freq">Die frequenz, mit der gesampelt wird</param> /// <param name="sampleRate">Schrittgröße in Sekunden, mit der gesampelt wird</param> /// <returns></returns> public static IEnumerator GetSoundSample(int freq = 44100, float sampleRate = 0.2f, float triggerThresh = 1e-5f) { if (aSrc == null) { yield break; } if (runFetch) { runFetch = false; yield return(new WaitWhile(() => fetching)); } runFetch = true; float[] sample = new float[freq * sampleLength]; Complex[] spec = new Complex[2048]; float maxAmp, maxAmp_together = 0, sample_val; float sum; int ptr = 0; int start = 0, end = 0; bool voiceHasStarted = false; bool voiceStopping = false; bool voiceHasStopped = false; //Create Hamming Window: float[] hamming = CreateHamming(spec.Length); aSrc.clip = Microphone.Start(null, true, sampleLength, freq); maxAmp_together = 0; fetching = true; while (!(voiceHasStarted && voiceHasStopped) || !runFetch) { yield return(new WaitWhile(() => pauseFetching)); yield return(new WaitForSeconds(sampleRate)); aSrc.clip.GetData(sample, ptr); //copy input data into array maxAmp = 0; for (int i = 0; i < 2048; i++) { if (ptr + i >= sample.Length) { ptr -= sample.Length; } sample_val = sample[ptr + i]; maxAmp = maxAmp < Mathf.Abs(sample_val) ? Mathf.Abs(sample_val) : maxAmp; spec[i] = new Complex(sample_val * hamming[i], 0); } sum = 0; if (maxAmp > 0.01f) { //https://www.dpamicrophones.de/mikrofon-universitaet/fakten-zur-sprachverstaendlichkeit#:~:text=sind%20%C3%BCberwiegend%20im%20Frequenzbereich%20oberhalb,2%20kHz%20bis%204%20kHz.&text=Dem%20Spektrum%20von%20auf%20der,Bereich%20von%202%20%2D%204%20kHz. //ein bin entspricht 22050 / 1024 = 21,5Hz //Get spectrum: FFT.CalculateFFT(spec, false); for (int i = 8; i < 512; i++) { sum += spec[i].fSqrMagnitude; } //normaler Weise bis 1024 -> Stimmbereich liegt jedoch meißt nur bis 8kHz } else { //no signal or to quiet } //Auswertung: //Debug.Log("sum: " + sum + ", maxA: " + maxAmp); if (sum > triggerThresh) //wenn spektrale leistung über den grenzwert geht: { if (!voiceHasStarted) //wahrscheinlich überlappend, daher wird der Start um einen Durchgang zurückverschoben { start = ptr - (int)(sampleRate * 4 * freq); if (start < 0) { start += sample.Length; } Debug.Log("start at: " + start); } ptr = Microphone.GetPosition(null); voiceHasStarted = true; voiceStopping = false; voiceHasStopped = false; maxAmp_together = maxAmp > maxAmp_together ? maxAmp : maxAmp_together; } else { ptr = Microphone.GetPosition(null); end = ptr; voiceHasStopped = voiceStopping; voiceStopping = true; } } Microphone.End(null); //end -= (int)(sampleRate * 2 * freq); Debug.Log("stop"); fetching = false; if (!runFetch) { yield break; } runFetch = false; //Bereite Soundclips for: int dataLength = end > start ? end - start : sample.Length - start + end; Debug.Log("maxAmp: " + maxAmp_together); if (maxAmp_together != 0) { maxAmp_together = 0.5f / maxAmp_together; } Debug.Log("amplify by : " + maxAmp_together); float[] tmp = new float[dataLength]; for (int i = 0; i < dataLength; i++) { if (start + i >= sample.Length) { start -= sample.Length; } tmp[i] = sample[start + i] * maxAmp_together; } //Soundclip: //Laufe aufnahme nochmals ab und ermittle den genauen Start- und Stoppunkt start = -1; end = -1; bool signal = false; int stepSize = (int)(freq * 0.02f); List <Complex> currentData = new List <Complex>(); for (int i = 0; i < 2048; i++) { currentData.Add(new Complex(tmp[i], 0)); } Debug.Log("ermittle genaue Position..."); for (int i = 0; i < tmp.Length - 2048; i += stepSize) { //Test: sum = 0; Complex[] fftData = FFT.CalculateFFT(currentData.ToArray(), false); for (int j = 8; j < 512; j++) { sum += fftData[j].fSqrMagnitude; } signal = sum > 1e-5f; if (signal && start == -1) { start = i; } else if (!signal && start != -1) { end = i + 2048; break; } //Ändere Werte: if (i + stepSize + 2048 >= tmp.Length) { break; } for (int j = 0; j < stepSize; j++) { currentData.RemoveAt(0); currentData.Add(new Complex(tmp[i + j + 2048], 0)); } } if (start == -1) { start = 0; } if (end == -1) { end = tmp.Length; } fetchedDataLength = end - start; float[] data = new float[fetchedDataLength]; for (int i = 0; i < fetchedDataLength; i++) { data[i] = tmp[start + i]; } Debug.Log("genaue Position ermittelt: start: " + start + ", ende: " + end); aSrc.clip = AudioClip.Create("name_normal", data.Length, 1, freq, false); aSrc.clip.SetData(data, 0); Debug.Log("name_normal created"); }