librosa/core/constantq.py
def icqt(C, sr=22050, hop_length=512, fmin=None, bins_per_octave=12,
         tuning=0.0, filter_scale=1, norm=1, sparsity=0.01, window='hann',
         scale=True, length=None, amin=util.Deprecated(), res_type='fft'):
    '''Compute the inverse constant-Q transform.

    Given a constant-Q transform representation `C` of an audio signal `y`,
    this function produces an approximation `y_hat`.


    Parameters
    ----------
    C : np.ndarray, [shape=(n_bins, n_frames)]
        Constant-Q representation as produced by `core.cqt`

    hop_length : int > 0 [scalar]
        number of samples between successive frames

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

    tuning : float in `[-0.5, 0.5)` [scalar]
        Tuning offset in fractions of a bin (cents).

    filter_scale : float > 0 [scalar]
        Filter scale factor. Small values (<1) use shorter windows
        for improved time resolution.

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

    sparsity : float in [0, 1)
        Sparsify the CQT basis by discarding up to `sparsity`
        fraction of the energy in each basis.

        Set `sparsity=0` to disable sparsification.

    window : str, tuple, number, or function
        Window specification for the basis filters.
        See `filters.get_window` for details.

    scale : bool
        If `True`, scale the CQT response by square-root the length
        of each channel's filter. This is analogous to `norm='ortho'` in FFT.

        If `False`, do not scale the CQT. This is analogous to `norm=None`
        in FFT.

    length : int > 0, optional
        If provided, the output `y` is zero-padded or clipped to exactly
        `length` samples.

    amin : float or None [DEPRECATED]

        .. note:: This parameter is deprecated in 0.7.0 and will be removed in 0.8.0.

    res_type : string
        Resampling mode.  By default, this uses `fft` mode for high-quality 
        reconstruction, but this may be slow depending on your signal duration.
        See `librosa.resample` for supported modes.

    Returns
    -------
    y : np.ndarray, [shape=(n_samples), dtype=np.float]
        Audio time-series reconstructed from the CQT representation.

    See Also
    --------
    cqt
    core.resample

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

    Examples
    --------
    Using default parameters

    >>> y, sr = librosa.load(librosa.util.example_audio_file(), duration=15)
    >>> C = librosa.cqt(y=y, sr=sr)
    >>> y_hat = librosa.icqt(C=C, sr=sr)

    Or with a different hop length and frequency resolution:

    >>> hop_length = 256
    >>> bins_per_octave = 12 * 3
    >>> C = librosa.cqt(y=y, sr=sr, hop_length=256, n_bins=7*bins_per_octave,
    ...                 bins_per_octave=bins_per_octave)
    >>> y_hat = librosa.icqt(C=C, sr=sr, hop_length=hop_length,
    ...                 bins_per_octave=bins_per_octave)
    '''

    if fmin is None:
        fmin = note_to_hz('C1')

    # Get the top octave of frequencies
    n_bins = len(C)

    freqs = cqt_frequencies(n_bins, fmin,
                            bins_per_octave=bins_per_octave,
                            tuning=tuning)[-bins_per_octave:]

    n_filters = min(n_bins, bins_per_octave)

    fft_basis, n_fft, lengths = __cqt_filter_fft(sr, np.min(freqs),
                                                 n_filters,
                                                 bins_per_octave,
                                                 tuning,
                                                 filter_scale,
                                                 norm,
                                                 sparsity=sparsity,
                                                 window=window)

    if hop_length > min(lengths):
        warnings.warn('hop_length={} exceeds minimum CQT filter length={:.3f}.\n'
                      'This will probably cause unpleasant acoustic artifacts. '
                      'Consider decreasing your hop length or increasing the frequency resolution of your CQT.'.format(hop_length, min(lengths)))

    # The basis gets renormalized by the effective window length above;
    # This step undoes that
    fft_basis = fft_basis.todense() * n_fft / lengths[:, np.newaxis]

    # This step conjugate-transposes the filter
    inv_basis = fft_basis.H

    # How many octaves do we have?
    n_octaves = int(np.ceil(float(n_bins) / bins_per_octave))

    y = None
    for octave in range(n_octaves - 1, -1, -1):
        slice_ = slice(-(octave+1) * bins_per_octave - 1,
                       -(octave) * bins_per_octave - 1)

        # Slice this octave
        C_oct = C[slice_]
        inv_oct = inv_basis[:, -C_oct.shape[0]:]

        oct_hop = hop_length // 2**octave

        # Apply energy corrections
        if scale:
            C_scale = np.sqrt(lengths[-C_oct.shape[0]:, np.newaxis]) / n_fft
        else:
            C_scale = lengths[-C_oct.shape[0]:, np.newaxis] * np.sqrt(2**octave) / n_fft

        # Inverse-project the basis for each octave
        D_oct = inv_oct.dot(C_oct / C_scale)

        # Inverse-STFT that response
        y_oct = istft(D_oct, window='ones', hop_length=oct_hop)

        # Up-sample that octave
        if y is None:
            y = y_oct
        else:
            # Up-sample the previous buffer and add in the new one
            # Scipy-resampling is fast here, since it's a power-of-two relation
            y = audio.resample(y, 1, 2, scale=True, res_type=res_type, fix=False)

            y[:len(y_oct)] += y_oct

    if length:
        y = util.fix_length(y, length)

    return y
