Skip to content

Commit c2fe225

Browse files
committed
✨ feat(Cargo.lock): Add arc-swap, portable-atomic, pyo3-log packages
🔧 fix(Cargo.lock): Update pyo3, pyo3-build-config, pyo3-ffi, pyo3-macros, pyo3-macros-backend versions to 0.20.3 🔧 fix(pyproject.toml): Update shazamio_core version to 1.1.0-rc.2 🔧 fix(Cargo.toml): Update shazamio-core version to 1.1.0-rc.2, add pyo3-log and log dependencies 🔧 fix(src/lib.rs): Add logging initialization and messages, update segment duration to 10 seconds 🔧 fix(src/fingerprinting/algorithm.rs): Update segment duration to 10 seconds 🔧 fix(shazamio_core/shazamio_core.py): Update segment duration to 10 seconds, add type hints and docstrings 🔧 fix(shazamio_core/shazamio_core.pyi): Update segment duration to 10 seconds, add type hints and docstrings 🔧 fix(.github/workflows/CI.yml): Update comments for macOS targets
1 parent 86d3bee commit c2fe225

File tree

8 files changed

+154
-40
lines changed

8 files changed

+154
-40
lines changed

.github/workflows/CI.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
fail-fast: false
4545
matrix:
4646
include:
47-
# macOS 13 (x86_64) со всеми версиями Python
47+
# macOS 13 (x86_64)
4848
- os: macos-13
4949
target: x86_64-apple-darwin
5050
python-version: "3.9"
@@ -58,7 +58,7 @@ jobs:
5858
target: x86_64-apple-darwin
5959
python-version: "3.12"
6060

61-
# macOS-latest (arm64) со всеми версиями Python
61+
# macOS-latest (arm64)
6262
- os: macos-latest
6363
target: aarch64-apple-darwin
6464
python-version: "3.9"

Cargo.lock

Lines changed: 38 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "shazamio-core"
3-
version = "1.1.0-rc.1"
3+
version = "1.1.0-rc.2"
44
edition = "2021"
55
rust-version = "1.62"
66

@@ -23,8 +23,10 @@ futures = { version = "0.3.30", features = [] }
2323
serde = { version = "1.0.196", features = ["derive"] }
2424
bytes = "1.5.0"
2525
tempdir = "0.3.7"
26-
pyo3 = "0.20.2"
26+
pyo3 = "0.20.3"
2727
pyo3-asyncio = { version = "0.20.0", features = ["async-std-runtime", "async-std", "tokio", "tokio-runtime"] }
28+
pyo3-log = "=0.8.4"
29+
log = "0.4.20"
2830

2931
[features]
3032
default = ["pyo3/extension-module"]

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "shazamio_core"
3-
version = "1.1.0-rc.1"
3+
version = "1.1.0-rc.2"
44
description = ""
55
authors = ["dotX12 <dev@shitposting.team>"]
66
readme = "README.md"

shazamio_core/shazamio_core.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from dataclasses import dataclass
2+
from typing import Union
3+
from os import PathLike
24

35

46
@dataclass
@@ -35,21 +37,47 @@ def __repr__(self) -> str:
3537

3638

3739
class Recognizer:
38-
def __init__(self, segment_duration_seconds: int = 12) -> None:
40+
"""
41+
Recognizer uses a Rust implementation under the hood.
42+
43+
This class provides an interface for recognizing audio files, but the actual
44+
processing logic is implemented in Rust and accessed via FFI.
45+
"""
46+
47+
def __init__(self, segment_duration_seconds: int = 10) -> None:
48+
"""
49+
:param segment_duration_seconds: The duration (in seconds) of the audio segment to analyze.
50+
- **Default:** 12 seconds.
51+
- **If the audio file is longer than this duration**, a centered segment of the specified duration is selected.
52+
- Example: If the audio is **60 seconds** and `segment_duration_seconds = 10`, the extracted segment will be **from 25s to 35s**.
53+
- **If the audio file is shorter than this duration**, the entire file is used.
54+
- Example: If the audio is **8 seconds** and `segment_duration_seconds = 10`, the entire **8-second file** will be processed.
55+
- **Audio is always converted to mono and downsampled to 16 kHz** before analysis.
56+
- This parameter determines the number of samples used for frequency analysis and fingerprint generation.
57+
"""
58+
self.segment_duration_seconds = segment_duration_seconds
3959
raise NotImplemented
4060

41-
async def recognize_path(self, value: str) -> Signature:
61+
async def recognize_path(self, value: Union[str, PathLike]) -> Signature:
4262
"""
43-
:param value: path file
44-
:return: Signature object
45-
:raises SignatureError: if there is any error
63+
Recognize audio from a file path.
64+
65+
This method is a Python wrapper around a Rust implementation.
66+
67+
:param value: Path to an audio file.
68+
:return: Signature object.
69+
:raises SignatureError: if an error occurs.
4670
"""
4771
raise NotImplemented
4872

