@cache(level=<NUM_LIT:30>)<EOL>def nn_filter(S, rec=None, aggregate=None, axis=-<NUM_LIT:1>, **kwargs):

if aggregate is None:<EOL><INDENT>aggregate = np.mean<EOL><DEDENT>if rec is None:<EOL><INDENT>kwargs = dict(kwargs)<EOL>kwargs['<STR_LIT>'] = True<EOL>rec = segment.recurrence_matrix(S, axis=axis, **kwargs)<EOL><DEDENT>elif not scipy.sparse.issparse(rec):<EOL><INDENT>rec = scipy.sparse.csr_matrix(rec)<EOL><DEDENT>if rec.shape[<NUM_LIT:0>] != S.shape[axis] or rec.shape[<NUM_LIT:0>] != rec.shape[<NUM_LIT:1>]:<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(rec.shape,<EOL>S.shape))<EOL><DEDENT>return __nn_filter_helper(rec.data, rec.indices, rec.indptr,<EOL>S.swapaxes(<NUM_LIT:0>, axis), aggregate).swapaxes(<NUM_LIT:0>, axis)<EOL>

Filtering by nearest-neighbors.

    Each data point (e.g, spectrogram column) is replaced
    by aggregating its nearest neighbors in feature space.

    This can be useful for de-noising a spectrogram or feature matrix.

    The non-local means method [1]_ can be recovered by providing a
    weighted recurrence matrix as input and specifying `aggregate=np.average`.

    Similarly, setting `aggregate=np.median` produces sparse de-noising
    as in REPET-SIM [2]_.

    .. [1] Buades, A., Coll, B., & Morel, J. M.
        (2005, June). A non-local algorithm for image denoising.
        In Computer Vision and Pattern Recognition, 2005.
        CVPR 2005. IEEE Computer Society Conference on (Vol. 2, pp. 60-65). IEEE.

    .. [2] Rafii, Z., & Pardo, B.
        (2012, October).  "Music/Voice Separation Using the Similarity Matrix."
        International Society for Music Information Retrieval Conference, 2012.

    Parameters
    ----------
    S : np.ndarray
        The input data (spectrogram) to filter

    rec : (optional) scipy.sparse.spmatrix or np.ndarray
        Optionally, a pre-computed nearest-neighbor matrix
        as provided by `librosa.segment.recurrence_matrix`

    aggregate : function
        aggregation function (default: `np.mean`)

        If `aggregate=np.average`, then a weighted average is
        computed according to the (per-row) weights in `rec`.

        For all other aggregation functions, all neighbors
        are treated equally.

    axis : int
        The axis along which to filter (by default, columns)

    kwargs
        Additional keyword arguments provided to
        `librosa.segment.recurrence_matrix` if `rec` is not provided

    Returns
    -------
    S_filtered : np.ndarray
        The filtered data

    Raises
    ------
    ParameterError
        if `rec` is provided and its shape is incompatible with `S`.

    See also
    --------
    decompose
    hpss
    librosa.segment.recurrence_matrix

    Notes
    -----
    This function caches at level 30.

    Examples
    --------

    De-noise a chromagram by non-local median filtering.
    By default this would use euclidean distance to select neighbors,
    but this can be overridden directly by setting the `metric` parameter.

    >>> y, sr = librosa.load(librosa.util.example_audio_file(),
    ...                      offset=30, duration=10)
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr)
    >>> chroma_med = librosa.decompose.nn_filter(chroma,
    ...                                          aggregate=np.median,
    ...                                          metric='cosine')

    To use non-local means, provide an affinity matrix and `aggregate=np.average`.

    >>> rec = librosa.segment.recurrence_matrix(chroma, mode='affinity',
    ...                                         metric='cosine', sparse=True)
    >>> chroma_nlm = librosa.decompose.nn_filter(chroma, rec=rec,
    ...                                          aggregate=np.average)

    >>> import matplotlib.pyplot as plt
    >>> plt.figure(figsize=(10, 8))
    >>> plt.subplot(5, 1, 1)
    >>> librosa.display.specshow(chroma, y_axis='chroma')
    >>> plt.colorbar()
    >>> plt.title('Unfiltered')
    >>> plt.subplot(5, 1, 2)
    >>> librosa.display.specshow(chroma_med, y_axis='chroma')
    >>> plt.colorbar()
    >>> plt.title('Median-filtered')
    >>> plt.subplot(5, 1, 3)
    >>> librosa.display.specshow(chroma_nlm, y_axis='chroma')
    >>> plt.colorbar()
    >>> plt.title('Non-local means')
    >>> plt.subplot(5, 1, 4)
    >>> librosa.display.specshow(chroma - chroma_med,
    ...                          y_axis='chroma')
    >>> plt.colorbar()
    >>> plt.title('Original - median')
    >>> plt.subplot(5, 1, 5)
    >>> librosa.display.specshow(chroma - chroma_nlm,
    ...                          y_axis='chroma', x_axis='time')
    >>> plt.colorbar()
    >>> plt.title('Original - NLM')
    >>> plt.tight_layout()


def __nn_filter_helper(R_data, R_indices, R_ptr, S, aggregate):

s_out = np.empty_like(S)<EOL>for i in range(len(R_ptr)-<NUM_LIT:1>):<EOL><INDENT>targets = R_indices[R_ptr[i]:R_ptr[i+<NUM_LIT:1>]]<EOL>if not len(targets):<EOL><INDENT>s_out[i] = S[i]<EOL>continue<EOL><DEDENT>neighbors = np.take(S, targets, axis=<NUM_LIT:0>)<EOL>if aggregate is np.average:<EOL><INDENT>weights = R_data[R_ptr[i]:R_ptr[i+<NUM_LIT:1>]]<EOL>s_out[i] = aggregate(neighbors, axis=<NUM_LIT:0>, weights=weights)<EOL><DEDENT>else:<EOL><INDENT>s_out[i] = aggregate(neighbors, axis=<NUM_LIT:0>)<EOL><DEDENT><DEDENT>return s_out<EOL>

Nearest-neighbor filter helper function.

    This is an internal function, not for use outside of the decompose module.

    It applies the nearest-neighbor filter to S, assuming that the first index
    corresponds to observations.

    Parameters
    ----------
    R_data, R_indices, R_ptr : np.ndarrays
        The `data`, `indices`, and `indptr` of a scipy.sparse matrix

    S : np.ndarray
        The observation data to filter

    aggregate : callable
        The aggregation operator

    Returns
    -------
    S_out : np.ndarray like S
        The filtered data array


def beat_track(y=None, sr=<NUM_LIT>, onset_envelope=None, hop_length=<NUM_LIT>,<EOL>start_bpm=<NUM_LIT>, tightness=<NUM_LIT:100>, trim=True, bpm=None,<EOL>units='<STR_LIT>'):

<EOL>if onset_envelope is None:<EOL><INDENT>if y is None:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>onset_envelope = onset.onset_strength(y=y,<EOL>sr=sr,<EOL>hop_length=hop_length,<EOL>aggregate=np.median)<EOL><DEDENT>if not onset_envelope.any():<EOL><INDENT>return (<NUM_LIT:0>, np.array([], dtype=int))<EOL><DEDENT>if bpm is None:<EOL><INDENT>bpm = tempo(onset_envelope=onset_envelope,<EOL>sr=sr,<EOL>hop_length=hop_length,<EOL>start_bpm=start_bpm)[<NUM_LIT:0>]<EOL><DEDENT>beats = __beat_tracker(onset_envelope,<EOL>bpm,<EOL>float(sr) / hop_length,<EOL>tightness,<EOL>trim)<EOL>if units == '<STR_LIT>':<EOL><INDENT>pass<EOL><DEDENT>elif units == '<STR_LIT>':<EOL><INDENT>beats = core.frames_to_samples(beats, hop_length=hop_length)<EOL><DEDENT>elif units == '<STR_LIT:time>':<EOL><INDENT>beats = core.frames_to_time(beats, hop_length=hop_length, sr=sr)<EOL><DEDENT>else:<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(units))<EOL><DEDENT>return (bpm, beats)<EOL>