def icqt(C, sr=22050, hop_length=512, fmin=None, bins_per_octave=12,
         tuning=0.0, filter_scale=1, norm=1, sparsity=0.01, window='hann',
         scale=True, length=None, amin=util.Deprecated(), res_type='fft'):
    '''Compute the inverse constant-Q transform.

    Given a constant-Q transform representation `C` of an audio signal `y`,
    this function produces an approximation `y_hat`.


    Parameters
    ----------
    C : np.ndarray, [shape=(n_bins, n_frames)]
        Constant-Q representation as produced by `core.cqt`

    hop_length : int > 0 [scalar]
        number of samples between successive frames

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

    tuning : float in `[-0.5, 0.5)` [scalar]
        Tuning offset in fractions of a bin (cents).

    filter_scale : float > 0 [scalar]
        Filter scale factor. Small values (<1) use shorter windows
        for improved time resolution.

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

    sparsity : float in [0, 1)
        Sparsify the CQT basis by discarding up to `sparsity`
        fraction of the energy in each basis.

        Set `sparsity=0` to disable sparsification.

    window : str, tuple, number, or function
        Window specification for the basis filters.
        See `filters.get_window` for details.

    scale : bool
        If `True`, scale the CQT response by square-root the length
        of each channel's filter. This is analogous to `norm='ortho'` in FFT.

        If `False`, do not scale the CQT. This is analogous to `norm=None`
        in FFT.

    length : int > 0, optional
        If provided, the output `y` is zero-padded or clipped to exactly
        `length` samples.

    amin : float or None [DEPRECATED]

        .. note:: This parameter is deprecated in 0.7.0 and will be removed in 0.8.0.

    res_type : string
        Resampling mode.  By default, this uses `fft` mode for high-quality 
        reconstruction, but this may be slow depending on your signal duration.
        See `librosa.resample` for supported modes.

    Returns
    -------
    y : np.ndarray, [shape=(n_samples), dtype=np.float]
        Audio time-series reconstructed from the CQT representation.

    See Also
    --------
    cqt
    core.resample

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

    Examples
    --------
    Using default parameters

    >>> y, sr = librosa.load(librosa.util.example_audio_file(), duration=15)
    >>> C = librosa.cqt(y=y, sr=sr)
    >>> y_hat = librosa.icqt(C=C, sr=sr)

    Or with a different hop length and frequency resolution:

    >>> hop_length = 256
    >>> bins_per_octave = 12 * 3
    >>> C = librosa.cqt(y=y, sr=sr, hop_length=256, n_bins=7*bins_per_octave,
    ...                 bins_per_octave=bins_per_octave)
    >>> y_hat = librosa.icqt(C=C, sr=sr, hop_length=hop_length,
    ...                 bins_per_octave=bins_per_octave)
    '''

    if fmin is None:
        fmin = note_to_hz('C1')

    # Get the top octave of frequencies
    n_bins = len(C)

    freqs = cqt_frequencies(n_bins, fmin,
                            bins_per_octave=bins_per_octave,
                            tuning=tuning)[-bins_per_octave:]

    n_filters = min(n_bins, bins_per_octave)

    fft_basis, n_fft, lengths = __cqt_filter_fft(sr, np.min(freqs),
                                                 n_filters,
                                                 bins_per_octave,
                                                 tuning,
                                                 filter_scale,
                                                 norm,
                                                 sparsity=sparsity,
                                                 window=window)

    if hop_length > min(lengths):
        warnings.warn('hop_length={} exceeds minimum CQT filter length={:.3f}.\n'
                      'This will probably cause unpleasant acoustic artifacts. '
                      'Consider decreasing your hop length or increasing the frequency resolution of your CQT.'.format(hop_length, min(lengths)))

    # The basis gets renormalized by the effective window length above;
    # This step undoes that
    fft_basis = fft_basis.todense() * n_fft / lengths[:, np.newaxis]

    # This step conjugate-transposes the filter
    inv_basis = fft_basis.H

    # How many octaves do we have?
    n_octaves = int(np.ceil(float(n_bins) / bins_per_octave))

    y = None
    for octave in range(n_octaves - 1, -1, -1):
        slice_ = slice(-(octave+1) * bins_per_octave - 1,
                       -(octave) * bins_per_octave - 1)

        # Slice this octave
        C_oct = C[slice_]
        inv_oct = inv_basis[:, -C_oct.shape[0]:]

        oct_hop = hop_length // 2**octave

        # Apply energy corrections
        if scale:
            C_scale = np.sqrt(lengths[-C_oct.shape[0]:, np.newaxis]) / n_fft
        else:
            C_scale = lengths[-C_oct.shape[0]:, np.newaxis] * np.sqrt(2**octave) / n_fft

        # Inverse-project the basis for each octave
        D_oct = inv_oct.dot(C_oct / C_scale)

        # Inverse-STFT that response
        y_oct = istft(D_oct, window='ones', hop_length=oct_hop)

        # Up-sample that octave
        if y is None:
            y = y_oct
        else:
            # Up-sample the previous buffer and add in the new one
            # Scipy-resampling is fast here, since it's a power-of-two relation
            y = audio.resample(y, 1, 2, scale=True, res_type=res_type, fix=False)

            y[:len(y_oct)] += y_oct

    if length:
        y = util.fix_length(y, length)

    return y
