Skip to content

feat: add TTA as a Stream-to-Stream ConvertFile/CutFile destination - #127

Merged
cloud-hai-vo merged 1 commit into
mainfrom
feat/tta-stream-destination
Oct 18, 2026
Merged

cloud-hai-vo merged 1 commit into
mainfrom
feat/tta-stream-destination

Conversation

@cloud-hai-vo

Copy link
Copy Markdown
Contributor

Summary

Continues docs/feature-roadmap.md item 1's own "destination-Stream" half (WAV/AIFF/AU/FLAC already done — see #108, #122). This item: TTA.

  • TtaEncoderSession.OpenSession(Stream destStream, ...) -- a new overload, mirroring WavWriter/AiffWriter/AuWriter/FlacEncoder's own Create(Stream, ...)/OpenSession(Stream, ...) overloads. Needs no Stream.CanSeek at all -- unlike FLAC (the only prior destination that genuinely requires it), TTA already holds every compressed frame in memory until Finish() (TtaEncoderSession's own pre-existing design, since TtaWriter's own seek table needs every frame's final size up front regardless), at which point TtaWriter.Write writes the header, seek table, and frame data in a single forward pass with no patch-up ever needed. Confirmed directly via a test that writes through a destination whose Seek/Position throw, not just assumed from the absence of a CanSeek check.
  • TtaEncoderSession's own destination field was widened from FileStream to Stream plus a leaveOpen flag (mirroring WavWriter's own convention) so Dispose() only closes a stream this type actually owns.
  • Channel/bit-depth/sample-rate validation factored into a shared private helper so the path-based and Stream-based OpenSession overloads can't drift apart on what's valid.
  • Wired into AudioCutter.Stream.cs's OpenSinkStream as the AudioFormat.Tta destination case -- no DeferredFixedHeaderSink needed, same reasoning as FLAC's own case.

Docs synced: CLAUDE.md, README.md, llms.txt, llms-full.txt, docs/feature-roadmap.md item 1's own status note.

Test plan

  • New TtaEncoderSessionTest cases: null stream, unsupported channel count/bit depth/sample rate, exact round-trip via a MemoryStream destination, a genuinely non-seekable destination (confirms no CanSeek requirement end-to-end, not just an absent check), and Dispose() not disposing the caller's stream.
  • New AudioCutterStreamTest cases: WAV source → TTA Stream destination round-trip (exact samples, lossless), and a non-seekable TTA destination succeeding through the full AudioCutter.Convert call.
  • dotnet test --configuration Release (net10.0 locally): 1759 passed (1750 baseline + 9 new), 2 pre-existing skips (1 WMA, 1 the already-tracked MP3 synthesis-filter bug), 0 failed.
  • dotnet build --configuration Release: 0 warnings, 0 errors, all target frameworks.

🤖 Generated with Claude Code

TtaEncoderSession.OpenSession gained a Stream-based overload, mirroring
WavWriter/AiffWriter/AuWriter/FlacEncoder's own Create(Stream, ...)/
OpenSession(Stream, ...) overloads. Unlike FLAC (the only prior destination
that needs CanSeek), TTA needs no CanSeek at all despite also needing no
exactTotalFrames up front: TtaEncoderSession already holds every compressed
frame in memory until Finish(), at which point TtaWriter writes the header,
seek table, and frame data in one single forward pass -- no patch-up ever
needed. Confirmed directly (not just assumed from the absence of a CanSeek
check) via a test that writes through a destination whose Seek/Position
throw.

TtaEncoderSession's own destination field was widened from FileStream to
Stream plus a leaveOpen flag (mirroring WavWriter's own convention) so
Dispose() only closes a stream this type actually owns. Channel/bit-depth/
sample-rate validation was factored into a shared private helper so the
path-based and Stream-based OpenSession overloads can't drift apart.

Wired into AudioCutter.Stream.cs's OpenSinkStream as the AudioFormat.Tta
destination case -- no DeferredFixedHeaderSink needed, same reasoning as
FLAC's own case.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cloud-hai-vo
cloud-hai-vo merged commit 4c4f64f into main Oct 18, 2026
9 checks passed
@cloud-hai-vo
cloud-hai-vo deleted the feat/tta-stream-destination branch October 18, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant