class_docstr: Beat tracking with RNNs and a dynamic Bayesian network (DBN) approximated
  by a Hidden Markov Model (HMM).
  
  Parameters
  ----------
  min_bpm : float, optional
      Minimum tempo used for beat tracking [bpm].
  max_bpm : float, optional
      Maximum tempo used for beat tracking [bpm].
  num_tempi : int, optional
      Number of tempi to model; if set, limit the number of tempi and use a
      log spacing, otherwise a linear spacing.
  transition_lambda : float, optional
      Lambda for the exponential tempo change distribution (higher values
      prefer a constant tempo from one beat to the next one).
  observation_lambda : int, optional
      Split one beat period into `observation_lambda` parts, the first
      representing beat states and the remaining non-beat states.
  threshold : float, optional
      Threshold the observations before Viterbi decoding.
  correct : bool, optional
      Correct the beats (i.e. align them to the nearest peak of the beat
      activation function).
  fps : float, optional
      Frames per second.
  online : bool, optional
      Use the forward algorithm (instead of Viterbi) to decode the beats.
  
  Notes
  -----
  Instead of the originally proposed state space and transition model for
  the DBN [1]_, the more efficient version proposed in [2]_ is used.
  
  References
  ----------
  .. [1] Sebastian Böck, Florian Krebs and Gerhard Widmer,
         "A Multi-Model Approach to Beat Tracking Considering Heterogeneous
         Music Styles",
         Proceedings of the 15th International Society for Music Information
         Retrieval Conference (ISMIR), 2014.
  .. [2] Florian Krebs, Sebastian Böck and Gerhard Widmer,
         "An Efficient State Space Model for Joint Tempo and Meter Tracking",
         Proceedings of the 16th International Society for Music Information
         Retrieval Conference (ISMIR), 2015.
  
  Examples
  --------
  Create a DBNBeatTrackingProcessor. The returned array represents the
  positions of the beats in seconds, thus the expected sampling rate has to
  be given.
  
  >>> proc = DBNBeatTrackingProcessor(fps=100)
  >>> proc  # doctest: +ELLIPSIS
  <madmom.features.beats.DBNBeatTrackingProcessor object at 0x...>
  
  Call this DBNBeatTrackingProcessor with the beat activation function
  returned by RNNBeatProcessor to obtain the beat positions.
  
  >>> act = RNNBeatProcessor()('tests/data/audio/sample.wav')
  >>> proc(act)
  array([0.1 , 0.45, 0.8 , 1.12, 1.48, 1.8 , 2.15, 2.49])
class_docstr_tok: ["Beat","tracking","with","RNNs","and","a","dynamic","Bayesian","network","(","DBN",")","approximated","by","a","Hidden","Markov","Model","(","HMM",")",".","Parameters","--","--","--","--","--","min_bpm",":","float",",","optional","Minimum","tempo","used","for","beat","tracking","[","bpm","]",".","max_bpm",":","float",",","optional","Maximum","tempo","used","for","beat","tracking","[","bpm","]",".","num_tempi",":","int",",","optional","Number","of","tempi","to","model",";","if","set",",","limit","the","number","of","tempi","and","use","a","log","spacing",",","otherwise","a","linear","spacing",".","transition_lambda",":","float",",","optional","Lambda","for","the","exponential","tempo","change","distribution","(","higher","values","prefer","a","constant","tempo","from","one","beat","to","the","next","one",")",".","observation_lambda",":","int",",","optional","Split","one","beat","period","into","`","observation_lambda","`","parts",",","the","first","representing","beat","states","and","the","remaining","non-beat","states",".","threshold",":","float",",","optional","Threshold","the","observations","before","Viterbi","decoding",".","correct",":","bool",",","optional","Correct","the","beats","(","i.e",".","align","them","to","the","nearest","peak","of","the","beat","activation","function",")",".","fps",":","float",",","optional","Frames","per","second",".","online",":","bool",",","optional","Use","the","forward","algorithm","(","instead","of","Viterbi",")","to","decode","the","beats",".","Notes","--","--","-","Instead","of","the","originally","proposed","state","space","and","transition","model","for","the","DBN","[","1","]","_",",","the","more","efficient","version","proposed","in","[","2","]","_","is","used",".","References","--","--","--","--","--","..","[","1","]","Sebastian","B\u00f6ck",",","Florian","Krebs","and","Gerhard","Widmer",",","``","A","Multi-Model","Approach","to","Beat","Tracking","Considering","Heterogeneous","Music","Styles","''",",","Proceedings","of","the","15th","International","Society","for","Music","Information","Retrieval","Conference","(","ISMIR",")",",","2014",".","..","[","2","]","Florian","Krebs",",","Sebastian","B\u00f6ck","and","Gerhard","Widmer",",","``","An","Efficient","State","Space","Model","for","Joint","Tempo","and","Meter","Tracking","''",",","Proceedings","of","the","16th","International","Society","for","Music","Information","Retrieval","Conference","(","ISMIR",")",",","2015",".","Examples","--","--","--","--","Create","a","DBNBeatTrackingProcessor",".","The","returned","array","represents","the","positions","of","the","beats","in","seconds",",","thus","the","expected","sampling","rate","has","to","be","given",".",">",">",">","proc","=","DBNBeatTrackingProcessor","(","fps=100",")",">",">",">","proc","#","doctest",":","+ELLIPSIS","<","madmom.features.beats.DBNBeatTrackingProcessor","object","at","0x","...",">","Call","this","DBNBeatTrackingProcessor","with","the","beat","activation","function","returned","by","RNNBeatProcessor","to","obtain","the","beat","positions",".",">",">",">","act","=","RNNBeatProcessor","(",")","(","'tests\/data\/audio\/sample.wav","'",")",">",">",">","proc","(","act",")","array","(","[","0.1",",","0.45",",","0.8",",","1.12",",","1.48",",","1.8",",","2.15",",","2.49","]",")"]
docstr: Detect the beats in the given activation function with Viterbi
  decoding.
  
  Parameters
  ----------
  activations : numpy array
      Beat activation function.
  
  Returns
  -------
  beats : numpy array
      Detected beat positions [seconds].
