Extract temporal properties (envelope, periodicity, temporal fine structure) from sound signals
Project description
Tempobox
Extract temporal properties from sound signals by decomposing audio into three fundamental acoustic components: envelope, periodicity, and temporal fine structure (TFS).
Overview
This library enables acoustic research and speech processing by separating sound signals into their core temporal components:
- Envelope: The overall amplitude contour or modulation of the signal
- Periodicity: The repeating/cyclical characteristics of the signal
- Temporal Fine Structure (TFS): The fine details and rapid fluctuations within each cycle
These components can be extracted individually, in pairs, or regenerated to reconstruct the original signal. The library also supports generating speech chimeras by mixing temporal components from different audio sources.
Installation
We suggest using uv to install packages and handle Python environments.
uv add tempobox
If you wish to use pip, you can install this package by
pip install tempobox
Quick Start
Interactive Terminal UI
The easiest way to get started is using the interactive Terminal User Interface (TUI):
# Launch the TUI
tempobox
# or using uv
uv run -m tempobox
The TUI provides an intuitive workflow for:
- Loading audio files
- Selecting temporal components to extract
- Visualizing results
- Saving outputs
Extract temporal properties from audio (Python)
from tempobox import Waveform
# Load audio from file
waveform = Waveform.from_file("audio.wav")
# Extract envelope only
envelope = waveform.extract("env")
# Extract periodicity and TFS (removes envelope)
per_tfs = waveform.extract("per", "tfs")
# Save extracted waveform to WAV file
envelope.save("envelope.wav")
# Plot waveform
waveform.plot(save_path="plot.png")
Use extraction functions directly
from tempobox import extract_env, extract_per, extract_tfs
import numpy as np
# Use pre-loaded numpy array and sample rate
waveform = np.random.randn(16000) # 1 second of audio at 16kHz
sr = 16000
# Extract individual components
envelope = extract_env(waveform, sr=sr)
periodicity = extract_per(waveform)
tfs = extract_tfs(waveform)
# Extract combinations
from tempobox import extract_env_and_per, extract_env_and_tfs, extract_per_and_tfs
env_and_per = extract_env_and_per(waveform, sr=sr)
env_and_tfs = extract_env_and_tfs(waveform)
per_and_tfs = extract_per_and_tfs(waveform)
Regenerate audio from components
from tempobox import extract_env, extract_per, extract_tfs, Waveform
waveform = Waveform.from_file("audio.wav")
# Extract components
envelope = waveform.extract("env")
periodicity = waveform.extract("per")
tfs = waveform.extract("tfs")
# Save individual components
envelope.save("envelope.wav")
periodicity.save("periodicity.wav")
tfs.save("tfs.wav")
Reconstruct audio from individual components
from tempobox.api import reconstruct_from_waveforms
from tempobox import Waveform
# Load extracted components (or extract them)
env = Waveform.from_file("envelope.wav")
per = Waveform.from_file("periodicity.wav")
tfs = Waveform.from_file("tfs.wav")
# Reconstruct the original signal from components
reconstructed = reconstruct_from_waveforms(env, tfs, per)
reconstructed.save("reconstructed.wav")
Batch process multiple audio files
from tempobox import BatchProcessor
# Create processor from directory
batch = BatchProcessor.from_directory("audio_files/", glob_pattern="*.wav")
# Extract from all files with progress tracking
results = batch.extract("env", "per", "tfs", verbose=True)
# Access results
print(f"Successful: {results.success_count}, Failed: {results.failure_count}")
for filepath, waveform in results.successful.items():
print(f"Processed: {filepath}")
Evaluate extraction quality
from tempobox import Evaluator
import numpy as np
# Create evaluator from two signals
evaluator = Evaluator(baseline, to_evaluate, baseline_sr, to_evaluate_sr)
# Or create from Waveform objects
evaluator = Evaluator.from_waveforms(baseline_waveform, to_evaluate_waveform)
# Calculate various quality metrics
snr_value = evaluator.snr() # Higher is better
mse_value = evaluator.mse() # Lower is better
mfcc_cosine_sim = evaluator.mfcc_cosine_similarity() # Higher is better
print(f"SNR: {snr_value:.2f} dB")
print(f"MSE: {mse_value:.4f}")
print(f"MFCC Similarity: {mfcc_cosine_sim:.4f}")
Generate speech chimeras
Mix temporal components from different audio sources:
from tempobox import generate_chimera
# Create chimera: envelope from speaker A, TFS from speaker B
chimera = generate_chimera(
envelope_source="speaker_a.wav",
tfs_source="speaker_b.wav",
sr=22050
)
You can also pass pre-loaded numpy arrays instead of file paths:
import librosa
import numpy as np
audio_a, sr = librosa.load("speaker_a.wav")
audio_b, sr = librosa.load("speaker_b.wav")
chimera = generate_chimera(
envelope_source=audio_a,
tfs_source=audio_b,
sr=sr
)
API Reference
Waveform Class
Waveform(signal: np.ndarray, sr: int)
Main class for working with audio waveforms and extracting temporal features.
Class Methods:
from_file(file_path: str | Path) -> Waveform- Load audio from file using librosa
Instance Methods:
extract(*properties: TemporalProperty, **kwargs) -> Waveform- Extract temporal properties*properties: Any combination of"env","per","tfs"- Returns new Waveform with extracted components
save(file_path: str | Path) -> None- Save waveform to WAV file using soundfileplot(figsize: tuple[int, int] = (12, 4), save_path: str | Path | None = None) -> None- Plot and optionally save waveform visualizationduration() -> float- Get duration in secondsresample(target_sr: int) -> Waveform- Resample to target sample rate__len__() -> int- Get number of samples__str__() -> str- Human-readable representation
Properties:
signal: np.ndarray- Audio samples (1D array)sr: int- Sample rate in Hz
Batch Processing
BatchProcessor(filepaths: list[str | Path])
Process multiple audio files efficiently with lazy loading and progress tracking.
Class Methods:
from_directory(directory: str | Path, glob_pattern: str = "**/*.wav") -> BatchProcessor- Load files from directory
Instance Methods:
extract(*properties: str, verbose: bool = True, **kwargs) -> BatchResults- Extract temporal components from all files__len__() -> int- Get number of files to process
BatchResults
Results container from batch processing operations.
Properties:
successful: dict[str, Waveform]- Successfully processed files mapping filepath to extracted Waveformfailed: dict[str, str]- Failed files mapping filepath to error messagesuccess_count: int- Number of successfully processed filesfailure_count: int- Number of failed filestotal_count: int- Total files processed
Reconstruction
reconstruct_from_waveforms(env: Waveform, tfs: Waveform, per: Waveform) -> Waveform
Reconstruct audio signal from temporal component Waveforms. Automatically handles sample rate mismatches by resampling.
reconstruct(env: np.ndarray, tfs: np.ndarray, per: np.ndarray) -> np.ndarray
Reconstruct audio signal from numpy arrays of temporal components.
Quality Evaluation
Evaluator(baseline: np.ndarray, to_evaluate: np.ndarray, baseline_sr: int, to_evaluate_sr: int)
Evaluate the quality of extracted or processed signals against a baseline.
Class Methods:
from_waveforms(baseline: Waveform, to_evaluate: Waveform) -> Evaluator- Create from Waveform objects
Instance Methods:
snr() -> float- Signal-to-Noise Ratio in dB (higher is better)mse() -> float- Mean Squared Error (lower is better)mfcc_cosine_similarity(n_mfcc: int = 80) -> float- MFCC cosine similarity (higher is better)
Extraction Functions
All extraction functions accept a waveform and return a numpy array of the same shape.
extract_env(waveform, sr, cutoff=30, order=5)- Extract envelope (amplitude modulation)extract_per(waveform)- Extract periodicity (cyclical characteristics)extract_tfs(waveform)- Extract temporal fine structure (fine details within cycles)extract_env_and_per(waveform, sr, cutoff=30, order=5)- Extract envelope and periodicity (removes TFS)extract_env_and_tfs(waveform)- Extract envelope and TFS (removes periodicity)extract_per_and_tfs(waveform)- Extract periodicity and TFS (removes envelope)
Utility Functions
generate_chimera(envelope_source, tfs_source, sr, cutoff=30, order=5)- Generate speech chimera from two audio sources (numpy arrays or file paths)- Returns numpy array with envelope from first source and TFS from second source
Accessing API Elements
The primary API and extraction functions are available at the package level for easy access:
from tempobox import (
Waveform,
BatchProcessor,
Evaluator,
generate_chimera,
reconstruct,
reconstruct_from_waveforms,
extract_env,
extract_per,
extract_tfs,
extract_env_and_per,
extract_env_and_tfs,
extract_per_and_tfs,
)
# Internal metric functions available in core
from tempobox.core.metrics import snr, mse, mfcc_cosine_similarity
Package Structure
The package is organized into several modules:
-
api/- User-facing API (all classes and functions users interact with directly)waveform.py- MainWaveformclass for audio processingextractions.py- Temporal component extraction functionschimera.py- Speech chimera generationreconstruct.py- Signal reconstruction from componentsbatchprocessor.py- Batch processing of multiple filesevaluator.py- Signal quality evaluation withEvaluatorclass
-
core/- Internal utilities (lower-level signal processing and helper functions)signal_processing.py- Filtering and signal processingperiodicity.py- Cycle and periodicity manipulationtransforms.py- Core signal transformations (IPC, ITW)metrics.py- Signal quality metric functions (used by Evaluator)array_utils.py- Array manipulation utilitiesconstants.py- Package constantsvalidation.py- Input validation utilitiesplotting.py- Visualization utilities
-
tui/- Terminal user interface for interactive audio processing
Version History
- 0.3.0 - Signal reconstruction, batch processing, quality evaluation (Evaluator), loguru migration
- 0.2.1 - Input validation, logging support, comprehensive test coverage (115 tests, 63%)
- 0.2.0 - Refactored package architecture for better organization
- 0.1.1 - TUI support added
- 0.1.0 - Initial release
Extraction Algorithms
The library uses signal processing techniques to decompose audio:
- Infinite Peak Clipping (IPC): Converts signal to ±1 signs, removing amplitude information
- Hilbert Transform: Extracts instantaneous amplitude (envelope)
- Isochronous Time Warping (ITW): Removes periodicity by normalizing cycle lengths
- Butterworth Filtering: Low-pass filtering for envelope smoothing
- Zero-crossing Detection: Identifies signal cycles for cycle-based operations
Component Interactions
The three components can be combined to reconstruct the signal with minimal loss. Periodicity can be reinjected to the envelope and temporal fine structure arrays to acquire env_per, and tfs_per, respectively. The multiplication of these two approximates the original signal.
Features
Text User Interface (TUI)
The integrated TUI makes audio processing accessible without programming:
- File Loading: Browse and load audio files with a file path input
- Feature Selection: Toggle checkboxes to select envelope, periodicity, and TFS
- Real-time Info: Display audio duration, sample rate, and sample count
- Visualization: Generate and save side-by-side comparison plots
- Error Handling: Clear error messages and status notifications
- Navigation: Intuitive screen-based navigation with back buttons
Programmatic API
For advanced workflows and automation:
- Load and manipulate waveforms directly in Python
- Extract components individually or in combinations
- Generate speech chimeras by mixing audio sources
- Create custom visualizations with utility functions
- Integrate with other signal processing libraries
Requirements
- Python ≥ 3.11
- numpy ≥ 2.4.4
- scipy ≥ 1.17.1
- librosa ≥ 0.11.0
- matplotlib ≥ 3.10.8 (for visualization)
Optional Dependencies (for TUI)
- Textual ≥ 8.2.3 (included in dev dependencies)
Examples
Speech Processing
Extract components to analyze speaker-independent acoustic properties:
from tempobox import Waveform
waveform = Waveform.from_file("speech.wav")
envelope = waveform.extract("env")
tfs = waveform.extract("tfs")
# Save for analysis
envelope.save("speech_envelope.wav")
tfs.save("speech_tfs.wav")
# Envelope captures prosody and speaking rate
# TFS captures speaker identity and phonetic details
Audio Synthesis
Create synthetic speech by mixing temporal components:
from tempobox import generate_chimera
# Mix speaker A's prosody with speaker B's voice quality
chimera = generate_chimera(
envelope_source="speaker_a.wav",
tfs_source="speaker_b.wav",
sr=22050
)
Visualization
Compare original and extracted components:
from tempobox import Waveform
from tempobox.tui.utils import side_by_side_plotting
waveform = Waveform.from_file("audio.wav")
extracted = waveform.extract("env", "per")
# Create comparison plot
side_by_side_plotting(waveform, extracted, "ENV+PER", save_path="comparison.png")
References
This library implements techniques commonly used in auditory research and speech processing:
TODO: Add references
License
MIT
Contributing
Contributions are welcome! Please feel free to submit pull requests or open issues.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tempobox-0.3.0.tar.gz.
File metadata
- Download URL: tempobox-0.3.0.tar.gz
- Upload date:
- Size: 27.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8082dfa8138b9104f6ae79e2eb526e41f302761602d6e69d4ab753329c3a52e2
|
|
| MD5 |
a1405df59a1d7d05b92090a378eb9a3e
|
|
| BLAKE2b-256 |
58a78ed079ab4faef5b2661d8902112eccf86fb2d81727214980c53de114a759
|
File details
Details for the file tempobox-0.3.0-py3-none-any.whl.
File metadata
- Download URL: tempobox-0.3.0-py3-none-any.whl
- Upload date:
- Size: 36.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a076012b654515459ae7a88e7e670e6b2df1273474f6c73c09ae0a4570b9b28
|
|
| MD5 |
de6ad20231acdbe375fc70ba4735bd74
|
|
| BLAKE2b-256 |
c05f218cae04521968667e6ead29ef7f3779e3405d0cf0a75a694f80ca6ffead
|