Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何应用二进制掩码和STFT生成音频文件?_Python_Audio_Linear Algebra_Spectrogram_Librosa - Fatal编程技术网

Python 如何应用二进制掩码和STFT生成音频文件?

Python 如何应用二进制掩码和STFT生成音频文件?,python,audio,linear-algebra,spectrogram,librosa,Python,Audio,Linear Algebra,Spectrogram,Librosa,这里的想法是:你可以使用短时傅立叶变换stft从音频文件中生成频谱图。然后,一些人生成了一种称为二进制掩码的东西,以生成不同的音频,即从逆stft中去除背景噪声等 以下是我的理解: stft是一个应用于音频文件的简单公式,它生成的信息可以很容易地显示在频谱图上。 通过取stft矩阵的逆矩阵,并将其乘以一个大小相同的矩阵(二进制矩阵),您可以创建一个包含信息的新矩阵,以生成带有屏蔽声音的音频文件 一旦我做了矩阵乘法,新的音频文件是如何创建的 虽然不多,但以下是我在代码方面得到的: from lib

这里的想法是:你可以使用短时傅立叶变换stft从音频文件中生成频谱图。然后,一些人生成了一种称为二进制掩码的东西,以生成不同的音频,即从逆stft中去除背景噪声等

以下是我的理解:

stft是一个应用于音频文件的简单公式,它生成的信息可以很容易地显示在频谱图上。 通过取stft矩阵的逆矩阵,并将其乘以一个大小相同的矩阵(二进制矩阵),您可以创建一个包含信息的新矩阵,以生成带有屏蔽声音的音频文件

一旦我做了矩阵乘法,新的音频文件是如何创建的

虽然不多,但以下是我在代码方面得到的:

from librosa import load
from librosa.core import stft, istft
y, sample_rate = load('1.wav')
spectrum = stft(y)
back_y = istft(spectrum)

谢谢,这里有一些幻灯片让我走到了这一步。如果您能给我一个python的示例/演示,我将不胜感激。Librosa的STFT功能齐全,因此除非您非常小心地处理频谱,否则您将无法从其istft获得合理的输出

下面是我从头开始编写的一对函数,stft和istft,它们表示正向和反向stft,还有一个助手方法,可以为您提供stft阵列中每个像素的时间和频率位置,以及一个演示:

import numpy as np
import numpy.fft as fft


def stft(x, Nwin, Nfft=None):
    """
    Short-time Fourier transform: convert a 1D vector to a 2D array

    The short-time Fourier transform (STFT) breaks a long vector into disjoint
    chunks (no overlap) and runs an FFT (Fast Fourier Transform) on each chunk.

    The resulting 2D array can 

    Parameters
    ----------
    x : array_like
        Input signal (expected to be real)
    Nwin : int
        Length of each window (chunk of the signal). Should be ≪ `len(x)`.
    Nfft : int, optional
        Zero-pad each chunk to this length before FFT. Should be ≥ `Nwin`,
        (usually with small prime factors, for fastest FFT). Default: `Nwin`.

    Returns
    -------
    out : complex ndarray
        `len(x) // Nwin` by `Nfft` complex array representing the STFT of `x`.

    See also
    --------
    istft : inverse function (convert a STFT array back to a data vector)
    stftbins : time and frequency bins corresponding to `out`
    """
    Nfft = Nfft or Nwin
    Nwindows = x.size // Nwin
    # reshape into array `Nwin` wide, and as tall as possible. This is
    # optimized for C-order (row-major) layouts.
    arr = np.reshape(x[:Nwindows * Nwin], (-1, Nwin))
    stft = fft.rfft(arr, Nfft)
    return stft


