Files
noteflow/spikes/spike_02_audio_capture/levels_impl.py
Travis Vasceannie af1285b181 Add initial project structure and files
- Introduced .python-version for Python version management.
- Added AGENTS.md for documentation on agent usage and best practices.
- Created alembic.ini for database migration configurations.
- Implemented main.py as the entry point for the application.
- Established pyproject.toml for project dependencies and configurations.
- Initialized README.md for project overview.
- Generated uv.lock for dependency locking.
- Documented milestones and specifications in docs/milestones.md and docs/spec.md.
- Created logs/status_line.json for logging status information.
- Added initial spike implementations for UI tray hotkeys, audio capture, ASR latency, and encryption validation.
- Set up NoteFlow core structure in src/noteflow with necessary modules and services.
- Developed test suite in tests directory for application, domain, infrastructure, and integration testing.
- Included initial migration scripts in infrastructure/persistence/migrations for database setup.
- Established security protocols in infrastructure/security for key management and encryption.
- Implemented audio infrastructure for capturing and processing audio data.
- Created converters for ASR and ORM in infrastructure/converters.
- Added export functionality for different formats in infrastructure/export.
- Ensured all new files are included in the repository for future development.
2025-12-17 18:28:59 +00:00

87 lines
2.1 KiB
Python

"""Audio level computation implementation.
Provides RMS and dB level calculation for VU meter display.
"""
from __future__ import annotations
import math
from typing import Final
import numpy as np
from numpy.typing import NDArray
class RmsLevelProvider:
"""RMS-based audio level provider.
Computes RMS (Root Mean Square) level from audio frames for VU meter display.
"""
# Minimum dB value to report (silence threshold)
MIN_DB: Final[float] = -60.0
def get_rms(self, frames: NDArray[np.float32]) -> float:
"""Calculate RMS level from audio frames.
Args:
frames: Audio samples as float32 array (normalized -1.0 to 1.0).
Returns:
RMS level normalized to 0.0-1.0 range.
"""
if len(frames) == 0:
return 0.0
# Calculate RMS: sqrt(mean(samples^2))
rms = float(np.sqrt(np.mean(frames.astype(np.float64) ** 2)))
# Clamp to 0.0-1.0 range
return min(1.0, max(0.0, rms))
def get_db(self, frames: NDArray[np.float32]) -> float:
"""Calculate dB level from audio frames.
Args:
frames: Audio samples as float32 array (normalized -1.0 to 1.0).
Returns:
Level in dB (MIN_DB to 0 range).
"""
rms = self.get_rms(frames)
if rms <= 0:
return self.MIN_DB
# Convert to dB: 20 * log10(rms)
db = 20.0 * math.log10(rms)
# Clamp to MIN_DB to 0 range
return max(self.MIN_DB, min(0.0, db))
def rms_to_db(self, rms: float) -> float:
"""Convert RMS value to dB.
Args:
rms: RMS level (0.0-1.0).
Returns:
Level in dB (MIN_DB to 0 range).
"""
if rms <= 0:
return self.MIN_DB
db = 20.0 * math.log10(rms)
return max(self.MIN_DB, min(0.0, db))
def db_to_rms(self, db: float) -> float:
"""Convert dB value to RMS.
Args:
db: Level in dB.
Returns:
RMS level (0.0-1.0).
"""
return 0.0 if db <= self.MIN_DB else 10.0 ** (db / 20.0)