Skip to content

Commit

Permalink
Merge pull request #403 from librosa/hpss_softmask_return
Browse files Browse the repository at this point in the history
hpss now returns soft masks
  • Loading branch information
bmcfee committed Aug 16, 2016
2 parents 394c37d + 39e283b commit 98469b4
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 29 deletions.
47 changes: 21 additions & 26 deletions librosa/decompose.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,18 @@ def hpss(S, kernel_size=31, power=2.0, mask=False, margin=1.0):
of the percussive filter.
power : float > 0 [scalar]
Exponent for the Wiener filter when constructing mask matrices.
Mask matrices are defined by
`mask_H = (r_H ** power) / (r_H ** power + r_P ** power)`
where `r_H` and `r_P` are the median-filter responses for
harmonic and percussive components.
Exponent for the Wiener filter when constructing soft mask matrices.
mask : bool
Return the (binary) masking matrices instead of components
Return the masking matrices instead of components.
Masking matrices contain non-negative real values that
can be used to measure the assignment of energy from `S`
into harmonic or percussive components.
Components can be recovered by multiplying `S * mask_H`
or `S * mask_P`.
margin : float or tuple (margin_harmonic, margin_percussive)
margin size(s) for the masks (as described in [2]_)
Expand Down Expand Up @@ -294,18 +297,17 @@ def hpss(S, kernel_size=31, power=2.0, mask=False, margin=1.0):
>>> mask_H, mask_P = librosa.decompose.hpss(D, mask=True)
>>> mask_H
array([[ 1., 0., ..., 0., 0.],
[ 1., 0., ..., 0., 0.],
array([[ 1.000e+00, 1.469e-01, ..., 2.648e-03, 2.164e-03],
[ 1.000e+00, 2.368e-01, ..., 9.413e-03, 7.703e-03],
...,
[ 0., 0., ..., 0., 0.],
[ 0., 0., ..., 0., 0.]])
[ 8.869e-01, 5.673e-02, ..., 4.603e-02, 1.247e-05],
[ 7.068e-01, 2.194e-02, ..., 4.453e-02, 1.205e-05]], dtype=float32)
>>> mask_P
array([[ 0., 1., ..., 1., 1.],
[ 0., 1., ..., 1., 1.],
array([[ 2.858e-05, 8.531e-01, ..., 9.974e-01, 9.978e-01],
[ 1.586e-05, 7.632e-01, ..., 9.906e-01, 9.923e-01],
...,
[ 1., 1., ..., 1., 1.],
[ 1., 1., ..., 1., 1.]])
[ 1.131e-01, 9.433e-01, ..., 9.540e-01, 1.000e+00],
[ 2.932e-01, 9.781e-01, ..., 9.555e-01, 1.000e+00]], dtype=float32)
Separate into harmonic/percussive/residual components by using a margin > 1.0
Expand Down Expand Up @@ -343,7 +345,8 @@ def hpss(S, kernel_size=31, power=2.0, mask=False, margin=1.0):

# margin minimum is 1.0
if margin_harm < 1 or margin_perc < 1:
raise ParameterError("Margins must be >= 1.0. A typical range is between 1 and 10.")
raise ParameterError("Margins must be >= 1.0. "
"A typical range is between 1 and 10.")

# Compute median filters. Pre-allocation here preserves memory layout.
harm = np.empty_like(S)
Expand All @@ -363,15 +366,7 @@ def hpss(S, kernel_size=31, power=2.0, mask=False, margin=1.0):
split_zeros=split_zeros)

if mask:
# If the margins are tight, H + P should sum to 1, so we use >=.
# Otherwise, comparisons should be strict on both sides.
if margin_harm == 1 and margin_perc == 1:
compare = np.greater_equal
else:
compare = np.greater

return ((mask_harm > mask_perc).astype(float),
compare(mask_perc, mask_harm).astype(float))
return mask_harm, mask_perc

return ((S * mask_harm) * phase, (S * mask_perc) * phase)

Expand Down
7 changes: 4 additions & 3 deletions tests/test_decompose.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,17 @@ def test_real_hpss():
D = np.abs(librosa.stft(y))

def __hpss_test(window, power, mask, margin):
H, P = librosa.decompose.hpss(D, kernel_size=window, power=power, mask=mask, margin=margin)
H, P = librosa.decompose.hpss(D, kernel_size=window, power=power,
mask=mask, margin=margin)

if margin == 1.0 or margin == (1.0, 1.0):
if mask:
assert np.allclose(H + P, np.ones_like(D))
else:
assert np.allclose(H + P, D)
else:
if mask:
assert not np.any(H.astype(bool) & P.astype(bool))
if mask:
assert np.all(H + P <= np.ones_like(D))
else:
assert np.all(H + P <= D)

Expand Down

0 comments on commit 98469b4

Please sign in to comment.