def stftbins(x, Nwin, Nfft=None, d=1.0):
    """
    Time and frequency bins corresponding to short-time Fourier transform.

    Call this with the same arguments as `stft`, plus one extra argument: `d`
    sample spacing, to get the time and frequency axes that the output of
    `stft` correspond to.

    Parameters
    ----------
    x : array_like
        same as `stft`
    Nwin : int
        same as `stft`
    Nfft : int, optional
        same as `stft`
    d : float, optional
        Sample spacing of `x` (or 1 / sample frequency), units of seconds.
        Default: 1.0.

    Returns
    -------
    t : ndarray
        Array of length `len(x) // Nwin`, in units of seconds, corresponding to
        the first dimension (height) of the output of `stft`.
    f : ndarray
        Array of length `Nfft`, in units of Hertz, corresponding to the second
        dimension (width) of the output of `stft`.
    """
    Nfft = Nfft or Nwin
    Nwindows = x.size // Nwin
    t = np.arange(Nwindows) * (Nwin * d)
    f = fft.rfftfreq(Nfft, d)
    return t, f


def istft(stftArr, Nwin):
    """
    Inverse short-time Fourier transform (ISTFT)

    Given an array representing the output of `stft`, convert it back to the
    original samples.

    Parameters
    ----------
    stftArr : ndarray
        Output of `stft` (or something the same size)
    Nwin : int
        Same input as `stft`: length of each chunk that the STFT was calculated
        over.

    Returns
    -------
    y : ndarray
        Data samples corresponding to STFT data.

    See also:
    stft : the forward transform
    """
    arr = fft.irfft(stftArr)[:, :Nwin]
    return np.reshape(arr, -1)


if __name__ == '__main__':
    sampleRate = 100.0  # Hertz
    N = 1024
    Nwin = 64

    # Generate a chirp: start frequency at 5 Hz and going down at 2 Hz/s
    time = np.arange(N) / sampleRate  # seconds
    x = np.cos(2 * np.pi * time * (5 - 2 * 0.5 * time))

    # Test with Nfft bigger than Nwin
    Nfft = Nwin * 2
    s = stft(x, Nwin, Nfft=Nfft)
    y = istft(s, Nwin)

    # Make sure the stft and istft are inverses. Caveat: `x` and `y` won't be
    # the same length if `N/Nwin` isn't integral!
    maxerr = np.max(np.abs(x - y))
    assert (maxerr < np.spacing(1) * 10)

    # Test `stftbins`
    t, f = stftbins(x, Nwin, Nfft=Nfft, d=1 / sampleRate)
    assert (len(t) == s.shape[0])
    assert (len(f) == s.shape[1])

    try:
        import pylab as plt
        plt.imshow(np.abs(s), aspect="auto", extent=[f[0], f[-1], t[-1], t[0]])
        plt.xlabel('frequency (Hertz)')
        plt.ylabel('time (seconds (start of chunk))')
        plt.title('STFT with chirp example')
        plt.show()
    except ModuleNotFoundError:
        pass
这是一个如果你更容易阅读的话

整个模块假设只有真实数据,并使用Numpy的rfft函数。您完全可以将其推广到复杂数据或使用librosa,但对于您的应用程序音频掩蔽,使用纯实变换可以更容易地确保一切正常,并且逆STFT的输出是真实的。如果您使用的是完全通用的复杂STFT,则很容易搞砸,在保持对称性时需要小心

演示首先生成一些测试数据,并确认数据stft上的istft再次生成数据。测试数据是一个啁啾,从5 Hz开始,以每秒2 Hz的速度下降,因此在约10秒的数据中,啁啾的频率环绕,最终约为15 Hz。演示通过获取STFT阵列的绝对值来绘制STFT:

所以

将此代码放入stft.py文件中, 将其作为导入stft导入, 将STFT计算为频谱=STFT.stfty,128, 如演示中所示,可视化您的频谱。请确保预先添加stft。对于stft.py!中定义的函数!, 选择要衰减/放大的频率,然后将这些效果应用于频谱阵列 最后通过back_y=stft.istftspectrum获得处理后的音频,128。 屏蔽/放大/衰减频率内容意味着只需缩放频谱阵列中的一些容器。如果您有关于如何做的具体问题,请告诉我们。但这有望为您提供一种应用任意效果的万无一失的方法

如果您真的想使用librosa的函数,请告诉我们,我们也可以向您展示如何使用librosa的函数