Metadata-Version: 2.5
Name: convolinear
Version: 0.2.0
Summary: Fluent signal processing for Python, one line at a time.
Project-URL: Homepage, https://github.com/sahmed0/convolinear#readme
Project-URL: Repository, https://github.com/sahmed0/convolinear
Project-URL: Issues, https://github.com/sahmed0/convolinear/issues
Author-email: Sajid Ahmed <bracer.chasm-8i@icloud.com>
License: MIT
License-File: LICENSE
Keywords: audio-processing,data-pipeline,dsp,fft,filter,filtering,fluent-interface,frequency-domain,numpy,pandas,peak-detection,power-spectrum,scipy,signal-processing,spectral-analysis,spectrogram,time-series
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
Classifier: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: numpy>=1.23.2
Requires-Dist: scipy>=1.9.2
Provides-Extra: audio
Requires-Dist: soundfile>=0.13.0; extra == 'audio'
Provides-Extra: pandas
Requires-Dist: pandas>=2.0; extra == 'pandas'
Requires-Dist: pyarrow>=14.0; extra == 'pandas'
Provides-Extra: plot
Requires-Dist: matplotlib>=3.6.0; extra == 'plot'
Description-Content-Type: text/markdown

[![MIT License](https://img.shields.io/badge/MIT-2026_Sajid_Ahmed-limegreen.svg)](https://opensource.org/license/mit)
[![Python](https://img.shields.io/badge/Python-3.11+-blue)](https://www.python.org/)

# convolinear - Fluent Signal Processing for Python

Fluent signal processing for Python, one line at a time.

`convolinear` wraps the power of NumPy and SciPy in a fluent, readable API. Common DSP tasks -
loading audio, filtering, mixing, and spectral analysis - become short, expressive one-liners
instead of 10+ lines of boilerplate.

Extract data from a `.wav` file, bandpass it, normalise it, take the Fourier transform, and plot it.
**All in a single line of code:**

```python
Signal.from_wav("audio.wav").bandpass(300, 3000).normalize().fft().plot()
```

<p align="center">
  <img src="https://github.com/sahmed0/convolinear/blob/main/demo_output.png?raw=true" alt="convolinear signal processing pipeline result: bandpass filter, normalize, and FFT plot of an audio signal" width="700">
</p>

## Installation

**Core requirements:** Python 3.11+, NumPy >= 1.23.2, SciPy >= 1.9.2

**Optional dependencies** unlock the following loaders and features:

| Extra | Packages installed | Unlocks |
|-------|--------------------|---------|
| `plot` | matplotlib | every `.plot()` method |
| `audio` | soundfile | `Signal.from_audio()` |
| `pandas` | pandas, pyarrow | `from_csv()`, `from_parquet()`, `from_pandas()`, `to_dataframe()` |

MATLAB `.mat` files load through SciPy, already a core dependency - no extra needed.

### With pip

`convolinear` is published on [PyPi](https://pypi.org/project/convolinear):

```bash
pip install convolinear
```

```bash
pip install "convolinear[plot,audio,pandas]"
```

### With conda

`convolinear` is published on [conda-forge](https://anaconda.org/conda-forge/convolinear):

```bash
conda install -c conda-forge convolinear
```

conda-forge packages don't support pip-style extras - install the optional dependencies as
separate packages instead:

```bash
conda install -c conda-forge convolinear matplotlib soundfile pandas pyarrow
```

### With uv

```bash
uv add convolinear
```

```bash
uv add "convolinear[plot,audio,pandas]"
```

## Quickstart

Clean up a noisy tone, then find out what is in it:

```python
from convolinear import Signal

tone = Signal.sine(440, duration=1.0, sample_rate=8000)
noise = Signal.noise(duration=1.0, sample_rate=8000, amplitude=0.5, seed=42)

cleaned = (tone + noise).bandpass(300, 600).normalize()

spectrum = cleaned.fft()
print(f"Dominant frequency: {spectrum.peak_frequency:.1f} Hz")   # ~440.0 Hz

for freq, magnitude in spectrum.top_n(3):
    print(f"{freq:7.1f} Hz   magnitude {magnitude:.4f}")
```

Every transformation returns a **new** object - the original is never modified, and a `Signal`'s
sample array is genuinely read-only - so branching from one source is always safe.

### Not just audio

Sample rates are floats, and rates below 1 Hz work exactly like any other. Three years of daily
temperatures, one sample per day:

```python
sig = Signal(temps, sample_rate=1 / 86400)
cycle_hz = sig.remove_dc().fft(window="hann").peak_frequency
print(f"Dominant period: {1 / cycle_hz / 86400:.0f} days")   # Dominant period: 365 days
```

## Capabilities

- **Load from anywhere** - WAV, FLAC/OGG/MP3 (via soundfile), CSV, Parquet, NumPy, pandas, MATLAB,
  or generated tones, noise and arbitrary functions. Sample rates are inferred from dated data.
- **Transform** - normalize, trim, gain, concat, resample, window, remove DC, reverse, clip, fade.
- **Filter** - Butterworth lowpass, highpass, bandpass and bandstop.
- **Analyse** - convolution and correlation, time-delay estimation, peak detection.
- **Frequency domain** - `fft()` returns a `Spectrum` of raw complex coefficients that inverts
  losslessly; `psd()` gives a Welch power spectral density; `spectrogram()` shows how content
  evolves over time.
- **Plot** - one-call matplotlib views of any signal, spectrum, PSD or spectrogram.

## Documentation

- **[Full documentation and API reference](https://sahmed0.github.io/convolinear/)**
- [Quickstart](https://sahmed0.github.io/convolinear/quickstart/) - five worked recipes.
- [ECG: heart rate from raw samples](https://sahmed0.github.io/convolinear/examples/ecg_heart_rate/) -
  raw signal to beats per minute.
- [Daily data: finding slow cycles](https://sahmed0.github.io/convolinear/examples/daily_cycles/) -
  sub-1 Hz sample rates.
- [Benchmarks](https://sahmed0.github.io/convolinear/examples/benchmarks/) - measured throughput.
- [CHANGELOG](https://github.com/sahmed0/convolinear/blob/main/CHANGELOG.md) - release history and migration notes.

Runnable scripts live in [`examples/`](https://github.com/sahmed0/convolinear/tree/main/examples).

## Development

If you want to contribute to this project:

1. Fork the repository on GitHub.
2. Set up an editable clone with [uv](https://docs.astral.sh/uv/):

```bash
git clone https://github.com/yourusername/convolinear
cd convolinear
uv sync
uv run pytest
```

3. Make a new branch for your edits.
4. Make changes.
5. Run the same checks CI runs:

```bash
uv run ruff check .
uv run ruff format --check .
uv run mypy convolinear
uv run pytest
```

6. Commit changes to your fork.
7. Open a Pull Request.

## License

This project is licensed under the [MIT License](https://github.com/sahmed0/convolinear/blob/main/LICENSE).

Copyright © 2026 Sajid Ahmed
