C# Example for NAudio WaveIn with SoundTouch BPMDetect

742 Views Asked by At

does anybody have an example how to use the BPMDetect class with naudio WaveIn?

I'm alwys getting 0 BPM.

This is what i have so far:

        const int ConstWaveInSampleRate = 44100;

    private BufferedWaveProvider bufferedWaveProvider;

    private WaveIn m_WaveIn;
    private WaveOut m_WaveOut;

    private BPMDetect m_BpmDetect;
    public NAudioBpmDetect()
    {
        int deviceNumber = 0;
        m_WaveIn = new WaveIn();
        m_WaveIn.DeviceNumber = deviceNumber;
        int channels = NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels;
        m_WaveIn.WaveFormat = new WaveFormat(ConstWaveInSampleRate, 16, 1);
        m_WaveOut = new WaveOut();

        m_BpmDetect = new BPMDetect(channels, ConstWaveInSampleRate);
        m_WaveIn.DataAvailable += new EventHandler<WaveInEventArgs>(WaveIn_DataAvailable);

        bufferedWaveProvider = new BufferedWaveProvider(m_WaveIn.WaveFormat);
        bufferedWaveProvider.DiscardOnBufferOverflow = true;

        m_WaveOut.Init(bufferedWaveProvider);
        m_WaveIn.StartRecording();
        m_WaveOut.Play();

    }

    void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
    {
        bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
        byte[] buffer = e.Buffer.Where((value, index) => index % 2 == 0).ToArray();
        var waveBuffer = new WaveBuffer(buffer);
        uint count = (uint)waveBuffer.FloatBuffer.Count();
        m_BpmDetect.PutSamples(waveBuffer.FloatBuffer, count);
        Console.WriteLine(m_BpmDetect.Bpm);
    }

May there be an issue with splitting the channel-data from the buffer?

1

There are 1 best solutions below

0
On

I'm not familiar with the BPMDetect class, but there are a few problems with how you're feeding data into it:

  • You're recording in mono, so you don't need to split channels out.
  • You're probably initializing BPMDetect with 2 channels which is incorrect here.
  • Even if you were recording in stereo, each sample is two bytes, so you can't just take every other byte.
  • WaveBuffer only performs a re-interpret cast. It won't turn 16 bit integer samples into 32 bit floating point samples.

What you need to do is take each pair of bytes in the captured buffer, interpret it as a Int16 (e.g. using BitConverter) and then convert that into a float in the range +/- 1.0 by dividing by 32768f. That will give you samples that your BPM detector should be able to use.