public VorbisCachedSound(Stream sound)
        {
            using (var audioFileReader = new VorbisWaveReader(sound))
            {
                // TODO: could add resampling in here if required
                WaveFormat = audioFileReader.WaveFormat;

                var sp = audioFileReader.ToSampleProvider();

                var wholeFile     = new List <float>((int)(audioFileReader.Length / 4));
                var sourceSamples = (int)(audioFileReader.Length / (audioFileReader.WaveFormat.BitsPerSample / 8));
                var sampleData    = new float[sourceSamples];
                int samplesRead;

                while ((samplesRead = sp.Read(sampleData, 0, sourceSamples)) > 0)
                {
                    wholeFile.AddRange(sampleData.Take(samplesRead));
                }

                AudioData = wholeFile.ToArray();
            }
        }
Beispiel #2
0
        public BPMDetector(string audioFile, int start = 0, int length = 0)
        {
            // Load the file
            if (Path.GetExtension(audioFile) == ".ogg" || Path.GetExtension(audioFile) == ".egg")
            {
                using (VorbisWaveReader reader = new VorbisWaveReader(audioFile))
                {
                    // Originally the sample rate was constant (44100), and the number of channels was 2.
                    // Let's just in case take them from file's properties
                    sampleRate = reader.WaveFormat.SampleRate;
                    channels   = reader.WaveFormat.Channels;

                    int bytesPerSample = reader.WaveFormat.BitsPerSample / 8;
                    if (bytesPerSample == 0)
                    {
                        bytesPerSample = 2; // assume 16 bit
                    }

                    int sampleCount = (int)reader.Length / bytesPerSample;

                    // Read the wave data

                    start  *= channels * sampleRate;
                    length *= channels * sampleRate;
                    if (start >= sampleCount)
                    {
                        groups = new BPMGroup[0];
                        return;
                    }
                    if (length == 0 || start + length >= sampleCount)
                    {
                        length = sampleCount - start;
                    }

                    length = (int)(length / channels) * channels;

                    ISampleProvider sampleReader = reader.ToSampleProvider();
                    float[]         samples      = new float[length];
                    sampleReader.Read(samples, start, length);

                    // Beats, or kicks, generally occur around the 100 to 150 hz range.
                    // Below this is often the bassline.  So let's focus just on that.

                    for (int ch = 0; ch < channels; ++ch)
                    {
                        // First a lowpass to remove most of the song.

                        BiQuadFilter lowpass = BiQuadFilter.LowPassFilter(sampleRate, 150.0F, 1.0F);

                        // Now a highpass to remove the bassline.

                        BiQuadFilter highpass = BiQuadFilter.HighPassFilter(sampleRate, 100.0F, 1.0F);

                        for (int i = ch; i < length; i += channels)
                        {
                            samples[i] = highpass.Transform(lowpass.Transform(samples[i]));
                        }
                    }

                    Peak[] peaks = getPeaks(samples);

                    BPMGroup[] allGroups = getIntervals(peaks);

                    Array.Sort(allGroups, (x, y) => y.Count.CompareTo(x.Count));

                    if (allGroups.Length > 5)
                    {
                        Array.Resize(ref allGroups, 5);
                    }

                    this.groups = allGroups;
                }
            }
            else
            {
                using (MediaFoundationReader reader = new MediaFoundationReader(audioFile))
                {
                    // Originally the sample rate was constant (44100), and the number of channels was 2.
                    // Let's just in case take them from file's properties
                    sampleRate = reader.WaveFormat.SampleRate;
                    channels   = reader.WaveFormat.Channels;

                    int bytesPerSample = reader.WaveFormat.BitsPerSample / 8;
                    if (bytesPerSample == 0)
                    {
                        bytesPerSample = 2; // assume 16 bit
                    }

                    int sampleCount = (int)reader.Length / bytesPerSample;

                    // Read the wave data

                    start  *= channels * sampleRate;
                    length *= channels * sampleRate;
                    if (start >= sampleCount)
                    {
                        groups = new BPMGroup[0];
                        return;
                    }
                    if (length == 0 || start + length >= sampleCount)
                    {
                        length = sampleCount - start;
                    }

                    length = (int)(length / channels) * channels;

                    ISampleProvider sampleReader = reader.ToSampleProvider();
                    float[]         samples      = new float[length];
                    sampleReader.Read(samples, start, length);

                    // Beats, or kicks, generally occur around the 100 to 150 hz range.
                    // Below this is often the bassline.  So let's focus just on that.

                    for (int ch = 0; ch < channels; ++ch)
                    {
                        // First a lowpass to remove most of the song.

                        BiQuadFilter lowpass = BiQuadFilter.LowPassFilter(sampleRate, 150.0F, 1.0F);

                        // Now a highpass to remove the bassline.

                        BiQuadFilter highpass = BiQuadFilter.HighPassFilter(sampleRate, 100.0F, 1.0F);

                        for (int i = ch; i < length; i += channels)
                        {
                            samples[i] = highpass.Transform(lowpass.Transform(samples[i]));
                        }
                    }

                    Peak[] peaks = getPeaks(samples);

                    BPMGroup[] allGroups = getIntervals(peaks);

                    Array.Sort(allGroups, (x, y) => y.Count.CompareTo(x.Count));

                    if (allGroups.Length > 5)
                    {
                        Array.Resize(ref allGroups, 5);
                    }

                    this.groups = allGroups;
                }
            }
        }