Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Expanded Audio Format Support with Soundfile #8

Merged
merged 2 commits into from
May 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
run: |
sudo apt-get update && sudo apt-get install libsndfile1
python -m pip install --upgrade pip
python -m pip install pytest hypothesis coverage pytest-coverage html5lib
python -m pip install pytest pytest-xdist hypothesis coverage pytest-coverage html5lib
python -m pip install ".[all]"
- name: Run Tests
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
run: |
sudo apt-get update && sudo apt-get install libsndfile1
python -m pip install --upgrade pip
python -m pip install pytest hypothesis ruff pyright html5lib
python -m pip install pytest pytest-xdist hypothesis ruff pyright html5lib
python -m pip install ".[all]"
- name: Make sure types are consistent
run: pyright src
Expand Down
2 changes: 1 addition & 1 deletion docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Now, let's discuss why these data schemas matter to us bioacousticians:
data? Schemas make it happen. They enable you to check an object against the
schema, validating if the data has everything it needs and is correct.

3. **Enhanced develper experience**: Python is entering the era of Type hints.
3. **Enhanced developer experience**: Python is entering the era of Type hints.
Using these hints makes your code more robust, acting like guardrails to
ensure that your data follows the rules.

Expand Down
10 changes: 10 additions & 0 deletions docs/javascripts/katex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
document$.subscribe(({ body }) => {
renderMathInElement(body, {
delimiters: [
{ left: "$$", right: "$$", display: true },
{ left: "$", right: "$", display: false },
{ left: "\\(", right: "\\)", display: false },
{ left: "\\[", right: "\\]", display: true },
],
});
});
10 changes: 10 additions & 0 deletions docs/user_guide/2_loading_audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@
`xarray.DataArray` objects, see the
[xarray documentation](https://docs.xarray.dev/en/stable/getting-started-guide/why-xarray.html).


!!! note "Supported audio formats"

`soundevent` supports most of the audio file formats supported by the
[`soundfile`](https://python-soundfile.readthedocs.io/) library. Some
formats were excluded because they do not support seeking and are not
suitable for random access. This still includes most of the common audio
file formats, such as WAV, FLAC, AIFF, and MP3. For a full list of
supported formats, see the
[audio.is_audio_file][soundevent.audio.is_audio_file] documentation.
"""

# %%
Expand Down
35 changes: 34 additions & 1 deletion docs/user_guide/3_computing_spectrograms.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
# First, we will load a recording. We will use the
# the example recording from the (audio loading tutorial)[audio_loading].

from soundevent import audio, data
import numpy as np
from soundevent import audio, data, arrays

recording = data.Recording.from_file("sample_audio.wav")
wave = audio.load_recording(recording)
Expand All @@ -44,3 +45,35 @@
# *frequency*, the second is *time*, and the third is *channel*. The
# spectrogram is computed separately for each channel of the audio
# signal.
#
# One of the nice things about using xarray is that it allows us to
# easily plot the spectrogram using the built-in plotting functions.

spectrogram.plot()

# %%
# The initial plot is hard to interpret due to the linear scale. Decibels (dB)
# are more perceptually relevant for sound.
# Let's convert it to decibels using the
# [`arrays.to_db`][soundevent.arrays.to_db] function.

spectrogram_db = arrays.to_db(spectrogram)
spectrogram_db.plot()

# %%
# This is much better! We can now clearly see the frequency
# content evolving over time.
#
# To make subtle details even more apparent, we can apply a
# de-noising technique like PCEN (Per-Channel Energy
# Normalization). PCEN helps reduce background noise and
# enhance the target sounds. We can apply PCEN using the
# [`audio.pcen`][soundevent.audio.pcen] function.

pcen = audio.pcen(spectrogram)
pcen_db = arrays.to_db(pcen)
pcen_db.plot()

# %%
# In this case the PCEN transformation has not made a huge
# difference, but it can be very useful in other cases.
6 changes: 6 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,19 @@ markdown_extensions:
toc_depth: 4
permalink: "#"
separator: "_"
- pymdownx.arithmatex:
generic: true
extra_javascript:
- javascripts/jquery-3.3.1.min.js
- javascripts/jquery.json-viewer.js
- javascripts/json-viewer.js
- optionalConfig.js
- https://unpkg.com/[email protected]/dist/mermaid.min.js
- extra-loader.js
- javascripts/katex.js
- https://unpkg.com/katex@0/dist/katex.min.js
- https://unpkg.com/katex@0/dist/contrib/auto-render.min.js
extra_css:
- stylesheets/jquery.json-viewer.css
- css/mkdocstrings.css
- https://unpkg.com/katex@0/dist/katex.min.css
8 changes: 6 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ rye = { dev-dependencies = [
"pytest-testmon>=2.0.12",
"html5lib>=1.1",
"pyright>=1.1.362",
"pytest-xdist>=3.6.1",
] }

[tool.pytest.ini_options]
addopts = "-vv"
addopts = "-vv -n auto"

[tool.ruff]
line-length = 79
Expand All @@ -76,10 +77,13 @@ ignore = ["D1"]
[tool.ruff.lint.pydocstyle]
convention = "numpy"

[tool.ruff.lint.isort]
known-local-folder = ["src", "soundevent"]

[tool.pyright]
venvPath = "."
venv = ".venv"
include = ["src", "tests"]
include = ["src"]
verboseOutput = true

[tool.coverage.run]
Expand Down
4 changes: 4 additions & 0 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ evfuncs==0.3.5.post1
exceptiongroup==1.2.1
# via hypothesis
# via pytest
execnet==2.1.1
# via pytest-xdist
executing==2.0.1
# via icecream
filelock==3.13.4
Expand Down Expand Up @@ -210,13 +212,15 @@ pytest==8.1.2
# via pytest-cov
# via pytest-testmon
# via pytest-watch
# via pytest-xdist
pytest-cov==5.0.0
# via pytest-cover
pytest-cover==3.0.0
# via pytest-coverage
pytest-coverage==0.0
pytest-testmon==2.1.1
pytest-watch==4.2.0
pytest-xdist==3.6.1
python-dateutil==2.9.0.post0
# via ghp-import
# via matplotlib
Expand Down
13 changes: 5 additions & 8 deletions src/soundevent/audio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
"""Soundevent functions for handling audio files and arrays."""

from .files import is_audio_file
from .filter import filter_audio
from .files import get_audio_files, is_audio_file
from .io import load_audio, load_clip, load_recording
from .media_info import MediaInfo, compute_md5_checksum, get_media_info
from .resample import resample_audio
from .scaling import clamp_amplitude, pcen, scale_amplitude
from .operations import filter, pcen, resample
from .spectrograms import compute_spectrogram

__all__ = [
"MediaInfo",
"compute_spectrogram",
"compute_md5_checksum",
"get_media_info",
"get_audio_files",
"load_audio",
"load_clip",
"load_recording",
"is_audio_file",
"resample_audio",
"filter_audio",
"scale_amplitude",
"clamp_amplitude",
"resample",
"filter",
"pcen",
]
17 changes: 17 additions & 0 deletions src/soundevent/audio/attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Definition of common attributes for audio objects."""

from enum import Enum

__all__ = [
"AudioAttrs",
]


class AudioAttrs(str, Enum):
samplerate = "samplerate"

recording_id = "recording_id"

clip_id = "clip_id"

path = "path"
146 changes: 0 additions & 146 deletions src/soundevent/audio/chunks.py

This file was deleted.

Loading
Loading