feat(api): derive Mix waveform datum density from duration (~333 samples/sec, capped/floored) instead of fixed 2048 buckets

This commit is contained in:
daniel-c-harvey
2026-06-14 16:21:57 -04:00
parent da08ac4efb
commit 09a980ba2a
4 changed files with 158 additions and 9 deletions
@@ -17,10 +17,6 @@ namespace DeepDrftAPI.Services;
/// </summary>
public class UnifiedReleaseService
{
// High-res bucket count for Mix waveforms — 4x the player-bar default (512), feeding the
// public-site MixWaveformVisualizer.
private const int MixWaveformBucketCount = 2048;
/// <summary>Error message returned when the Mix release has no linked track.</summary>
public const string MixHasNoTrackMessage = "Mix release has no track.";
@@ -104,9 +100,11 @@ public class UnifiedReleaseService
}
/// <summary>
/// Fetch the Mix's track audio from the vault, compute a high-res (2048-bucket) waveform datum,
/// store it in the MixWaveforms vault under the track's EntryKey, then point the release's Mix
/// satellite at that same key. The datum key equals the track's EntryKey — the Mix is single-track.
/// Fetch the Mix's track audio from the vault, compute a high-res waveform datum at a constant time
/// resolution (≈333 samples/sec derived from the track's duration; see
/// <see cref="MixWaveformResolution"/>), store it in the MixWaveforms vault under the track's
/// EntryKey, then point the release's Mix satellite at that same key. The datum key equals the
/// track's EntryKey — the Mix is single-track.
/// </summary>
public async Task<Result> TriggerMixWaveformAsync(long releaseId, CancellationToken ct)
{
@@ -149,8 +147,11 @@ public class UnifiedReleaseService
return Result.CreateFailResult(MixTrackNoAudioMessage);
}
// Duration-derived, constant-time-resolution capture (≈333 samples/sec) so long mixes are not
// under-sampled by a fixed bucket count — see MixWaveformResolution / spec §F.
var bucketCount = MixWaveformResolution.BucketCountForDuration(audio.Duration);
var computed = await _waveformProfileService.ComputeAndStoreAsync(
audio.Buffer, entryKey, MixWaveformBucketCount, VaultConstants.MixWaveforms);
audio.Buffer, entryKey, bucketCount, VaultConstants.MixWaveforms);
if (!computed)
{
_logger.LogError("TriggerMixWaveform: waveform computation/storage failed for {EntryKey}", entryKey);