Skip to content

Commit

Permalink
Implement and test Gain transform
Browse files Browse the repository at this point in the history
  • Loading branch information
iver56 committed Aug 17, 2020
1 parent a1d2c84 commit 7b9c5fe
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 2 deletions.
34 changes: 34 additions & 0 deletions audiomentations/augmentations/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
calculate_rms,
calculate_desired_noise_rms,
get_file_paths,
convert_decibels_to_amplitude_ratio,
)


Expand Down Expand Up @@ -750,3 +751,36 @@ def randomize_parameters(self, samples, sample_rate):

def apply(self, samples, sample_rate):
return -samples


class Gain(BasicTransform):
"""
Multiply the audio by a random amplitude factor to reduce or increase the volume. This
technique can help a model become somewhat invariant to the overall gain of the input audio.
Warning: This transform can return samples outside the [-1, 1] range, which may lead to
clipping or wrap distortion, depending on what you do with the audio in a later stage.
See also https://en.wikipedia.org/wiki/Clipping_(audio)#Digital_clipping
"""

def __init__(self, min_gain_in_db=-12, max_gain_in_db=12, p=0.5):
"""
:param p:
"""
super().__init__(p)
assert min_gain_in_db <= max_gain_in_db
self.min_gain_in_db = min_gain_in_db
self.max_gain_in_db = max_gain_in_db

def randomize_parameters(self, samples, sample_rate):
super().randomize_parameters(samples, sample_rate)
if self.parameters["should_apply"]:
self.parameters["gain_in_db"] = random.uniform(
self.min_gain_in_db, self.max_gain_in_db
)

def apply(self, samples, sample_rate):
amplitude_ratio = convert_decibels_to_amplitude_ratio(
self.parameters["gain_in_db"]
)
return samples * amplitude_ratio
4 changes: 4 additions & 0 deletions audiomentations/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ def calculate_desired_noise_rms(clean_rms, snr):
a = float(snr) / 20
noise_rms = clean_rms / (10 ** a)
return noise_rms


def convert_decibels_to_amplitude_ratio(decibels):
return 10 ** (decibels / 20)
19 changes: 18 additions & 1 deletion demo/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
AddBackgroundNoise,
AddShortNoises,
PolarityInversion,
)
Gain)

SAMPLE_RATE = 16000
CHANNELS = 1
Expand Down Expand Up @@ -202,3 +202,20 @@ def load_wav_file(sound_file_path):
)
augmented_samples = augmenter(samples=samples, sample_rate=SAMPLE_RATE)
wavfile.write(output_file_path, rate=SAMPLE_RATE, data=augmented_samples)

# Gain
augmenter = Compose(
[
Gain(
min_gain_in_db=-6,
max_gain_in_db=6,
p=1.0,
)
]
)
for i in range(5):
output_file_path = os.path.join(
output_dir, "Gain_{:03d}.wav".format(i)
)
augmented_samples = augmenter(samples=samples, sample_rate=SAMPLE_RATE)
wavfile.write(output_file_path, rate=SAMPLE_RATE, data=augmented_samples)
23 changes: 23 additions & 0 deletions tests/test_gain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import unittest

import numpy as np
from numpy.testing import assert_almost_equal

from audiomentations.augmentations.transforms import Gain
from audiomentations.core.composition import Compose


class TestGain(unittest.TestCase):
def test_gain(self):
samples = np.array([1.0, 0.5, -0.25, -0.125, 0.0], dtype=np.float32)
sample_rate = 16000

augment = Compose([Gain(min_gain_in_db=-6, max_gain_in_db=-6, p=1.0)])
processed_samples = augment(samples=samples, sample_rate=sample_rate)
assert_almost_equal(
processed_samples,
np.array(
[0.5011872, 0.2505936, -0.1252968, -0.0626484, 0.0], dtype=np.float32
),
)
self.assertEqual(processed_samples.dtype, np.float32)
12 changes: 11 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import unittest

from audiomentations import calculate_desired_noise_rms
from audiomentations.core.utils import (
calculate_desired_noise_rms,
convert_decibels_to_amplitude_ratio,
)


class TestUtils(unittest.TestCase):
def test_calculate_desired_noise_rms(self):
noise_rms = calculate_desired_noise_rms(clean_rms=0.5, snr=6)
self.assertAlmostEqual(noise_rms, 0.2505936168136362)

def test_convert_decibels_to_amplitude_ratio(self):
amplitude_ratio = convert_decibels_to_amplitude_ratio(decibels=-6)
self.assertAlmostEqual(amplitude_ratio, 0.5011872336272722)

amplitude_ratio = convert_decibels_to_amplitude_ratio(decibels=6)
self.assertAlmostEqual(amplitude_ratio, 1.9952623149688795)

0 comments on commit 7b9c5fe

Please sign in to comment.