Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

# Data
data/

# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
.Python
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
BPM Detector in Python
=======================


## Installation

### Activate virtual environment
``` bash
source ./bin/activate
```

### Dependencies
- numpy
- PyWavelets
- scipy
- matplotlib
``` bash
pip install -r requirements.txt
```

## Test
``` bash
python ./bpm_detection/bpm_detection.py --filename ./data/*.wav
```

## Help

### Converting mp3
``` bash
mpg123 -w [path/to/original.mp3] [./data/wavfile.wav]
```

## Original Readme
Implementation of a Beats Per Minute (BPM) detection algorithm, as presented in the paper of G. Tzanetakis, G. Essl and P. Cook titled: "Audio Analysis using the Discrete Wavelet Transform".

You can find it here: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.63.5712
Expand All @@ -9,4 +40,3 @@ Based on the work done in the MATLAB code located at github.com/panagiop/the-BPM
Process .wav file to determine the Beats Per Minute.

Dependencies: scipy, numpy, pywt, matplotlib

32 changes: 20 additions & 12 deletions bpm_detection/bpm_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def read_wav(filename):
except IOError, e:
print e
return

# test eddit
# typ = choose_type( wf.getsampwidth() ) #TODO: implement choose_type
nsamps = wf.getnframes();
assert(nsamps > 0);
Expand Down Expand Up @@ -50,9 +50,9 @@ def bpm_detector(data,fs):
cD_sum = []
levels = 4
max_decimation = 2**(levels-1);
min_ndx = 60./ 220 * (fs/max_decimation)
max_ndx = 60./ 40 * (fs/max_decimation)
min_ndx = int(60./ 220 * (fs/max_decimation))
max_ndx = int(60./ 40 * (fs/max_decimation))

for loop in range(0,levels):
cD = []
# 1) DWT
Expand Down Expand Up @@ -90,14 +90,13 @@ def bpm_detector(data,fs):
midpoint = len(correl) / 2
correl_midpoint_tmp = correl[midpoint:]
peak_ndx = peak_detect(correl_midpoint_tmp[min_ndx:max_ndx]);

if len(peak_ndx) > 1:
return no_audio_data()

peak_ndx_adjusted = peak_ndx[0]+min_ndx;
bpm = 60./ peak_ndx_adjusted * (fs/max_decimation)
print bpm
return bpm,correl

return bpm,correl,peak_ndx[0][0]

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Process .wav file to determine the Beats Per Minute.')
Expand All @@ -112,13 +111,14 @@ def bpm_detector(data,fs):
data = []
correl=[]
bpm = 0
n=0;
#n=0;
nsamps = len(samps)
window_samps = int(args.window*fs)
samps_ndx = 0; #first sample in window_ndx
window_samps = int(args.window*fs) # second * frame/second = frames
samps_ndx = 0; #first sample in window_ndx # frames
max_window_ndx = nsamps / window_samps;
bpms = numpy.zeros(max_window_ndx)

last_bpm = None
#iterate through all windows
for window_ndx in xrange(0,max_window_ndx):

Expand All @@ -128,15 +128,23 @@ def bpm_detector(data,fs):
if not ((len(data) % window_samps) == 0):
raise AssertionError( str(len(data) ) )

bpm, correl_temp = bpm_detector(data,fs)
bpm, correl_temp, first_ndx = bpm_detector(data,fs)
if bpm == None:
continue

time_value = 1.0*(samps_ndx+first_ndx)/fs #frames / (frame/second) = second
bpm_value = bpm[0]
if last_bpm != bpm_value:
last_bpm = bpm_value

print "(Time, BPM): %.2f, %.2f"% (time_value, bpm_value)

bpms[window_ndx] = bpm
correl = correl_temp

#iterate at the end of the loop
samps_ndx = samps_ndx+window_samps;
n=n+1; #counter for debug...
#n=n+1; #counter for debug...

bpm = numpy.median(bpms)
print 'Completed. Estimated Beats Per Minute:', bpm
Expand Down
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
numpy
PyWavelets
scipy
matplotlib