-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathOnsets.py
97 lines (93 loc) · 3.51 KB
/
Onsets.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import numpy as np
import matplotlib.pyplot as plt
import sys
import scipy.misc
import subprocess
import os
def getMultiFeatureOnsets(XAudio, Fs, hopSize):
"""
Call Essentia's implemtation of multi feature
beat tracking
:param XAudio: Numpy array of raw audio samples
:param Fs: Sample rate
:param hopSize: Hop size of each onset function value
:returns (tempo, beats): Average tempo, numpy array
of beat intervals in seconds
"""
from essentia import Pool, array
import essentia.standard as ess
X = array(XAudio)
b = ess.BeatTrackerMultiFeature()
beats = b(X)
print("Beat confidence: ", beats[1])
beats = beats[0]
tempo = 60/np.mean(beats[1::] - beats[0:-1])
beats = np.array(np.round(beats*Fs/hopSize), dtype=np.int64)
return (tempo, beats)
def getDegaraOnsets(XAudio, Fs, hopSize):
"""
Call Essentia's implementation of Degara's technique
:param XAudio: Numpy array of raw audio samples
:param Fs: Sample rate
:param hopSize: Hop size of each onset function value
:returns (tempo, beats): Average tempo, numpy array
of beat intervals in seconds
"""
from essentia import Pool, array
import essentia.standard as ess
X = array(XAudio)
b = ess.BeatTrackerDegara()
beats = b(X)
tempo = 60/np.mean(beats[1::] - beats[0:-1])
beats = np.array(np.round(beats*Fs/hopSize), dtype=np.int64)
return (tempo, beats)
def getRNNDBNOnsets(filename, Fs, hopSize):
"""
Call Madmom's implementation of RNN + DBN beat tracking
:param filename: Path to audio file
:param Fs: Sample rate
:param hopSize: Hop size of each onset function value
:returns (tempo, beats): Average tempo, numpy array
of beat intervals in seconds
"""
print("Computing madmom beats...")
from madmom.features.beats import RNNBeatProcessor, DBNBeatTrackingProcessor
proc = DBNBeatTrackingProcessor(fps=100)
act = RNNBeatProcessor()(filename)
b = proc(act)
tempo = 60/np.mean(b[1::] - b[0:-1])
beats = np.array(np.round(b*Fs/hopSize), dtype=np.int64)
return (tempo, beats)
def getBeats(XAudio, Fs, TempoBias, hopSize, filename = ""):
"""
Get beat intervals using dynamic programming beat
tracking with a tempo bias, or if a tempo bias
isn't specified, use the madmom RNN+DBN implementation
:param XAudio: Flat numpy array of audio samples
:param Fs: Sample rate
:param TempoBias: If 0, use Degara if a filename isn't\
specified, or Madmom if a filename is specified.\
If > 0, use Ellis dynamic programming\
If < 0, return constant intervals at |hopSize*TempoBias|
:param hopSize: Hop size of each onset function value
:param filename: Path to audio file
:returns (tempo, beats): Average tempo, numpy array
of beat intervals in seconds
"""
if TempoBias == 0:
if len(filename) == 0:
return getDegaraOnsets(XAudio, Fs, hopSize)
return getRNNDBNOnsets(filename, Fs, hopSize)
elif TempoBias < 0:
tempo = 60.0/np.abs(TempoBias*hopSize/float(Fs))
N = int(np.floor(XAudio.size/hopSize))
beats = np.arange(0, N, -TempoBias)
return (tempo, beats)
try:
import librosa
return librosa.beat.beat_track(XAudio, Fs, start_bpm = TempoBias, hop_length = hopSize)
except:
print("Falling back to Degara for beat tracking...")
if len(filename) == 0:
return getDegaraOnsets(XAudio, Fs, hopSize)
return getRNNDBNOnsets(filename, Fs, hopSize)