docstr_tok: ["Detect","the","beats","in","the","given","activation","function","with","Viterbi","decoding",".","Parameters","--","--","--","--","--","activations",":","numpy","array","Beat","activation","function",".","Returns","--","--","--","-","beats",":","numpy","array","Detected","beat","positions","[","seconds","]","."]
code: def process_offline(self, activations, **kwargs):
      """
      Detect the beats in the given activation function with Viterbi
      decoding.
  
      Parameters
      ----------
      activations : numpy array
          Beat activation function.
  
      Returns
      -------
      beats : numpy array
          Detected beat positions [seconds].
  
      """
      # init the beats to return and the offset
      beats = np.empty(0, dtype=int)
      first = 0
      # use only the activations > threshold
      if self.threshold:
          activations, first = threshold_activations(
              activations, self.threshold
          )
      # return no beats if no activations given / remain after thresholding
      if not activations.any():
          return beats
      # get the best state path by calling the viterbi algorithm
      path, _ = self.hmm.viterbi(activations)
      # also return no beats if no path was found
      if not path.any():
          return beats
      # correct the beat positions if needed
      if self.correct:
          # for each detection determine the "beat range", i.e. states where
          # the pointers of the observation model are 1
          beat_range = self.om.pointers[path]
          # get all change points between True and False
          idx = np.nonzero(np.diff(beat_range))[0] + 1
          # if the first frame is in the beat range, add a change at frame 0
          if beat_range[0]:
              idx = np.r_[0, idx]
          # if the last frame is in the beat range, append the length of the
          # array
          if beat_range[-1]:
              idx = np.r_[idx, beat_range.size]
          # iterate over all regions
          if idx.any():
              for left, right in idx.reshape((-1, 2)):
                  # pick the frame with the highest activations value
                  peak = np.argmax(activations[left:right]) + left
                  beats = np.hstack((beats, peak))
      else:
          # just take the frames with the smallest beat state values
          from scipy.signal import argrelmin
  
          beats = argrelmin(self.st.state_positions[path], mode="wrap")[
              0
          ]
          # recheck if they are within the "beat range", i.e. the pointers
          # of the observation model for that state must be 1
          # Note: interpolation and alignment of the beats to be at state 0
          #       does not improve results over this simple method
          beats = beats[self.om.pointers[path[beats]] == 1]
      # convert the detected beats to seconds and return them
      return (beats + first) / float(self.fps)
  
imports: from __future__ import absolute_import, division, print_function
  import sys
  import numpy
  from ..audio.signal import signal_frame, smooth
  from ..ml.nn import average_predictions
  from ..processors import OnlineProcessor, ParallelProcessor, Processor, SequentialProcessor
label_desc: Use image node_id 3 for calling the DBNBeatTrackingProcessor obj's underlying member method code with example usage: obj.process_offline(activations) and returns: unknown, beats, beats