4973
async def recognize_bytes(self, value: bytes) -> Signature:
5074
"""
51-
:param value: bytes file
52-
:return: Signature object
53-
:raises SignatureError: if there is any error
75+
Recognize audio from raw bytes.
76+
77+
This method is a Python wrapper around a Rust implementation.
78+
79+
:param value: Raw audio file as bytes.
80+
:return: Signature object.
81+
:raises SignatureError: if an error occurs.
5482
"""
5583
raise NotImplemented

shazamio_core/shazamio_core.pyi

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,83 @@
11
from dataclasses import dataclass
2+
from typing import Union
3+
from os import PathLike
4+
25

36
@dataclass
47
class Geolocation:
58
altitude: int
69
latitude: int
710
longitude: int
811

12+
913
@dataclass
1014
class SignatureSong:
1115
samples: int
1216
timestamp: int
1317
uri: str
1418

19+
1520
@dataclass
1621
class Signature:
1722
geolocation: Geolocation
1823
signature: SignatureSong
1924
timestamp: int
2025
timezone: str
2126

27+
2228
class SignatureError(Exception):
2329
def __init__(self, message: str):
2430
self.message = message
31+
2532
def __str__(self) -> str:
2633
return self.message
34+
2735
def __repr__(self) -> str:
2836
return f"SignatureError({self.message})"
2937

38+
3039
class Recognizer:
31-
def __init__(self, segment_duration_seconds: int = 12) -> None:
40+
"""
41+
Recognizer uses a Rust implementation under the hood.
42+
43+
This class provides an interface for recognizing audio files, but the actual
44+
processing logic is implemented in Rust and accessed via FFI.
45+
"""
46+
47+
def __init__(self, segment_duration_seconds: int = 10) -> None:
48+
"""
49+
:param segment_duration_seconds: The duration (in seconds) of the audio segment to analyze.
50+
- **Default:** 12 seconds.
51+
- **If the audio file is longer than this duration**, a centered segment of the specified duration is selected.
52+
- Example: If the audio is **60 seconds** and `segment_duration_seconds = 10`, the extracted segment will be **from 25s to 35s**.
53+
- **If the audio file is shorter than this duration**, the entire file is used.
54+
- Example: If the audio is **8 seconds** and `segment_duration_seconds = 10`, the entire **8-second file** will be processed.
55+
- **Audio is always converted to mono and downsampled to 16 kHz** before analysis.
56+
- This parameter determines the number of samples used for frequency analysis and fingerprint generation.
57+
"""
58+
self.segment_duration_seconds = segment_duration_seconds
3259
raise NotImplemented
3360

34-
async def recognize_path(self, value: str) -> Signature:
61+
async def recognize_path(self, value: Union[str, PathLike]) -> Signature:
3562
"""
36-
:param value: path file
37-
:return: Signature object
38-
:raises SignatureError: if there is any error
63+
Recognize audio from a file path.
64+
65+
This method is a Python wrapper around a Rust implementation.
66+
67+
:param value: Path to an audio file.
68+
:return: Signature object.
69+
:raises SignatureError: if an error occurs.
3970
"""
4071
raise NotImplemented
72+
4173
async def recognize_bytes(self, value: bytes) -> Signature:
4274
"""
43-
:param value: bytes file
44-
:return: Signature object
45-
:raises SignatureError: if there is any error
75+
Recognize audio from raw bytes.
76+
77+
This method is a Python wrapper around a Rust implementation.
78+
79+
:param value: Raw audio file as bytes.
80+
:return: Signature object.
81+
:raises SignatureError: if an error occurs.
4682
"""
4783
raise NotImplemented

src/fingerprinting/algorithm.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl SignatureGenerator {
3535
let raw_pcm_samples: Vec<i16> = converted_file.collect();
3636

3737
// Process the PCM samples as in make_signature_from_buffer
38-
let duration_seconds = segment_duration_seconds.unwrap_or(12);
38+
let duration_seconds = segment_duration_seconds.unwrap_or(10);
3939
let sample_rate = 16000;
4040
let segment_samples = (duration_seconds * sample_rate) as usize;
4141

@@ -74,8 +74,8 @@ impl SignatureGenerator {
7474
}
7575

7676
// Downsample the raw PCM samples to 16 KHz, and skip to the middle of the file
77-
// in order to increase recognition odds. Take N (12 default) seconds of sample.
78-
let duration_seconds = segment_duration_seconds.unwrap_or(12);
77+
// in order to increase recognition odds. Take N (10 default) seconds of sample.
78+
let duration_seconds = segment_duration_seconds.unwrap_or(10);
7979
let sample_rate = 16000;
8080
let segment_samples = (duration_seconds * sample_rate) as usize;
8181

@@ -187,10 +187,8 @@ impl SignatureGenerator {
187187
.max(spread_fft_results[position + 2]);
188188
}
189189

190-
// Сначала скопируем данные, чтобы избежать одновременной мутации.
191190
let spread_fft_results_copy = spread_fft_results.clone();
192191

193-
// Теперь, используя копию, мы можем обновить исходные данные без конфликта мутации.
194192
for position in 0..=1024 {
195193
for former_fft_number in &[1, 3, 6] {
196194
let former_fft_output = &mut self.spread_fft_outputs

0 commit comments

Comments
 (0)