Skip to content

Commit

Permalink
✨ feat(Cargo.lock): Add arc-swap, portable-atomic, pyo3-log packages
Browse files Browse the repository at this point in the history
🔧 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
  • Loading branch information
dotX12 committed Feb 3, 2025
1 parent 86d3bee commit c2fe225
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 40 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
fail-fast: false
matrix:
include:
# macOS 13 (x86_64) со всеми версиями Python
# macOS 13 (x86_64)
- os: macos-13
target: x86_64-apple-darwin
python-version: "3.9"
Expand All @@ -58,7 +58,7 @@ jobs:
target: x86_64-apple-darwin
python-version: "3.12"

# macOS-latest (arm64) со всеми версиями Python
# macOS-latest (arm64)
- os: macos-latest
target: aarch64-apple-darwin
python-version: "3.9"
Expand Down
49 changes: 38 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shazamio-core"
version = "1.1.0-rc.1"
version = "1.1.0-rc.2"
edition = "2021"
rust-version = "1.62"

Expand All @@ -23,8 +23,10 @@ futures = { version = "0.3.30", features = [] }
serde = { version = "1.0.196", features = ["derive"] }
bytes = "1.5.0"
tempdir = "0.3.7"
pyo3 = "0.20.2"
pyo3 = "0.20.3"
pyo3-asyncio = { version = "0.20.0", features = ["async-std-runtime", "async-std", "tokio", "tokio-runtime"] }
pyo3-log = "=0.8.4"
log = "0.4.20"

[features]
default = ["pyo3/extension-module"]
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "shazamio_core"
version = "1.1.0-rc.1"
version = "1.1.0-rc.2"
description = ""
authors = ["dotX12 <[email protected]>"]
readme = "README.md"
Expand Down
44 changes: 36 additions & 8 deletions shazamio_core/shazamio_core.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from dataclasses import dataclass
from typing import Union
from os import PathLike


@dataclass
Expand Down Expand Up @@ -35,21 +37,47 @@ def __repr__(self) -> str:


class Recognizer:
def __init__(self, segment_duration_seconds: int = 12) -> None:
"""
Recognizer uses a Rust implementation under the hood.
This class provides an interface for recognizing audio files, but the actual
processing logic is implemented in Rust and accessed via FFI.
"""

def __init__(self, segment_duration_seconds: int = 10) -> None:
"""
:param segment_duration_seconds: The duration (in seconds) of the audio segment to analyze.
- **Default:** 12 seconds.
- **If the audio file is longer than this duration**, a centered segment of the specified duration is selected.
- Example: If the audio is **60 seconds** and `segment_duration_seconds = 10`, the extracted segment will be **from 25s to 35s**.
- **If the audio file is shorter than this duration**, the entire file is used.
- Example: If the audio is **8 seconds** and `segment_duration_seconds = 10`, the entire **8-second file** will be processed.
- **Audio is always converted to mono and downsampled to 16 kHz** before analysis.
- This parameter determines the number of samples used for frequency analysis and fingerprint generation.
"""
self.segment_duration_seconds = segment_duration_seconds
raise NotImplemented

async def recognize_path(self, value: str) -> Signature:
async def recognize_path(self, value: Union[str, PathLike]) -> Signature:
"""
:param value: path file
:return: Signature object
:raises SignatureError: if there is any error
Recognize audio from a file path.
This method is a Python wrapper around a Rust implementation.
:param value: Path to an audio file.
:return: Signature object.
:raises SignatureError: if an error occurs.
"""
raise NotImplemented

async def recognize_bytes(self, value: bytes) -> Signature:
"""
:param value: bytes file
:return: Signature object
:raises SignatureError: if there is any error
Recognize audio from raw bytes.
This method is a Python wrapper around a Rust implementation.
:param value: Raw audio file as bytes.
:return: Signature object.
:raises SignatureError: if an error occurs.
"""
raise NotImplemented
52 changes: 44 additions & 8 deletions shazamio_core/shazamio_core.pyi
Original file line number Diff line number Diff line change
@@ -1,47 +1,83 @@
from dataclasses import dataclass
from typing import Union
from os import PathLike


@dataclass
class Geolocation:
altitude: int
latitude: int
longitude: int


@dataclass
class SignatureSong:
samples: int
timestamp: int
uri: str


@dataclass
class Signature:
geolocation: Geolocation
signature: SignatureSong
timestamp: int
timezone: str


class SignatureError(Exception):
def __init__(self, message: str):
self.message = message

def __str__(self) -> str:
return self.message

def __repr__(self) -> str:
return f"SignatureError({self.message})"


class Recognizer:
def __init__(self, segment_duration_seconds: int = 12) -> None:
"""
Recognizer uses a Rust implementation under the hood.
This class provides an interface for recognizing audio files, but the actual
processing logic is implemented in Rust and accessed via FFI.
"""

def __init__(self, segment_duration_seconds: int = 10) -> None:
"""
:param segment_duration_seconds: The duration (in seconds) of the audio segment to analyze.
- **Default:** 12 seconds.
- **If the audio file is longer than this duration**, a centered segment of the specified duration is selected.
- Example: If the audio is **60 seconds** and `segment_duration_seconds = 10`, the extracted segment will be **from 25s to 35s**.
- **If the audio file is shorter than this duration**, the entire file is used.
- Example: If the audio is **8 seconds** and `segment_duration_seconds = 10`, the entire **8-second file** will be processed.
- **Audio is always converted to mono and downsampled to 16 kHz** before analysis.
- This parameter determines the number of samples used for frequency analysis and fingerprint generation.
"""
self.segment_duration_seconds = segment_duration_seconds
raise NotImplemented

async def recognize_path(self, value: str) -> Signature:
async def recognize_path(self, value: Union[str, PathLike]) -> Signature:
"""
:param value: path file
:return: Signature object
:raises SignatureError: if there is any error
Recognize audio from a file path.
This method is a Python wrapper around a Rust implementation.
:param value: Path to an audio file.
:return: Signature object.
:raises SignatureError: if an error occurs.
"""
raise NotImplemented

async def recognize_bytes(self, value: bytes) -> Signature:
"""
:param value: bytes file
:return: Signature object
:raises SignatureError: if there is any error
Recognize audio from raw bytes.
This method is a Python wrapper around a Rust implementation.
:param value: Raw audio file as bytes.
:return: Signature object.
:raises SignatureError: if an error occurs.
"""
raise NotImplemented
8 changes: 3 additions & 5 deletions src/fingerprinting/algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl SignatureGenerator {
let raw_pcm_samples: Vec<i16> = converted_file.collect();

// Process the PCM samples as in make_signature_from_buffer
let duration_seconds = segment_duration_seconds.unwrap_or(12);
let duration_seconds = segment_duration_seconds.unwrap_or(10);
let sample_rate = 16000;
let segment_samples = (duration_seconds * sample_rate) as usize;

Expand Down Expand Up @@ -74,8 +74,8 @@ impl SignatureGenerator {
}

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

Expand Down Expand Up @@ -187,10 +187,8 @@ impl SignatureGenerator {
.max(spread_fft_results[position + 2]);
}

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

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

0 comments on commit c2fe225

Please sign in to comment.