noisereduce

Noise reduction in python using spectral gating (speech, bioacoustics, audio, time-domain signals)

https://github.com/timsainb/noisereduce

Science Score: 59.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 4 DOI reference(s) in README
  • Academic publication links
    Links to: frontiersin.org
  • Committers with academic emails
    1 of 7 committers (14.3%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (13.3%) to scientific vocabulary
Last synced: 6 months ago · JSON representation

Repository

Noise reduction in python using spectral gating (speech, bioacoustics, audio, time-domain signals)

Basic Info
  • Host: GitHub
  • Owner: timsainb
  • License: mit
  • Language: Jupyter Notebook
  • Default Branch: master
  • Homepage:
  • Size: 36.1 MB
Statistics
  • Stars: 1,737
  • Watchers: 23
  • Forks: 253
  • Open Issues: 32
  • Releases: 8
Created almost 7 years ago · Last pushed 7 months ago
Metadata Files
Readme License

README.md

Build Status Coverage Status Binder Open In Colab PyPI version

Noise reduction in python using spectral gating

Noisereduce is a noise reduction algorithm in python that reduces noise in time-domain signals like speech, bioacoustics, and physiological signals. It relies on a method called "spectral gating" which is a form of Noise Gate. It works by computing a spectrogram of a signal (and optionally a noise signal) and estimating a noise threshold (or gate) for each frequency band of that signal/noise. That threshold is used to compute a mask, which gates noise below the frequency-varying threshold.

The most recent version of noisereduce comprises two algorithms: 1. Stationary Noise Reduction: Keeps the estimated noise threshold at the same level across the whole signal 2. Non-stationary Noise Reduction: Continuously updates the estimated noise threshold over time

Version 3 Updates:

  • Includes a PyTorch-based implementation of Spectral Gating, an algorithm for denoising audio signals.
  • You can now create a noisereduce nn.Module object which allows it to be used either as a standalone module or as part of a larger neural network architecture.
  • The run time of the algorithm decreases substantially.

Version 2 Updates:

  • Added two forms of spectral gating noise reduction: stationary noise reduction, and non-stationary noise reduction.
  • Added multiprocessing so you can perform noise reduction on bigger data.
  • The new version breaks the API of the old version.
  • The previous version is still available at from noisereduce.noisereducev1 import reduce_noise
  • You can now create a noisereduce object which allows you to reduce noise on subsets of longer recordings

Stationary Noise Reduction

  • The basic intuition is that statistics are calculated on each frequency channel to determine a noise gate. Then the gate is applied to the signal.
  • This algorithm is based (but not completely reproducing) on the one outlined by Audacity for the noise reduction effect (Link to C++ code)
  • The algorithm takes two inputs:
    1. A noise clip containing prototypical noise of clip (optional)
    2. A signal clip containing the signal and the noise intended to be removed

Steps of the Stationary Noise Reduction algorithm

  1. A spectrogram is calculated over the noise audio clip
  2. Statistics are calculated over spectrogram of the noise (in frequency)
  3. A threshold is calculated based upon the statistics of the noise (and the desired sensitivity of the algorithm)
  4. A spectrogram is calculated over the signal
  5. A mask is determined by comparing the signal spectrogram to the threshold
  6. The mask is smoothed with a filter over frequency and time
  7. The mask is applied to the spectrogram of the signal, and is inverted If the noise signal is not provided, the algorithm will treat the signal as the noise clip, which tends to work pretty well

Non-stationary Noise Reduction

  • The non-stationary noise reduction algorithm is an extension of the stationary noise reduction algorithm, but allowing the noise gate to change over time.
  • When you know the timescale that your signal occurs on (e.g. a bird call can be a few hundred milliseconds), you can set your noise threshold based on the assumption that events occurring on longer timescales are noise.
  • This algorithm was motivated by a recent method in bioacoustics called Per-Channel Energy Normalization.

Steps of the Non-stationary Noise Reduction algorithm

  1. A spectrogram is calculated over the signal
  2. A time-smoothed version of the spectrogram is computed using an IIR filter applied forward and backward on each frequency channel.
  3. A mask is computed based on that time-smoothed spectrogram
  4. The mask is smoothed with a filter over frequency and time
  5. The mask is applied to the spectrogram of the signal, and is inverted

Installation

pip install noisereduce

Usage

See example notebook: Open In Colab Parallel computing example: Open In Colab

reduce_noise

Simplest usage

``` from scipy.io import wavfile import noisereduce as nr

load data

rate, data = wavfile.read("mywav.wav")

perform noise reduction

reducednoise = nr.reducenoise(y=data, sr=rate) wavfile.write("mywavreducednoise.wav", rate, reduced_noise) ```

Arguments to reduce_noise

y : np.ndarray [shape=(# frames,) or (# channels, # frames)], real-valued input signal sr : int sample rate of input signal / noise signal y_noise : np.ndarray [shape=(# frames,) or (# channels, # frames)], real-valued noise signal to compute statistics over (only for non-stationary noise reduction). stationary : bool, optional Whether to perform stationary, or non-stationary noise reduction, by default False prop_decrease : float, optional The proportion to reduce the noise by (1.0 = 100%), by default 1.0 time_constant_s : float, optional The time constant, in seconds, to compute the noise floor in the non-stationary algorithm, by default 2.0 freq_mask_smooth_hz : int, optional The frequency range to smooth the mask over in Hz, by default 500 time_mask_smooth_ms : int, optional The time range to smooth the mask over in milliseconds, by default 50 thresh_n_mult_nonstationary : int, optional Only used in nonstationary noise reduction., by default 1 sigmoid_slope_nonstationary : int, optional Only used in nonstationary noise reduction., by default 10 n_std_thresh_stationary : int, optional Number of standard deviations above mean to place the threshold between signal and noise., by default 1.5 tmp_folder : [type], optional Temp folder to write waveform to during parallel processing. Defaults to default temp folder for python., by default None chunk_size : int, optional Size of signal chunks to reduce noise over. Larger sizes will take more space in memory, smaller sizes can take longer to compute. , by default 60000 padding : int, optional How much to pad each chunk of signal by. Larger pads are needed for larger time constants., by default 30000 n_fft : int, optional length of the windowed signal after padding with zeros. The number of rows in the STFT matrix ``D`` is ``(1 + n_fft/2)``. The default value, ``n_fft=2048`` samples, corresponds to a physical duration of 93 milliseconds at a sample rate of 22050 Hz. This value is well adapted for music signals. However, in speech processing, the recommended value is 512, corresponding to 23 milliseconds at a sample rate of 22050 Hz. In any case, we recommend setting ``n_fft`` to a power of two for optimizing the speed of the fast Fourier transform (FFT) algorithm., by default 1024 win_length : [type], optional Each frame of audio is windowed by ``window`` of length ``win_length`` and then padded with zeros to match ``n_fft``. Smaller values improve the temporal resolution of the STFT (i.e. the ability to discriminate impulses that are closely spaced in time) at the expense of frequency resolution (i.e. the ability to discriminate pure tones that are closely spaced in frequency). This effect is known as the time-frequency localization trade-off and needs to be adjusted according to the properties of the input signal ``y``. If unspecified, defaults to ``win_length = n_fft``., by default None hop_length : [type], optional number of audio samples between adjacent STFT columns. Smaller values increase the number of columns in ``D`` without affecting the frequency resolution of the STFT. If unspecified, defaults to ``win_length // 4`` (see below)., by default None n_jobs : int, optional Number of parallel jobs to run. Set at -1 to use all CPU cores, by default 1 use_torch: bool, optional Whether to use the torch version of spectral gating, by default False device: str, optional A device to run the torch spectral gating on, by default "cuda"

Torch

See example notebook: Open In Colab

Simplest usage

``` import torch from noisereduce.torchgate import TorchGate as TG device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")

Create TorchGating instance

tg = TG(sr=8000, nonstationary=True).to(device)

Apply Spectral Gate to noisy speech signal

noisyspeech = torch.randn(3, 32000, device=device) enhancedspeech = tg(noisy_speech) ```

Arguments

| Parameter | Description | |--------------------------|-------------------------------------------------------------------------------------------------------| | sr | Sample rate of the input signal. | | nfft | The size of the FFT. | | hoplength | The number of samples between adjacent STFT columns. | | winlength | The window size for the STFT. If None, defaults to nfft. | | freqmasksmoothhz | The frequency smoothing width in Hz for the masking filter. If None, no frequency masking is applied. | | timemasksmoothms | The time smoothing width in milliseconds for the masking filter. If None, no time masking is applied. | | nstdthreshstationary | The number of standard deviations above the noise mean to consider as signal for stationary noise. | | nonstationary | Whether to use non-stationary noise masking. | | nmovemeannonstationary | The number of frames to use for the moving average in the non-stationary noise mask. | | nthreshnonstationary | The multiplier to apply to the sigmoid function in the non-stationary noise mask. | | tempcoeffnonstationary | The temperature coefficient to apply to the sigmoid function in the non-stationary noise mask. | | propdecrease | The proportion of decrease to apply to the mask. |

Choosing between Stationary and non-stantionary noise reduction

I discuss stationary and non-stationary noise reduction in this paper.

Figure caption: Stationary and non-stationary spectral gating noise reduction. (A) An overview of each algorithm. Stationary noise reduction typically takes in an explicit noise signal to calculate statistics and performs noise reduction over the entire signal uniformly. Non-stationary noise reduction dynamically estimates and reduces noise concurrently. (B) Stationary and non-stationary spectral gating noise reduction using the noisereduce Python package (Sainburg, 2019) applied to a Common chiffchaff (Phylloscopus collybita) song (Stowell et al., 2019) with an airplane noise in the background. The bottom frame depicts the difference between the two algorithms.

Citation

If you use this code in your research, please cite it: ```

@article{sainburg2020finding, title={Finding, visualizing, and quantifying latent structure across diverse animal vocal repertoires}, author={Sainburg, Tim and Thielk, Marvin and Gentner, Timothy Q}, journal={PLoS computational biology}, volume={16}, number={10}, pages={e1008228}, year={2020}, publisher={Public Library of Science} }

@software{timsainburg2019_3243139, author = {Tim Sainburg}, title = {timsainb/noisereduce: v1.0}, month = jun, year = 2019, publisher = {Zenodo}, version = {db94fe2}, doi = {10.5281/zenodo.3243139}, url = {https://doi.org/10.5281/zenodo.3243139} }

```

Project based on the cookiecutter data science project template. #cookiecutterdatascience

Owner

  • Name: Tim Sainburg
  • Login: timsainb
  • Kind: user
  • Location: San Diego, CA
  • Company: Harvard Medical School

Postdoc at Harvard

GitHub Events

Total
  • Issues event: 5
  • Watch event: 273
  • Issue comment event: 23
  • Push event: 6
  • Pull request event: 3
  • Fork event: 23
  • Create event: 1
Last Year
  • Issues event: 5
  • Watch event: 273
  • Issue comment event: 23
  • Push event: 6
  • Pull request event: 3
  • Fork event: 23
  • Create event: 1

Committers

Last synced: over 2 years ago

All Time
  • Total Commits: 33
  • Total Committers: 7
  • Avg Commits per committer: 4.714
  • Development Distribution Score (DDS): 0.212
Past Year
  • Commits: 5
  • Committers: 3
  • Avg Commits per committer: 1.667
  • Development Distribution Score (DDS): 0.6
Top Committers
Name Email Commits
Tim Sainburg t****b@g****m 26
Asaf Zorea z****f@g****m 2
Ali Saghiran a****n@g****m 1
rjfarber r****r@u****u 1
Lff5 l****z@g****m 1
Kareem Amr k****3@g****m 1
fardage 4****e 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 79
  • Total pull requests: 53
  • Average time to close issues: 5 months
  • Average time to close pull requests: 7 months
  • Total issue authors: 75
  • Total pull request authors: 17
  • Average comments per issue: 2.61
  • Average comments per pull request: 0.51
  • Merged pull requests: 34
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 6
  • Pull requests: 8
  • Average time to close issues: 20 days
  • Average time to close pull requests: less than a minute
  • Issue authors: 6
  • Pull request authors: 3
  • Average comments per issue: 2.83
  • Average comments per pull request: 0.13
  • Merged pull requests: 2
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • mukundt (2)
  • KoushikiNath19 (2)
  • timsainb (2)
  • JackSCJackson (2)
  • abhinashsivan (1)
  • jeromew (1)
  • dheerajcs (1)
  • zrg0712 (1)
  • polar-kev (1)
  • mcr-is (1)
  • DamienDeepgram (1)
  • hananell (1)
  • DanTremonti (1)
  • olivecha (1)
  • by011 (1)
Pull Request Authors
  • timsainb (28)
  • nuniz (4)
  • BenRogersNewsome (2)
  • coezbek (2)
  • abhinashsivan (2)
  • aksh98md (2)
  • blaine12100 (2)
  • soheilpaper (2)
  • typicalfeline (1)
  • ArnaudWald (1)
  • migperfer (1)
  • kareemamrr (1)
  • awildfivreld (1)
  • rjfarber (1)
  • lff5 (1)
Top Labels
Issue Labels
enhancement (5) bug (2) good first issue (1) invalid (1)
Pull Request Labels
torch (1)

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 191,576 last-month
  • Total docker downloads: 12,105
  • Total dependent packages: 12
  • Total dependent repositories: 257
  • Total versions: 11
  • Total maintainers: 1
pypi.org: noisereduce

Noise reduction using Spectral Gating in Python

  • Versions: 11
  • Dependent Packages: 12
  • Dependent Repositories: 257
  • Downloads: 191,576 Last month
  • Docker Downloads: 12,105
Rankings
Dependent repos count: 1.0%
Dependent packages count: 1.0%
Downloads: 1.7%
Stargazers count: 1.9%
Average: 2.0%
Docker downloads count: 2.7%
Forks count: 3.5%
Maintainers (1)
Last synced: 6 months ago

Dependencies

requirements-test.txt pypi
  • tensorflow >=2.0.0
requirements.txt pypi
  • coverage *
  • librosa *
  • matplotlib *
  • numpy *
  • pytest >=3.6
  • pytest-cov *
  • pytest-ordering *
  • python-coveralls *
  • scipy *
  • tqdm *
setup.py pypi
  • scipy *
test-requirements.txt pypi
  • tensorflow >=2.0
.github/workflows/python-publish.yml actions
  • actions/checkout v3 composite
  • actions/setup-python v3 composite
  • pypa/gh-action-pypi-publish 27b31702a0e7fc50959f5ad993c78deac1bdfc29 composite
environment.yml conda
  • librosa
  • matplotlib
  • notebook >5.2
  • numpy
  • python 3.6
  • scipy
  • tqdm