Skip to main content

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 soundfile
  • plot(figsize: tuple[int, int] = (12, 4), save_path: str | Path | None = None) -> None - Plot and optionally save waveform visualization
  • duration() -> float - Get duration in seconds
  • resample(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 Waveform
  • failed: dict[str, str] - Failed files mapping filepath to error message
  • success_count: int - Number of successfully processed files
  • failure_count: int - Number of failed files
  • total_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 - Main Waveform class for audio processing
    • extractions.py - Temporal component extraction functions
    • chimera.py - Speech chimera generation
    • reconstruct.py - Signal reconstruction from components
    • batchprocessor.py - Batch processing of multiple files
    • evaluator.py - Signal quality evaluation with Evaluator class
  • core/ - Internal utilities (lower-level signal processing and helper functions)

    • signal_processing.py - Filtering and signal processing
    • periodicity.py - Cycle and periodicity manipulation
    • transforms.py - Core signal transformations (IPC, ITW)
    • metrics.py - Signal quality metric functions (used by Evaluator)
    • array_utils.py - Array manipulation utilities
    • constants.py - Package constants
    • validation.py - Input validation utilities
    • plotting.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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tempobox-0.3.0.tar.gz (27.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tempobox-0.3.0-py3-none-any.whl (36.7 kB view details)

Uploaded Python 3

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

Hashes for tempobox-0.3.0.tar.gz
Algorithm Hash digest
SHA256 8082dfa8138b9104f6ae79e2eb526e41f302761602d6e69d4ab753329c3a52e2
MD5 a1405df59a1d7d05b92090a378eb9a3e
BLAKE2b-256 58a78ed079ab4faef5b2661d8902112eccf86fb2d81727214980c53de114a759

See more details on using hashes here.

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

Hashes for tempobox-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8a076012b654515459ae7a88e7e670e6b2df1273474f6c73c09ae0a4570b9b28
MD5 de6ad20231acdbe375fc70ba4735bd74
BLAKE2b-256 c05f218cae04521968667e6ead29ef7f3779e3405d0cf0a75a694f80ca6ffead

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page