r'''Dynamic programming beat tracker.

    Beats are detected in three stages, following the method of [1]_:
      1. Measure onset strength
      2. Estimate tempo from onset correlation
      3. Pick peaks in onset strength approximately consistent with estimated
         tempo

    .. [1] Ellis, Daniel PW. "Beat tracking by dynamic programming."
           Journal of New Music Research 36.1 (2007): 51-60.
           http://labrosa.ee.columbia.edu/projects/beattrack/

    Parameters
    ----------

    y : np.ndarray [shape=(n,)] or None
        audio time series

    sr : number > 0 [scalar]
        sampling rate of `y`

    onset_envelope : np.ndarray [shape=(n,)] or None
        (optional) pre-computed onset strength envelope.

    hop_length : int > 0 [scalar]
        number of audio samples between successive `onset_envelope` values

    start_bpm  : float > 0 [scalar]
        initial guess for the tempo estimator (in beats per minute)

    tightness  : float [scalar]
        tightness of beat distribution around tempo

    trim       : bool [scalar]
        trim leading/trailing beats with weak onsets

    bpm        : float [scalar]
        (optional) If provided, use `bpm` as the tempo instead of
        estimating it from `onsets`.

    units : {'frames', 'samples', 'time'}
        The units to encode detected beat events in.
        By default, 'frames' are used.

    Returns
    -------

    tempo : float [scalar, non-negative]
        estimated global tempo (in beats per minute)

    beats : np.ndarray [shape=(m,)]
        estimated beat event locations in the specified units
        (default is frame indices)

    .. note::
        If no onset strength could be detected, beat_tracker estimates 0 BPM
        and returns an empty list.

    Raises
    ------
    ParameterError
        if neither `y` nor `onset_envelope` are provided

        or if `units` is not one of 'frames', 'samples', or 'time'

    See Also
    --------
    librosa.onset.onset_strength

    Examples
    --------
    Track beats using time series input

    >>> y, sr = librosa.load(librosa.util.example_audio_file())

    >>> tempo, beats = librosa.beat.beat_track(y=y, sr=sr)
    >>> tempo
    64.599609375

    Print the first 20 beat frames

    >>> beats[:20]
    array([ 320,  357,  397,  436,  480,  525,  569,  609,  658,
            698,  737,  777,  817,  857,  896,  936,  976, 1016,
           1055, 1095])

    Or print them as timestamps

    >>> librosa.frames_to_time(beats[:20], sr=sr)
    array([  7.43 ,   8.29 ,   9.218,  10.124,  11.146,  12.19 ,
            13.212,  14.141,  15.279,  16.208,  17.113,  18.042,
            18.971,  19.9  ,  20.805,  21.734,  22.663,  23.591,
            24.497,  25.426])

    Track beats using a pre-computed onset envelope

    >>> onset_env = librosa.onset.onset_strength(y, sr=sr,
    ...                                          aggregate=np.median)
    >>> tempo, beats = librosa.beat.beat_track(onset_envelope=onset_env,
    ...                                        sr=sr)
    >>> tempo
    64.599609375
    >>> beats[:20]
    array([ 320,  357,  397,  436,  480,  525,  569,  609,  658,
            698,  737,  777,  817,  857,  896,  936,  976, 1016,
           1055, 1095])

    Plot the beat events against the onset strength envelope

    >>> import matplotlib.pyplot as plt
    >>> hop_length = 512
    >>> plt.figure(figsize=(8, 4))
    >>> times = librosa.frames_to_time(np.arange(len(onset_env)),
    ...                                sr=sr, hop_length=hop_length)
    >>> plt.plot(times, librosa.util.normalize(onset_env),
    ...          label='Onset strength')
    >>> plt.vlines(times[beats], 0, 1, alpha=0.5, color='r',
    ...            linestyle='--', label='Beats')
    >>> plt.legend(frameon=True, framealpha=0.75)
    >>> # Limit the plot to a 15-second window
    >>> plt.xlim(15, 30)
    >>> plt.gca().xaxis.set_major_formatter(librosa.display.TimeFormatter())
    >>> plt.tight_layout()


@cache(level=<NUM_LIT:30>)<EOL>def tempo(y=None, sr=<NUM_LIT>, onset_envelope=None, hop_length=<NUM_LIT>, start_bpm=<NUM_LIT>,<EOL>std_bpm=<NUM_LIT:1.0>, ac_size=<NUM_LIT>, max_tempo=<NUM_LIT>, aggregate=np.mean):

if start_bpm <= <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>win_length = np.asscalar(core.time_to_frames(ac_size, sr=sr,<EOL>hop_length=hop_length))<EOL>tg = tempogram(y=y, sr=sr,<EOL>onset_envelope=onset_envelope,<EOL>hop_length=hop_length,<EOL>win_length=win_length)<EOL>if aggregate is not None:<EOL><INDENT>tg = aggregate(tg, axis=<NUM_LIT:1>, keepdims=True)<EOL><DEDENT>bpms = core.tempo_frequencies(tg.shape[<NUM_LIT:0>], hop_length=hop_length, sr=sr)<EOL>prior = np.exp(-<NUM_LIT:0.5> * ((np.log2(bpms) - np.log2(start_bpm)) / std_bpm)**<NUM_LIT:2>)<EOL>if max_tempo is not None:<EOL><INDENT>max_idx = np.argmax(bpms < max_tempo)<EOL>prior[:max_idx] = <NUM_LIT:0><EOL><DEDENT>best_period = np.argmax(tg * prior[:, np.newaxis], axis=<NUM_LIT:0>)<EOL>tempi = bpms[best_period]<EOL>tempi[best_period == <NUM_LIT:0>] = start_bpm<EOL>return tempi<EOL>

Estimate the tempo (beats per minute)

    Parameters
    ----------
    y : np.ndarray [shape=(n,)] or None
        audio time series

    sr : number > 0 [scalar]
        sampling rate of the time series

    onset_envelope    : np.ndarray [shape=(n,)]
        pre-computed onset strength envelope

    hop_length : int > 0 [scalar]
        hop length of the time series

    start_bpm : float [scalar]
        initial guess of the BPM

    std_bpm : float > 0 [scalar]
        standard deviation of tempo distribution

    ac_size : float > 0 [scalar]
        length (in seconds) of the auto-correlation window

    max_tempo : float > 0 [scalar, optional]
        If provided, only estimate tempo below this threshold

    aggregate : callable [optional]
        Aggregation function for estimating global tempo.
        If `None`, then tempo is estimated independently for each frame.

    Returns
    -------
    tempo : np.ndarray [scalar]
        estimated tempo (beats per minute)

    See Also
    --------
    librosa.onset.onset_strength
    librosa.feature.tempogram

    Notes
    -----
    This function caches at level 30.

    Examples
    --------
    >>> # Estimate a static tempo
    >>> y, sr = librosa.load(librosa.util.example_audio_file())
    >>> onset_env = librosa.onset.onset_strength(y, sr=sr)
    >>> tempo = librosa.beat.tempo(onset_envelope=onset_env, sr=sr)
    >>> tempo
    array([129.199])

    >>> # Or a dynamic tempo
    >>> dtempo = librosa.beat.tempo(onset_envelope=onset_env, sr=sr,
    ...                             aggregate=None)
    >>> dtempo
    array([ 143.555,  143.555,  143.555, ...,  161.499,  161.499,
            172.266])

    Plot the estimated tempo against the onset autocorrelation

    >>> import matplotlib.pyplot as plt
    >>> # Convert to scalar
    >>> tempo = np.asscalar(tempo)
    >>> # Compute 2-second windowed autocorrelation
    >>> hop_length = 512
    >>> ac = librosa.autocorrelate(onset_env, 2 * sr // hop_length)
    >>> freqs = librosa.tempo_frequencies(len(ac), sr=sr,
    ...                                   hop_length=hop_length)
    >>> # Plot on a BPM axis.  We skip the first (0-lag) bin.
    >>> plt.figure(figsize=(8,4))
    >>> plt.semilogx(freqs[1:], librosa.util.normalize(ac)[1:],
    ...              label='Onset autocorrelation', basex=2)
    >>> plt.axvline(tempo, 0, 1, color='r', alpha=0.75, linestyle='--',
    ...            label='Tempo: {:.2f} BPM'.format(tempo))
    >>> plt.xlabel('Tempo (BPM)')
    >>> plt.grid()
    >>> plt.title('Static tempo estimation')
    >>> plt.legend(frameon=True)
    >>> plt.axis('tight')

    Plot dynamic tempo estimates over a tempogram

    >>> plt.figure()
    >>> tg = librosa.feature.tempogram(onset_envelope=onset_env, sr=sr,
    ...                                hop_length=hop_length)
    >>> librosa.display.specshow(tg, x_axis='time', y_axis='tempo')
    >>> plt.plot(librosa.frames_to_time(np.arange(len(dtempo))), dtempo,
    ...          color='w', linewidth=1.5, label='Tempo estimate')
    >>> plt.title('Dynamic tempo estimation')
    >>> plt.legend(frameon=True, framealpha=0.75)


def __beat_tracker(onset_envelope, bpm, fft_res, tightness, trim):

if bpm <= <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>period = round(<NUM_LIT> * fft_res / bpm)<EOL>localscore = __beat_local_score(onset_envelope, period)<EOL>backlink, cumscore = __beat_track_dp(localscore, period, tightness)<EOL>beats = [__last_beat(cumscore)]<EOL>while backlink[beats[-<NUM_LIT:1>]] >= <NUM_LIT:0>:<EOL><INDENT>beats.append(backlink[beats[-<NUM_LIT:1>]])<EOL><DEDENT>beats = np.array(beats[::-<NUM_LIT:1>], dtype=int)<EOL>beats = __trim_beats(localscore, beats, trim)<EOL>return beats<EOL>

Internal function that tracks beats in an onset strength envelope.

    Parameters
    ----------
    onset_envelope : np.ndarray [shape=(n,)]
        onset strength envelope

    bpm : float [scalar]
        tempo estimate

    fft_res  : float [scalar]
        resolution of the fft (sr / hop_length)

    tightness: float [scalar]
        how closely do we adhere to bpm?

    trim : bool [scalar]
        trim leading/trailing beats with weak onsets?

    Returns
    -------
    beats : np.ndarray [shape=(n,)]
        frame numbers of beat events


norm = onsets.std(ddof=<NUM_LIT:1>)<EOL>if norm > <NUM_LIT:0>:<EOL><INDENT>onsets = onsets / norm<EOL><DEDENT>return onsets<EOL>

Maps onset strength function into the range [0, 1]


window = np.exp(-<NUM_LIT:0.5> * (np.arange(-period, period+<NUM_LIT:1>)*<NUM_LIT>/period)**<NUM_LIT:2>)<EOL>return scipy.signal.convolve(__normalize_onsets(onset_envelope),<EOL>window,<EOL>'<STR_LIT>')<EOL>

Construct the local score for an onset envlope and given period


def __beat_track_dp(localscore, period, tightness):

backlink = np.zeros_like(localscore, dtype=int)<EOL>cumscore = np.zeros_like(localscore)<EOL>window = np.arange(-<NUM_LIT:2> * period, -np.round(period / <NUM_LIT:2>) + <NUM_LIT:1>, dtype=int)<EOL>if tightness <= <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>txwt = -tightness * (np.log(-window / period) ** <NUM_LIT:2>)<EOL>first_beat = True<EOL>for i, score_i in enumerate(localscore):<EOL><INDENT>z_pad = np.maximum(<NUM_LIT:0>, min(- window[<NUM_LIT:0>], len(window)))<EOL>candidates = txwt.copy()<EOL>candidates[z_pad:] = candidates[z_pad:] + cumscore[window[z_pad:]]<EOL>beat_location = np.argmax(candidates)<EOL>cumscore[i] = score_i + candidates[beat_location]<EOL>if first_beat and score_i < <NUM_LIT> * localscore.max():<EOL><INDENT>backlink[i] = -<NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>backlink[i] = window[beat_location]<EOL>first_beat = False<EOL><DEDENT>window = window + <NUM_LIT:1><EOL><DEDENT>return backlink, cumscore<EOL>


maxes = util.localmax(cumscore)<EOL>med_score = np.median(cumscore[np.argwhere(maxes)])<EOL>return np.argwhere((cumscore * maxes * <NUM_LIT:2> > med_score)).max()<EOL>

Get the last beat from the cumulative score array


def __trim_beats(localscore, beats, trim):

smooth_boe = scipy.signal.convolve(localscore[beats],<EOL>scipy.signal.hann(<NUM_LIT:5>),<EOL>'<STR_LIT>')<EOL>if trim:<EOL><INDENT>threshold = <NUM_LIT:0.5> * ((smooth_boe**<NUM_LIT:2>).mean()**<NUM_LIT:0.5>)<EOL><DEDENT>else:<EOL><INDENT>threshold = <NUM_LIT:0.0><EOL><DEDENT>valid = np.argwhere(smooth_boe > threshold)<EOL>return beats[valid.min():valid.max()]<EOL>

Final post-processing: throw out spurious leading/trailing beats


@cache(level=<NUM_LIT:10>)<EOL>def mel(sr, n_fft, n_mels=<NUM_LIT>, fmin=<NUM_LIT:0.0>, fmax=None, htk=False,<EOL>norm=<NUM_LIT:1>, dtype=np.float32):

if fmax is None:<EOL><INDENT>fmax = float(sr) / <NUM_LIT:2><EOL><DEDENT>if norm is not None and norm != <NUM_LIT:1> and norm != np.inf:<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(repr(norm)))<EOL><DEDENT>n_mels = int(n_mels)<EOL>weights = np.zeros((n_mels, int(<NUM_LIT:1> + n_fft // <NUM_LIT:2>)), dtype=dtype)<EOL>fftfreqs = fft_frequencies(sr=sr, n_fft=n_fft)<EOL>mel_f = mel_frequencies(n_mels + <NUM_LIT:2>, fmin=fmin, fmax=fmax, htk=htk)<EOL>fdiff = np.diff(mel_f)<EOL>ramps = np.subtract.outer(mel_f, fftfreqs)<EOL>for i in range(n_mels):<EOL><INDENT>lower = -ramps[i] / fdiff[i]<EOL>upper = ramps[i+<NUM_LIT:2>] / fdiff[i+<NUM_LIT:1>]<EOL>weights[i] = np.maximum(<NUM_LIT:0>, np.minimum(lower, upper))<EOL><DEDENT>if norm == <NUM_LIT:1>:<EOL><INDENT>enorm = <NUM_LIT> / (mel_f[<NUM_LIT:2>:n_mels+<NUM_LIT:2>] - mel_f[:n_mels])<EOL>weights *= enorm[:, np.newaxis]<EOL><DEDENT>if not np.all((mel_f[:-<NUM_LIT:2>] == <NUM_LIT:0>) | (weights.max(axis=<NUM_LIT:1>) > <NUM_LIT:0>)):<EOL><INDENT>warnings.warn('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>return weights<EOL>

Create a Filterbank matrix to combine FFT bins into Mel-frequency bins

    Parameters
    ----------
    sr        : number > 0 [scalar]
        sampling rate of the incoming signal

    n_fft     : int > 0 [scalar]
        number of FFT components

    n_mels    : int > 0 [scalar]
        number of Mel bands to generate

    fmin      : float >= 0 [scalar]
        lowest frequency (in Hz)

    fmax      : float >= 0 [scalar]
        highest frequency (in Hz).
        If `None`, use `fmax = sr / 2.0`

    htk       : bool [scalar]
        use HTK formula instead of Slaney

    norm : {None, 1, np.inf} [scalar]
        if 1, divide the triangular mel weights by the width of the mel band
        (area normalization).  Otherwise, leave all the triangles aiming for
        a peak value of 1.0

    dtype : np.dtype
        The data type of the output basis.
        By default, uses 32-bit (single-precision) floating point.

    Returns
    -------
    M         : np.ndarray [shape=(n_mels, 1 + n_fft/2)]
        Mel transform matrix

    Notes
    -----
    This function caches at level 10.

    Examples
    --------
    >>> melfb = librosa.filters.mel(22050, 2048)
    >>> melfb
    array([[ 0.   ,  0.016, ...,  0.   ,  0.   ],
           [ 0.   ,  0.   , ...,  0.   ,  0.   ],
           ...,
           [ 0.   ,  0.   , ...,  0.   ,  0.   ],
           [ 0.   ,  0.   , ...,  0.   ,  0.   ]])

    Clip the maximum frequency to 8KHz

    >>> librosa.filters.mel(22050, 2048, fmax=8000)
    array([[ 0.  ,  0.02, ...,  0.  ,  0.  ],
           [ 0.  ,  0.  , ...,  0.  ,  0.  ],
           ...,
           [ 0.  ,  0.  , ...,  0.  ,  0.  ],
           [ 0.  ,  0.  , ...,  0.  ,  0.  ]])

    >>> import matplotlib.pyplot as plt
    >>> plt.figure()
    >>> librosa.display.specshow(melfb, x_axis='linear')
    >>> plt.ylabel('Mel filter')
    >>> plt.title('Mel filter bank')
    >>> plt.colorbar()
    >>> plt.tight_layout()


@cache(level=<NUM_LIT:10>)<EOL>def chroma(sr, n_fft, n_chroma=<NUM_LIT:12>, A440=<NUM_LIT>, ctroct=<NUM_LIT>,<EOL>octwidth=<NUM_LIT:2>, norm=<NUM_LIT:2>, base_c=True, dtype=np.float32):

wts = np.zeros((n_chroma, n_fft))<EOL>frequencies = np.linspace(<NUM_LIT:0>, sr, n_fft, endpoint=False)[<NUM_LIT:1>:]<EOL>frqbins = n_chroma * hz_to_octs(frequencies, A440)<EOL>frqbins = np.concatenate(([frqbins[<NUM_LIT:0>] - <NUM_LIT> * n_chroma], frqbins))<EOL>binwidthbins = np.concatenate((np.maximum(frqbins[<NUM_LIT:1>:] - frqbins[:-<NUM_LIT:1>],<EOL><NUM_LIT:1.0>), [<NUM_LIT:1>]))<EOL>D = np.subtract.outer(frqbins, np.arange(<NUM_LIT:0>, n_chroma, dtype='<STR_LIT:d>')).T<EOL>n_chroma2 = np.round(float(n_chroma) / <NUM_LIT:2>)<EOL>D = np.remainder(D + n_chroma2 + <NUM_LIT:10>*n_chroma, n_chroma) - n_chroma2<EOL>wts = np.exp(-<NUM_LIT:0.5> * (<NUM_LIT:2>*D / np.tile(binwidthbins, (n_chroma, <NUM_LIT:1>)))**<NUM_LIT:2>)<EOL>wts = util.normalize(wts, norm=norm, axis=<NUM_LIT:0>)<EOL>if octwidth is not None:<EOL><INDENT>wts *= np.tile(<EOL>np.exp(-<NUM_LIT:0.5> * (((frqbins/n_chroma - ctroct)/octwidth)**<NUM_LIT:2>)),<EOL>(n_chroma, <NUM_LIT:1>))<EOL><DEDENT>if base_c:<EOL><INDENT>wts = np.roll(wts, -<NUM_LIT:3>, axis=<NUM_LIT:0>)<EOL><DEDENT>return np.ascontiguousarray(wts[:, :int(<NUM_LIT:1> + n_fft/<NUM_LIT:2>)], dtype=dtype)<EOL>

Create a Filterbank matrix to convert STFT to chroma

    Parameters
    ----------
    sr        : number > 0 [scalar]
        audio sampling rate

    n_fft     : int > 0 [scalar]
        number of FFT bins

    n_chroma  : int > 0 [scalar]
        number of chroma bins

    A440      : float > 0 [scalar]
        Reference frequency for A440

    ctroct    : float > 0 [scalar]

    octwidth  : float > 0 or None [scalar]
        `ctroct` and `octwidth` specify a dominance window -
        a Gaussian weighting centered on `ctroct` (in octs, A0 = 27.5Hz)
        and with a gaussian half-width of `octwidth`.
        Set `octwidth` to `None` to use a flat weighting.

    norm : float > 0 or np.inf
        Normalization factor for each filter

    base_c : bool
        If True, the filter bank will start at 'C'.
        If False, the filter bank will start at 'A'.

    dtype : np.dtype
        The data type of the output basis.
        By default, uses 32-bit (single-precision) floating point.

    Returns
    -------
    wts : ndarray [shape=(n_chroma, 1 + n_fft / 2)]
        Chroma filter matrix

    See Also
    --------
    util.normalize
    feature.chroma_stft

    Notes
    -----
    This function caches at level 10.

    Examples
    --------
    Build a simple chroma filter bank

    >>> chromafb = librosa.filters.chroma(22050, 4096)
    array([[  1.689e-05,   3.024e-04, ...,   4.639e-17,   5.327e-17],
           [  1.716e-05,   2.652e-04, ...,   2.674e-25,   3.176e-25],
    ...,
           [  1.578e-05,   3.619e-04, ...,   8.577e-06,   9.205e-06],
           [  1.643e-05,   3.355e-04, ...,   1.474e-10,   1.636e-10]])

    Use quarter-tones instead of semitones

    >>> librosa.filters.chroma(22050, 4096, n_chroma=24)
    array([[  1.194e-05,   2.138e-04, ...,   6.297e-64,   1.115e-63],
           [  1.206e-05,   2.009e-04, ...,   1.546e-79,   2.929e-79],
    ...,
           [  1.162e-05,   2.372e-04, ...,   6.417e-38,   9.923e-38],
           [  1.180e-05,   2.260e-04, ...,   4.697e-50,   7.772e-50]])

    Equally weight all octaves

    >>> librosa.filters.chroma(22050, 4096, octwidth=None)
    array([[  3.036e-01,   2.604e-01, ...,   2.445e-16,   2.809e-16],
           [  3.084e-01,   2.283e-01, ...,   1.409e-24,   1.675e-24],
    ...,
           [  2.836e-01,   3.116e-01, ...,   4.520e-05,   4.854e-05],
           [  2.953e-01,   2.888e-01, ...,   7.768e-10,   8.629e-10]])

    >>> import matplotlib.pyplot as plt
    >>> plt.figure()
    >>> librosa.display.specshow(chromafb, x_axis='linear')
    >>> plt.ylabel('Chroma filter')
    >>> plt.title('Chroma filter bank')
    >>> plt.colorbar()
    >>> plt.tight_layout()


def _wrap(n, *args, **kwargs):<EOL><INDENT>'''<STR_LIT>'''<EOL>n_min, n_max = int(np.floor(n)), int(np.ceil(n))<EOL>window = get_window(window_spec, n_min)<EOL>if len(window) < n_max:<EOL><INDENT>window = np.pad(window, [(<NUM_LIT:0>, n_max - len(window))],<EOL>mode='<STR_LIT>')<EOL><DEDENT>window[n_min:] = <NUM_LIT:0.0><EOL>return window<EOL><DEDENT>return _wrap<EOL>

Decorator function for windows with fractional input.

    This function guarantees that for fractional `x`, the following hold:

    1. `__float_window(window_function)(x)` has length `np.ceil(x)`
    2. all values from `np.floor(x)` are set to 0.

    For integer-valued `x`, there should be no change in behavior.


@cache(level=<NUM_LIT:10>)<EOL>def constant_q(sr, fmin=None, n_bins=<NUM_LIT>, bins_per_octave=<NUM_LIT:12>, tuning=<NUM_LIT:0.0>,<EOL>window='<STR_LIT>', filter_scale=<NUM_LIT:1>, pad_fft=True, norm=<NUM_LIT:1>,<EOL>dtype=np.complex64, **kwargs):

if fmin is None:<EOL><INDENT>fmin = note_to_hz('<STR_LIT>')<EOL><DEDENT>lengths = constant_q_lengths(sr, fmin,<EOL>n_bins=n_bins,<EOL>bins_per_octave=bins_per_octave,<EOL>tuning=tuning,<EOL>window=window,<EOL>filter_scale=filter_scale)<EOL>correction = <NUM_LIT>**(float(tuning) / bins_per_octave)<EOL>fmin = correction * fmin<EOL>Q = float(filter_scale) / (<NUM_LIT>**(<NUM_LIT:1.> / bins_per_octave) - <NUM_LIT:1>)<EOL>freqs = Q * sr / lengths<EOL>filters = []<EOL>for ilen, freq in zip(lengths, freqs):<EOL><INDENT>sig = np.exp(np.arange(-ilen//<NUM_LIT:2>, ilen//<NUM_LIT:2>, dtype=float) * <NUM_LIT> * <NUM_LIT:2> * np.pi * freq / sr)<EOL>sig = sig * __float_window(window)(len(sig))<EOL>sig = util.normalize(sig, norm=norm)<EOL>filters.append(sig)<EOL><DEDENT>max_len = max(lengths)<EOL>if pad_fft:<EOL><INDENT>max_len = int(<NUM_LIT>**(np.ceil(np.log2(max_len))))<EOL><DEDENT>else:<EOL><INDENT>max_len = int(np.ceil(max_len))<EOL><DEDENT>filters = np.asarray([util.pad_center(filt, max_len, **kwargs)<EOL>for filt in filters], dtype=dtype)<EOL>return filters, np.asarray(lengths)<EOL>

r'''Construct a constant-Q basis.

    This uses the filter bank described by [1]_.

    .. [1] McVicar, Matthew.
            "A machine learning approach to automatic chord extraction."
            Dissertation, University of Bristol. 2013.

    Parameters
    ----------
    sr : number > 0 [scalar]
        Audio sampling rate

    fmin : float > 0 [scalar]
        Minimum frequency bin. Defaults to `C1 ~= 32.70`

    n_bins : int > 0 [scalar]
        Number of frequencies.  Defaults to 7 octaves (84 bins).

    bins_per_octave : int > 0 [scalar]
        Number of bins per octave

    tuning : float in `[-0.5, +0.5)` [scalar]
        Tuning deviation from A440 in fractions of a bin

    window : string, tuple, number, or function
        Windowing function to apply to filters.

    filter_scale : float > 0 [scalar]
        Scale of filter windows.
        Small values (<1) use shorter windows for higher temporal resolution.

    pad_fft : boolean
        Center-pad all filters up to the nearest integral power of 2.

        By default, padding is done with zeros, but this can be overridden
        by setting the `mode=` field in *kwargs*.

    norm : {inf, -inf, 0, float > 0}
        Type of norm to use for basis function normalization.
        See librosa.util.normalize

    dtype : np.dtype
        The data type of the output basis.
        By default, uses 64-bit (single precision) complex floating point.

    kwargs : additional keyword arguments
        Arguments to `np.pad()` when `pad==True`.

    Returns
    -------
    filters : np.ndarray, `len(filters) == n_bins`
        `filters[i]` is `i`\ th time-domain CQT basis filter

    lengths : np.ndarray, `len(lengths) == n_bins`
        The (fractional) length of each filter

    Notes
    -----
    This function caches at level 10.

    See Also
    --------
    constant_q_lengths
    librosa.core.cqt
    librosa.util.normalize

    Examples
    --------
    Use a shorter window for each filter

    >>> basis, lengths = librosa.filters.constant_q(22050, filter_scale=0.5)

    Plot one octave of filters in time and frequency

    >>> import matplotlib.pyplot as plt
    >>> basis, lengths = librosa.filters.constant_q(22050)
    >>> plt.figure(figsize=(10, 6))
    >>> plt.subplot(2, 1, 1)
    >>> notes = librosa.midi_to_note(np.arange(24, 24 + len(basis)))
    >>> for i, (f, n) in enumerate(zip(basis, notes[:12])):
    ...     f_scale = librosa.util.normalize(f) / 2
    ...     plt.plot(i + f_scale.real)
    ...     plt.plot(i + f_scale.imag, linestyle=':')
    >>> plt.axis('tight')
    >>> plt.yticks(np.arange(len(notes[:12])), notes[:12])
    >>> plt.ylabel('CQ filters')
    >>> plt.title('CQ filters (one octave, time domain)')
    >>> plt.xlabel('Time (samples at 22050 Hz)')
    >>> plt.legend(['Real', 'Imaginary'], frameon=True, framealpha=0.8)
    >>> plt.subplot(2, 1, 2)
    >>> F = np.abs(np.fft.fftn(basis, axes=[-1]))
    >>> # Keep only the positive frequencies
    >>> F = F[:, :(1 + F.shape[1] // 2)]
    >>> librosa.display.specshow(F, x_axis='linear')
    >>> plt.yticks(np.arange(len(notes))[::12], notes[::12])
    >>> plt.ylabel('CQ filters')
    >>> plt.title('CQ filter magnitudes (frequency domain)')
    >>> plt.tight_layout()


@cache(level=<NUM_LIT:10>)<EOL>def constant_q_lengths(sr, fmin, n_bins=<NUM_LIT>, bins_per_octave=<NUM_LIT:12>,<EOL>tuning=<NUM_LIT:0.0>, window='<STR_LIT>', filter_scale=<NUM_LIT:1>):

if fmin <= <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if bins_per_octave <= <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if filter_scale <= <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if n_bins <= <NUM_LIT:0> or not isinstance(n_bins, int):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>correction = <NUM_LIT>**(float(tuning) / bins_per_octave)<EOL>fmin = correction * fmin<EOL>Q = float(filter_scale) / (<NUM_LIT>**(<NUM_LIT:1.> / bins_per_octave) - <NUM_LIT:1>)<EOL>freq = fmin * (<NUM_LIT> ** (np.arange(n_bins, dtype=float) / bins_per_octave))<EOL>if freq[-<NUM_LIT:1>] * (<NUM_LIT:1> + <NUM_LIT:0.5> * window_bandwidth(window) / Q) > sr / <NUM_LIT>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>lengths = Q * sr / freq<EOL>return lengths<EOL>

r'''Return length of each filter in a constant-Q basis.

    Parameters
    ----------
    sr : number > 0 [scalar]
        Audio sampling rate

    fmin : float > 0 [scalar]
        Minimum frequency bin.

    n_bins : int > 0 [scalar]
        Number of frequencies.  Defaults to 7 octaves (84 bins).

    bins_per_octave : int > 0 [scalar]
        Number of bins per octave

    tuning : float in `[-0.5, +0.5)` [scalar]
        Tuning deviation from A440 in fractions of a bin

    window : str or callable
        Window function to use on filters

    filter_scale : float > 0 [scalar]
        Resolution of filter windows. Larger values use longer windows.

    Returns
    -------
    lengths : np.ndarray
        The length of each filter.

    Notes
    -----
    This function caches at level 10.

    See Also
    --------
    constant_q
    librosa.core.cqt


@cache(level=<NUM_LIT:10>)<EOL>def cq_to_chroma(n_input, bins_per_octave=<NUM_LIT:12>, n_chroma=<NUM_LIT:12>,<EOL>fmin=None, window=None, base_c=True, dtype=np.float32):

<EOL>n_merge = float(bins_per_octave) / n_chroma<EOL>if fmin is None:<EOL><INDENT>fmin = note_to_hz('<STR_LIT>')<EOL><DEDENT>if np.mod(n_merge, <NUM_LIT:1>) != <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>cq_to_ch = np.repeat(np.eye(n_chroma), n_merge, axis=<NUM_LIT:1>)<EOL>cq_to_ch = np.roll(cq_to_ch, - int(n_merge // <NUM_LIT:2>), axis=<NUM_LIT:1>)<EOL>n_octaves = np.ceil(np.float(n_input) / bins_per_octave)<EOL>cq_to_ch = np.tile(cq_to_ch, int(n_octaves))[:, :n_input]<EOL>midi_0 = np.mod(hz_to_midi(fmin), <NUM_LIT:12>)<EOL>if base_c:<EOL><INDENT>roll = midi_0<EOL><DEDENT>else:<EOL><INDENT>roll = midi_0 - <NUM_LIT:9><EOL><DEDENT>roll = int(np.round(roll * (n_chroma / <NUM_LIT>)))<EOL>cq_to_ch = np.roll(cq_to_ch, roll, axis=<NUM_LIT:0>).astype(dtype)<EOL>if window is not None:<EOL><INDENT>cq_to_ch = scipy.signal.convolve(cq_to_ch,<EOL>np.atleast_2d(window),<EOL>mode='<STR_LIT>')<EOL><DEDENT>return cq_to_ch<EOL>

Convert a Constant-Q basis to Chroma.

    Parameters
    ----------
    n_input : int > 0 [scalar]
        Number of input components (CQT bins)

    bins_per_octave : int > 0 [scalar]
        How many bins per octave in the CQT

    n_chroma : int > 0 [scalar]
        Number of output bins (per octave) in the chroma

    fmin : None or float > 0
        Center frequency of the first constant-Q channel.
        Default: 'C1' ~= 32.7 Hz

    window : None or np.ndarray
        If provided, the cq_to_chroma filter bank will be
        convolved with `window`.

    base_c : bool
        If True, the first chroma bin will start at 'C'
        If False, the first chroma bin will start at 'A'

    dtype : np.dtype
        The data type of the output basis.
        By default, uses 32-bit (single-precision) floating point.

    Returns
    -------
    cq_to_chroma : np.ndarray [shape=(n_chroma, n_input)]
        Transformation matrix: `Chroma = np.dot(cq_to_chroma, CQT)`

    Raises
    ------
    ParameterError
        If `n_input` is not an integer multiple of `n_chroma`

    Notes
    -----
    This function caches at level 10.

    Examples
    --------
    Get a CQT, and wrap bins to chroma

    >>> y, sr = librosa.load(librosa.util.example_audio_file())
    >>> CQT = np.abs(librosa.cqt(y, sr=sr))
    >>> chroma_map = librosa.filters.cq_to_chroma(CQT.shape[0])
    >>> chromagram = chroma_map.dot(CQT)
    >>> # Max-normalize each time step
    >>> chromagram = librosa.util.normalize(chromagram, axis=0)

    >>> import matplotlib.pyplot as plt
    >>> plt.subplot(3, 1, 1)
    >>> librosa.display.specshow(librosa.amplitude_to_db(CQT,
    ...                                                  ref=np.max),
    ...                          y_axis='cqt_note')
    >>> plt.title('CQT Power')
    >>> plt.colorbar()
    >>> plt.subplot(3, 1, 2)
    >>> librosa.display.specshow(chromagram, y_axis='chroma')
    >>> plt.title('Chroma (wrapped CQT)')
    >>> plt.colorbar()
    >>> plt.subplot(3, 1, 3)
    >>> chroma = librosa.feature.chroma_stft(y=y, sr=sr)
    >>> librosa.display.specshow(chroma, y_axis='chroma', x_axis='time')
    >>> plt.title('librosa.feature.chroma_stft')
    >>> plt.colorbar()
    >>> plt.tight_layout()


if hasattr(window, '<STR_LIT>'):<EOL><INDENT>key = window.__name__<EOL><DEDENT>else:<EOL><INDENT>key = window<EOL><DEDENT>if key not in WINDOW_BANDWIDTHS:<EOL><INDENT>win = get_window(window, n)<EOL>WINDOW_BANDWIDTHS[key] = n * np.sum(win**<NUM_LIT:2>) / np.sum(np.abs(win))**<NUM_LIT:2><EOL><DEDENT>return WINDOW_BANDWIDTHS[key]<EOL>

Get the equivalent noise bandwidth of a window function.

    Parameters
    ----------
    window : callable or string
        A window function, or the name of a window function.
        Examples:
        - scipy.signal.hann
        - 'boxcar'

    n : int > 0
        The number of coefficients to use in estimating the
        window bandwidth

    Returns
    -------
    bandwidth : float
        The equivalent noise bandwidth (in FFT bins) of the
        given window function

    Notes
    -----
    This function caches at level 10.

    See Also
    --------
    get_window


@cache(level=<NUM_LIT:10>)<EOL>def get_window(window, Nx, fftbins=True):

if six.callable(window):<EOL><INDENT>return window(Nx)<EOL><DEDENT>elif (isinstance(window, (six.string_types, tuple)) or<EOL>np.isscalar(window)):<EOL><INDENT>return scipy.signal.get_window(window, Nx, fftbins=fftbins)<EOL><DEDENT>elif isinstance(window, (np.ndarray, list)):<EOL><INDENT>if len(window) == Nx:<EOL><INDENT>return np.asarray(window)<EOL><DEDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(len(window), Nx))<EOL><DEDENT>else:<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(window))<EOL><DEDENT>

Compute a window function.

    This is a wrapper for `scipy.signal.get_window` that additionally
    supports callable or pre-computed windows.

    Parameters
    ----------
    window : string, tuple, number, callable, or list-like
        The window specification:

        - If string, it's the name of the window function (e.g., `'hann'`)
        - If tuple, it's the name of the window function and any parameters
          (e.g., `('kaiser', 4.0)`)
        - If numeric, it is treated as the beta parameter of the `'kaiser'`
          window, as in `scipy.signal.get_window`.
        - If callable, it's a function that accepts one integer argument
          (the window length)
        - If list-like, it's a pre-computed window of the correct length `Nx`

    Nx : int > 0
        The length of the window

    fftbins : bool, optional
        If True (default), create a periodic window for use with FFT
        If False, create a symmetric window for filter design applications.

    Returns
    -------
    get_window : np.ndarray
        A window of length `Nx` and type `window`

    See Also
    --------
    scipy.signal.get_window

    Notes
    -----
    This function caches at level 10.

    Raises
    ------
    ParameterError
        If `window` is supplied as a vector of length != `n_fft`,
        or is otherwise mis-specified.


@cache(level=<NUM_LIT:10>)<EOL>def _multirate_fb(center_freqs=None, sample_rates=None, Q=<NUM_LIT>,<EOL>passband_ripple=<NUM_LIT:1>, stopband_attenuation=<NUM_LIT:50>, ftype='<STR_LIT>', flayout='<STR_LIT>'):

if center_freqs is None:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if sample_rates is None:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if center_freqs.shape != sample_rates.shape:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>nyquist = <NUM_LIT:0.5> * sample_rates<EOL>filter_bandwidths = center_freqs / float(Q)<EOL>filterbank = []<EOL>for cur_center_freq, cur_nyquist, cur_bw in zip(center_freqs, nyquist, filter_bandwidths):<EOL><INDENT>passband_freqs = [cur_center_freq - <NUM_LIT:0.5> * cur_bw, cur_center_freq + <NUM_LIT:0.5> * cur_bw] / cur_nyquist<EOL>stopband_freqs = [cur_center_freq - cur_bw, cur_center_freq + cur_bw] / cur_nyquist<EOL>cur_filter = scipy.signal.iirdesign(passband_freqs, stopband_freqs,<EOL>passband_ripple, stopband_attenuation,<EOL>analog=False, ftype=ftype, output=flayout)<EOL>filterbank.append(cur_filter)<EOL><DEDENT>return filterbank, sample_rates<EOL>

r'''Helper function to construct a multirate filterbank.

     A filter bank consists of multiple band-pass filters which divide the input signal
     into subbands. In the case of a multirate filter bank, the band-pass filters
     operate with resampled versions of the input signal, e.g. to keep the length
     of a filter constant while shifting its center frequency.

     This implementation uses `scipy.signal.iirdesign` to design the filters.

    Parameters
    ----------
    center_freqs : np.ndarray [shape=(n,), dtype=float]
        Center frequencies of the filter kernels.
        Also defines the number of filters in the filterbank.

    sample_rates : np.ndarray [shape=(n,), dtype=float]
        Samplerate for each filter (used for multirate filterbank).

    Q : float
        Q factor (influences the filter bandwith).

    passband_ripple : float
        The maximum loss in the passband (dB)
        See `scipy.signal.iirdesign` for details.

    stopband_attenuation : float
        The minimum attenuation in the stopband (dB)
        See `scipy.signal.iirdesign` for details.

    ftype : str
        The type of IIR filter to design
        See `scipy.signal.iirdesign` for details.

    flayout : string
        Valid `output` argument for `scipy.signal.iirdesign`.
        - If `ba`, returns numerators/denominators of the transfer functions,
          used for filtering with `scipy.signal.filtfilt`.
          Can be unstable for high-order filters.
        - If `sos`, returns a series of second-order filters,
          used for filtering with `scipy.signal.sosfiltfilt`.
          Minimizes numerical precision errors for high-order filters, but is slower.
        - If `zpk`, returns zeros, poles, and system gains of the transfer functions.

    Returns
    -------
    filterbank : list [shape=(n,), dtype=float]
        Each list entry comprises the filter coefficients for a single filter.

    sample_rates : np.ndarray [shape=(n,), dtype=float]
        Samplerate for each filter.

    Notes
    -----
    This function caches at level 10.

    See Also
    --------
    scipy.signal.iirdesign

    Raises
    ------
    ParameterError
        If `center_freqs` is `None`.
        If `sample_rates` is `None`.
        If `center_freqs.shape` does not match `sample_rates.shape`.


center_freqs = midi_to_hz(np.arange(<NUM_LIT> + tuning, <NUM_LIT> + tuning))<EOL>sample_rates = np.asarray(len(np.arange(<NUM_LIT:0>, <NUM_LIT>)) * [<NUM_LIT>, ] +<EOL>len(np.arange(<NUM_LIT>, <NUM_LIT>)) * [<NUM_LIT>, ] +<EOL>len(np.arange(<NUM_LIT>, <NUM_LIT>)) * [<NUM_LIT>, ])<EOL>return center_freqs, sample_rates<EOL>

r'''Helper function for generating center frequency and sample rate pairs.

    This function will return center frequency and corresponding sample rates
    to obtain similar pitch filterbank settings as described in [1]_.
    Instead of starting with MIDI pitch `A0`, we start with `C0`.

    .. [1] Müller, Meinard.
           "Information Retrieval for Music and Motion."
           Springer Verlag. 2007.

    Parameters
    ----------
    tuning : float in `[-0.5, +0.5)` [scalar]
        Tuning deviation from A440, measure as a fraction of the equally
        tempered semitone (1/12 of an octave).

    Returns
    -------
    center_freqs : np.ndarray [shape=(n,), dtype=float]
        Center frequencies of the filter kernels.
        Also defines the number of filters in the filterbank.

    sample_rates : np.ndarray [shape=(n,), dtype=float]
        Sample rate for each filter, used for multirate filterbank.

    Notes
    -----
    This function caches at level 10.

    See Also
    --------
    librosa.filters.semitone_filterbank
    librosa.filters._multirate_fb


def semitone_filterbank(center_freqs=None, tuning=<NUM_LIT:0.0>, sample_rates=None, flayout='<STR_LIT>', **kwargs):

if (center_freqs is None) and (sample_rates is None):<EOL><INDENT>center_freqs, sample_rates = mr_frequencies(tuning)<EOL><DEDENT>filterbank, fb_sample_rates = _multirate_fb(center_freqs=center_freqs, sample_rates=sample_rates,<EOL>flayout=flayout, **kwargs)<EOL>return filterbank, fb_sample_rates<EOL>

r'''Constructs a multirate filterbank of infinite-impulse response (IIR)
    band-pass filters at user-defined center frequencies and sample rates.

    By default, these center frequencies are set equal to the 88 fundamental
    frequencies of the grand piano keyboard, according to a pitch tuning standard
    of A440, that is, note A above middle C set to 440 Hz. The center frequencies
    are tuned to the twelve-tone equal temperament, which means that they grow
    exponentially at a rate of 2**(1/12), that is, twelve notes per octave.

    The A440 tuning can be changed by the user while keeping twelve-tone equal
    temperament. While A440 is currently the international standard in the music
    industry (ISO 16), some orchestras tune to A441-A445, whereas baroque musicians
    tune to A415.

    See [1]_ for details.

    .. [1] Müller, Meinard.
           "Information Retrieval for Music and Motion."
           Springer Verlag. 2007.

    Parameters
    ----------
    center_freqs : np.ndarray [shape=(n,), dtype=float]
        Center frequencies of the filter kernels.
        Also defines the number of filters in the filterbank.

    tuning : float in `[-0.5, +0.5)` [scalar]
        Tuning deviation from A440 as a fraction of a semitone (1/12 of an octave
        in equal temperament).

    sample_rates : np.ndarray [shape=(n,), dtype=float]
        Sample rates of each filter in the multirate filterbank.

    flayout : string
        - If `ba`, the standard difference equation is used for filtering with `scipy.signal.filtfilt`.
          Can be unstable for high-order filters.
        - If `sos`, a series of second-order filters is used for filtering with `scipy.signal.sosfiltfilt`.
          Minimizes numerical precision errors for high-order filters, but is slower.

    kwargs : additional keyword arguments
        Additional arguments to the private function `_multirate_fb()`.

    Returns
    -------
    filterbank : list [shape=(n,), dtype=float]
        Each list entry contains the filter coefficients for a single filter.

    fb_sample_rates : np.ndarray [shape=(n,), dtype=float]
        Sample rate for each filter.

    See Also
    --------
    librosa.core.cqt
    librosa.core.iirt
    librosa.filters._multirate_fb
    librosa.filters.mr_frequencies
    scipy.signal.iirdesign

    Examples
    --------
    >>> import matplotlib.pyplot as plt
    >>> import numpy as np
    >>> import scipy.signal
    >>> semitone_filterbank, sample_rates = librosa.filters.semitone_filterbank()
    >>> plt.figure(figsize=(10, 6))
    >>> for cur_sr, cur_filter in zip(sample_rates, semitone_filterbank):
    ...    w, h = scipy.signal.freqz(cur_filter[0], cur_filter[1], worN=2000)
    ...    plt.plot((cur_sr / (2 * np.pi)) * w, 20 * np.log10(abs(h)))
    >>> plt.semilogx()
    >>> plt.xlim([20, 10e3])
    >>> plt.ylim([-60, 3])
    >>> plt.title('Magnitude Responses of the Pitch Filterbank')
    >>> plt.xlabel('Log-Frequency (Hz)')
    >>> plt.ylabel('Magnitude (dB)')
    >>> plt.tight_layout()


@jit(nopython=True, cache=True)<EOL>def __window_ss_fill(x, win_sq, n_frames, hop_length):

n = len(x)<EOL>n_fft = len(win_sq)<EOL>for i in range(n_frames):<EOL><INDENT>sample = i * hop_length<EOL>x[sample:min(n, sample + n_fft)] += win_sq[:max(<NUM_LIT:0>, min(n_fft, n - sample))]<EOL><DEDENT>

Helper function for window sum-square calculation.


def window_sumsquare(window, n_frames, hop_length=<NUM_LIT>, win_length=None, n_fft=<NUM_LIT>,<EOL>dtype=np.float32, norm=None):

if win_length is None:<EOL><INDENT>win_length = n_fft<EOL><DEDENT>n = n_fft + hop_length * (n_frames - <NUM_LIT:1>)<EOL>x = np.zeros(n, dtype=dtype)<EOL>win_sq = get_window(window, win_length)<EOL>win_sq = util.normalize(win_sq, norm=norm)**<NUM_LIT:2><EOL>win_sq = util.pad_center(win_sq, n_fft)<EOL>__window_ss_fill(x, win_sq, n_frames, hop_length)<EOL>return x<EOL>

Compute the sum-square envelope of a window function at a given hop length.

This is used to estimate modulation effects induced by windowing observations
in short-time fourier transforms.

Parameters
----------
window : string, tuple, number, callable, or list-like
    Window specification, as in `get_window`

n_frames : int > 0
    The number of analysis frames

hop_length : int > 0
    The number of samples to advance between frames

win_length : [optional]
    The length of the window function.  By default, this matches `n_fft`.

n_fft : int > 0
    The length of each analysis frame.

dtype : np.dtype
    The data type of the output

Returns
-------
wss : np.ndarray, shape=`(n_fft + hop_length * (n_frames - 1))`
    The sum-squared envelope of the window function

Examples
--------
For a fixed frame length (2048), compare modulation effects for a Hann window
at different hop lengths:

>>> n_frames = 50
>>> wss_256 = librosa.filters.window_sumsquare('hann', n_frames, hop_length=256)
>>> wss_512 = librosa.filters.window_sumsquare('hann', n_frames, hop_length=512)
>>> wss_1024 = librosa.filters.window_sumsquare('hann', n_frames, hop_length=1024)

>>> import matplotlib.pyplot as plt
>>> plt.figure()
>>> plt.subplot(3,1,1)
>>> plt.plot(wss_256)
>>> plt.title('hop_length=256')
>>> plt.subplot(3,1,2)
>>> plt.plot(wss_512)
>>> plt.title('hop_length=512')
>>> plt.subplot(3,1,3)
>>> plt.plot(wss_1024)
>>> plt.title('hop_length=1024')
>>> plt.tight_layout()


@cache(level=<NUM_LIT:10>)<EOL>def diagonal_filter(window, n, slope=<NUM_LIT:1.0>, angle=None, zero_mean=False):

if angle is None:<EOL><INDENT>angle = np.arctan(slope)<EOL><DEDENT>win = np.diag(get_window(window, n, fftbins=False))<EOL>if not np.isclose(angle, np.pi/<NUM_LIT:4>):<EOL><INDENT>win = scipy.ndimage.rotate(win, <NUM_LIT> - angle * <NUM_LIT> / np.pi,<EOL>order=<NUM_LIT:5>, prefilter=False)<EOL><DEDENT>np.clip(win, <NUM_LIT:0>, None, out=win)<EOL>win /= win.sum()<EOL>if zero_mean:<EOL><INDENT>win -= win.mean()<EOL><DEDENT>return win<EOL>

Build a two-dimensional diagonal filter.

    This is primarily used for smoothing recurrence or self-similarity matrices.

    Parameters
    ----------
    window : string, tuple, number, callable, or list-like
        The window function to use for the filter.

        See `get_window` for details.

        Note that the window used here should be non-negative.

    n : int > 0
        the length of the filter

    slope : float
        The slope of the diagonal filter to produce

    angle : float or None
        If given, the slope parameter is ignored,
        and angle directly sets the orientation of the filter (in radians).
        Otherwise, angle is inferred as `arctan(slope)`.

    zero_mean : bool
        If True, a zero-mean filter is used.
        Otherwise, a non-negative averaging filter is used.

        This should be enabled if you want to enhance paths and suppress
        blocks.

    Returns
    -------
    kernel : np.ndarray, shape=[(m, m)]
        The 2-dimensional filter kernel

    Notes
    -----
    This function caches at level 10.


def dtw(X=None, Y=None, C=None, metric='<STR_LIT>', step_sizes_sigma=None,<EOL>weights_add=None, weights_mul=None, subseq=False, backtrack=True,<EOL>global_constraints=False, band_rad=<NUM_LIT>):

<EOL>if step_sizes_sigma is None:<EOL><INDENT>step_sizes_sigma = np.array([[<NUM_LIT:1>, <NUM_LIT:1>], [<NUM_LIT:0>, <NUM_LIT:1>], [<NUM_LIT:1>, <NUM_LIT:0>]])<EOL><DEDENT>if weights_add is None:<EOL><INDENT>weights_add = np.zeros(len(step_sizes_sigma))<EOL><DEDENT>if weights_mul is None:<EOL><INDENT>weights_mul = np.ones(len(step_sizes_sigma))<EOL><DEDENT>if len(step_sizes_sigma) != len(weights_add):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if len(step_sizes_sigma) != len(weights_mul):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if C is None and (X is None or Y is None):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if C is not None and (X is not None or Y is not None):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if C is None:<EOL><INDENT>X = np.atleast_2d(X)<EOL>Y = np.atleast_2d(Y)<EOL>try:<EOL><INDENT>C = cdist(X.T, Y.T, metric=metric)<EOL><DEDENT>except ValueError:<EOL><INDENT>msg = ('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL>six.reraise(ParameterError, ParameterError(msg))<EOL><DEDENT>if subseq and (X.shape[<NUM_LIT:1>] > Y.shape[<NUM_LIT:1>]):<EOL><INDENT>C = C.T<EOL><DEDENT><DEDENT>C = np.atleast_2d(C)<EOL>if np.array_equal(step_sizes_sigma, np.array([[<NUM_LIT:1>, <NUM_LIT:1>]])) and (C.shape[<NUM_LIT:0>] > C.shape[<NUM_LIT:1>]):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>max_0 = step_sizes_sigma[:, <NUM_LIT:0>].max()<EOL>max_1 = step_sizes_sigma[:, <NUM_LIT:1>].max()<EOL>if global_constraints:<EOL><INDENT>fill_off_diagonal(C, band_rad, value=np.inf)<EOL><DEDENT>D = np.ones(C.shape + np.array([max_0, max_1])) * np.inf<EOL>D[max_0, max_1] = C[<NUM_LIT:0>, <NUM_LIT:0>]<EOL>if subseq:<EOL><INDENT>D[max_0, max_1:] = C[<NUM_LIT:0>, :]<EOL><DEDENT>D_steps = -<NUM_LIT:1> * np.ones(D.shape, dtype=np.int)<EOL>D, D_steps = __dtw_calc_accu_cost(C, D, D_steps,<EOL>step_sizes_sigma,<EOL>weights_mul, weights_add,<EOL>max_0, max_1)<EOL>D = D[max_0:, max_1:]<EOL>D_steps = D_steps[max_0:, max_1:]<EOL>if backtrack:<EOL><INDENT>if subseq:<EOL><INDENT>wp_end_idx = np.argmin(D[-<NUM_LIT:1>, :]) + <NUM_LIT:1><EOL>wp = __dtw_backtracking(D_steps[:, :wp_end_idx], step_sizes_sigma)<EOL><DEDENT>else:<EOL><INDENT>wp = __dtw_backtracking(D_steps, step_sizes_sigma)<EOL><DEDENT>wp = np.asarray(wp, dtype=int)<EOL>if subseq and (X.shape[<NUM_LIT:1>] > Y.shape[<NUM_LIT:1>]):<EOL><INDENT>wp = np.fliplr(wp)<EOL><DEDENT>return D, wp<EOL><DEDENT>else:<EOL><INDENT>return D<EOL><DEDENT>

Dynamic time warping (DTW).

    This function performs a DTW and path backtracking on two sequences.
    We follow the nomenclature and algorithmic approach as described in [1]_.

    .. [1] Meinard Mueller
           Fundamentals of Music Processing — Audio, Analysis, Algorithms, Applications
           Springer Verlag, ISBN: 978-3-319-21944-8, 2015.

    Parameters
    ----------
    X : np.ndarray [shape=(K, N)]
        audio feature matrix (e.g., chroma features)

    Y : np.ndarray [shape=(K, M)]
        audio feature matrix (e.g., chroma features)

    C : np.ndarray [shape=(N, M)]
        Precomputed distance matrix. If supplied, X and Y must not be supplied and
        ``metric`` will be ignored.

    metric : str
        Identifier for the cost-function as documented
        in `scipy.spatial.cdist()`

    step_sizes_sigma : np.ndarray [shape=[n, 2]]
        Specifies allowed step sizes as used by the dtw.

    weights_add : np.ndarray [shape=[n, ]]
        Additive weights to penalize certain step sizes.

    weights_mul : np.ndarray [shape=[n, ]]
        Multiplicative weights to penalize certain step sizes.

    subseq : binary
        Enable subsequence DTW, e.g., for retrieval tasks.

    backtrack : binary
        Enable backtracking in accumulated cost matrix.

    global_constraints : binary
        Applies global constraints to the cost matrix ``C`` (Sakoe-Chiba band).

    band_rad : float
        The Sakoe-Chiba band radius (1/2 of the width) will be
        ``int(radius*min(C.shape))``.

    Returns
    -------
    D : np.ndarray [shape=(N,M)]
        accumulated cost matrix.
        D[N,M] is the total alignment cost.
        When doing subsequence DTW, D[N,:] indicates a matching function.

    wp : np.ndarray [shape=(N,2)]
        Warping path with index pairs.
        Each row of the array contains an index pair n,m).
        Only returned when ``backtrack`` is True.

    Raises
    ------
    ParameterError
        If you are doing diagonal matching and Y is shorter than X or if an incompatible
        combination of X, Y, and C are supplied.
        If your input dimensions are incompatible.

    Examples
    --------
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> y, sr = librosa.load(librosa.util.example_audio_file(), offset=10, duration=15)
    >>> X = librosa.feature.chroma_cens(y=y, sr=sr)
    >>> noise = np.random.rand(X.shape[0], 200)
    >>> Y = np.concatenate((noise, noise, X, noise), axis=1)
    >>> D, wp = librosa.sequence.dtw(X, Y, subseq=True)
    >>> plt.subplot(2, 1, 1)
    >>> librosa.display.specshow(D, x_axis='frames', y_axis='frames')
    >>> plt.title('Database excerpt')
    >>> plt.plot(wp[:, 1], wp[:, 0], label='Optimal path', color='y')
    >>> plt.legend()
    >>> plt.subplot(2, 1, 2)
    >>> plt.plot(D[-1, :] / wp.shape[0])
    >>> plt.xlim([0, Y.shape[1]])
    >>> plt.ylim([0, 2])
    >>> plt.title('Matching cost function')
    >>> plt.tight_layout()


@jit(nopython=True, cache=True)<EOL>def __dtw_calc_accu_cost(C, D, D_steps, step_sizes_sigma,<EOL>weights_mul, weights_add, max_0, max_1):

for cur_n in range(max_0, D.shape[<NUM_LIT:0>]):<EOL><INDENT>for cur_m in range(max_1, D.shape[<NUM_LIT:1>]):<EOL><INDENT>for cur_step_idx, cur_w_add, cur_w_mul in zip(range(step_sizes_sigma.shape[<NUM_LIT:0>]),<EOL>weights_add, weights_mul):<EOL><INDENT>cur_D = D[cur_n - step_sizes_sigma[cur_step_idx, <NUM_LIT:0>],<EOL>cur_m - step_sizes_sigma[cur_step_idx, <NUM_LIT:1>]]<EOL>cur_C = cur_w_mul * C[cur_n - max_0, cur_m - max_1]<EOL>cur_C += cur_w_add<EOL>cur_cost = cur_D + cur_C<EOL>if cur_cost < D[cur_n, cur_m]:<EOL><INDENT>D[cur_n, cur_m] = cur_cost<EOL>D_steps[cur_n, cur_m] = cur_step_idx<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return D, D_steps<EOL>

Calculate the accumulated cost matrix D.

    Use dynamic programming to calculate the accumulated costs.

    Parameters
    ----------
    C : np.ndarray [shape=(N, M)]
        pre-computed cost matrix

    D : np.ndarray [shape=(N, M)]
        accumulated cost matrix

    D_steps : np.ndarray [shape=(N, M)]
        steps which were used for calculating D

    step_sizes_sigma : np.ndarray [shape=[n, 2]]
        Specifies allowed step sizes as used by the dtw.

    weights_add : np.ndarray [shape=[n, ]]
        Additive weights to penalize certain step sizes.

    weights_mul : np.ndarray [shape=[n, ]]
        Multiplicative weights to penalize certain step sizes.

    max_0 : int
        maximum number of steps in step_sizes_sigma in dim 0.

    max_1 : int
        maximum number of steps in step_sizes_sigma in dim 1.

    Returns
    -------
    D : np.ndarray [shape=(N,M)]
        accumulated cost matrix.
        D[N,M] is the total alignment cost.
        When doing subsequence DTW, D[N,:] indicates a matching function.

    D_steps : np.ndarray [shape=(N,M)]
        steps which were used for calculating D.

    See Also
    --------
    dtw


@jit(nopython=True, cache=True)<EOL>def __dtw_backtracking(D_steps, step_sizes_sigma):

wp = []<EOL>cur_idx = (D_steps.shape[<NUM_LIT:0>] - <NUM_LIT:1>, D_steps.shape[<NUM_LIT:1>] - <NUM_LIT:1>)<EOL>wp.append((cur_idx[<NUM_LIT:0>], cur_idx[<NUM_LIT:1>]))<EOL>while cur_idx[<NUM_LIT:0>] > <NUM_LIT:0>:<EOL><INDENT>cur_step_idx = D_steps[(cur_idx[<NUM_LIT:0>], cur_idx[<NUM_LIT:1>])]<EOL>cur_idx = (cur_idx[<NUM_LIT:0>] - step_sizes_sigma[cur_step_idx][<NUM_LIT:0>],<EOL>cur_idx[<NUM_LIT:1>] - step_sizes_sigma[cur_step_idx][<NUM_LIT:1>])<EOL>wp.append((cur_idx[<NUM_LIT:0>], cur_idx[<NUM_LIT:1>]))<EOL><DEDENT>return wp<EOL>

Backtrack optimal warping path.

    Uses the saved step sizes from the cost accumulation
    step to backtrack the index pairs for an optimal
    warping path.

    Parameters
    ----------
    D_steps : np.ndarray [shape=(N, M)]
        Saved indices of the used steps used in the calculation of D.

    step_sizes_sigma : np.ndarray [shape=[n, 2]]
        Specifies allowed step sizes as used by the dtw.

    Returns
    -------
    wp : list [shape=(N,)]
        Warping path with index pairs.
        Each list entry contains an index pair
        (n,m) as a tuple

    See Also
    --------
    dtw


@jit(nopython=True, cache=True)<EOL>def _viterbi(log_prob, log_trans, log_p_init, state, value, ptr):

n_steps, n_states = log_prob.shape<EOL>value[<NUM_LIT:0>] = log_prob[<NUM_LIT:0>] + log_p_init<EOL>for t in range(<NUM_LIT:1>, n_steps):<EOL><INDENT>trans_out = value[t - <NUM_LIT:1>] + log_trans.T<EOL>for j in range(n_states):<EOL><INDENT>ptr[t, j] = np.argmax(trans_out[j])<EOL>value[t, j] = log_prob[t, j] + trans_out[j, ptr[t][j]]<EOL><DEDENT><DEDENT>state[-<NUM_LIT:1>] = np.argmax(value[-<NUM_LIT:1>])<EOL>for t in range(n_steps - <NUM_LIT:2>, -<NUM_LIT:1>, -<NUM_LIT:1>):<EOL><INDENT>state[t] = ptr[t+<NUM_LIT:1>, state[t+<NUM_LIT:1>]]<EOL><DEDENT>

Core Viterbi algorithm.

    This is intended for internal use only.

    Parameters
    ----------
    log_prob : np.ndarray [shape=(T, m)]
        `log_prob[t, s]` is the conditional log-likelihood
        log P[X = X(t) | State(t) = s]

    log_trans : np.ndarray [shape=(m, m)]
        The log transition matrix
        `log_trans[i, j]` = log P[State(t+1) = j | State(t) = i]

    log_p_init : np.ndarray [shape=(m,)]
        log of the initial state distribution

    state : np.ndarray [shape=(T,), dtype=int]
        Pre-allocated state index array

    value : np.ndarray [shape=(T, m)] float
        Pre-allocated value array

    ptr : np.ndarray [shape=(T, m), dtype=int]
        Pre-allocated pointer array

    Returns
    -------
    None
        All computations are performed in-place on `state, value, ptr`.


def viterbi(prob, transition, p_init=None, return_logp=False):

n_states, n_steps = prob.shape<EOL>if transition.shape != (n_states, n_states):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(transition.shape,<EOL>(n_states, n_states)))<EOL><DEDENT>if np.any(transition < <NUM_LIT:0>) or not np.allclose(transition.sum(axis=<NUM_LIT:1>), <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>if np.any(prob < <NUM_LIT:0>) or np.any(prob > <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>states = np.zeros(n_steps, dtype=int)<EOL>values = np.zeros((n_steps, n_states), dtype=float)<EOL>ptr = np.zeros((n_steps, n_states), dtype=int)<EOL>epsilon = np.finfo(prob.dtype).tiny<EOL>log_trans = np.log(transition + epsilon)<EOL>log_prob = np.log(prob.T + epsilon)<EOL>if p_init is None:<EOL><INDENT>p_init = np.empty(n_states)<EOL>p_init.fill(<NUM_LIT:1.>/n_states)<EOL><DEDENT>elif np.any(p_init < <NUM_LIT:0>) or not np.allclose(p_init.sum(), <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(p_init))<EOL><DEDENT>log_p_init = np.log(p_init + epsilon)<EOL>_viterbi(log_prob, log_trans, log_p_init, states, values, ptr)<EOL>if return_logp:<EOL><INDENT>return states, values[-<NUM_LIT:1>, states[-<NUM_LIT:1>]]<EOL><DEDENT>return states<EOL>

Viterbi decoding from observation likelihoods.

    Given a sequence of observation likelihoods `prob[s, t]`,
    indicating the conditional likelihood of seeing the observation
    at time `t` from state `s`, and a transition matrix
    `transition[i, j]` which encodes the conditional probability of
    moving from state `i` to state `j`, the Viterbi algorithm [1]_ computes
    the most likely sequence of states from the observations.

    .. [1] Viterbi, Andrew. "Error bounds for convolutional codes and an
        asymptotically optimum decoding algorithm."
        IEEE transactions on Information Theory 13.2 (1967): 260-269.

    Parameters
    ----------
    prob : np.ndarray [shape=(n_states, n_steps), non-negative]
        `prob[s, t]` is the probability of observation at time `t`
        being generated by state `s`.

    transition : np.ndarray [shape=(n_states, n_states), non-negative]
        `transition[i, j]` is the probability of a transition from i->j.
        Each row must sum to 1.

    p_init : np.ndarray [shape=(n_states,)]
        Optional: initial state distribution.
        If not provided, a uniform distribution is assumed.

    return_logp : bool
        If `True`, return the log-likelihood of the state sequence.

    Returns
    -------
    Either `states` or `(states, logp)`:

    states : np.ndarray [shape=(n_steps,)]
        The most likely state sequence.

    logp : scalar [float]
        If `return_logp=True`, the log probability of `states` given
        the observations.

    See Also
    --------
    viterbi_discriminative : Viterbi decoding from state likelihoods

    Examples
    --------
    Example from https://en.wikipedia.org/wiki/Viterbi_algorithm#Example

    In this example, we have two states ``healthy`` and ``fever``, with
    initial probabilities 60% and 40%.

    We have three observation possibilities: ``normal``, ``cold``, and
    ``dizzy``, whose probabilities given each state are:

    ``healthy => {normal: 50%, cold: 40%, dizzy: 10%}`` and
    ``fever => {normal: 10%, cold: 30%, dizzy: 60%}``

    Finally, we have transition probabilities:

    ``healthy => healthy (70%)`` and
    ``fever => fever (60%)``.

    Over three days, we observe the sequence ``[normal, cold, dizzy]``,
    and wish to know the maximum likelihood assignment of states for the
    corresponding days, which we compute with the Viterbi algorithm below.

    >>> p_init = np.array([0.6, 0.4])
    >>> p_emit = np.array([[0.5, 0.4, 0.1],
    ...                    [0.1, 0.3, 0.6]])
    >>> p_trans = np.array([[0.7, 0.3], [0.4, 0.6]])
    >>> path, logp = librosa.sequence.viterbi(p_emit, p_trans, p_init,
    ...                                       return_logp=True)
    >>> print(logp, path)
    -4.19173690823075 [0 0 1]


def viterbi_discriminative(prob, transition, p_state=None, p_init=None, return_logp=False):

n_states, n_steps = prob.shape<EOL>if transition.shape != (n_states, n_states):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(transition.shape,<EOL>(n_states, n_states)))<EOL><DEDENT>if np.any(transition < <NUM_LIT:0>) or not np.allclose(transition.sum(axis=<NUM_LIT:1>), <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>if np.any(prob < <NUM_LIT:0>) or not np.allclose(prob.sum(axis=<NUM_LIT:0>), <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>states = np.zeros(n_steps, dtype=int)<EOL>values = np.zeros((n_steps, n_states), dtype=float)<EOL>ptr = np.zeros((n_steps, n_states), dtype=int)<EOL>epsilon = np.finfo(prob.dtype).tiny<EOL>if p_state is None:<EOL><INDENT>p_state = np.empty(n_states)<EOL>p_state.fill(<NUM_LIT:1.>/n_states)<EOL><DEDENT>elif p_state.shape != (n_states,):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(p_state.shape))<EOL><DEDENT>elif np.any(p_state < <NUM_LIT:0>) or not np.allclose(p_state.sum(axis=-<NUM_LIT:1>), <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(p_state))<EOL><DEDENT>log_trans = np.log(transition + epsilon)<EOL>log_marginal = np.log(p_state + epsilon)<EOL>log_prob = np.log(prob.T + epsilon) - log_marginal<EOL>if p_init is None:<EOL><INDENT>p_init = np.empty(n_states)<EOL>p_init.fill(<NUM_LIT:1.>/n_states)<EOL><DEDENT>elif np.any(p_init < <NUM_LIT:0>) or not np.allclose(p_init.sum(), <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(p_init))<EOL><DEDENT>log_p_init = np.log(p_init + epsilon)<EOL>_viterbi(log_prob, log_trans, log_p_init, states, values, ptr)<EOL>if return_logp:<EOL><INDENT>return states, values[-<NUM_LIT:1>, states[-<NUM_LIT:1>]]<EOL><DEDENT>return states<EOL>

Viterbi decoding from discriminative state predictions.

    Given a sequence of conditional state predictions `prob[s, t]`,
    indicating the conditional likelihood of state `s` given the
    observation at time `t`, and a transition matrix `transition[i, j]`
    which encodes the conditional probability of moving from state `i`
    to state `j`, the Viterbi algorithm computes the most likely sequence
    of states from the observations.

    This implementation uses the standard Viterbi decoding algorithm
    for observation likelihood sequences, under the assumption that
    `P[Obs(t) | State(t) = s]` is proportional to
    `P[State(t) = s | Obs(t)] / P[State(t) = s]`, where the denominator
    is the marginal probability of state `s` occurring as given by `p_state`.

    Parameters
    ----------
    prob : np.ndarray [shape=(n_states, n_steps), non-negative]
        `prob[s, t]` is the probability of state `s` conditional on
        the observation at time `t`.
        Must be non-negative and sum to 1 along each column.

    transition : np.ndarray [shape=(n_states, n_states), non-negative]
        `transition[i, j]` is the probability of a transition from i->j.
        Each row must sum to 1.

    p_state : np.ndarray [shape=(n_states,)]
        Optional: marginal probability distribution over states,
        must be non-negative and sum to 1.
        If not provided, a uniform distribution is assumed.

    p_init : np.ndarray [shape=(n_states,)]
        Optional: initial state distribution.
        If not provided, it is assumed to be uniform.

    return_logp : bool
        If `True`, return the log-likelihood of the state sequence.

    Returns
    -------
    Either `states` or `(states, logp)`:

    states : np.ndarray [shape=(n_steps,)]
        The most likely state sequence.

    logp : scalar [float]
        If `return_logp=True`, the log probability of `states` given
        the observations.

    See Also
    --------
    viterbi : Viterbi decoding from observation likelihoods
    viterbi_binary: Viterbi decoding for multi-label, conditional state likelihoods

    Examples
    --------
    This example constructs a simple, template-based discriminative chord estimator,
    using CENS chroma as input features.

    .. note:: this chord model is not accurate enough to use in practice. It is only
            intended to demonstrate how to use discriminative Viterbi decoding.

    >>> # Create templates for major, minor, and no-chord qualities
    >>> maj_template = np.array([1,0,0, 0,1,0, 0,1,0, 0,0,0])
    >>> min_template = np.array([1,0,0, 1,0,0, 0,1,0, 0,0,0])
    >>> N_template   = np.array([1,1,1, 1,1,1, 1,1,1, 1,1,1.]) / 4.
    >>> # Generate the weighting matrix that maps chroma to labels
    >>> weights = np.zeros((25, 12), dtype=float)
    >>> labels = ['C:maj', 'C#:maj', 'D:maj', 'D#:maj', 'E:maj', 'F:maj',
    ...           'F#:maj', 'G:maj', 'G#:maj', 'A:maj', 'A#:maj', 'B:maj',
    ...           'C:min', 'C#:min', 'D:min', 'D#:min', 'E:min', 'F:min',
    ...           'F#:min', 'G:min', 'G#:min', 'A:min', 'A#:min', 'B:min',
    ...           'N']
    >>> for c in range(12):
    ...     weights[c, :] = np.roll(maj_template, c) # c:maj
    ...     weights[c + 12, :] = np.roll(min_template, c)  # c:min
    >>> weights[-1] = N_template  # the last row is the no-chord class
    >>> # Make a self-loop transition matrix over 25 states
    >>> trans = librosa.sequence.transition_loop(25, 0.9)

    >>> # Load in audio and make features
    >>> y, sr = librosa.load(librosa.util.example_audio_file())
    >>> chroma = librosa.feature.chroma_cens(y=y, sr=sr, bins_per_octave=36)
    >>> # Map chroma (observations) to class (state) likelihoods
    >>> probs = np.exp(weights.dot(chroma))  # P[class | chroma] proportional to exp(template' chroma)
    >>> probs /= probs.sum(axis=0, keepdims=True)  # probabilities must sum to 1 in each column
    >>> # Compute independent frame-wise estimates
    >>> chords_ind = np.argmax(probs, axis=0)
    >>> # And viterbi estimates
    >>> chords_vit = librosa.sequence.viterbi_discriminative(probs, trans)

    >>> # Plot the features and prediction map
    >>> import matplotlib.pyplot as plt
    >>> plt.figure(figsize=(10, 6))
    >>> plt.subplot(2,1,1)
    >>> librosa.display.specshow(chroma, x_axis='time', y_axis='chroma')
    >>> plt.colorbar()
    >>> plt.subplot(2,1,2)
    >>> librosa.display.specshow(weights, x_axis='chroma')
    >>> plt.yticks(np.arange(25) + 0.5, labels)
    >>> plt.ylabel('Chord')
    >>> plt.colorbar()
    >>> plt.tight_layout()

    >>> # And plot the results
    >>> plt.figure(figsize=(10, 4))
    >>> librosa.display.specshow(probs, x_axis='time', cmap='gray')
    >>> plt.colorbar()
    >>> times = librosa.frames_to_time(np.arange(len(chords_vit)))
    >>> plt.scatter(times, chords_ind + 0.75, color='lime', alpha=0.5, marker='+', s=15, label='Independent')
    >>> plt.scatter(times, chords_vit + 0.25, color='deeppink', alpha=0.5, marker='o', s=15, label='Viterbi')
    >>> plt.yticks(0.5 + np.unique(chords_vit), [labels[i] for i in np.unique(chords_vit)], va='center')
    >>> plt.legend(loc='best')
    >>> plt.tight_layout()


def viterbi_binary(prob, transition, p_state=None, p_init=None, return_logp=False):

prob = np.atleast_2d(prob)<EOL>n_states, n_steps = prob.shape<EOL>if transition.shape == (<NUM_LIT:2>, <NUM_LIT:2>):<EOL><INDENT>transition = np.tile(transition, (n_states, <NUM_LIT:1>, <NUM_LIT:1>))<EOL><DEDENT>elif transition.shape != (n_states, <NUM_LIT:2>, <NUM_LIT:2>):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>'.format(transition.shape, (n_states)))<EOL><DEDENT>if np.any(transition < <NUM_LIT:0>) or not np.allclose(transition.sum(axis=-<NUM_LIT:1>), <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>if np.any(prob < <NUM_LIT:0>) or np.any(prob > <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if p_state is None:<EOL><INDENT>p_state = np.empty(n_states)<EOL>p_state.fill(<NUM_LIT:0.5>)<EOL><DEDENT>else:<EOL><INDENT>p_state = np.atleast_1d(p_state)<EOL><DEDENT>if p_state.shape != (n_states,) or np.any(p_state < <NUM_LIT:0>) or np.any(p_state > <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(p_state))<EOL><DEDENT>if p_init is None:<EOL><INDENT>p_init = np.empty(n_states)<EOL>p_init.fill(<NUM_LIT:0.5>)<EOL><DEDENT>else:<EOL><INDENT>p_init = np.atleast_1d(p_init)<EOL><DEDENT>if p_init.shape != (n_states,) or np.any(p_init < <NUM_LIT:0>) or np.any(p_init > <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(p_init))<EOL><DEDENT>states = np.empty((n_states, n_steps), dtype=int)<EOL>logp = np.empty(n_states)<EOL>prob_binary = np.empty((<NUM_LIT:2>, n_steps))<EOL>p_state_binary = np.empty(<NUM_LIT:2>)<EOL>p_init_binary = np.empty(<NUM_LIT:2>)<EOL>for state in range(n_states):<EOL><INDENT>prob_binary[<NUM_LIT:0>] = <NUM_LIT:1> - prob[state]<EOL>prob_binary[<NUM_LIT:1>] = prob[state]<EOL>p_state_binary[<NUM_LIT:0>] = <NUM_LIT:1> - p_state[state]<EOL>p_state_binary[<NUM_LIT:1>] = p_state[state]<EOL>p_init_binary[<NUM_LIT:0>] = <NUM_LIT:1> - p_init[state]<EOL>p_init_binary[<NUM_LIT:1>] = p_init[state]<EOL>states[state, :], logp[state] = viterbi_discriminative(prob_binary,<EOL>transition[state],<EOL>p_state=p_state_binary,<EOL>p_init=p_init_binary,<EOL>return_logp=True)<EOL><DEDENT>if return_logp:<EOL><INDENT>return states, logp<EOL><DEDENT>return states<EOL>

Viterbi decoding from binary (multi-label), discriminative state predictions.

    Given a sequence of conditional state predictions `prob[s, t]`,
    indicating the conditional likelihood of state `s` being active
    conditional on observation at time `t`, and a 2*2 transition matrix
    `transition` which encodes the conditional probability of moving from
    state `s` to state `~s` (not-`s`), the Viterbi algorithm computes the
    most likely sequence of states from the observations.

    This function differs from `viterbi_discriminative` in that it does not assume the
    states to be mutually exclusive.  `viterbi_binary` is implemented by
    transforming the multi-label decoding problem to a collection
    of binary Viterbi problems (one for each *state* or label).

    The output is a binary matrix `states[s, t]` indicating whether each
    state `s` is active at time `t`.

    Parameters
    ----------
    prob : np.ndarray [shape=(n_steps,) or (n_states, n_steps)], non-negative
        `prob[s, t]` is the probability of state `s` being active
        conditional on the observation at time `t`.
        Must be non-negative and less than 1.

        If `prob` is 1-dimensional, it is expanded to shape `(1, n_steps)`.

    transition : np.ndarray [shape=(2, 2) or (n_states, 2, 2)], non-negative
        If 2-dimensional, the same transition matrix is applied to each sub-problem.
        `transition[0, i]` is the probability of the state going from inactive to `i`,
        `transition[1, i]` is the probability of the state going from active to `i`.
        Each row must sum to 1.

        If 3-dimensional, `transition[s]` is interpreted as the 2x2 transition matrix
        for state label `s`.

    p_state : np.ndarray [shape=(n_states,)]
        Optional: marginal probability for each state (between [0,1]).
        If not provided, a uniform distribution (0.5 for each state)
        is assumed.

    p_init : np.ndarray [shape=(n_states,)]
        Optional: initial state distribution.
        If not provided, it is assumed to be uniform.

    return_logp : bool
        If `True`, return the log-likelihood of the state sequence.

    Returns
    -------
    Either `states` or `(states, logp)`:

    states : np.ndarray [shape=(n_states, n_steps)]
        The most likely state sequence.

    logp : np.ndarray [shape=(n_states,)]
        If `return_logp=True`, the log probability of each state activation
        sequence `states`

    See Also
    --------
    viterbi : Viterbi decoding from observation likelihoods
    viterbi_discriminative : Viterbi decoding for discriminative (mutually exclusive) state predictions

    Examples
    --------
    In this example, we have a sequence of binary state likelihoods that we want to de-noise
    under the assumption that state changes are relatively uncommon.  Positive predictions
    should only be retained if they persist for multiple steps, and any transient predictions
    should be considered as errors.  This use case arises frequently in problems such as
    instrument recognition, where state activations tend to be stable over time, but subject
    to abrupt changes (e.g., when an instrument joins the mix).

    We assume that the 0 state has a self-transition probability of 90%, and the 1 state
    has a self-transition probability of 70%.  We assume the marginal and initial
    probability of either state is 50%.

    >>> trans = np.array([[0.9, 0.1], [0.3, 0.7]])
    >>> prob = np.array([0.1, 0.7, 0.4, 0.3, 0.8, 0.9, 0.8, 0.2, 0.6, 0.3])
    >>> librosa.sequence.viterbi_binary(prob, trans, p_state=0.5, p_init=0.5)
    array([[0, 0, 0, 0, 1, 1, 1, 0, 0, 0]])


if not isinstance(n_states, int) or n_states <= <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>transition = np.empty((n_states, n_states), dtype=np.float)<EOL>transition.fill(<NUM_LIT:1.>/n_states)<EOL>return transition<EOL>

Construct a uniform transition matrix over `n_states`.

    Parameters
    ----------
    n_states : int > 0
        The number of states

    Returns
    -------
    transition : np.ndarray [shape=(n_states, n_states)]
        `transition[i, j] = 1./n_states`

    Examples
    --------

    >>> librosa.sequence.transition_uniform(3)
    array([[0.333, 0.333, 0.333],
           [0.333, 0.333, 0.333],
           [0.333, 0.333, 0.333]])


if not isinstance(n_states, int) or n_states <= <NUM_LIT:1>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>transition = np.empty((n_states, n_states), dtype=np.float)<EOL>prob = np.asarray(prob, dtype=np.float)<EOL>if prob.ndim == <NUM_LIT:0>:<EOL><INDENT>prob = np.tile(prob, n_states)<EOL><DEDENT>if prob.shape != (n_states,):<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(prob, n_states))<EOL><DEDENT>if np.any(prob < <NUM_LIT:0>) or np.any(prob > <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(prob))<EOL><DEDENT>for i, prob_i in enumerate(prob):<EOL><INDENT>transition[i] = (<NUM_LIT:1.> - prob_i) / (n_states - <NUM_LIT:1>)<EOL>transition[i, i] = prob_i<EOL><DEDENT>return transition<EOL>

Construct a self-loop transition matrix over `n_states`.

    The transition matrix will have the following properties:

        - `transition[i, i] = p` for all i
        - `transition[i, j] = (1 - p) / (n_states - 1)` for all `j != i`

    This type of transition matrix is appropriate when states tend to be
    locally stable, and there is no additional structure between different
    states.  This is primarily useful for de-noising frame-wise predictions.

    Parameters
    ----------
    n_states : int > 1
        The number of states

    prob : float in [0, 1] or iterable, length=n_states
        If a scalar, this is the probability of a self-transition.

        If a vector of length `n_states`, `p[i]` is the probability of state `i`'s self-transition.

    Returns
    -------
    transition : np.ndarray [shape=(n_states, n_states)]
        The transition matrix

    Examples
    --------
    >>> librosa.sequence.transition_loop(3, 0.5)
    array([[0.5 , 0.25, 0.25],
           [0.25, 0.5 , 0.25],
           [0.25, 0.25, 0.5 ]])

    >>> librosa.sequence.transition_loop(3, [0.8, 0.5, 0.25])
    array([[0.8  , 0.1  , 0.1  ],
           [0.25 , 0.5  , 0.25 ],
           [0.375, 0.375, 0.25 ]])


if not isinstance(n_states, int) or n_states <= <NUM_LIT:1>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>transition = np.zeros((n_states, n_states), dtype=np.float)<EOL>prob = np.asarray(prob, dtype=np.float)<EOL>if prob.ndim == <NUM_LIT:0>:<EOL><INDENT>prob = np.tile(prob, n_states)<EOL><DEDENT>if prob.shape != (n_states,):<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(prob, n_states))<EOL><DEDENT>if np.any(prob < <NUM_LIT:0>) or np.any(prob > <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(prob))<EOL><DEDENT>for i, prob_i in enumerate(prob):<EOL><INDENT>transition[i, np.mod(i + <NUM_LIT:1>, n_states)] = <NUM_LIT:1.> - prob_i<EOL>transition[i, i] = prob_i<EOL><DEDENT>return transition<EOL>

Construct a cyclic transition matrix over `n_states`.

    The transition matrix will have the following properties:

        - `transition[i, i] = p`
        - `transition[i, i + 1] = (1 - p)`

    This type of transition matrix is appropriate for state spaces
    with cyclical structure, such as metrical position within a bar.
    For example, a song in 4/4 time has state transitions of the form

        1->{1, 2}, 2->{2, 3}, 3->{3, 4}, 4->{4, 1}.

    Parameters
    ----------
    n_states : int > 1
        The number of states

    prob : float in [0, 1] or iterable, length=n_states
        If a scalar, this is the probability of a self-transition.

        If a vector of length `n_states`, `p[i]` is the probability of state
        `i`'s self-transition.

    Returns
    -------
    transition : np.ndarray [shape=(n_states, n_states)]
        The transition matrix

    Examples
    --------
    >>> librosa.sequence.transition_cycle(4, 0.9)
    array([[0.9, 0.1, 0. , 0. ],
           [0. , 0.9, 0.1, 0. ],
           [0. , 0. , 0.9, 0.1],
           [0.1, 0. , 0. , 0.9]])


def transition_local(n_states, width, window='<STR_LIT>', wrap=False):

if not isinstance(n_states, int) or n_states <= <NUM_LIT:1>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>width = np.asarray(width, dtype=int)<EOL>if width.ndim == <NUM_LIT:0>:<EOL><INDENT>width = np.tile(width, n_states)<EOL><DEDENT>if width.shape != (n_states,):<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(width, n_states))<EOL><DEDENT>if np.any(width < <NUM_LIT:1>):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>transition = np.zeros((n_states, n_states), dtype=np.float)<EOL>for i, width_i in enumerate(width):<EOL><INDENT>trans_row = pad_center(get_window(window, width_i, fftbins=False), n_states)<EOL>trans_row = np.roll(trans_row, n_states//<NUM_LIT:2> + i + <NUM_LIT:1>)<EOL>if not wrap:<EOL><INDENT>trans_row[min(n_states, i + width_i//<NUM_LIT:2> + <NUM_LIT:1>):] = <NUM_LIT:0><EOL>trans_row[:max(<NUM_LIT:0>, i - width_i//<NUM_LIT:2>)] = <NUM_LIT:0><EOL><DEDENT>transition[i] = trans_row<EOL><DEDENT>transition /= transition.sum(axis=<NUM_LIT:1>, keepdims=True)<EOL>return transition<EOL>

Construct a localized transition matrix.

    The transition matrix will have the following properties:

        - `transition[i, j] = 0` if `|i - j| > width`
        - `transition[i, i]` is maximal
        - `transition[i, i - width//2 : i + width//2]` has shape `window`

    This type of transition matrix is appropriate for state spaces
    that discretely approximate continuous variables, such as in fundamental
    frequency estimation.

    Parameters
    ----------
    n_states : int > 1
        The number of states

    width : int >= 1 or iterable
        The maximum number of states to treat as "local".
        If iterable, it should have length equal to `n_states`,
        and specify the width independently for each state.

    window : str, callable, or window specification
        The window function to determine the shape of the "local" distribution.

        Any window specification supported by `filters.get_window` will work here.

        .. note:: Certain windows (e.g., 'hann') are identically 0 at the boundaries,
            so and effectively have `width-2` non-zero values.  You may have to expand
            `width` to get the desired behavior.

    wrap : bool
        If `True`, then state locality `|i - j|` is computed modulo `n_states`.
        If `False` (default), then locality is absolute.

    See Also
    --------
    filters.get_window

    Returns
    -------
    transition : np.ndarray [shape=(n_states, n_states)]
        The transition matrix

    Examples
    --------

    Triangular distributions with and without wrapping

    >>> librosa.sequence.transition_local(5, 3, window='triangle', wrap=False)
    array([[0.667, 0.333, 0.   , 0.   , 0.   ],
           [0.25 , 0.5  , 0.25 , 0.   , 0.   ],
           [0.   , 0.25 , 0.5  , 0.25 , 0.   ],
           [0.   , 0.   , 0.25 , 0.5  , 0.25 ],
           [0.   , 0.   , 0.   , 0.333, 0.667]])

    >>> librosa.sequence.transition_local(5, 3, window='triangle', wrap=True)
    array([[0.5 , 0.25, 0.  , 0.  , 0.25],
           [0.25, 0.5 , 0.25, 0.  , 0.  ],
           [0.  , 0.25, 0.5 , 0.25, 0.  ],
           [0.  , 0.  , 0.25, 0.5 , 0.25],
           [0.25, 0.  , 0.  , 0.25, 0.5 ]])

    Uniform local distributions with variable widths and no wrapping

    >>> librosa.sequence.transition_local(5, [1, 2, 3, 3, 1], window='ones', wrap=False)
    array([[1.   , 0.   , 0.   , 0.   , 0.   ],
           [0.5  , 0.5  , 0.   , 0.   , 0.   ],
           [0.   , 0.333, 0.333, 0.333, 0.   ],
           [0.   , 0.   , 0.333, 0.333, 0.333],
           [0.   , 0.   , 0.   , 0.   , 1.   ]])


def cmap(data, robust=True, cmap_seq='<STR_LIT>', cmap_bool='<STR_LIT>', cmap_div='<STR_LIT>'):

data = np.atleast_1d(data)<EOL>if data.dtype == '<STR_LIT:bool>':<EOL><INDENT>return get_cmap(cmap_bool)<EOL><DEDENT>data = data[np.isfinite(data)]<EOL>if robust:<EOL><INDENT>min_p, max_p = <NUM_LIT:2>, <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>min_p, max_p = <NUM_LIT:0>, <NUM_LIT:100><EOL><DEDENT>max_val = np.percentile(data, max_p)<EOL>min_val = np.percentile(data, min_p)<EOL>if min_val >= <NUM_LIT:0> or max_val <= <NUM_LIT:0>:<EOL><INDENT>return get_cmap(cmap_seq)<EOL><DEDENT>return get_cmap(cmap_div)<EOL>

Get a default colormap from the given data.

    If the data is boolean, use a black and white colormap.

    If the data has both positive and negative values,
    use a diverging colormap.

    Otherwise, use a sequential colormap.

    Parameters
    ----------
    data : np.ndarray
        Input data

    robust : bool
        If True, discard the top and bottom 2% of data when calculating
        range.

    cmap_seq : str
        The sequential colormap name

    cmap_bool : str
        The boolean colormap name

    cmap_div : str
        The diverging colormap name

    Returns
    -------
    cmap : matplotlib.colors.Colormap
        The colormap to use for `data`

    See Also
    --------
    matplotlib.pyplot.colormaps


return util.frame(x, hop_length=hop, frame_length=hop).max(axis=<NUM_LIT:0>)<EOL>

Compute the max-envelope of x at a stride/frame length of h


def waveplot(y, sr=<NUM_LIT>, max_points=<NUM_LIT>, x_axis='<STR_LIT:time>', offset=<NUM_LIT:0.0>,<EOL>max_sr=<NUM_LIT:1000>, ax=None, **kwargs):

util.valid_audio(y, mono=False)<EOL>if not (isinstance(max_sr, int) and max_sr > <NUM_LIT:0>):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>target_sr = sr<EOL>hop_length = <NUM_LIT:1><EOL>if max_points is not None:<EOL><INDENT>if max_points <= <NUM_LIT:0>:<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if max_points < y.shape[-<NUM_LIT:1>]:<EOL><INDENT>target_sr = min(max_sr, (sr * y.shape[-<NUM_LIT:1>]) // max_points)<EOL><DEDENT>hop_length = sr // target_sr<EOL>if y.ndim == <NUM_LIT:1>:<EOL><INDENT>y = __envelope(y, hop_length)<EOL><DEDENT>else:<EOL><INDENT>y = np.vstack([__envelope(_, hop_length) for _ in y])<EOL><DEDENT><DEDENT>if y.ndim > <NUM_LIT:1>:<EOL><INDENT>y_top = y[<NUM_LIT:0>]<EOL>y_bottom = -y[<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>y_top = y<EOL>y_bottom = -y<EOL><DEDENT>axes = __check_axes(ax)<EOL>kwargs.setdefault('<STR_LIT>', next(axes._get_lines.prop_cycler)['<STR_LIT>'])<EOL>locs = offset + core.frames_to_time(np.arange(len(y_top)),<EOL>sr=sr,<EOL>hop_length=hop_length)<EOL>out = axes.fill_between(locs, y_bottom, y_top, **kwargs)<EOL>axes.set_xlim([locs.min(), locs.max()])<EOL>if x_axis == '<STR_LIT:time>':<EOL><INDENT>axes.xaxis.set_major_formatter(TimeFormatter(lag=False))<EOL>axes.xaxis.set_label_text('<STR_LIT>')<EOL><DEDENT>elif x_axis is None or x_axis in ['<STR_LIT>', '<STR_LIT:none>']:<EOL><INDENT>axes.set_xticks([])<EOL><DEDENT>else:<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(x_axis))<EOL><DEDENT>return out<EOL>

Plot the amplitude envelope of a waveform.

    If `y` is monophonic, a filled curve is drawn between `[-abs(y), abs(y)]`.

    If `y` is stereo, the curve is drawn between `[-abs(y[1]), abs(y[0])]`,
    so that the left and right channels are drawn above and below the axis,
    respectively.

    Long signals (`duration >= max_points`) are down-sampled to at
    most `max_sr` before plotting.

    Parameters
    ----------
    y : np.ndarray [shape=(n,) or (2,n)]
        audio time series (mono or stereo)

    sr : number > 0 [scalar]
        sampling rate of `y`

    max_points : postive number or None
        Maximum number of time-points to plot: if `max_points` exceeds
        the duration of `y`, then `y` is downsampled.

        If `None`, no downsampling is performed.

    x_axis : str {'time', 'off', 'none'} or None
        If 'time', the x-axis is given time tick-marks.

    ax : matplotlib.axes.Axes or None
        Axes to plot on instead of the default `plt.gca()`.

    offset : float
        Horizontal offset (in seconds) to start the waveform plot

    max_sr : number > 0 [scalar]
        Maximum sampling rate for the visualization

    kwargs
        Additional keyword arguments to `matplotlib.pyplot.fill_between`

    Returns
    -------
    pc : matplotlib.collections.PolyCollection
        The PolyCollection created by `fill_between`.

    See also
    --------
    librosa.core.resample
    matplotlib.pyplot.fill_between

    Examples
    --------
    Plot a monophonic waveform

    >>> import matplotlib.pyplot as plt
    >>> y, sr = librosa.load(librosa.util.example_audio_file(), duration=10)
    >>> plt.figure()
    >>> plt.subplot(3, 1, 1)
    >>> librosa.display.waveplot(y, sr=sr)
    >>> plt.title('Monophonic')

    Or a stereo waveform

    >>> y, sr = librosa.load(librosa.util.example_audio_file(),
    ...                      mono=False, duration=10)
    >>> plt.subplot(3, 1, 2)
    >>> librosa.display.waveplot(y, sr=sr)
    >>> plt.title('Stereo')

    Or harmonic and percussive components with transparency

    >>> y, sr = librosa.load(librosa.util.example_audio_file(), duration=10)
    >>> y_harm, y_perc = librosa.effects.hpss(y)
    >>> plt.subplot(3, 1, 3)
    >>> librosa.display.waveplot(y_harm, sr=sr, alpha=0.25)
    >>> librosa.display.waveplot(y_perc, sr=sr, color='r', alpha=0.5)
    >>> plt.title('Harmonic + Percussive')
    >>> plt.tight_layout()