Skip to content

Commit

Permalink
refactor hist_buffer to base tempo estimator class
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Böck committed Aug 31, 2017
1 parent 3282b4a commit c7746a8
Showing 1 changed file with 49 additions and 38 deletions.
87 changes: 49 additions & 38 deletions madmom/features/tempo.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ class TempoHistogramProcessor(OnlineProcessor):
Smooth the activation function over `act_smooth` seconds.
hist_smooth : int
Smooth the tempo histogram over `hist_smooth` bins.
hist_buffer : float
Aggregate the tempo histogram over `hist_buffer` seconds.
fps : float, optional
Frames per second.
Expand All @@ -265,16 +267,20 @@ class TempoHistogramProcessor(OnlineProcessor):
"""

def __init__(self, min_bpm, max_bpm, act_smooth, hist_smooth, fps=None,
online=False, **kwargs):
def __init__(self, min_bpm, max_bpm, act_smooth, hist_smooth,
hist_buffer=None, fps=None, online=False, **kwargs):
# pylint: disable=unused-argument
super(TempoHistogramProcessor, self).__init__(online=online)
# save variables
self.min_bpm = min_bpm
self.max_bpm = max_bpm
self.act_smooth = act_smooth
self.hist_smooth = hist_smooth
self.hist_buffer = hist_buffer
self.fps = fps
if self.online:
self._hist_buffer = BufferProcessor((int(hist_buffer * self.fps),
len(self.intervals)))

@property
def min_interval(self):
Expand All @@ -291,9 +297,13 @@ def intervals(self):
"""Beat intervals [frames]."""
return np.arange(self.min_interval, self.max_interval + 1)

def reset(self):
"""Reset the tempo histogram."""
self._hist_buffer.reset()

@staticmethod
def add_arguments(parser, min_bpm=None, max_bpm=None, act_smooth=None,
hist_smooth=None):
hist_smooth=None, hist_buffer=None):
"""
Add tempo estimation related arguments to an existing parser.
Expand All @@ -309,6 +319,8 @@ def add_arguments(parser, min_bpm=None, max_bpm=None, act_smooth=None,
Smooth the activation function over `act_smooth` seconds.
hist_smooth : int, optional
Smooth the tempo histogram over `hist_smooth` bins.
hist_buffer : float, optional
Aggregate the tempo histogram over `hist_buffer` seconds.
Returns
-------
Expand Down Expand Up @@ -340,6 +352,11 @@ def add_arguments(parser, min_bpm=None, max_bpm=None, act_smooth=None,
default=hist_smooth,
help='smooth the tempo histogram over N bins '
'[default=%(default)d]')
if hist_buffer is not None:
g.add_argument('--hist_buffer', action='store', type=float,
default=hist_smooth,
help='aggregate the tempo histogram over N seconds '
'[default=%(default).2f]')
# return the argument group so it can be modified if needed
return g

Expand All @@ -354,15 +371,14 @@ class CombFilterTempoHistogramProcessor(TempoHistogramProcessor):
Minimum tempo to detect [bpm].
max_bpm : float, optional
Maximum tempo to detect [bpm].
alpha : float, optional
Scaling factor for the comb filter.
act_smooth : float, optional
Smooth the activation function over `act_smooth` seconds.
hist_smooth : int, optional
Smooth the tempo histogram over `hist_smooth` bins.
alpha : float, optional
Scaling factor for the comb filter.
buffer_size : float, optional
Use a buffer of this size to sum the max. bins in online mode
[seconds].
hist_buffer : float
Aggregate the tempo histogram over `hist_buffer` seconds.
fps : float, optional
Frames per second.
online : bool, optional
Expand All @@ -371,30 +387,29 @@ class CombFilterTempoHistogramProcessor(TempoHistogramProcessor):
"""
MIN_BPM = 40.
MAX_BPM = 250.
HIST_SMOOTH = 9
ACT_SMOOTH = 0.14
ALPHA = 0.79
BUFFER_SIZE = 10.
ACT_SMOOTH = 0.14
HIST_SMOOTH = 9
HIST_BUFFER = 10.

def __init__(self, min_bpm=MIN_BPM, max_bpm=MAX_BPM, act_smooth=ACT_SMOOTH,
hist_smooth=HIST_SMOOTH, alpha=ALPHA, buffer_size=BUFFER_SIZE,
fps=None, online=False, **kwargs):
def __init__(self, min_bpm=MIN_BPM, max_bpm=MAX_BPM, alpha=ALPHA,
act_smooth=ACT_SMOOTH, hist_smooth=HIST_SMOOTH,
hist_buffer=HIST_BUFFER, fps=None, online=False, **kwargs):
# pylint: disable=unused-argument
super(CombFilterTempoHistogramProcessor, self).__init__(
min_bpm=min_bpm, max_bpm=max_bpm, act_smooth=act_smooth,
hist_smooth=hist_smooth, fps=fps, online=online, **kwargs)
hist_smooth=hist_smooth, hist_buffer=hist_buffer, fps=fps,
online=online, **kwargs)
# save additional variables
self.alpha = alpha
if self.online:
self._comb_buffer = BufferProcessor((np.max(self.intervals) + 1,
len(self.intervals)))
self._hist_buffer = BufferProcessor((int(buffer_size * self.fps),
len(self.intervals)))

def reset(self):
"""Reset to initial state."""
super(CombFilterTempoHistogramProcessor, self).reset()
self._comb_buffer.reset()
self._hist_buffer.reset()

def process_offline(self, activations, **kwargs):
"""
Expand Down Expand Up @@ -512,11 +527,8 @@ class ACFTempoHistogramProcessor(TempoHistogramProcessor):
Smooth the activation function over `act_smooth` seconds.
hist_smooth : int, optional
Smooth the tempo histogram over `hist_smooth` bins.
alpha : float, optional
Scaling factor for the comb filter.
buffer_size : float, optional
Use a buffer of this size for the activations to calculate the
auto-correlation function [seconds].
hist_buffer : float
Aggregate the tempo histogram over `hist_buffer` seconds.
fps : float, optional
Frames per second.
online : bool, optional
Expand All @@ -525,26 +537,25 @@ class ACFTempoHistogramProcessor(TempoHistogramProcessor):
"""
MIN_BPM = 40.
MAX_BPM = 250.
HIST_SMOOTH = 9
ACT_SMOOTH = 0.14
BUFFER_SIZE = 10.
HIST_SMOOTH = 9
HIST_BUFFER = 10.

def __init__(self, min_bpm=MIN_BPM, max_bpm=MAX_BPM, act_smooth=ACT_SMOOTH,
hist_smooth=HIST_SMOOTH, buffer_size=BUFFER_SIZE, fps=None,
hist_smooth=HIST_SMOOTH, hist_buffer=HIST_BUFFER, fps=None,
online=False, **kwargs):
# pylint: disable=unused-argument
super(ACFTempoHistogramProcessor, self).__init__(
min_bpm=min_bpm, max_bpm=max_bpm, act_smooth=act_smooth,
hist_smooth=hist_smooth, fps=fps, online=online, **kwargs)
hist_smooth=hist_smooth, hist_buffer=hist_buffer, fps=fps,
online=online, **kwargs)
if self.online:
self._act_buffer = BufferProcessor((np.max(self.intervals) + 1, 1))
self._hist_buffer = BufferProcessor((int(buffer_size * self.fps),
len(self.intervals)))

def reset(self):
"""Reset to initial state."""
super(ACFTempoHistogramProcessor, self).reset()
self._act_buffer.reset()
self._hist_buffer.reset()

def process_offline(self, activations, **kwargs):
"""
Expand Down Expand Up @@ -620,6 +631,8 @@ class DBNTempoHistogramProcessor(TempoHistogramProcessor):
Smooth the activation function over `act_smooth` seconds.
hist_smooth : int, optional
Smooth the tempo histogram over `hist_smooth` bins.
hist_buffer : float
Aggregate the tempo histogram over `hist_buffer` seconds.
fps : float, optional
Frames per second.
online : bool, optional
Expand All @@ -628,30 +641,28 @@ class DBNTempoHistogramProcessor(TempoHistogramProcessor):
"""
MIN_BPM = 40.
MAX_BPM = 250.
HIST_SMOOTH = 9
ACT_SMOOTH = 0.
BUFFER_SIZE = 10.
HIST_SMOOTH = 9
HIST_BUFFER = 10.

def __init__(self, min_bpm=MIN_BPM, max_bpm=MAX_BPM, act_smooth=ACT_SMOOTH,
hist_smooth=HIST_SMOOTH, buffer_size=BUFFER_SIZE, fps=None,
hist_smooth=HIST_SMOOTH, hist_buffer=HIST_BUFFER, fps=None,
online=False, **kwargs):
# pylint: disable=unused-argument
super(DBNTempoHistogramProcessor, self).__init__(
min_bpm=min_bpm, max_bpm=max_bpm, act_smooth=act_smooth,
hist_smooth=hist_smooth, fps=fps, online=online, **kwargs)
hist_smooth=hist_smooth, hist_buffer=hist_buffer, fps=fps,
online=online, **kwargs)
# save additional variables
from .beats import DBNBeatTrackingProcessor
self.dbn = DBNBeatTrackingProcessor(min_bpm=self.min_bpm,
max_bpm=self.max_bpm,
fps=self.fps, **kwargs)
if self.online:
self._hist_buffer = BufferProcessor((int(buffer_size * self.fps),
len(self.intervals)))

def reset(self):
"""Reset to initial state."""
super(DBNTempoHistogramProcessor, self).reset()
self.dbn.hmm.reset()
self._hist_buffer.reset()

def process_offline(self, activations, **kwargs):
"""
Expand Down

0 comments on commit c7746a8

Please sign in to comment.