Files
Melo/lib/player/replay_gain.dart
dustinandClaude Opus 5 4ebd0a8dd4 Songtext aus Datei-Tags, Warteschlangen-Aktionen, Kategorie-Cover im
Sperrbildschirm und ReplayGain

- DB-Schema 6: lyrics + gain_db
- Songtext bevorzugt lokalen Tag, Server nur als Rueckfall; Song-ID-Bug
  beim Lyrics-Aufruf behoben
- "Als Naechstes spielen" / "Zur Warteschlange hinzufuegen" ohne Eingriff
  in Favoriten oder Wiedergabelisten
- songToMediaItem nimmt eine Cover-Vorgabe: Sperrbildschirm zeigt das
  Kategorie-Cover
- ReplayGain: Tags werden gelesen, laute Titel abgesenkt, abschaltbar

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011snPXPafPC5i87o68H14W7
2026-08-20 18:41:36 +02:00

21 lines
832 B
Dart

import 'dart:math' as math;
/// Liest einen ReplayGain-Wert aus einem Tag wie "-6.54 dB".
/// Gibt null zurück, wenn im Tag nichts Brauchbares steht.
double? parseReplayGain(String? raw) {
if (raw == null) return null;
final match = RegExp(r'-?\+?\d+(\.\d+)?').firstMatch(raw.trim());
if (match == null) return null;
return double.tryParse(match.group(0)!.replaceFirst('+', ''));
}
/// Rechnet eine ReplayGain-Angabe in Dezibel in einen Lautstärkefaktor um.
///
/// Angeglichen wird ausschließlich **nach unten**: laute Titel werden leiser
/// gemacht. Über 100 % hinaus kann der Player nicht verstärken, deshalb
/// bleiben Titel mit positivem Wert unverändert.
double volumeForGain(double? gainDb) {
if (gainDb == null || gainDb >= 0) return 1.0;
return math.pow(10, gainDb / 20).toDouble().clamp(0.0, 1.0);
}