Skip to content

Commit e46eb41

Browse files
committed
release: Bump version to 1.0.1 with performance, CLI, and packaging improvements
Performance: - Parallelize MusicAnalyzer feature precomputation with std::async - Optimize HPSS median filter using sorted insertion arrays and multi-threading - Add automatic downsampling from 44100 Hz to 22050 Hz in audio_io - Unify quick API (detect_bpm, etc.) with MusicAnalyzer for consistent results CLI: - Add progress bar to analysis output - Add system-info subcommand - Add bpm-detector style formatted output Python (bindings/python/): - Publish pip package to PyPI via trusted publisher - Add sonare CLI entry point wrapping the C++ binary - Expand test suite from 42 to 64 tests (test_analyzer.py) - Add requirements.lock and requirements-dev.lock for reproducible builds - Update analyzer.py, audio.py, cli.py with expanded API surface npm (package.json, README.npm.md): - Publish @libraz/libsonare with OIDC provenance - Fix postinstall script to work correctly for package consumers CI: - Add multi-platform wheel builds: Linux x86_64/aarch64, macOS arm64 - Configure PyPI trusted publisher workflow Tests: - Expand C++ test coverage across analysis, core, effects, feature, and util - Relax version format check to accept semver strings Docs: - Update README.md, README_ja.md, README.npm.md, and bindings/python/README.md
1 parent 318c523 commit e46eb41

77 files changed

Lines changed: 2289 additions & 1232 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.16)
2-
project(libsonare VERSION 1.0.0 LANGUAGES C CXX)
2+
project(libsonare VERSION 1.0.1 LANGUAGES C CXX)
33

44
set(CMAKE_CXX_STANDARD 17)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)

README.md

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,63 @@
11
# libsonare
22

