1

I'm using the following code to get the BPMS of an WAV file: https://github.com/scaperot/the-BPM-detector-python/blob/master/bpm_detection/bpm_detection.py

I'm trying to call this script from my own script but since bpm_detection.py just printing (and not returning anything) I can get the bottom line value:

print 'Completed. Estimated Beats Per Minute:', bpm

I tried to edit bpm_detection.py script by adding a main() function that I can call. But it mess something up and bmp resulting in Nan:

def main(filename, window):
    parser = argparse.ArgumentParser(description='Process .wav file to determine the Beats Per Minute.')
    parser.add_argument('--filename',
                    help='.wav file for processing')
    parser.add_argument('--window', type=float, default=3,
                    help='size of the the window (seconds) that will         be scanned to determine the bpm.  Typically less than 10 seconds. [3]')

    #args = parser.parse_args()
    samps, fs = read_wav(filename)
    print ("testing")
    #print (fs,samps)

    data = []
    correl = []
    bpm = 0
    n = 0
    nsamps = len(samps)
    print ("nsamps")
    print(nsamps)

    window_samps = int(window * fs)
    print ("window, window samp")
    print (window, window_samps)
    print ("fs")
    print (fs)

    samps_ndx = 0  # first sample in window_ndx
    max_window_ndx = nsamps / window_samps
    print ("max_window_nds")
    print (max_window_ndx)

    bpms = numpy.zeros(max_window_ndx)
    print ("bmps")
    print (bpms)

    # iterate through all windows
    for window_ndx in range(0, int(max_window_ndx)):

        # get a new set of samples
        # print n,":",len(bpms),":",max_window_ndx,":",fs,":",nsamps,":",samps_ndx
        data = samps[samps_ndx:samps_ndx + window_samps]
        if not ((len(data) % window_samps) == 0):
            raise AssertionError(str(len(data)))

        bpm, correl_temp = bpm_detector(data, fs)
        if bpm == None:
            continue
        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...

    bpm = numpy.median(bpms)
    print('Completed.  Estimated Beats Per Minute:', bpm)
    return bpm

As you could see, I added a lot of print to debug it. It seems that all the values are fine up until the following line where max_window_nds is getting 0.0:

max_window_ndx = nsamps / window_samps
print ("max_window_nds")

printing both nsamps and window_samps resulting in: 6195200 and 333333

So I'm failing to find what am I doing wrong. My final goal is to find a way to get bmp variable.

Johndt
  • 4,187
  • 1
  • 23
  • 29
Yakir Mordehay
  • 227
  • 2
  • 3
  • 10

2 Answers2

0

The code in bpm_detection.py is written for Python 2, you can spot this at the final print statement. You are using Python 3 (can also be seen from your use of the print function. Another thing which has changed from Python 2 to Python 3 and which you have to port is the division operator /. In Python 2 if both operands are integer it means integer division. In Python 3 it is always returning a float. You have to check all divisions if an integer division was intended and then use Python 3 integer division operator //. Note, that this may not the only thing to port to Python 3.

mkiever
  • 894
  • 5
  • 13
  • I indeed forgot to mentioned I convert the script from Python 2 to Python 3. I tried to change division operator to // but it still results in 0 instead of 0.0 – Yakir Mordehay Jan 16 '17 at 19:38
  • Note, that porting this code is not for the faint of heart, if you don't know the involved mathematics. – mkiever Jan 16 '17 at 19:41
  • @Yakir Mordehay: Double check. From the values you give in the question the result should be `18`. – mkiever Jan 16 '17 at 19:43
0

Do you actually need to access the variable directly or can you still parse what the script you're calling actually prints? Because you can always use subprocess module to call another script.

import subprocess

p = subprocess.Popen(
    ['python','-u','bpm_detection.py',
    'arg_to_bmp_detection.py'], stdout=subprocess.PIPE)

prints_out = p.communicate()

If you want something fancy (like a progress bar wrapper), use a thread to async process the output while your main program does something to wait for the subprocess to finish: Non-blocking read on a subprocess.PIPE in python

Community
  • 1
  • 1
cowbert
  • 3,212
  • 2
  • 25
  • 34