@cache(level=<NUM_LIT:30>)<EOL>def onset_strength_multi(y=None, sr=<NUM_LIT>, S=None, lag=<NUM_LIT:1>, max_size=<NUM_LIT:1>,<EOL>ref=None, detrend=False, center=True, feature=None,<EOL>aggregate=None, channels=None, **kwargs):
if feature is None:<EOL><INDENT>feature = melspectrogram<EOL>kwargs.setdefault('<STR_LIT>', <NUM_LIT>)<EOL><DEDENT>if aggregate is None:<EOL><INDENT>aggregate = np.mean<EOL><DEDENT>if lag < <NUM_LIT:1> or not isinstance(lag, int):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if max_size < <NUM_LIT:1> or not isinstance(max_size, int):<EOL><INDENT>raise ParameterError('<STR_LIT>')<EOL><DEDENT>if S is None:<EOL><INDENT>S = np.abs(feature(y=y, sr=sr, **kwargs))<EOL>S = core.power_to_db(S)<EOL><DEDENT>n_fft = kwargs.get('<STR_LIT>', <NUM_LIT>)<EOL>hop_length = kwargs.get('<STR_LIT>', <NUM_LIT>)<EOL>S = np.atleast_2d(S)<EOL>if ref is None:<EOL><INDENT>if max_size == <NUM_LIT:1>:<EOL><INDENT>ref = S<EOL><DEDENT>else:<EOL><INDENT>ref = scipy.ndimage.maximum_filter1d(S, max_size, axis=<NUM_LIT:0>)<EOL><DEDENT><DEDENT>elif ref.shape != S.shape:<EOL><INDENT>raise ParameterError('<STR_LIT>'.format(ref.shape, S.shape))<EOL><DEDENT>onset_env = S[:, lag:] - ref[:, :-lag]<EOL>onset_env = np.maximum(<NUM_LIT:0.0>, onset_env)<EOL>pad = True<EOL>if channels is None:<EOL><INDENT>channels = [slice(None)]<EOL><DEDENT>else:<EOL><INDENT>pad = False<EOL><DEDENT>if aggregate:<EOL><INDENT>onset_env = util.sync(onset_env, channels,<EOL>aggregate=aggregate,<EOL>pad=pad, axis=<NUM_LIT:0>)<EOL><DEDENT>pad_width = lag<EOL>if center:<EOL><INDENT>pad_width += n_fft // (<NUM_LIT:2> * hop_length)<EOL><DEDENT>onset_env = np.pad(onset_env, ([<NUM_LIT:0>, <NUM_LIT:0>], [int(pad_width), <NUM_LIT:0>]),<EOL>mode='<STR_LIT>')<EOL>if detrend:<EOL><INDENT>onset_env = scipy.signal.lfilter([<NUM_LIT:1.0>, -<NUM_LIT:1.0>], [<NUM_LIT:1.0>, -<NUM_LIT>],<EOL>onset_env, axis=-<NUM_LIT:1>)<EOL><DEDENT>if center:<EOL><INDENT>onset_env = onset_env[:, :S.shape[<NUM_LIT:1>]]<EOL><DEDENT>return onset_env<EOL>
Compute a spectral flux onset strength envelope across multiple channels.

    Onset strength for channel `i` at time `t` is determined by:

    `mean_{f in channels[i]} max(0, S[f, t+1] - S[f, t])`


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

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

    S        : np.ndarray [shape=(d, m)]
        pre-computed (log-power) spectrogram

    lag      : int > 0
        time lag for computing differences

    max_size : int > 0
        size (in frequency bins) of the local max filter.
        set to `1` to disable filtering.

    ref : None or np.ndarray [shape=(d, m)]
        An optional pre-computed reference spectrum, of the same shape as `S`.
        If not provided, it will be computed from `S`.
        If provided, it will override any local max filtering governed by `max_size`.

    detrend : bool [scalar]
        Filter the onset strength to remove the DC component

    center : bool [scalar]
        Shift the onset function by `n_fft / (2 * hop_length)` frames

    feature : function
        Function for computing time-series features, eg, scaled spectrograms.
        By default, uses `librosa.feature.melspectrogram` with `fmax=11025.0`

    aggregate : function or False
        Aggregation function to use when combining onsets
        at different frequency bins.

        If `False`, then no aggregation is performed.

        Default: `np.mean`

    channels : list or None
        Array of channel boundaries or slice objects.
        If `None`, then a single channel is generated to span all bands.

    kwargs : additional keyword arguments
        Additional parameters to `feature()`, if `S` is not provided.


    Returns
    -------
    onset_envelope   : np.ndarray [shape=(n_channels, m)]
        array containing the onset strength envelope for each specified channel


    Raises
    ------
    ParameterError
        if neither `(y, sr)` nor `S` are provided


    See Also
    --------
    onset_strength

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

    Examples
    --------
    First, load some audio and plot the spectrogram

    >>> import matplotlib.pyplot as plt
    >>> y, sr = librosa.load(librosa.util.example_audio_file(),
    ...                      duration=10.0)
    >>> D = np.abs(librosa.stft(y))
    >>> plt.figure()
    >>> plt.subplot(2, 1, 1)
    >>> librosa.display.specshow(librosa.amplitude_to_db(D, ref=np.max),
    ...                          y_axis='log')
    >>> plt.title('Power spectrogram')

    Construct a standard onset function over four sub-bands

    >>> onset_subbands = librosa.onset.onset_strength_multi(y=y, sr=sr,
    ...                                                     channels=[0, 32, 64, 96, 128])
    >>> plt.subplot(2, 1, 2)
    >>> librosa.display.specshow(onset_subbands, x_axis='time')
    >>> plt.ylabel('Sub-bands')
    >>> plt.title('Sub-band onset strength')