Skip to content

Commit

Permalink
Merge bc1ba08 into fb87932
Browse files Browse the repository at this point in the history
  • Loading branch information
bmcfee committed Nov 1, 2016
2 parents fb87932 + bc1ba08 commit 370b996
Showing 1 changed file with 79 additions and 7 deletions.
86 changes: 79 additions & 7 deletions librosa/effects.py
Expand Up @@ -33,12 +33,13 @@

from . import core
from . import decompose
from . import feature
from . import util
from .util.exceptions import ParameterError

__all__ = ['hpss', 'harmonic', 'percussive',
'time_stretch', 'pitch_shift',
'remix']
'remix', 'trim']


def hpss(y, **kwargs):
Expand Down Expand Up @@ -77,7 +78,7 @@ def hpss(y, **kwargs):
>>> y, sr = librosa.load(librosa.util.example_audio_file())
>>> y_harmonic, y_percussive = librosa.effects.hpss(y)
>>> # Get a more isolated percussive component by widening its margin
>>> # Get a more isolated percussive component by widening its margin
>>> y_harmonic, y_percussive = librosa.effects.hpss(y, margin=(1.0,5.0))
'''
Expand All @@ -94,6 +95,7 @@ def hpss(y, **kwargs):

return y_harm, y_perc


def harmonic(y, **kwargs):
'''Extract harmonic elements from an audio time-series.
Expand All @@ -117,14 +119,13 @@ def harmonic(y, **kwargs):
Examples
--------
>>> # Extract harmonic component
>>> # Extract harmonic component
>>> y, sr = librosa.load(librosa.util.example_audio_file())
>>> y_harmonic = librosa.effects.harmonic(y)
>>> # Use a margin > 1.0 for greater harmonic separation
>>> y_harmonic = librosa.effects.harmonic(y, margin=3.0)
'''

# Compute the STFT matrix
Expand All @@ -138,6 +139,7 @@ def harmonic(y, **kwargs):

return y_harm


def percussive(y, **kwargs):
'''Extract percussive elements from an audio time-series.
Expand All @@ -160,15 +162,14 @@ def percussive(y, **kwargs):
librosa.decompose.hpss : HPSS for spectrograms
Examples
--------
>>> # Extract percussive component
--------
>>> # Extract percussive component
>>> y, sr = librosa.load(librosa.util.example_audio_file())
>>> y_percussive = librosa.effects.percussive(y)
>>> # Use a margin > 1.0 for greater percussive separation
>>> y_percussive = librosa.effects.percussive(y, margin=3.0)
'''

# Compute the STFT matrix
Expand Down Expand Up @@ -374,3 +375,74 @@ def remix(y, intervals, align_zeros=True):
y_out.append(y[clip])

return np.concatenate(y_out, axis=-1)


def trim(y, top_db=60, n_fft=2048, hop_length=512, index=False):
'''Trim leading and trailing silence from an audio signal.
Parameters
----------
y : np.ndarray, shape=(n,) or (2,n)
Audio signal, can be mono or stereo
top_db : number > 0
The threshold (in decibels) below peak to consider as
silence
n_fft : int > 0
The number of samples per analysis frame
hop_length : int > 0
The number of samples between analysis frames
index : bool
If `True`, return the start and end of the non-silent
region of `y` along with the trimmed signal.
If `False`, only return the trimmed signal.
Returns
-------
y_trimmed : np.ndarray, shape=(m,) or (2, m)
The trimmed signal
index : slice, optional
If `index=True` is provided, then this contains
the slice of `y` corresponding to the non-silent region:
`y_trimmed = y[index]`.
Examples
--------
>>> # Load some audio
>>> y, sr = librosa.load(librosa.util.example_audio_file())
>>> # Trim the beginning and ending silence
>>> yt = librosa.effects.trim(y)
>>> # Print the durations
>>> print(librosa.get_duration(y), librosa.get_duration(yt))
61.45886621315193 60.58086167800454
'''

# Convert to mono
y_mono = core.to_mono(y)

# Compute the MSE for the signal
mse = feature.rmse(y=y_mono, n_fft=n_fft, hop_length=hop_length)**2

# Compute the log power indicator and non-zero positions
logp = core.logamplitude(mse, ref_power=np.max, top_db=None) > - top_db
nonzero = np.flatnonzero(logp)

# Compute the start and end positions
# End position goes one frame past the last non-zero
start = int(core.frames_to_samples(nonzero[0], hop_length))
end = min(len(y_mono),
int(core.frames_to_samples(nonzero[-1] + 1, hop_length)))

# Build the mono/stereo index
full_index = [slice(None)] * y.ndim
full_index[-1] = slice(start, end)

if index:
return y[full_index], full_index[-1]
else:
return y[full_index]

0 comments on commit 370b996

Please sign in to comment.