Compute the inverse constant-Q transform.

    Given a constant-Q transform representation `C` of an audio signal `y`,
    this function produces an approximation `y_hat`.


    Parameters
    ----------
    C : np.ndarray, [shape=(n_bins, n_frames)]
        Constant-Q representation as produced by `core.cqt`

    hop_length : int > 0 [scalar]
        number of samples between successive frames

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

    tuning : float in `[-0.5, 0.5)` [scalar]
        Tuning offset in fractions of a bin (cents).

    filter_scale : float > 0 [scalar]
        Filter scale factor. Small values (<1) use shorter windows
        for improved time resolution.

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

    sparsity : float in [0, 1)
        Sparsify the CQT basis by discarding up to `sparsity`
        fraction of the energy in each basis.

        Set `sparsity=0` to disable sparsification.

    window : str, tuple, number, or function
        Window specification for the basis filters.
        See `filters.get_window` for details.

    scale : bool
        If `True`, scale the CQT response by square-root the length
        of each channel's filter. This is analogous to `norm='ortho'` in FFT.

        If `False`, do not scale the CQT. This is analogous to `norm=None`
        in FFT.

    length : int > 0, optional
        If provided, the output `y` is zero-padded or clipped to exactly
        `length` samples.

    amin : float or None [DEPRECATED]

        .. note:: This parameter is deprecated in 0.7.0 and will be removed in 0.8.0.

    res_type : string
        Resampling mode.  By default, this uses `fft` mode for high-quality 
        reconstruction, but this may be slow depending on your signal duration.
        See `librosa.resample` for supported modes.

    Returns
    -------
    y : np.ndarray, [shape=(n_samples), dtype=np.float]
        Audio time-series reconstructed from the CQT representation.

    See Also
    --------
    cqt
    core.resample

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

    Examples
    --------
    Using default parameters

    >>> y, sr = librosa.load(librosa.util.example_audio_file(), duration=15)
    >>> C = librosa.cqt(y=y, sr=sr)
    >>> y_hat = librosa.icqt(C=C, sr=sr)

    Or with a different hop length and frequency resolution:

    >>> hop_length = 256
    >>> bins_per_octave = 12 * 3
    >>> C = librosa.cqt(y=y, sr=sr, hop_length=256, n_bins=7*bins_per_octave,
    ...                 bins_per_octave=bins_per_octave)
    >>> y_hat = librosa.icqt(C=C, sr=sr, hop_length=hop_length,
    ...                 bins_per_octave=bins_per_octave)