Skip to content

Commit

Permalink
Add documentation page for Aliasing
Browse files Browse the repository at this point in the history
  • Loading branch information
iver56 committed Mar 15, 2024
1 parent 72823c1 commit f31d2df
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 4 deletions.
7 changes: 5 additions & 2 deletions audiomentations/augmentations/aliasing.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ def __init__(
self, min_sample_rate: int = 8000, max_sample_rate: int = 30000, p: float = 0.5
):
"""
:param min_sample_rate: The minimum sample rate used during an aliasing
:param max_sample_rate: The maximum sample rate used during an aliasing
:param min_sample_rate: Minimum target sample rate to downsample to
:param max_sample_rate: Maximum target sample rate to downsample to
:param p: The probability of applying this transform
"""
super().__init__(p)

if min_sample_rate < 2:
raise ValueError("min_sample_rate must be greater than or equal to 2")

if min_sample_rate > max_sample_rate:
raise ValueError("min_sample_rate must not be larger than max_sample_rate")

Expand Down
24 changes: 24 additions & 0 deletions demo/generate_examples_for_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
Limiter,
AddGaussianSNR,
BitCrush,
Aliasing,
)
from audiomentations.core.audio_loading_utils import load_sound_file
from audiomentations.core.utils import get_max_abs_amplitude
Expand Down Expand Up @@ -287,6 +288,29 @@ def generate_example(self):
return sound, transformed_sound, sample_rate


@register
class AliasingExample(TransformUsageExample):
transform_class = Aliasing

def generate_example(self):
random.seed(42)
np.random.seed(42)
transform = Aliasing(
min_sample_rate=12000,
max_sample_rate=12000,
p=1.0,
)

sound, sample_rate = load_sound_file(
os.path.join(DEMO_DIR, "p286_011.wav"), sample_rate=None
)
sound = sound[..., int(0.5 * sample_rate) : int(2.9 * sample_rate)]

transformed_sound = transform(sound, sample_rate)

return sound, transformed_sound, sample_rate


@register
class ApplyImpulseResponseExample(TransformUsageExample):
transform_class = ApplyImpulseResponse
Expand Down
Binary file added docs/waveform_transforms/Aliasing.webp
Binary file not shown.
Binary file added docs/waveform_transforms/Aliasing_input.flac
Binary file not shown.
Binary file not shown.
48 changes: 48 additions & 0 deletions docs/waveform_transforms/aliasing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# `Aliasing`

_To be added in v0.35.0_

Downsample the audio to a lower sample rate by linear interpolation, without low-pass
filtering it first, resulting in aliasing artifacts. You get aliasing artifacts when
there is high-frequency audio in the input audio that falls above the nyquist frequency
of the chosen target sample rate. Audio with frequencies above the nyquist frequency
cannot be reproduced accurately and get "reflected"/mirrored to other frequencies.

After the downsampling, the signal gets upsampled to the original signal again, so the
length of the output becomes the same as the length of the input.

For more information, see

* [Sample rate reduction :octicons-link-external-16:](https://en.wikipedia.org/wiki/Bitcrusher#Sample_rate_reduction){target=_blank} on Wikipedia
* [Intro to downsampling :octicons-link-external-16:](http://gdsp.hf.ntnu.no/lessons/1/3/){target=_blank} by NTNU, Department of Music, Music Technology. Note: that article describes a slightly different downsampling technique, called sample-and-hold, while audiomentations implements linear interpolation. However, both methods lead to aliasing artifacts.

## Input-output example

Here we target a sample rate of 12000 Hz. Note the vertical mirroring in the spectrogram in the transformed sound.

![Input-output waveforms and spectrograms](Aliasing.webp)

| Input sound | Transformed sound |
|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|
| <audio controls><source src="../Aliasing_input.flac" type="audio/flac"></audio> | <audio controls><source src="../Aliasing_transformed.flac" type="audio/flac"></audio> |

## Usage example

```python
from audiomentations import Aliasing

transform = Aliasing(min_sample_rate=8000, max_sample_rate=30000, p=1.0)

augmented_sound = transform(my_waveform_ndarray, sample_rate=44100)
```

# Aliasing API

[`min_sample_rate`](#min_sample_rate){ #min_sample_rate }: `int` • unit: Hz • range: [2, ∞)
: :octicons-milestone-24: Minimum target sample rate to downsample to

[`max_sample_rate`](#max_sample_rate){ #max_sample_rate }: `int` • unit: Hz • range: [2, ∞)
: :octicons-milestone-24: Maximum target sample rate to downsample to

[`p`](#p){ #p }: `float` • range: [0.0, 1.0]
: :octicons-milestone-24: Default: `0.5`. The probability of applying this transform.
4 changes: 2 additions & 2 deletions docs/waveform_transforms/resample.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ sampling rate and vice versa to do upsampling only.

# Resample API

[`min_sample_rate`](#min_sample_rate){ #min_sample_rate }: `int`
[`min_sample_rate`](#min_sample_rate){ #min_sample_rate }: `int` • unit: Hz
: :octicons-milestone-24: Default: `8000`. Minimum sample rate

[`max_sample_rate`](#max_sample_rate){ #max_sample_rate }: `int`
[`max_sample_rate`](#max_sample_rate){ #max_sample_rate }: `int` • unit: Hz
: :octicons-milestone-24: Default: `44100`. Maximum sample rate

[`p`](#p){ #p }: `float` • range: [0.0, 1.0]
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ nav:
- AddShortNoises: waveform_transforms/add_short_noises.md
- AdjustDuration: waveform_transforms/adjust_duration.md
- AirAbsorption: waveform_transforms/air_absorption.md
- Aliasing: waveform_transforms/aliasing.md
- ApplyImpulseResponse: waveform_transforms/apply_impulse_response.md
- BitCrush: waveform_transforms/bit_crush.md
- BandPassFilter: waveform_transforms/band_pass_filter.md
Expand Down
5 changes: 5 additions & 0 deletions tests/test_aliasing.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ def test_multichannel(self):
assert samples.shape == distorted_samples.shape
assert not np.array_equal(samples, distorted_samples)

def test_param_range(self):
with pytest.raises(ValueError):
Aliasing(min_sample_rate=0, max_sample_rate=6000, p=1.0)
with pytest.raises(ValueError):
Aliasing(min_sample_rate=8000, max_sample_rate=6000, p=1.0)

0 comments on commit f31d2df

Please sign in to comment.