fix(api): stream audio store path to eliminate whole-file buffering (OOM)
Processors now emit a ProcessedAudio plan with a streamed writer instead of a whole-file AudioBinary; vault writes stream via RegisterResourceStreamingAsync. Header parsing is bounded. Wave 2 (waveform/Opus) still re-reads the full file by design.
This commit is contained in:
@@ -68,9 +68,9 @@ public class TrackReplaceAudioTests
|
||||
var originalDuration = before!.Duration;
|
||||
|
||||
var replacement = await WriteWavAsync(BuildMinimalPcmWav(6.0), ".wav");
|
||||
var newAudio = await content.ReplaceTrackAudioAsync(entryKey, replacement);
|
||||
var newDuration = await content.ReplaceTrackAudioAsync(entryKey, replacement);
|
||||
|
||||
Assert.That(newAudio, Is.Not.Null, "Replace should return the freshly stored audio");
|
||||
Assert.That(newDuration, Is.Not.Null, "Replace should return the freshly stored audio's duration");
|
||||
|
||||
var after = await content.GetAudioBinaryAsync(entryKey);
|
||||
Assert.Multiple(() =>
|
||||
@@ -78,8 +78,8 @@ public class TrackReplaceAudioTests
|
||||
Assert.That(after, Is.Not.Null, "The track must remain retrievable under the same EntryKey");
|
||||
Assert.That(after!.Duration, Is.GreaterThan(originalDuration),
|
||||
"The retrieved audio must reflect the longer replacement, not the original");
|
||||
Assert.That(newAudio!.Duration, Is.EqualTo(after.Duration),
|
||||
"The returned binary must match what is stored under the key");
|
||||
Assert.That(newDuration!.Value, Is.EqualTo(after.Duration),
|
||||
"The returned duration must match what is stored under the key");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ public class TrackReplaceAudioTests
|
||||
Assert.That(wavFilesBefore, Is.Not.Empty, "Sanity: the original .wav backing file exists");
|
||||
|
||||
var replacement = await WriteFlacAsync();
|
||||
var newAudio = await content.ReplaceTrackAudioAsync(entryKey, replacement);
|
||||
var newDuration = await content.ReplaceTrackAudioAsync(entryKey, replacement);
|
||||
|
||||
Assert.That(newAudio, Is.Not.Null);
|
||||
Assert.That(newDuration, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(Directory.GetFiles(vaultDir, "*.wav"), Is.Empty,
|
||||
@@ -135,12 +135,15 @@ public class TrackReplaceAudioTests
|
||||
Assert.That(staleHighRes, Is.Not.Null);
|
||||
|
||||
var replacement = await WriteWavAsync(BuildMinimalPcmWav(20.0), ".wav");
|
||||
var newAudio = await content.ReplaceTrackAudioAsync(entryKey, replacement);
|
||||
Assert.That(newAudio, Is.Not.Null);
|
||||
var newDuration = await content.ReplaceTrackAudioAsync(entryKey, replacement);
|
||||
Assert.That(newDuration, Is.Not.Null);
|
||||
|
||||
// Regen step (mirrors the orchestrator).
|
||||
Assert.That(await waveforms.ComputeAndStoreAsync(newAudio!.Buffer, entryKey), Is.True);
|
||||
Assert.That(await waveforms.ComputeAndStoreHighResAsync(newAudio.Buffer, entryKey, newAudio.Duration), Is.True);
|
||||
// Regen step (mirrors the orchestrator, which re-reads the freshly stored audio from the vault
|
||||
// rather than consuming an in-memory buffer the streamed store no longer hands back).
|
||||
var newStored = await content.GetAudioBinaryAsync(entryKey);
|
||||
Assert.That(newStored, Is.Not.Null);
|
||||
Assert.That(await waveforms.ComputeAndStoreAsync(newStored!.Buffer, entryKey), Is.True);
|
||||
Assert.That(await waveforms.ComputeAndStoreHighResAsync(newStored.Buffer, entryKey, newStored.Duration), Is.True);
|
||||
|
||||
var freshHighRes = await waveforms.GetProfileAsync(entryKey, VaultConstants.TrackWaveforms);
|
||||
var freshProfile = await waveforms.GetProfileAsync(entryKey);
|
||||
|
||||
Reference in New Issue
Block a user