33
[![CI](https://img.shields.io/github/actions/workflow/status/libraz/libsonare/ci.yml?branch=main&label=CI)](https://github.com/libraz/libsonare/actions)
4+
[![npm](https://img.shields.io/npm/v/@libraz/libsonare)](https://www.npmjs.com/package/@libraz/libsonare)
5+
[![PyPI](https://img.shields.io/pypi/v/libsonare)](https://pypi.org/project/libsonare/)
46
[![codecov](https://codecov.io/gh/libraz/libsonare/branch/main/graph/badge.svg)](https://codecov.io/gh/libraz/libsonare)
57
[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/libraz/libsonare/blob/main/LICENSE)
68
[![C++17](https://img.shields.io/badge/C%2B%2B-17-blue?logo=c%2B%2B)](https://en.cppreference.com/w/cpp/17)
79
[![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20WebAssembly-lightgrey)](https://github.com/libraz/libsonare)
810

9-
**librosa-like audio analysis for C++ and browsers.** Fast, dependency-free, runs anywhere.
11+
**librosa-like audio analysis for C++, Python, and browsers.** Fast, dependency-free, runs anywhere.
1012

11-
## Use Cases
13+
Tens of times faster than librosa/Python.
1214

13-
- **Love librosa, need native speed?** → C++ with Eigen3 vectorization
14-
- **Audio analysis in the browser?** → WebAssembly build (262KB)
15-
- **Building a music app?** → BPM, key, chords, beats, sections in one library
15+
## Installation
16+
17+
```bash
18+
npm install @libraz/libsonare # JavaScript / TypeScript (WASM)
19+
pip install libsonare # Python
20+
```
1621

1722
## Quick Start
1823

1924
### JavaScript / TypeScript
2025

21-
```bash
22-
npm install @libraz/sonare # Coming soon (currently in beta)
26+
```typescript
27+
import { init, detectBpm, detectKey, analyze } from '@libraz/libsonare';
28+
29+
await init();
30+
31+
const bpm = detectBpm(samples, sampleRate);
32+
const key = detectKey(samples, sampleRate); // { name: "C major", confidence: 0.95 }
33+
const result = analyze(samples, sampleRate);
2334
```
2435

25-
```typescript
26-
import { Sonare } from '@libraz/sonare';
36+
### Python
37+
38+
```python
39+
import libsonare
40+
41+
bpm = libsonare.detect_bpm(samples, sample_rate=22050)
42+
key = libsonare.detect_key(samples, sample_rate=22050)
43+
result = libsonare.analyze(samples, sample_rate=22050)
44+
45+
# Or use the Audio class
46+
audio = libsonare.Audio.from_file("song.mp3")
47+
print(f"BPM: {audio.detect_bpm()}, Key: {audio.detect_key()}")
48+
```
49+
50+
### Python CLI
51+
52+
```bash
53+
pip install libsonare
54+
55+
sonare analyze song.mp3
56+
# > Estimated BPM : 161.00 BPM (conf 75.0%)
57+
# > Estimated Key : C major (conf 100.0%)
2758

28-
const sonare = await Sonare.create();
29-
const bpm = sonare.detectBpm(samples, sampleRate);
30-
const key = sonare.detectKey(samples, sampleRate); // { root: "C", mode: "Major" }
31-
const beats = sonare.detectBeats(samples, sampleRate);
59+
sonare bpm song.mp3 --json
60+
# {"bpm": 161.0}
3261
```
3362

3463
### C++
@@ -37,8 +66,8 @@ const beats = sonare.detectBeats(samples, sampleRate);
3766
#include <sonare/sonare.h>
3867

3968
auto audio = sonare::Audio::from_file("music.mp3");
40-
float bpm = sonare::quick::detect_bpm(audio.data(), audio.size(), audio.sample_rate());
41-
auto key = sonare::quick::detect_key(audio.data(), audio.size(), audio.sample_rate());
69+
auto result = sonare::MusicAnalyzer(audio).analyze();
70+
std::cout << "BPM: " << result.bpm << ", Key: " << result.key.to_string() << std::endl;
4271
```
4372

4473
## Features
@@ -48,42 +77,44 @@ auto key = sonare::quick::detect_key(audio.data(), audio.size(), audio.sample_ra
4877
| BPM / Tempo | STFT / iSTFT | HPSS |
4978
| Key Detection | Mel Spectrogram | Time Stretch |
5079
| Beat Tracking | MFCC | Pitch Shift |
51-
| Chord Recognition | Chroma | Normalize |
80+
| Chord Recognition | Chroma | Normalize / Trim |
5281
| Section Detection | CQT / VQT | |
82+
| Timbre / Dynamics | Spectral Features | |
83+
| Pitch Tracking (YIN/pYIN) | Onset Detection | |
84+
| Real-time Streaming | Resample | |
5385

54-
## librosa Compatibility
86+
## Performance
5587

56-
libsonare implements librosa-compatible algorithms with identical default parameters. Migration is straightforward.
88+
Dramatically faster than Python-based alternatives. Parallelized analysis with automatic CPU detection, optimized HPSS with multi-threaded median filter.
5789

58-
```python
59-
# librosa
60-
S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128, fmax=8000)
61-
```
90+
See [Benchmarks](https://libsonare.libraz.net/docs/benchmarks) for detailed comparisons.
6291

63-
```cpp
64-
// libsonare
65-
auto mel = sonare::MelSpectrogram(sr, 2048, 512, 128, 0, 8000);
66-
auto S = mel.compute(audio);
67-
```
92+
## librosa Compatibility
6893

69-
See [librosa Compatibility Guide](https://libsonare.libraz.net/docs/librosa-compatibility) for details.
94+
Default parameters match librosa:
95+
- Sample rate: 22050 Hz
96+
- n_fft: 2048, hop_length: 512, n_mels: 128
97+
- fmin: 0.0, fmax: sr/2
7098

71-
## Build
99+
## Build from Source
72100

73101
```bash
74-
# Native
102+
# Native (C++ library + CLI)
75103
make build && make test
76104

77-
# WebAssembly (requires: source /path/to/emsdk/emsdk_env.sh)
105+
# WebAssembly
78106
make wasm
107+
108+
# Release (optimized)
109+
make release
79110
```
80111

81112
## Documentation
82113

83114
- [Getting Started](https://libsonare.libraz.net/docs/getting-started)
84115
- [JavaScript API](https://libsonare.libraz.net/docs/js-api)
116+
- [Python API](https://libsonare.libraz.net/docs/python-api)
85117
- [C++ API](https://libsonare.libraz.net/docs/cpp-api)
86-
- [Examples](https://libsonare.libraz.net/docs/examples)
87118
- [WebAssembly Guide](https://libsonare.libraz.net/docs/wasm)
88119

89120
## License

README.npm.md

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,34 @@
22

33
[![CI](https://img.shields.io/github/actions/workflow/status/libraz/libsonare/ci.yml?branch=main&label=CI)](https://github.com/libraz/libsonare/actions)
44
[![npm](https://img.shields.io/npm/v/@libraz/libsonare)](https://www.npmjs.com/package/@libraz/libsonare)
5-
[![codecov](https://codecov.io/gh/libraz/libsonare/branch/main/graph/badge.svg)](https://codecov.io/gh/libraz/libsonare)
5+
[![PyPI](https://img.shields.io/pypi/v/libsonare)](https://pypi.org/project/libsonare/)
66
[![License](https://img.shields.io/github/license/libraz/libsonare)](https://github.com/libraz/libsonare/blob/main/LICENSE)
7-
[![C++17](https://img.shields.io/badge/C%2B%2B-17-blue?logo=c%2B%2B)](https://en.cppreference.com/w/cpp/17)
87

9-
Fast, dependency-free audio analysis library for browser and Node.js via WebAssembly. A librosa-like API for music information retrieval.
8+
Fast, dependency-free audio analysis library for browser and Node.js via WebAssembly. A librosa-like API for music information retrieval -- **tens of times faster** than Python.
9+
10+
## Installation
11+
12+
```bash
13+
npm install @libraz/libsonare
14+
```
1015

1116
## Usage
1217

1318
```typescript
14-
import { init, detectBpm, detectKey, analyze } from '@libraz/libsonare';
19+
import { init, detectBpm, detectKey, analyze, Audio } from '@libraz/libsonare';
1520

1621
await init();
1722

18-
// Quick analysis
19-
const result = await analyze(audioBuffer, sampleRate);
20-
console.log(`BPM: ${result.bpm}, Key: ${result.key.tonic} ${result.key.mode}`);
23+
// Function API
24+
const bpm = detectBpm(samples, sampleRate);
25+
const key = detectKey(samples, sampleRate);
26+
const result = analyze(samples, sampleRate);
27+
console.log(`BPM: ${result.bpm}, Key: ${result.key.name}`);
2128

22-
// Individual features
23-
const bpm = detectBpm(audioBuffer, sampleRate);
24-
const key = detectKey(audioBuffer, sampleRate);
29+
// Audio class API
30+
const audio = Audio.fromBuffer(samples, sampleRate);
31+
console.log(`BPM: ${audio.detectBpm()}`);
32+
console.log(`Key: ${audio.detectKey().name}`);
2533
```
2634

2735
### Browser (CDN)
@@ -35,7 +43,7 @@ const key = detectKey(audioBuffer, sampleRate);
3543
</script>
3644
```
3745

38-
### Bundlers (webpack, Vite, Next.js, etc.)
46+
### Bundlers (Vite, webpack, Next.js, etc.)
3947

4048
If your bundler doesn't automatically resolve the `.wasm` file, specify its path:
4149

@@ -46,19 +54,36 @@ import { init } from '@libraz/libsonare';
4654
await init({ wasmPath: wasmUrl });
4755
```
4856

57+
### Real-time Streaming
58+
59+
```typescript
60+
import { init, StreamAnalyzer } from '@libraz/libsonare';
61+
62+
await init();
63+
64+
const analyzer = new StreamAnalyzer({ sampleRate: 44100 });
65+
66+
// In audio processing callback
67+
analyzer.process(audioChunk);
68+
69+
const stats = analyzer.stats();
70+
console.log(`BPM: ${stats.estimate.bpm}, Key: ${stats.estimate.key}`);
71+
```
72+
4973
## Features
5074

51-
- BPM / tempo detection
52-
- Key detection (major/minor)
53-
- Beat tracking
54-
- Chord recognition
55-
- Onset detection
56-
- Mel spectrogram, MFCC, Chroma
57-
- Spectral features (centroid, bandwidth, rolloff, flatness)
58-
- Pitch detection (YIN, pYIN)
59-
- HPSS (harmonic-percussive separation)
60-
- Time stretching & pitch shifting
61-
- Real-time streaming analysis
75+
- **Detection**: BPM, key, beats, onsets, chords, sections
76+
- **Effects**: HPSS, time stretch, pitch shift, normalize, trim
77+
- **Features**: STFT, mel spectrogram, MFCC, chroma, CQT/VQT, spectral features
78+
- **Pitch**: YIN, pYIN algorithms
79+
- **Streaming**: Real-time analysis with progressive estimates
80+
- **Conversions**: Hz/mel/MIDI/note, frames/time, resample
81+
82+
## Also available
83+
84+
```bash
85+
pip install libsonare # Python bindings with CLI
86+
```
6287

6388
## License
6489

0 commit comments

Comments
 (0)