-
Notifications
You must be signed in to change notification settings - Fork 275
feat(decoders)!: comprehensive seeking and bit depth detection across all decoders #786
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I feel a bit guilty about this mega-commit. I got carried away while coding on the camping and this is what happened 😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a major enhancement to Rodio's decoder capabilities, adding universal seeking support and bit depth detection across all decoders while improving performance and reducing user-facing seek errors.
- Universal seeking support with configurable modes (fastest vs nearest) and automatic fallback behavior
- Bit depth detection for lossless audio formats through new
Source::bits_per_sample()
method - Performance improvements and bug fixes across multiple decoders (zero span length fix in Symphonia Ogg Vorbis, improved packet reading)
Reviewed Changes
Copilot reviewed 58 out of 59 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
tests/total_duration.rs | Completely removed old duration testing implementation |
tests/source_traits.rs | New comprehensive test suite for decoder functionality including duration, bit depth, and span length tests |
tests/seek.rs | Enhanced seeking tests with universal decoder support and improved error handling |
src/static_buffer.rs | Added bits_per_sample() implementation and updated seek error type |
src/source/*.rs | Added bits_per_sample() method to all source types with appropriate implementations |
src/source/mod.rs | Enhanced Source trait with bits_per_sample() method and expanded SeekError enum |
src/queue.rs | Added bits_per_sample() support for queue operations |
src/mixer.rs | Added bits_per_sample() aggregation across mixed sources |
src/math.rs | Minor documentation formatting improvements |
src/decoder/wav.rs | Complete rewrite with comprehensive documentation, enhanced seeking, and settings support |
src/decoder/vorbis.rs | Complete rewrite with granule-based seeking, duration scanning, and robust error handling |
src/decoder/utils.rs | New utility module with common decoder helper functions |
src/decoder/symphonia.rs | Major refactoring with improved multi-track support, enhanced seeking, and better error recovery |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
6k lines.... AAAHHHHGHHHHHH |
This might take more then one weekend to review 😅 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review still in progress
/// Attempts to decode the data as FLAC. | ||
pub fn new(mut data: R) -> Result<FlacDecoder<R>, R> { | ||
if !is_flac(data.by_ref()) { | ||
/// Attempts to decode the data as FLAC with default settings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to self: got till here (dont trust git to keep my review comments unless I send them now)
Sure take the time! I got that coming 😜 Anyway incorporating your review comments iteratively is a fine approach, because one comment may apply to a lot of other decoders as well without you needing to go through all of them. |
I got some smaller updates to this PR committed locally. Would you rather have me wait pushing them, so your review doesn't get mixed up? As you want. |
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to self, reviewed till here
Only see these now, lets keep them locally for now. Feel free to resolve the things I brought up once you've addressed them locally (or let me know why I'm wrong and I'll close em). I fear it might take me quite some time (few weekends) to review this as I don't have that much time throughout the week... |
Will do.
No haste. I'm back to work starting tomorrow, too. |
I'm in no haste. Though as it touches a lot of sources and I want to prevent rebasing as much as possible, I'll wait to have this reviewed before I start other Rodio development. |
I wanted to play with it, are there any uses of the |
No, though the Rustdoc contains a lot of examples. "Behind the scenes" the examples do use it, because |
- Improve clarity and conciseness of doc comments for all decoders - Remove redundant and overly verbose explanations - Add missing details to trait and method docs - Update examples to use consistent file paths and types - Move Settings struct visibility to crate-internal - Refactor Path/PathBuf decoder constructors for optimal hinting - Standardize iterator and trait method documentation across formats - Remove misleading or outdated implementation notes - Fix Zero source bits_per_sample to return None - Update seek test attributes for feature consistency
- Introduce BitDepth as a newtype for non-zero u32 - Update Source trait and all implementations to use Option<BitDepth> - Update decoders, sources, and tests to use BitDepth instead of u32 for bit depth - Replace NonZero usage for sample rate and channel count with SampleRate and ChannelCount types where appropriate - Update documentation and examples to reflect new types fix: change bits_per_sample to return Option<BitDepth>
53c2b81
to
65d7a2a
Compare
65d7a2a
to
88ad33b
Compare
style: cargo fmt
88ad33b
to
5ecd76b
Compare
I have a few hours each weekend for open source. I now realize I can not review a PR of this size in those hours. I can also not spread it between weekends since I will lose context in between. To get this merged it needs to be split into multiple PR's, each limited to around 1000 lines so it can be independently reviewed. I realize this is not easy. My recommendation is to add the new decoders in parallel to the existing. The new decoders would live under a feature flag. We can then merge each smaller PR without breaking the main lib (this is also known as CI). Ideally the small PR's each add a testable modular part of the new decoders that can be run independently. Though I realize that is too much to ask. However lets architect new efforts so that this can be done. Once the whole new decoder suite is in we can remove all the old code and the flag in one PR. |
I am sorry, I don’t see the point in making that effort. The CI is passing and at least one user has given a favorite review. I am not going to put in many hours of free time in something I don’t see the value in. I’m still up for a beer sometime in the east, or meeting online, if that expedites things. |
This is some really good work and would be a shame to see go to waste, if there's value and you want testing from a more complex user I'd be happy to. |
Is there some kind of recourse here? I can appreciate the desire to implement this in a way, and I can appreciate life outside of OSS, but the rejection of this PR hurts rodio and its users more than it provides any protection to the codebase. These are real and tangible changes. The premier audio playback crate of Rust should absolutely promote stable audio seeking. I'm not aware what the exact priorities of this project are, but I can't imagine that said functionality isn't of a considerable standing. I'm also willing to offer my help in resolving this however I can, although admittedly, I'm not a fraction the developer any of you are. Still, if there is no recourse here, I find it seriously unfair not only to the efforts of Roderick (who is a seriously talented and respectable developer), but to the broader community who will surely benefit from the enhanced functionality. |
I don't have anything against the core feature being added here, nor against the code. I can not review a PR of this size. So it needs to be split up and ideally also slimmed down. Some context on the size:
In my opinion that means this PR can be slimmed down to 2481 * 1.23 ~ 3kL in total. Split that up in roughly 3 parts and its quite reviewable. Almost all our users seem to use the symphonia decoders, this also PR supports all the current decoders. The symphonia decoders all have the same interface. Supporting all decoders must add a lot of extra code. This matches what I have seen while trying (and failing) to review this the past few weekends. So lets just drop support for all the other decoders in Rodio and in this PR. Then adding this PR might even slim Rodio down, increasing its maintainability. Instead of letting all that decoder code slip into the void we would move it to another crate: |
I am not sure what you want:
For item 2 I do not see obvious ways to make that work with the I have the feeling you detest the code comments. I already said we can cut down if you want. Beyond that, I do not understand your apprehension. You have set up Rodio with an extensive CI suite for decoders. For seeking in particular that's really not so easy to pass, yet this PR does. That gives some pretty strong behavioral guarantees. Sure, a passing CI suite does not ensure code quality. Beyond pulling the creds card hoping to have established some known quality standard, I could equally argue that CI also is releasing early and iterate often. I already said sorry for the camping-built mega commit and ask that we move forward pragmatically. |
@dvdsk to raise it to you again. |
@roderickvd I want to note something since I have seen this PR. As a user I might ask wheter it makes sense to keep any other backend than Symphonia? The point I am trying to make is that all other backends seem rather unmaintaned (they all have no real commits the last 2 or more years). Also I have looked into the code of rodio, the different backends increase the complexity alot. Furthermore Symphonia covers all those codes anyways and is actively maintained and used, by alot of people. There is as far as I know no real situation, where you shouldn't use Symphonia (I assume). So from a development effort point of view I think it might make sense to strip other Codecs to reduce complexity. Since most users will use Symphonia anyways and other could easily migrate. It would also give more time to improvements and new features. A single backend is also just less error prone, since it's less compile time conditionals to care about and more time to spend to fix it. However I don't think that should effect this PR in particular. Since this work had already been done and it doesn't make sense to just throw it away. So, if the backends get removed, it should be it's own seperate PR. Just keep in mind that I have little actual knowledge about how rodio actually works, so I might over simply a bit. |
@dvdsk bump on this too. |
I disagree there, this is currently blocked on being too big to review. If we consider removing the other backends then this will get significantly smaller and thus easier to cut into ~1000L pieces. |
I'd like to be able to review this PR, for that it needs to shrink to N independent PR's of about ~1k lines. The smaller the total size the faster we will have this merged. I've given some suggestions on how I think that can be achieved. It is up to whomever takes up the work how it is achieved. That does not have to be Roderick who is busy working on Cpal and many other open source projects. As there is clear intrest from the community I'd suggest one of you picks this up. |
This PR implements a major enhancement to Rodio's decoder capabilities, adding universal seeking support and bit depth detection while fixing some issues, improving performance, and reducing user-facing seek errors.
Key features
Universal seeking support
try_seek()
andnew_with_settings()
SeekMode::Fastest
(coarse) vsSeekMode::Nearest
(accurate)SeekMode
DecoderBuilder
with seeking configuration optionsBit depth detection
Source::bits_per_sample()
method returns bit depth for lossless formatsBug fixes
size_hint()
accuracy across all decodersPerformance improvements
VorbisDecoder
: improved packet readingFlacDecoder
: better block loading withFlacReaderOptions
API enhancements
New
DecoderBuilder
methodsTest coverage
Breaking changes
SeekError::NotSupported
renamed toSeekError::SeekingNotSupported
WavDecoder
no longer implementsExactSizeIterator
(for accuracy)DecoderBuilder::with_coarse_seek()
deprecated (usewith_seek_mode()
)Source::source_intact()
removed (too many unknowns)Decoder feature overview
Closes:
Source::total_duration
for non-wav sources? #190