package library import ( "context" "math" "path/filepath" "testing" "github.com/jackc/pgx/v5/pgtype" "git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq" ) func TestGainDBAndLinearPeak(t *testing.T) { f := func(v float32) *float32 { return &v } for _, c := range []struct { lufs, want float32 }{ {-18, 0}, // at the reference: no change {-9.5, -8.5}, // a loud master is turned down {-23.456, 5.46}, // a quiet one up, to 0.01 dB } { if got := GainDB(f(c.lufs)); got == nil || *got != c.want { t.Errorf("GainDB(%v) = %v, want %v", c.lufs, got, c.want) } } if GainDB(nil) != nil { t.Errorf("GainDB(nil) is not nil") } for _, c := range []struct { dbtp, want float32 }{ {0, 1}, // full scale {-6.0206, 0.5}, // half amplitude {1.2, 1.1482}, // an inter-sample over, above 1.0 } { got := LinearPeak(f(c.dbtp)) if got == nil || math.Abs(float64(*got-c.want)) > 0.0001 { t.Errorf("LinearPeak(%v) = %v, want %v", c.dbtp, got, c.want) } } if LinearPeak(nil) != nil { t.Errorf("LinearPeak(nil) is not nil") } } func TestReplayGainForTracks_Integration(t *testing.T) { pool := newPool(t) ctx := context.Background() q := dbq.New(pool) dir := t.TempDir() measured, album, artist := seedTrack(t, pool, filepath.Join(dir, "measured.mp3")) add := func(name string) dbq.Track { t.Helper() tr, err := q.UpsertTrack(ctx, dbq.UpsertTrackParams{ Title: name, AlbumID: album.ID, ArtistID: artist.ID, DurationMs: 1000, FilePath: filepath.Join(dir, name+".mp3"), FileSize: 100, FileFormat: "mp3", }) if err != nil { t.Fatalf("track %s: %v", name, err) } return tr } older := add("older") unmeasured := add("unmeasured") f := func(v float32) *float32 { return &v } for _, m := range []struct { tr dbq.Track lufs float32 version int16 }{ {measured, -12, loudnessVersion}, // A measurement by an older method is still a better gain than none. {older, -20, loudnessVersion - 1}, } { if err := q.UpsertTrackLoudness(ctx, dbq.UpsertTrackLoudnessParams{ TrackID: m.tr.ID, IntegratedLufs: f(m.lufs), TruePeakDbtp: f(-1), AnalysisVersion: m.version, }); err != nil { t.Fatalf("seed: %v", err) } } gains, err := ReplayGainForTracks(ctx, q, []pgtype.UUID{measured.ID, older.ID, unmeasured.ID}) if err != nil { t.Fatalf("lookup: %v", err) } if g := gains[measured.ID]; g.TrackGain == nil || *g.TrackGain != -6 || g.TrackPeak == nil { t.Errorf("measured track gains = %+v, want track gain -6 with a peak", g) } if g := gains[older.ID]; g.TrackGain == nil || *g.TrackGain != 2 { t.Errorf("older-version track gains = %+v, want track gain 2", g) } if _, ok := gains[unmeasured.ID]; ok { t.Errorf("unmeasured track has an entry; absent means no adjustment") } // No album value yet (none computed): the album pair is absent. if g := gains[measured.ID]; g.AlbumGain != nil || g.AlbumPeak != nil { t.Errorf("album pair present before album loudness exists: %+v", g) } if err := q.UpsertAlbumLoudness(ctx, dbq.UpsertAlbumLoudnessParams{ AlbumID: album.ID, IntegratedLufs: f(-14), TruePeakDbtp: f(-0.5), TracksTotal: 3, TracksSettled: 3, InputsDigest: "x", }); err != nil { t.Fatalf("seed album: %v", err) } gains, err = ReplayGainForTracks(ctx, q, []pgtype.UUID{unmeasured.ID}) if err != nil { t.Fatalf("lookup: %v", err) } if g := gains[unmeasured.ID]; g.TrackGain != nil || g.AlbumGain == nil || *g.AlbumGain != -4 || g.AlbumPeak == nil { t.Errorf("unmeasured track on a leveled album = %+v, want only the album pair (gain -4)", g) } byAlbum, err := ReplayGainForAlbums(ctx, q, []pgtype.UUID{album.ID}) if err != nil { t.Fatalf("album lookup: %v", err) } if g := byAlbum[album.ID]; g.AlbumGain == nil || *g.AlbumGain != -4 || g.TrackGain != nil { t.Errorf("album gains = %+v, want album gain -4 and no track pair", g) } }