BASS.NET API for the Un4seen BASS Audio Library

BPMCounterProcessAudio Method

BASS.NET API for the Un4seen BASS Audio Library
Processes the audio data (gets instant FFT samples) and calculates the live BPM.

Namespace:  Un4seen.Bass.Misc
Assembly:  Bass.Net (in Bass.Net.dll) Version: 2.4.17.5
Syntax

public bool ProcessAudio(
	int channel,
	bool bpmBeatsOnly
)

Parameters

channel
Type: SystemInt32
The channel who's audio signal should be processed to detect a beat.
bpmBeatsOnly
Type: SystemBoolean
Set this to , if you want the method to return only the counted BPM beats. If set to each detected beat will be returned.

Return Value

Type: Boolean
, if a beat was detected or , if no beat was detected.
Remarks

This is the main method doing the beat detection and live BPM calculation. Call this method in your timer callback as frequently as possibly (e.g. every 20ms is a good value, but every 50ms should also be okay).

Note: it is important, that you call this method in fixed time intervalls! The more often you call this method (the smaller your timer intervall is) the more exact will be the resulting BPM value. You must also call this method in the same interval as specified when you created the class instance.

Since beat detection is very complex this method might return incorrect values when using it with audio signals containing a lot of noise.

The method internally uses some history buffers, which needs first to be filled. So it will take around 1 second (or around 50 calls at 20ms) before you receive first results! Also note, that the internal buffer is flushed at certain intervals, so give the method some time to result newer and even 'better' values, especially, if the audio signal starts with different beats at the track beginning or has intermediate parts with no or different beats.

You might also use this method to detect a given beat (e.g. to perform automatic mixing) and so to determine a good mixer start point (cue point).

Note: This method might return 'intermediate' detected beats - so the detected beats might not always reflect your listening experiance like when using manual tapped beats. So with very slow jams (e.g. at 70 or 80bpm) the resulting BPM might sometimes be twice at high.

The method itself takes less than 1ms to perform it's task. Internally the algo is based on human ear simulation - meaning an average energy history of 1 second is used, since this is what the human ear can keep - so the BPM results might change and vary more often as with systems scanning the whole file or bigger parts of it. The advantage is therefore that this system might be used with live data and has a fast reaction time of about 1 second only - like our human ear.

Note: 1 BPM is worth about 5ms (at 120BMP) - or in other words: if your time intervall differs in 5ms the resulting BPM might have a difference of about 1 BPM. Therefor we use a BPM history buffer which we interleave and calculate the average to equalize this effect.

Examples

private int _stream;
// create a BPMCounter instance, the timer will be fired every 20ms
private BPMCounter _bpm = new BPMCounter(20, 44100);
...
// create a stream
_stream = Bass.BASS_StreamCreateFile(_fileName, 0, 0, BASSFlag.BASS_DEFAULT);
// get the samplerate of that stream
BASS_CHANNELINFO info = new BASS_CHANNELINFO();
Bass.BASS_ChannelGetInfo(_stream, info);
// and start playing the and also start the BPM counter
if (_stream != 0 && Bass.BASS_ChannelPlay(_stream, false) )
{
  //playing...
  _bpm.Reset(info.freq);
  // start our bpm timer callback
  this.timerBPM.Start();
}

private void timerBPM_Tick(object sender, System.EventArgs e)
{
  if ( _stream == 0 || Bass.BASS_ChannelIsActive(_stream) != BASSActive.BASS_ACTIVE_PLAYING)
  {
    this.timerBPM.Stop();
    return;
  }
  bool beat = _bpm.ProcessAudio(_stream, true);
  if (beat)
  {
    // display the live calculated BPM value
    this.labelBPM.Text = _bpm.BPM.ToString( "#00.0" );
  }
}
See Also

Reference