feat(audio): loudness_cache gains a content_key column (table only)
An ISRC or fingerprint column plus a partial index, with set_content_key / get_by_content_key helpers, so a local or Plex copy of the same recording can reuse an analysis. The analyser and every audio path are untouched; set/get keep their track_id contract. cc
This commit is contained in:
1 file changed
+44
@@ -47,6 +47,17 @@ impl LoudnessCache {
|
||||
)
|
||||
.map_err(|e| format!("Failed to create loudness table: {}", e))?;
|
||||
|
||||
// Identity beyond the Qobuz id (2026-08-28): an ISRC or a content
|
||||
// fingerprint, so a local/Plex copy of the same recording can reuse
|
||||
// the analysis. TABLE ONLY — the analyser and every audio path are
|
||||
// untouched; `set`/`get` keep their track_id contract. Additive,
|
||||
// idempotent (the duplicate-column error is the "already there" case).
|
||||
let _ = conn.execute_batch("ALTER TABLE track_loudness ADD COLUMN content_key TEXT;");
|
||||
let _ = conn.execute_batch(
|
||||
"CREATE INDEX IF NOT EXISTS idx_track_loudness_content_key
|
||||
ON track_loudness(content_key) WHERE content_key IS NOT NULL;",
|
||||
);
|
||||
|
||||
log::info!("[LoudnessCache] Opened at {}", db_path.display());
|
||||
|
||||
Ok(Self {
|
||||
@@ -71,6 +82,39 @@ impl LoudnessCache {
|
||||
.ok()
|
||||
}
|
||||
|
||||
/// Attach a cross-source content key (ISRC or fingerprint) to an
|
||||
/// existing row. No-op when the track has no analysis yet.
|
||||
pub fn set_content_key(&self, track_id: u64, content_key: &str) {
|
||||
if content_key.trim().is_empty() {
|
||||
return;
|
||||
}
|
||||
if let Ok(conn) = self.conn.lock() {
|
||||
let _ = conn.execute(
|
||||
"UPDATE track_loudness SET content_key = ?1 WHERE track_id = ?2",
|
||||
params![content_key.trim(), track_id as i64],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Look up cached loudness by content key (any source's copy of the
|
||||
/// same recording). Newest analysis wins.
|
||||
pub fn get_by_content_key(&self, content_key: &str) -> Option<CachedLoudness> {
|
||||
let conn = self.conn.lock().ok()?;
|
||||
conn.query_row(
|
||||
"SELECT gain_db, peak, source FROM track_loudness
|
||||
WHERE content_key = ?1 ORDER BY created_at DESC LIMIT 1",
|
||||
params![content_key.trim()],
|
||||
|row| {
|
||||
Ok(CachedLoudness {
|
||||
gain_db: row.get::<_, f64>(0)? as f32,
|
||||
peak: row.get::<_, f64>(1)? as f32,
|
||||
source: row.get(2)?,
|
||||
})
|
||||
},
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
|
||||
/// Store or update loudness data for a track.
|
||||
pub fn set(&self, track_id: u64, gain_db: f32, peak: f32, source: &str) {
|
||||
if let Ok(conn) = self.conn.lock() {
|
||||
|
||||
Reference in new issue
Block a user