예제 #1
0
    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++;
    }
예제 #2
0
    // 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);
    }
예제 #4
0
    // 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;
        }
    }
예제 #5
0
    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;
    }
예제 #6
0
파일: GA.cs 프로젝트: caloct77/Audiorunner
    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();
    }
예제 #7
0
    /// <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;
    }
예제 #8
0
    /// <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");
    }