### Install pre-commit utility Source: https://github.com/descriptinc/audiotools/blob/master/README.md Install the pre-commit utility using pip or Homebrew. ```bash pip install pre-commit # with pip ``` ```bash brew install pre-commit # on Mac ``` -------------------------------- ### Install AudioTools from source Source: https://github.com/descriptinc/audiotools/blob/master/README.md Clone the AudioTools repository and install it locally using pip. ```bash git clone https://github.com/descriptinc/audiotools cd audiotools pip install . ``` -------------------------------- ### Install Git Hooks with pre-commit Source: https://github.com/descriptinc/audiotools/blob/master/README.md Install the git hooks for the pre-commit utility. ```bash pre-commit install ``` -------------------------------- ### Install AudioTools with pip Source: https://github.com/descriptinc/audiotools/blob/master/README.md Install the AudioTools library directly from its GitHub repository using pip. ```bash pip install git+https://github.com/descriptinc/audiotools ``` -------------------------------- ### Initialize AudioSignal objects Source: https://github.com/descriptinc/audiotools/blob/master/docs/readme.md Setup the environment and load audio files for speaker, impulse response, and noise signals. ```python import torch import audiotools from audiotools import AudioSignal from audiotools import post import rich import matplotlib.pyplot as plt import markdown2 as md from IPython.display import HTML audiotools.core.playback.DEFAULT_EXTENSION = “.mp3” state = audiotools.util.random_state(0) spk = AudioSignal(“../tests/audio/spk/f10_script4_produced.wav”, offset=5, duration=5) ir = AudioSignal(“../tests/audio/ir/h179_Bar_1txts.wav”) nz = AudioSignal(“../tests/audio/nz/f5_script2_ipad_balcony1_room_tone.wav”) ``` -------------------------------- ### Quickstart: Load, Play, and Modify AudioSignal Source: https://github.com/descriptinc/audiotools/blob/master/README.md Load an audio file, play it, apply a low-pass filter, and play the modified signal. Requires ffplay for playback. ```python import audiotools from audiotools import AudioSignal signal = AudioSignal("tests/audio/spk/f10_script4_produced.wav", offset=5, duration=5) signal.play() # Play back the signal in your terminal using ffplay signal.low_pass(8000) # Low-pass the signal signal.play() # Play back the low-passed version of the signal ``` -------------------------------- ### Complete Room Simulator Transform Pipeline Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md A comprehensive example demonstrating a full transform pipeline for a room simulator. It includes preprocessing, core processing (RoomImpulseResponse, BackgroundNoise, ClippingDistortion, MuLawQuantization, LowPass), and postprocessing (RescaleAudio). The example also shows how to apply specific parts of the pipeline using `transform.filter()`. ```python :tags: [“output_scroll”] from pathlib import Path audio_path = “../../tests/audio/spk/f10_script4_produced.wav” signal = AudioSignal(audio_path, offset=6, duration=5) batch_size = 10 # Make it into a batch signal = AudioSignal.batch([signal.clone() for _ in range(batch_size)]) # Create each group of transforms preprocess = tfm.VolumeChange(name=”pre”) process = tfm.Compose( > [ > : tfm.RoomImpulseResponse(sources=[“../../tests/audio/ir”]), > tfm.BackgroundNoise(sources=[“../../tests/audio/nz”]), > tfm.ClippingDistortion(), > tfm.MuLawQuantization(), > tfm.LowPass(prob=0.5), > ], > name=”process”, > prob=0.9, ) postprocess = tfm.RescaleAudio(name=”post”) # Create transform transform = tfm.Compose([ > preprocess, > process, > postprocess, ]) # Instantiate transform (passing in signal because # some transforms require data). states = range(batch_size) kwargs = transform.batch_instantiate(states, signal) # Apply pre, process, and post to signal in sequence. output = transform(signal.clone(), ``` ** ``` kwargs) # Apply only pre and post to signal in sequence, skipping process. with transform.filter(“pre”, “post”): > target = transform(signal.clone(), > ``` > ** > ``` > kwargs) audio_dict = make_dict(target, output, kwargs) post.disp(audio_dict, first_column=”batch_idx”) ``` -------------------------------- ### Choose Transform Class Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md Example of initializing the Choose transform with specific sub-transforms. ```pycon >>> transforms.Choose(tfm.LowPass(), tfm.HighPass()) ``` -------------------------------- ### Write AudioSignal to disk Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Examples of writing an AudioSignal to a file, including batch indexing and fluent interface chaining. ```pycon >>> signal = AudioSignal(torch.randn(10, 1, 44100), 44100) >>> signal.write("/tmp/out.wav") ``` ```pycon >>> signal[5].write("/tmp/out.wav") ``` ```pycon >>> signal.write("/tmp/original.wav").low_pass(4000).write("/tmp/lowpass.wav") ``` -------------------------------- ### Instantiating Transforms Requiring Data Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md Example of how to instantiate transforms like BackgroundNoise or RoomImpulseResponse, which require a signal object for loading data at a compatible sample rate, channel count, and duration. ```python seed = ... signal = ... transform = tfm.BackgroundNoise(sources=["noise_folder"]) transform.instantiate(seed, signal) ``` -------------------------------- ### Choose Transform: Low-pass or High-pass Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md This example shows how to use the Choose transform with the order of HighPass and LowPass filters reversed, resulting in the low-pass path being taken. ```python transform = tfm.Choose( > [ > : tfm.LowPass(), > tfm.HighPass(), > ], ) kwargs = transform.batch_instantiate(seeds) output_batch = transform(signal_batch.clone(), ``` ** ``` kwargs) audio_dict = make_dict(signal_batch, output_batch) post.disp(audio_dict, first_column=”batch_idx”) ``` -------------------------------- ### Example: Conditional checkpointing with @when Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.ml.md This example demonstrates how to use the @when decorator to perform a checkpoint only every 100 iterations and when the local rank is 0. ```python >>> i = 0 >>> rank = 0 >>> >>> @when(lambda: i % 100 == 0 and rank == 0) >>> def checkpoint(): >>> print("Saving to /runs/exp1") >>> >>> for i in range(1000): >>> checkpoint() ``` -------------------------------- ### Configure Player and Add Playback Buttons Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/listening_tests.md Instantiates the player and adds a playback button for a specific audio reference. ```python with gr.Blocks() as app: > player = pr.Player(app) > player.create() > player.add(“Play Reference”) ``` -------------------------------- ### audiotools.data.datasets.ResumableSequentialSampler Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md A sequential sampler that can be resumed from a given start index. ```APIDOC ## class audiotools.data.datasets.ResumableSequentialSampler ### Description Sequential sampler that can be resumed from a given start index. ### Parameters - **dataset** – The dataset to sample from. - **start_idx** (int, optional) – The starting index to resume sampling from. Defaults to None. ``` -------------------------------- ### Instantiate and Configure Transforms Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md Demonstrates how to instantiate a transform with default or custom distribution parameters using a random seed. ```python from audiotools import transforms as tfm transform = tfm.LowPass() seed = 0 print(transform.instantiate(seed)) ``` ```python transform = tfm.LowPass( > cutoff = (“uniform”, 4000, 8000) ) print(transform.instantiate(seed)) ``` ```python transform = tfm.LowPass() seed = 0 print(transform.instantiate(seed)) ``` -------------------------------- ### audiotools.data.datasets.ResumableDistributedSampler Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md A distributed sampler that can be resumed from a given start index. ```APIDOC ## class audiotools.data.datasets.ResumableDistributedSampler ### Description Distributed sampler that can be resumed from a given start index. ### Parameters - **dataset** – The dataset to sample from. - **start_idx** (int, optional) – The starting index to resume sampling from. Defaults to None. ``` -------------------------------- ### Initialize AudioSignal with STFT Parameters Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Shows how to initialize an AudioSignal with specific STFT parameters and how to reset them to defaults. ```python >>> stft_params = STFTParams(128, 32) >>> signal1 = AudioSignal(torch.randn(44100), 44100, stft_params=stft_params) >>> signal2 = AudioSignal(torch.randn(44100), 44100, stft_params=signal1.stft_params) >>> signal1.stft_params = STFTParams() # Defaults ``` -------------------------------- ### GET /audiotools/post/in_notebook Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.post.md Determines if the current code execution is running in a notebook. ```APIDOC ## GET /audiotools/post/in_notebook ### Description Determines if code is running in a notebook. ### Response #### Success Response (200) - **result** (bool) - Whether or not this is running in a notebook. ``` -------------------------------- ### Get AudioSignal Duration Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Returns the total duration of the audio signal in seconds as a float. ```python signal.duration ``` -------------------------------- ### Initialize Audio Player Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/listening_tests.md Creates a Gradio-based audio player instance within a Gradio Blocks context. ```python with gr.Blocks() as app: > player = pr.Player(app) ``` -------------------------------- ### Create MUSHRA Listening Test with Gradio Source: https://context7.com/descriptinc/audiotools/llms.txt Sets up a MUSHRA test interface using Gradio. Requires audio samples in a specified folder. Results are saved to a CSV file. ```python from audiotools import preference as pr import gradio as gr # MUSHRA test setup def create_mushra_test(): with gr.Blocks() as app: samples = gr.State(pr.Samples( folder="path/to/audio", shuffle=True, n_samples=20 )) player = pr.Player(app) player.create() player.add("Play Reference") conditions = ["method_a", "method_b", "anchor"] ratings = [] for i, cond in enumerate(conditions): with gr.Row(): player.add(f"Play {cond}") ratings.append(gr.Slider(value=50, interactive=True)) # Results saved to CSV save_path = "results.csv" app.launch(share=True) ``` -------------------------------- ### Initialize and Load Audio Player Source: https://github.com/descriptinc/audiotools/blob/master/audiotools/core/templates/widget.html Instantiates a player with a specific ID, loads audio, image, and levels sources, and sets up a resize listener to redraw the player. ```javascript var PLAYER_ID = new Player('PLAYER_ID') PLAYER_ID.load( "AUDIO_SRC", "IMAGE_SRC", "LEVELS_SRC" ) window.addEventListener("resize", function() {PLAYER_ID.redraw()}) ``` -------------------------------- ### FFprobe Offset and Codec Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Retrieves the start time offset and codec of the first audio stream from a given file path. ```APIDOC ## GET /descriptinc/audiotools/core/ffmpeg/ffprobe_offset_and_codec ### Description Given a path to a file, returns the start time offset and codec of the first audio stream. ### Method GET ### Endpoint /descriptinc/audiotools/core/ffmpeg/ffprobe_offset_and_codec ### Parameters #### Query Parameters - **path** (str) - Required - Path to the audio file. ### Response #### Success Response (200) - **offset** (float) - The start time offset of the first audio stream. - **codec** (str) - The codec of the first audio stream. ### Response Example { "offset": 0.0, "codec": "aac" } ``` -------------------------------- ### Build and Deploy AudioTools Documentation Source: https://github.com/descriptinc/audiotools/blob/master/README.md Commands to build the HTML documentation locally and deploy it to the gh-pages branch. ```bash cd docs/ make html open _build/html/index.html ``` ```bash cd docs bash publish_docs.sh ``` -------------------------------- ### Batch Instantiate Audio Transforms Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md Demonstrates how to instantiate arguments for a batch of audio signals using a list of states. ```pycon >>> batch_size = 4 >>> signal = AudioSignal(audio_path, offset=10, duration=2) >>> signal_batch = AudioSignal.batch([signal.clone() for _ in range(batch_size)]) >>> >>> states = [seed + idx for idx in list(range(batch_size))] >>> kwargs = transform.batch_instantiate(states, signal_batch) >>> batch_output = transform(signal_batch, **kwargs) ``` -------------------------------- ### Get AudioSignal Device Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Retrieves the torch.device object indicating where the AudioSignal's tensors are currently stored (CPU or CUDA). ```python signal.device ``` -------------------------------- ### Instantiate and Apply Transform Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md Shows the process of instantiating transform parameters for a seed and applying the transform to a signal clone. ```pycon >>> for seed in range(10): >>> kwargs = transform.instantiate(seed, signal) >>> output = transform(signal.clone(), **kwargs) ``` -------------------------------- ### Get Discrete Cosine Transform Matrix Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Generates a Discrete Cosine Transform (DCT) matrix. Can be normalized and specified for a particular device. ```python AudioSignal.get_dct(n_mfcc=40, n_mels=128) ``` -------------------------------- ### Get tracker state with state_dict() Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.ml.md The state_dict function returns a dictionary containing the current state of the tracker, including its history and step. ```python def state_dict() → dict ``` -------------------------------- ### Initialize AudioTools and Utility Settings Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md Sets default playback extension and figure size, and configures the data path environment variable. This code is typically run at the beginning of a script or notebook. ```python import audiotools from audiotools import AudioSignal from audiotools import post, util, metrics from audiotools.data import preprocess from flatten_dict import flatten import torch import pprint from collections import defaultdict from audiotools import transforms as tfm import os audiotools.core.playback.DEFAULT_EXTENSION = ".mp3" util.DEFAULT_FIG_SIZE = (9, 3) os.environ["PATH_TO_DATA"] = os.path.abspath("../..") pp = pprint.PrettyPrinter() ``` -------------------------------- ### Initialize Compression State Source: https://github.com/descriptinc/audiotools/blob/master/audiotools/core/templates/headers.html Initializes the compression state and builds static Huffman trees for the first time. ```javascript a._tr_init=function(t){tt||(function(){var t,e,a,i,n,r=new Array(w+1);for(a=0,i=0;i<_-1;i++)for(O[i]=a,t=0;t<1<>=7;i folder: str = None > save_path: str = “results.csv” > conditions: list = None > reference: str = None > seed: int = 0 def random_sine(f): : fs = 44100 # sampling rate, Hz, must be integer duration = 5.0 # in seconds, may be float
# generate samples, note conversion to float32 array volume = 0.1 num_samples = int(fs \* duration) samples = volume \* np.sin(2 \* math.pi \* (f / fs) \* np.arange(num_samples))
return samples, fs def create_data(path): : path = Path(path) hz = [110, 140, 180]
for i in range(6): : name = f”condition_{string.ascii_lowercase[i]}” for j in range(3):
> sample_path = path / name / f”sample_{j}.wav” > sample_path.parent.mkdir(exist_ok=True, parents=True) > audio, sr = random_sine(hz[j] \* (2\*\*i)) > sf.write(sample_path, audio, sr) config = Config( : folder=”/tmp/pref/audio/”, save_path=”/tmp/pref/results.csv”, conditions=[“condition_a”, “condition_b”], reference=”condition_c”, ) create_data(config.folder) with gr.Blocks() as app: : save_path = config.save_path samples = gr.State(pr.Samples(config.folder))
reference = config.reference conditions = config.conditions
player = pr.Player(app) player.create() if reference is not None:
> player.add(“Play Reference”)
user = pr.create_tracker(app) ratings = []
with gr.Row(): : gr.HTML(“”) with gr.Column(scale=9):
> gr.HTML(pr.slider_mushra)
for i in range(len(conditions)): : with gr.Row().style(equal_height=True): : x = string.ascii_uppercase[i] player.add(f”Play {x}”) with gr.Column(scale=9):
> ratings.append(gr.Slider(value=50, interactive=True))
def build(user, samples,
``` * ```
ratings): : # Filter out samples user has done already, by looking in the CSV. samples.filter_completed(user, save_path)
# Write results to CSV if samples.current > 0:
> start_idx = 1 if reference is not None else 0 > name = samples.names[samples.current - 1] > result = {“sample”: name, “user”: user} > for k, r in zip(samples.order[start_idx:], ratings):
> > result[k] = r
> pr.save_result(result, save_path)
updates, done, pbar = samples.get_next_sample(reference, conditions) return updates + [gr.update(value=50) for \_ in ratings] + [done, samples, pbar]
progress = gr.HTML() begin = gr.Button(“Submit”, elem_id=”start-survey”) begin.click(
> fn=build, > inputs=[user, samples] + ratings, > outputs=player.to_list() + ratings + [begin, samples, progress],
).then(None, \_js=pr.reset_player)
# Comment this back in to actually launch the script. # app.launch() ``` -------------------------------- ### Load and Process Slakh Data Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md Example of loading Slakh multitrack data using AudioLoader and AudioDataset. Includes data augmentation and batch processing with PyTorch DataLoader. ```python >>> import audiotools as at >>> from pathlib import Path >>> from audiotools import transforms as tfm >>> import numpy as np >>> import torch >>> import glob >>> >>> def build_dataset( >>> sample_rate: int = 16000, >>> duration: float = 10.0, >>> slakh_path: str = "~/.data/slakh/", >>> ): >>> slakh_path = Path(slakh_path).expanduser() >>> >>> # Find the max number of sources in Slakh >>> src_names = [x.name for x in list(slakh_path.glob("**/*.wav")) if "S" in str(x.name)] >>> n_sources = len(list(set(src_names))) >>> >>> loaders = { >>> f"S{i:02d}": at.datasets.AudioLoader( >>> sources=[slakh_path], >>> transform=tfm.Compose( >>> tfm.VolumeNorm(("uniform", -20, -10)), >>> tfm.Silence(prob=0.1), >>> ), >>> ext=[f"S{i:02d}.wav"], >>> ) >>> for i in range(n_sources) >>> } >>> dataset = at.datasets.AudioDataset( >>> loaders=loaders, >>> sample_rate=sample_rate, >>> duration=duration, >>> num_channels=1, >>> aligned=True, >>> transform=tfm.RescaleAudio(), >>> shuffle_loaders=False, >>> ) >>> >>> return dataset, list(loaders.keys()) >>> >>> train_data, sources = build_dataset() >>> dataloader = torch.utils.data.DataLoader( >>> train_data, >>> batch_size=16, >>> num_workers=0, >>> collate_fn=train_data.collate, >>> ) >>> batch = next(iter(dataloader)) >>> >>> for k in sources: >>> src = batch[k] >>> src["transformed"] = train_data.loaders[k].transform( >>> src["signal"].clone(), **src["transform_args"] >>> ) >>> >>> mixture = sum(batch[k]["transformed"] for k in sources) >>> mixture = train_data.transform(mixture, **batch["transform_args"]) ``` -------------------------------- ### Generate Dummy Data for Listening Tests Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/listening_tests.md Sets up a directory structure and generates synthetic sine wave audio files for testing purposes. ```python import math import string import tempfile from dataclasses import dataclass from pathlib import Path import gradio as gr import numpy as np import soundfile as sf import rich from audiotools import preference as pr @dataclass class Config: > folder: str = None > save_path: str = “results.csv” > conditions: list = None > reference: str = None > seed: int = 0 def random_sine(f): : fs = 44100 # sampling rate, Hz, must be integer duration = 5.0 # in seconds, may be float
# generate samples, note conversion to float32 array volume = 0.1 num_samples = int(fs \* duration) samples = volume \* np.sin(2 \* math.pi \* (f / fs) \* np.arange(num_samples))
return samples, fs def create_data(path): : path = Path(path) hz = [110, 140, 180]
for i in range(6): : name = f”condition_{string.ascii_lowercase[i]}” for j in range(3):
> sample_path = path / name / f”sample_{j}.wav” > sample_path.parent.mkdir(exist_ok=True, parents=True) > audio, sr = random_sine(hz[j] \* (2\*\*i)) > sf.write(sample_path, audio, sr) config = Config( : folder=”/tmp/pref/audio/”, save_path=”/tmp/pref/results.csv”, conditions=[“condition_a”, “condition_b”], reference=”condition_c”, ) create_data(config.folder) ``` -------------------------------- ### Load Audio Samples Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/listening_tests.md Initializes the Samples object to organize audio files by condition from the specified directory. ```python from audiotools import preference as pr data = pr.Samples(config.folder) ``` -------------------------------- ### Choose Transform: High-pass or Low-pass Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md Use the Choose transform to apply either a HighPass or LowPass filter to an audio batch. This example demonstrates instantiating the transform and applying it to a signal batch. ```python transform = tfm.Choose( > [ > : tfm.HighPass(), > tfm.LowPass(), > ], ) seeds = range(batch_size) kwargs = transform.batch_instantiate(seeds) output_batch = transform(signal_batch.clone(), ``` ** ``` kwargs) audio_dict = make_dict(signal_batch, output_batch) post.disp(audio_dict, first_column=”batch_idx”) ``` -------------------------------- ### Load and Process MUSDB Multitrack Data Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md Example of loading MUSDB multitrack data using AudioLoader and AudioDataset. Includes data augmentation with VolumeNorm and Silence, and batch processing with PyTorch DataLoader. ```python >>> import audiotools as at >>> from pathlib import Path >>> from audiotools import transforms as tfm >>> import numpy as np >>> import torch >>> >>> def build_dataset( >>> sample_rate: int = 44100, >>> duration: float = 5.0, >>> musdb_path: str = "~/.data/musdb/", >>> ): >>> musdb_path = Path(musdb_path).expanduser() >>> loaders = { >>> src: at.datasets.AudioLoader( >>> sources=[musdb_path], >>> transform=tfm.Compose( >>> tfm.VolumeNorm(("uniform", -20, -10)), >>> tfm.Silence(prob=0.1), >>> ), >>> ext=[f"{src}.wav"], >>> ) >>> for src in ["vocals", "bass", "drums", "other"] >>> } >>> >>> dataset = at.datasets.AudioDataset( >>> loaders=loaders, >>> sample_rate=sample_rate, >>> duration=duration, >>> num_channels=1, >>> aligned=True, >>> transform=tfm.RescaleAudio(), >>> shuffle_loaders=True, >>> ) >>> return dataset, list(loaders.keys()) >>> >>> train_data, sources = build_dataset() >>> dataloader = torch.utils.data.DataLoader( >>> train_data, >>> batch_size=16, >>> num_workers=0, >>> collate_fn=train_data.collate, >>> ) >>> batch = next(iter(dataloader)) >>> >>> for k in sources: >>> src = batch[k] >>> src["transformed"] = train_data.loaders[k].transform( >>> src["signal"].clone(), **src["transform_args"] >>> ) >>> >>> mixture = sum(batch[k]["transformed"] for k in sources) >>> mixture = train_data.transform(mixture, **batch["transform_args"]) >>> >>> # Say a model takes the mix and gives back (n_batch, n_src, n_time). >>> # Construct the targets: >>> targets = at.AudioSignal.batch([batch[k]["transformed"] for k in sources], dim=1) ``` -------------------------------- ### Get Mel Filterbank Matrix Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Creates a Mel filterbank matrix used to convert FFT bins into Mel-frequency bins. Parameters include sample rate, FFT size, and number of Mel bins. ```python AudioSignal.get_mel_filters(sr=16000, n_fft=1024, n_mels=128) ``` -------------------------------- ### Apply Transforms to AudioSignal Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md Shows how to load an audio signal and apply a transform, noting the requirement to clone the signal to avoid in-place modification. ```python audio_path = "../../tests/audio/spk/f10_script4_produced.wav" signal = AudioSignal(audio_path, offset=6, duration=5) ``` ```python seed = 0 transform = tfm.LowPass() kwargs = transform.instantiate(seed) output = transform(signal.clone(), ``` ** ``` kwargs) # Lines below are to display the audio in a table in the # notebook. audio_dict = { > “signal”: signal, > “low_passed”: output, } post.disp(audio_dict) ``` ```python output = transform(signal.clone(), **kwargs) ``` -------------------------------- ### Sample from distributions using sample_from_dist Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Demonstrates sampling from uniform, constant, and normal distributions using a tuple-based configuration. ```pycon >>> dist_tuple = ("uniform", 0, 1) >>> sample_from_dist(dist_tuple) ``` ```pycon >>> dist_tuple = ("const", 0) >>> sample_from_dist(dist_tuple) ``` ```pycon >>> dist_tuple = ("normal", 0, 0.5) >>> sample_from_dist(dist_tuple) ``` -------------------------------- ### Pako Compression Library Initialization Source: https://github.com/descriptinc/audiotools/blob/master/audiotools/core/templates/headers.html Minified JavaScript wrapper for the Pako zlib compression library, supporting CommonJS, AMD, and global browser environments. ```javascript !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).pako=t()}}(function(){return function(){return function t(e,a,i){function n(s,o){if(!a[s]){if(!e[s]){var l="function"==typeof require&&require;if(!o&&l)return l(s,!0);if(r)return r(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var d=a[s]={exports:{}};e[s][0].call(d.exports,function(t){return n(e[s][1][t]||t)},d,d.exports,t,e,a,i)}return a[s].exports}for(var r="function"==typeof require&&require,s=0;s0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new o,this.strm.avail_out=0;var a=i.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(a!==h)throw new Error(s[a]);if(e.header&&i.deflateSetHeader(this.strm,e.header),e.dictionary){var c;if(c="string"==typeof e.dictionary?r.string2buf(e.dictionary):"[object ArrayBuffer]"===l.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,(a=i.deflateSetDictionary(this.strm,c))!==h)throw new Error(s[a]);this._dict_set=!0}}function c(t,e){var a=new u(e);if(a.push(t,!0),a.err)throw a.msg||s[a.err];return a.result}u.prototype.push=function(t,e){var a,s,o=this.strm,d=this.options.chunkSize;if(this.ended)return!1;s=e===~~e?e:!0===e?4:0,"string"==typeof t?o.input=r.string2buf(t):"[object ArrayBuffer]"===l.call(t)?o.input=new Uint8Array(t):o.input=t,o.next_in=0,o.avail_in=o.input.length;do{if(0===o.avail_out&&(o.output=new n.Buf8(d),o.next_out=0,o.avail_out=d),1!==(a=i.deflate(o,s))&&a!==h)return this.onEnd(a),this.ended=!0,!1;0!==o.avail_out&&(0!==o.avail_in||4!==s&&2!==s)||("string"===this.options.to?this.onData(r.buf2binstring(n.shrinkBuf(o.output,o.next_out))):this.onData(n.shrinkBuf(o.output,o.next_out)))}while((o.avail_in>0||0===o.avail_out)&&1!==a);return 4===s?(a=i.deflateEnd(this.strm),this.onEnd(a),this.ended=!0,a===h):2!==s||(this.onEnd(h),o.avail_out=0,!0)},u.prototype.onData=function(t){this.chunks.push(t)},u.prototype.onEnd=function(t){t===h&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=n.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},a.Deflate=u,a.deflate=c,a.deflateRaw=function(t,e){return(e=e||{}).raw=!0,c(t,e)},a.gzip=f ``` -------------------------------- ### Compare Compose with torch.nn.Sequential Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md Shows the similarity between Compose and torch.nn.Sequential in managing sequential operations. ```python net = torch.nn.Sequential( > torch.nn.Linear(1, 1), > torch.nn.Linear(1, 1), ) pp.pprint(net.state_dict()) ``` -------------------------------- ### Define and Save/Load a Custom BaseModel Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.ml.layers.md Demonstrates how to define a custom model inheriting from BaseModel, save it as a standard weights file, and then load it. It also shows saving as a torch.package and loading it back, including saving and loading from a folder with metadata. ```python class Model(ml.BaseModel): def __init__(self, arg1: float = 1.0): super().__init__() self.arg1 = arg1 self.linear = nn.Linear(1, 1) def forward(self, x): return self.linear(x) model1 = Model() with tempfile.NamedTemporaryFile(suffix=".pth") as f: model1.save( f.name, ) model2 = Model.load(f.name) out2 = seed_and_run(model2, x) assert torch.allclose(out1, out2) model1.save(f.name, package=True) model2 = Model.load(f.name) model2.save(f.name, package=False) model3 = Model.load(f.name) out3 = seed_and_run(model3, x) with tempfile.TemporaryDirectory() as d: model1.save_to_folder(d, {"data": 1.0}) Model.load_from_folder(d) ``` -------------------------------- ### Create an audio zip table Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.post.md Constructs a dictionary of audio signals and outputs, then generates an audio zip table. ```pycon >>> audio_dict = {} >>> for i in range(signal_batch.batch_size): >>> audio_dict[i] = { >>> "input": signal_batch[i], >>> "output": output_batch[i] >>> } >>> audiotools.post.audio_zip(audio_dict) ``` -------------------------------- ### Demonstrate All Implemented Audio Transforms Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md Iterates through available transforms in `audiotools.transforms`, applies each with probability 1.0, and displays the original and transformed audio signals along with spectral distance. Special source paths are provided for specific transforms like BackgroundNoise and RoomImpulseResponse. ```python seed = 0 transforms_to_demo = [] for x in dir(tfm): if hasattr(getattr(tfm, x), "transform"): if x not in ["Compose", "Choose", "Repeat", "RepeatUpTo"]: transforms_to_demo.append(x) audio_path = "../../tests/audio/spk/f10_script4_produced.wav" signal = AudioSignal(audio_path, offset=6, duration=5) signal.metadata["loudness"] = AudioSignal(audio_path).ffmpeg_loudness().item() audio_dict = { "Original": {"audio": signal, "spectral_distance": f"{0.0:1.2f}"} } distance = metrics.spectral.MelSpectrogramLoss() for transform_name in transforms_to_demo: kwargs = {} if transform_name == "BackgroundNoise": kwargs["sources"] = ["../../tests/audio/nz"] if transform_name == "RoomImpulseResponse": kwargs["sources"] = ["../../tests/audio/ir"] if transform_name == "CrossTalk": kwargs["sources"] = ["../../tests/audio/spk"] if "Quantization" in transform_name: kwargs["channels"] = ("choice", [8, 16, 32]) transform_cls = getattr(tfm, transform_name) t = transform_cls(prob=1.0, **kwargs) t_kwargs = t.instantiate(seed, signal) output = t(signal.clone(), t_kwargs) audio_dict[t.name] = { "audio": output, "spectral_distance": f"{distance(output, signal.clone()).item():1.2f}" } post.disp(audio_dict, first_column="transform") ``` -------------------------------- ### Batch AudioSignal Creation Source: https://github.com/descriptinc/audiotools/blob/master/docs/tutorials/transforms.md Initializes a batch of AudioSignals from a file. ```python audio_path = "../../tests/audio/spk/f10_script4_produced.wav" batch_size = 4 signal = AudioSignal(audio_path, offset=6, duration=5) signal_batch = AudioSignal.batch([signal.clone() for _ in range(batch_size)]) ``` -------------------------------- ### instantiate Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md Instantiates parameters for the transform. ```APIDOC ## instantiate ### Description Instantiates parameters for the transform. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **state** (RandomState, optional) – _description_, by default None * **signal** (AudioSignal, optional) – _description_, by default None ### Returns Dictionary containing instantiated arguments for every keyword argument to `self._transform`. ### Return type dict ### Request Example ```pycon >>> for seed in range(10): >>> kwargs = transform.instantiate(seed, signal) >>> output = transform(signal.clone(), **kwargs) ``` ``` -------------------------------- ### POST /audiotools/post/disp Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.post.md Displays an object, depending on if it is in a notebook or not. ```APIDOC ## POST /audiotools/post/disp ### Description Displays an object, depending on if its in a notebook or not. ### Parameters #### Request Body - **obj** (Any) - Required - Any object to display. ``` -------------------------------- ### batch_instantiate Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md Instantiates arguments for every item in a batch, given a list of states. Each state in the list corresponds to one item in the batch. ```APIDOC ## batch_instantiate ### Description Instantiates arguments for every item in a batch, given a list of states. Each state in the list corresponds to one item in the batch. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **states** (list, optional) – List of states, by default None * **signal** (AudioSignal, optional) – AudioSignal to pass to the `self.instantiate` section if it is needed for this transform, by default None ### Returns Collated dictionary of arguments. ### Return type dict ### Request Example ```pycon >>> batch_size = 4 >>> signal = AudioSignal(audio_path, offset=10, duration=2) >>> signal_batch = AudioSignal.batch([signal.clone() for _ in range(batch_size)]) >>> >>> states = [seed + idx for idx in list(range(batch_size))] >>> kwargs = transform.batch_instantiate(states, signal_batch) >>> batch_output = transform(signal_batch, **kwargs) ``` ``` -------------------------------- ### AudioSignal Manipulation and Creation Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.core.md Demonstrates creating and manipulating AudioSignal objects, including writing to disk, padding, and generating zero signals. ```APIDOC ## AudioSignal Examples ### Creating and writing a signal to disk: ```pycon >>> signal = AudioSignal(torch.randn(10, 1, 44100), 44100) >>> signal.write("/tmp/out.wav") ``` ### Writing a different element of the batch: ```pycon >>> signal[5].write("/tmp/out.wav") ``` ### Using this in a fluent interface: ```pycon >>> signal.write("/tmp/original.wav").low_pass(4000).write("/tmp/lowpass.wav") ``` ## zero_pad(before: int, after: int) ### Description Zero pads the audio_data tensor before and after. ### Parameters * **before** (*int*) – How many zeros to prepend to audio. * **after** (*int*) – How many zeros to append to audio. ### Returns AudioSignal with padding applied. ### Return type [AudioSignal](#audiotools.core.audio_signal.AudioSignal) ## zero_pad_to(length: int, mode: str = 'after') ### Description Pad with zeros to a specified length, either before or after the audio data. ### Parameters * **length** (*int*) – Length to pad to * **mode** (*str* *,* *optional*) – Whether to prepend or append zeros to signal, by default “after” ### Returns AudioSignal with padding applied. ### Return type [AudioSignal](#audiotools.core.audio_signal.AudioSignal) ## *classmethod* zeros(duration: float, sample_rate: int, num_channels: int = 1, batch_size: int = 1, **kwargs) ### Description Helper function create an AudioSignal of all zeros. ### Parameters * **duration** (*float*) – Duration of AudioSignal * **sample_rate** (*int*) – Sample rate of AudioSignal * **num_channels** (*int* *,* *optional*) – Number of channels, by default 1 * **batch_size** (*int* *,* *optional*) – Batch size, by default 1 ### Returns AudioSignal containing all zeros. ### Return type [AudioSignal](#audiotools.core.audio_signal.AudioSignal) ### Examples Generate 5 seconds of all zeros at a sample rate of 44100. ```pycon >>> signal = AudioSignal.zeros(5.0, 44100) ``` ``` -------------------------------- ### Run pre-commit on all files Source: https://github.com/descriptinc/audiotools/blob/master/README.md Execute pre-commit hooks on all files in the repository, not just staged ones. ```bash pre-commit run --all-files ``` -------------------------------- ### Apply a Transform to an Audio Signal Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.data.md Demonstrates the two-step process of instantiating transform parameters and applying the transform to a signal. Always clone the input signal to prevent in-place modification. ```pycon >>> seed = 0 >>> signal = ... >>> transform = transforms.NoiseFloor(db = ("uniform", -50.0, -30.0)) >>> kwargs = transform.instantiate() >>> output = transform(signal.clone(), **kwargs) ``` -------------------------------- ### Experiment Class Initialization Source: https://github.com/descriptinc/audiotools/blob/master/docs/source/audiotools.ml.md Initializes an Experiment object to manage experiment directories and CUDA devices. ```APIDOC ## Experiment Class ### Description This class contains utilities for managing experiments. It is a context manager that changes your directory to a specified experiment folder and sets the CUDA device. ### Method __init__ ### Parameters #### Path Parameters - **exp_directory** (str) - Optional - Folder where all experiments are saved, by default “runs/”. - **exp_name** (str) - Optional - Name of the experiment, by default uses the current time, date, and hostname to save. ### Request Example ```python from audiotools.ml.experiment import Experiment with Experiment(exp_directory='my_experiments/', exp_name='my_run') as exp: # Experiment context active pass ``` ### Response #### Success Response (200) - **None** - Initializes the experiment context. #### Response Example (No specific response body for initialization, context manager handles setup.) ``` -------------------------------- ### Visualize and play audio Source: https://github.com/descriptinc/audiotools/blob/master/docs/readme.md Display spectrograms and playback widgets for audio signals. ```python spk.specshow() plt.show() spk.embed(display=False) ``` ```python spk.widget() ``` -------------------------------- ### Dataset and DataLoader Integration Source: https://context7.com/descriptinc/audiotools/llms.txt Configuring audio datasets for PyTorch training pipelines, including multi-source alignment. ```python from audiotools.data.datasets import AudioLoader, AudioDataset from audiotools import transforms as tfm import torch # AudioLoader for loading audio from sources loader = AudioLoader( sources=["path/to/audio/folder", "path/to/audio.csv"], weights=[0.7, 0.3], # Sampling weights per source transform=tfm.Equalizer(), ext=[".wav", ".flac", ".mp3"], shuffle=True ) # AudioDataset wraps loaders for use with DataLoader dataset = AudioDataset( loaders=loader, sample_rate=44100, n_examples=1000, duration=5.0, loudness_cutoff=-40, num_channels=1, transform=tfm.RescaleAudio(), ) # Standard PyTorch DataLoader usage dataloader = torch.utils.data.DataLoader( dataset, batch_size=16, num_workers=4, collate_fn=dataset.collate, ) for batch in dataloader: signal = batch["signal"] transform_args = batch["transform_args"] # Apply transform augmented = dataset.transform(signal.clone(), **transform_args) # Multi-source aligned dataset (e.g., for source separation) loaders = { "vocals": AudioLoader(sources=["musdb/"], ext=["vocals.wav"]), "bass": AudioLoader(sources=["musdb/"], ext=["bass.wav"]), "drums": AudioLoader(sources=["musdb/"], ext=["drums.wav"]), } dataset = AudioDataset( loaders=loaders, sample_rate=44100, duration=5.0, aligned=True, # Aligned loading from same track shuffle_loaders=True, ) ```