Пример #1
0
        float[,] LoadSong(string path)
        {
            IWaveSource reader     = new MediaFoundationDecoder(path);
            var         sampleRate = reader.WaveFormat.SampleRate;

            reader = reader.ToMono();
            MemoryStream cache = new MemoryStream();

            reader.WriteToWaveStream(cache);
            cache.Position = 0;
            reader.Dispose();
            reader = new WaveFileReader(cache);
            var r = reader.ToSampleSource();

            // Samples per key
            var fftSamplesPerKey = 10;

            // Width of the array
            var fftWidth = 10000;

            // Number of subdivisions in each sample group
            // Higher = more precise
            var precisionMultiplier = 5;

            // Wavelengths in each sample
            // Higher = more precise
            var wavelengthsPerSample = 20;

            var fftResultLen = 128 * fftSamplesPerKey;
            int len          = (int)(reader.Length / 2);
            var result       = new float[fftWidth, fftResultLen];

            var datafull = new float[(int)len];

            r.Read(datafull, 0, (int)len);
            r.Dispose();

            int       progress = 0;
            object    lck      = new object();
            Stopwatch s        = new Stopwatch();

            s.Start();
            Parallel.For(0, fftResultLen, i =>
            {
                float key       = i / (float)fftSamplesPerKey - 0.5f / fftSamplesPerKey;
                float freq      = (float)Math.Pow(2, (key - 69 + 9 - 7 * 3 + 12 * 1) / 12) * 440;
                int waveSize    = (int)(sampleRate / freq) * wavelengthsPerSample;
                double waveStep = (double)waveSize * fftWidth / len;
                waveStep       /= precisionMultiplier;
                if (waveStep < 1)
                {
                    waveStep = 1;
                }
                waveStep = waveStep / fftWidth * len;
                if (waveSize < 1000)
                {
                    waveSize = 1000;
                }
                for (double _l = 0; _l + waveSize < len; _l += waveStep)
                {
                    var l       = (int)_l;
                    float mult  = freq / sampleRate * (float)Math.PI * 2;
                    float sum_r = 0;
                    float sum_i = 0;
                    for (int j = 0; j < waveSize; j++)
                    {
                        float a = mult * j + (float)Math.PI;
                        sum_r  += (float)Math.Cos(a) * datafull[l + j];
                        sum_i  += (float)Math.Sin(a) * datafull[l + j];
                    }
                    var val   = (Math.Abs(sum_r) + Math.Abs(sum_i)) / waveSize;
                    int start = (int)((double)l * fftWidth / len);
                    int end   = (int)((double)(l + waveSize) * fftWidth / len);
                    for (int p = start; p <= end; p++)
                    {
                        result[p, i] = val;
                    }
                }
                lock (lck)
                {
                    Console.WriteLine("Processed frequency bands: " + (++progress));
                }
            });
            Console.WriteLine("Complete! Seconds spent: " + Math.Round(s.ElapsedMilliseconds / 1000.0, 1));

            return(result);
        }
Пример #2
0
        float[,] LoadSong(string path)
        {
            IWaveSource reader     = new MediaFoundationDecoder(path);
            var         sampleRate = reader.WaveFormat.SampleRate;

            reader = reader.ToMono();
            MemoryStream cache = new MemoryStream();

            reader.WriteToWaveStream(cache);
            cache.Position = 0;
            reader.Dispose();
            reader = new WaveFileReader(cache);
            var r = reader.ToSampleSource();

            // Samples per key
            var fftSamplesPerKey = 10;

            // Width of the array
            var fftWidth = 10000;

            // Number of subdivisions in each sample group
            // Higher = more precise
            var precisionMultiplier = 5;

            // Wavelengths in each sample
            // Higher = more precise
            var wavelengthsPerSample = 20;

            var fftResultLen = 128 * fftSamplesPerKey;
            int len          = (int)(reader.Length / 2);
            var result       = new float[fftWidth, fftResultLen];

            var datafull = new float[(int)len];

            r.Read(datafull, 0, (int)len);
            r.Dispose();

            int       progress = 0;
            object    lck      = new object();
            Stopwatch s        = new Stopwatch();

            s.Start();
            unsafe
            {
                fixed(float *input_ptr = datafull)
                {
                    float *output_ptr = (float *)CudaFFT.process_audio((IntPtr)input_ptr, (ulong)len, (uint)sampleRate);
                    ulong  idx        = 0;

                    for (int x = 0; x < fftWidth; x++)
                    {
                        for (int y = 0; y < fftResultLen; y++)
                        {
                            result[x, y] = output_ptr[idx++];
                        }
                    }
                }
            }
            Console.WriteLine("Complete! Seconds spent: " + Math.Round(s.ElapsedMilliseconds / 1000.0, 1));

            return(result);
        }