Skip to content

refactor: Update symphonia from 0.5.5 to 0.6.1 - #920

Open
UnknownSuperficialNight wants to merge 1 commit into
RustAudio:masterfrom
UnknownSuperficialNight:migrate-symphonia-0.5.5-to-0.6.1
Open

refactor: Update symphonia from 0.5.5 to 0.6.1#920
UnknownSuperficialNight wants to merge 1 commit into
RustAudio:masterfrom
UnknownSuperficialNight:migrate-symphonia-0.5.5-to-0.6.1

Conversation

@UnknownSuperficialNight

@UnknownSuperficialNight UnknownSuperficialNight commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

This is a very rough draft (basically got it compiling and it works in the libopus example): @yara-blue

Seeking is especially rough. I would like some input on the best way to handle that.

Closes #919

Here are test results as of 47e574b:

running 26 tests
test seek_does_not_break_channel_order::case_3 ... ok
test seek_beyond_end_saturates::case_4 ... ok
test seek_beyond_end_saturates::case_3 ... ok
test seek_beyond_end_saturates::case_5 ... ok
test seek_beyond_end_saturates::case_2 ... ok
test random_access_seeks ... ok
test seek_beyond_end_saturates::case_1 ... FAILED
test seek_returns_err_if_unsupported::case_2 ... ok
test seek_returns_err_if_unsupported::case_3 ... ok
test seek_returns_err_if_unsupported::case_4 ... ok
test seek_returns_err_if_unsupported::case_5 ... ok
test seek_returns_err_if_unsupported::case_1 ... ok
test seek_possible_after_exausting_source::case_4 ... ok
test seek_possible_after_exausting_source::case_3 ... FAILED
test seek_results_in_correct_remaining_playtime::case_4 ... ok
test seek_possible_after_exausting_source::case_5 ... ok
test seek_results_in_correct_remaining_playtime::case_3 ... ok
test seek_does_not_break_channel_order::case_4 ... FAILED
test seek_possible_after_exausting_source::case_2 ... ok
test seek_results_in_correct_remaining_playtime::case_5 ... ok
test seek_results_in_correct_remaining_playtime::case_2 ... ok
test seek_does_not_break_channel_order::case_1 ... FAILED
test seek_does_not_break_channel_order::case_2 ... FAILED
test seek_does_not_break_channel_order::case_5 ... FAILED
test seek_possible_after_exausting_source::case_1 ... ok
test seek_results_in_correct_remaining_playtime::case_1 ... ok

failures:

---- seek_beyond_end_saturates::case_1 stdout ----
------------ TEST ARGUMENTS ------------
format = "ogg"
decoder_name = "symphonia"
-------------- TEST START --------------
seeking beyond end for: ogg	 decoded by: symphonia

thread 'seek_beyond_end_saturates::case_1' (3520265) panicked at tests/seek.rs:124:5:
err: Err(SymphoniaDecoder(Demuxer(SeekError(OutOfRange))))
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- seek_possible_after_exausting_source::case_3 stdout ----
------------ TEST ARGUMENTS ------------
format = "m4a"
_decoder_name = "symphonia"
-------------- TEST START --------------

thread 'seek_possible_after_exausting_source::case_3' (3520277) panicked at tests/seek.rs:182:5:
assertion failed: source.next().is_some()

---- seek_does_not_break_channel_order::case_4 stdout ----
------------ TEST ARGUMENTS ------------
format = "wav"
_decoder_name = "symphonia"
-------------- TEST START --------------

thread 'seek_does_not_break_channel_order::case_4' (3520273) panicked at tests/seek.rs:231:9:
channel0 should be silent,
    channel0 starts at idx: 1
    seek: 1.357709765s + 22.676µs
    samples: [3.0517578e-5, -0.0016174316, 0.0, -0.0026550293, 0.0, -0.0037231445, 0.0, -0.0048217773, 0.0, -0.00592041, 0.0, -0.0068359375, 0.0, -0.0076293945, 0.0, -0.008087158, 3.0517578e-5, -0.0082092285, -3.0517578e-5, -0.008117676, 0.0, -0.007537842, 0.0, -0.0066223145, 0.0, -0.005432129, 0.0, -0.0037841797, 0.0, -0.0018920898, 0.0, 0.0002746582, 0.0, 0.0025939941, -3.0517578e-5, 0.004852295, 0.0, 0.007171631, 3.0517578e-5, 0.009277344, 0.0, 0.011199951, -3.0517578e-5, 0.013580322, -3.0517578e-5, 0.01675415, 3.0517578e-5, 0.020812988, 3.0517578e-5, 0.025543213, -3.0517578e-5, 0.030456543, 0.0, 0.035614014, 3.0517578e-5, 0.040496826, -3.0517578e-5, 0.044647217, 3.0517578e-5, 0.048095703, 0.0, 0.0501709, -3.0517578e-5, 0.05078125, 6.1035156e-5, 0.049987793, 0.0, 0.047210693, -3.0517578e-5, 0.04272461, 3.0517578e-5, 0.036712646, -3.0517578e-5, 0.028808594, -3.0517578e-5, 0.019805908, 6.1035156e-5, 0.009796143, -3.0517578e-5, -0.0012512207, 0.0, -0.012481689, 3.0517578e-5, -0.023742676, -3.0517578e-5, -0.03475952, 0.0, -0.044799805, 3.0517578e-5, -0.053771973, -3.0517578e-5, -0.061309814, 0.0, -0.066986084, 0.0, -0.07080078, 0.0, -0.0725708, 0.0, -0.07223511]

---- seek_does_not_break_channel_order::case_1 stdout ----
------------ TEST ARGUMENTS ------------
format = "ogg"
_decoder_name = "symphonia"
-------------- TEST START --------------

thread 'seek_does_not_break_channel_order::case_1' (3520270) panicked at tests/seek.rs:231:9:
channel0 should be silent,
    channel0 starts at idx: 1
    seek: 1.357709765s + 22.676µs
    samples: [4.9912433e-8, 0.4392503, 5.834984e-7, 0.32712096, 8.8944273e-7, 0.2075035, 6.7825005e-7, 0.08379031, -3.972579e-8, -0.04053174, -9.2329697e-7, -0.16199267, -1.4915049e-6, -0.2772506, -1.4203649e-6, -0.3831966, -7.509369e-7, -0.47705132, 1.3289568e-7, -0.5564503, 7.475783e-7, -0.6195134, 8.160449e-7, -0.6648979, 4.3407422e-7, -0.69183284, -1.4623488e-8, -0.7001327, -1.3781239e-7, -0.6901939, 1.8062504e-7, -0.6629672, 6.8655174e-7, -0.6199163, 9.2156205e-7, -0.5629564, 5.4289205e-7, -0.49437943, -4.1678263e-7, -0.41676825, -1.529566e-6, -0.33290076, -2.2166344e-6, -0.24565068, -2.1050532e-6, -0.15788575, -1.2669452e-6, -0.07236801, -1.8295327e-7, 0.008339234, 5.5088833e-7, 0.081956394, 5.87114e-7, 0.14656077, 2.938458e-8, 0.20064433, -6.5391947e-7, 0.24315663, -9.451089e-7, 0.27352905, -6.1408866e-7, 0.29168102, 1.4185548e-7, 0.2980082, 8.4221085e-7, 0.29335254, 1.0509118e-6, 0.27895617, 6.6801135e-7, 0.25640103, -7.347481e-9, 0.22753577, -4.814534e-7, 0.19439438, -3.98785e-7, 0.15910749, 2.2027808e-7, 0.12381243, 9.948559e-7, 0.09056284, 1.4398854e-6, 0.061243095, 1.2898488e-6, 0.037490606, 6.7175e-7, 0.020627499, 1.10041185e-8, 0.01160603, -2.6587333e-7, 0.010969676, -2.9875025e-8, 0.018829666, 4.5535037e-7, 0.034859806, 7.11217e-7, 0.058308855, 3.8001764e-7, 0.08803026, -5.060404e-7, 0.12252779]

---- seek_does_not_break_channel_order::case_2 stdout ----
------------ TEST ARGUMENTS ------------
format = "mp3"
_decoder_name = "symphonia"
-------------- TEST START --------------

thread 'seek_does_not_break_channel_order::case_2' (3520271) panicked at tests/seek.rs:231:9:
channel0 should be silent,
    channel0 starts at idx: 1
    seek: 1.357709765s + 22.676µs
    samples: [1.0423112e-5, -0.0016294387, -4.9453974e-6, -0.0026536994, 8.9397e-6, -0.0036932616, 4.3690736e-7, -0.004755194, -1.0356765e-5, -0.0057819746, 9.4480165e-6, -0.0066954927, -7.91055e-6, -0.007394767, 4.067429e-6, -0.007800345, 1.5708369e-5, -0.007936013, -2.1292157e-5, -0.0077399723, -9.301568e-7, -0.0072024595, 9.291465e-6, -0.0063259234, -1.1032974e-5, -0.005101697, 8.563777e-6, -0.0035740598, -1.16098505e-7, -0.001723657, 2.02343e-6, 0.00036147257, 3.3597164e-6, 0.002491219, -3.290601e-5, 0.0046943063, 9.994318e-6, 0.0068566864, 3.647355e-5, 0.008782985, -1.03526245e-5, 0.010650539, -1.8692994e-5, 0.012840481, -1.7845161e-5, 0.015836604, 2.2732072e-5, 0.019732144, 3.2617714e-5, 0.024096046, -4.0639923e-5, 0.02880069, 7.1341714e-7, 0.03368114, 2.7875561e-5, 0.03821358, -2.6742986e-5, 0.04221207, 2.3462013e-5, 0.045432296, 2.5439124e-6, 0.04739777, -3.5672205e-5, 0.04806757, 4.494227e-5, 0.04727385, -2.0444643e-6, 0.04470345, -2.609535e-5, 0.04052583, 3.9288254e-5, 0.034779817, -3.2762022e-5, 0.02740809, -1.5781987e-5, 0.018852957, 5.1654155e-5, 0.009361489, -2.3770068e-5, -0.00096200145, -5.7022e-6, -0.011666289, 2.086379e-5, -0.02231333, -3.438963e-5, -0.032679107, 9.52124e-6, -0.04228663, 1.8188473e-5, -0.05078717, -2.229829e-5, -0.05795565, 9.5245305e-6, -0.0634677, 6.8758595e-6, -0.06710686, -9.058814e-6, -0.06889602, 2.4789674e-6, -0.06872114]

---- seek_does_not_break_channel_order::case_5 stdout ----
------------ TEST ARGUMENTS ------------
format = "flac"
_decoder_name = "symphonia"
-------------- TEST START --------------

thread 'seek_does_not_break_channel_order::case_5' (3520274) panicked at tests/seek.rs:231:9:
channel0 should be silent,
    channel0 starts at idx: 1
    seek: 1.357709765s + 22.676µs
    samples: [1.5377998e-5, -0.0016144514, -4.4107437e-6, -0.0026631355, 3.8146973e-6, -0.0037113428, 6.0796738e-6, -0.004824519, -1.4781952e-5, -0.0059326887, 1.347065e-5, -0.0068320036, -7.6293945e-6, -0.00762856, 5.9604645e-7, -0.008083582, 2.1100044e-5, -0.008194566, -2.6106834e-5, -0.00810349, -9.536743e-7, -0.007529974, 1.1086464e-5, -0.006628394, -1.347065e-5, -0.0054428577, 1.13248825e-5, -0.0037925243, -1.4305115e-6, -0.0019015074, 1.66893e-6, 0.00026142597, 5.722046e-6, 0.002597928, -3.4928322e-5, 0.004859805, 9.298325e-6, 0.007163763, 3.8027763e-5, 0.00926578, -1.0609627e-5, 0.011194587, -1.8954277e-5, 0.013587832, -1.8715858e-5, 0.016742945, 2.4080276e-5, 0.020828009, 3.528595e-5, 0.025547028, -4.3034554e-5, 0.030449033, 2.026558e-6, 0.035618305, 2.9921532e-5, 0.040507913, -2.9087067e-5, 0.04465449, 2.5868416e-5, 0.04810202, 1.4305115e-6, 0.05018556, -3.8266182e-5, 0.050781846, 4.887581e-5, 0.049995065, -3.5762787e-6, 0.047219396, -2.7418137e-5, 0.042734742, 4.184246e-5, 0.036702514, -3.6478043e-5, 0.028821826, -1.5974045e-5, 0.019791603, 5.4597855e-5, 0.009784818, -2.5391579e-5, -0.0012466908, -5.2452087e-6, -0.012483478, 2.1576881e-5, -0.02373743, -3.540516e-5, -0.03475201, 9.894371e-6, -0.04479909, 1.7285347e-5, -0.05376935, -2.3126602e-5, -0.061309457, 9.775162e-6, -0.06697428, 7.6293945e-6, -0.07078862, -8.46386e-6, -0.07256484, 9.536743e-7, -0.07222581]


failures:
    seek_beyond_end_saturates::case_1
    seek_does_not_break_channel_order::case_1
    seek_does_not_break_channel_order::case_2
    seek_does_not_break_channel_order::case_4
    seek_does_not_break_channel_order::case_5
    seek_possible_after_exausting_source::case_3

test result: FAILED. 20 passed; 6 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.50s

error: test failed, to rerun pass `--test seek`
     Running tests/total_duration.rs (target/debug/build/rodio/6ad925b750fdf439/out/total_duration-6ad925b750fdf439)

running 5 tests
test decoder_returns_total_duration::case_4 ... ok
test decoder_returns_total_duration::case_5 ... ok
test decoder_returns_total_duration::case_2 ... FAILED
test decoder_returns_total_duration::case_3 ... ok
test decoder_returns_total_duration::case_1 ... ok

failures:

---- decoder_returns_total_duration::case_2 stdout ----
------------ TEST ARGUMENTS ------------
format = "mp3"
correct_duration = 10.187755102s
decoder_name = "symphonia mp3"
-------------- TEST START --------------
decoder: symphonia mp3

thread 'decoder_returns_total_duration::case_2' (3520392) panicked at tests/total_duration.rs:97:5:
decoder got 10.152380952, correct is: 10.187755102
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    decoder_returns_total_duration::case_2

test result: FAILED. 4 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

- Bump symphonia to version 0.6.1 in `Cargo.toml`
- Migrate codec registry API from `register_all::<D>()` to
  `register_audio_decoder::<D>()`
- Replace `Decoder` and `SignalSpec` with new `AudioDecoder` and
  `AudioSpec` types
- Introduce lifetime parameters on `Decoder`, `LoopedDecoder`,
  `SymphoniaDecoder`, and `DecoderImpl`
- Refactor `SymphoniaDecoder` to handle EOF via `AudioDecoder`'s
  `last_decoded()` method
- Update test code to use the new lifetime-based `Decoder<'static, R>`
  types
Comment thread src/decoder/symphonia.rs
Comment on lines +53 to +64
fn samples_from_time_f64(
t: symphonia::core::units::Time,
sample_rate: u32,
channels: u32,
) -> usize {
let (secs_i64, nanos_u32) = t.parts();
if secs_i64 < 0 {
return 0;
}
let secs = secs_i64 as f64 + (nanos_u32 as f64) / 1e9_f64;
(secs * sample_rate as f64 * channels as f64).ceil() as usize
}

@UnknownSuperficialNight UnknownSuperficialNight Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably not a good idea but just a plaster/band-aid solution to get it compiling

@UnknownSuperficialNight

Copy link
Copy Markdown
Contributor Author

Also found this probably would be worth investigating seeing if its fixed in the new symphonia

rodio/tests/seek.rs

Lines 195 to 203 in c5f1e94

fn seek_does_not_break_channel_order(
#[case] format: &'static str,
#[case] _decoder_name: &'static str,
) {
if format == "m4a" {
// skip this test for m4a while the symphonia decoder has issues with aac timing.
// re-investigate when symphonia 0.5.5 or greater is released.
return;
}

@roderickvd

Copy link
Copy Markdown
Member

I like to use these opportunities to point out that in #786 and https://github.com/RustAudio/rodio/tree/feat/comprehensive-seeking-and-bit-depth I had fixed a gazillion of these difficult classes of bugs.

Would be great if that one could be updated. That would ideally go two ways: first checking if in master there have been any improvements that should be merged into that branch. Then, taking that new decoder and getting it into master again.

Comment thread src/decoder/symphonia.rs
@@ -215,9 +249,20 @@ impl Source for SymphoniaDecoder {
}

fn try_seek(&mut self, pos: Duration) -> Result<(), source::SeekError> {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what i need input on

@UnknownSuperficialNight

UnknownSuperficialNight commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

I like to use these opportunities to point out that in #786 and https://github.com/RustAudio/rodio/tree/feat/comprehensive-seeking-and-bit-depth I had fixed a gazillion of these difficult classes of bugs.

Would be great if that one could be updated. That would ideally go two ways: first checking if in master there have been any improvements that should be merged into that branch. Then, taking that new decoder and getting it into master again.

first checking if in master there have been any improvements that should be merged into that branch

Think that would be up-to (@yara-blue) as im not really to up to date on all the commits in master

Then, taking that new decoder and getting it into master again.

To clarify you saying basically check if anything in master should be merged into comprehensive-seeking-and-bit-depth then once that is completed take comprehensive-seeking-and-bit-depth and merge to main or use as a basis for this PR?

I'm kind of confused on the intent of your wording?

@roderickvd

Copy link
Copy Markdown
Member

Yes. It was some time ago so I imagine they have diverged. Personally, I would go from master to that branch by porting any fixes to symphonia.rs manually, then rebase the branch on master.

@UnknownSuperficialNight

Copy link
Copy Markdown
Contributor Author

Yes. It was some time ago so I imagine they have diverged. Personally, I would go from master to that branch by porting any fixes to symphonia.rs manually, then rebase the branch on master.

Do you mean make a new branch and and rebase comprehensive-seeking-and-bit-depth into master get it fixed up then make a pr then after than consider what im doing on this branch?

or do you mean since this current branch is based on the current master rebasing comprehensive-seeking-and-bit-depth onto migrate-symphonia-0.5.5-to-0.6.1

@yara-blue

Copy link
Copy Markdown
Member

Would be great if we could get those improvements in, but I do not want to scope creep beyond what @UnknownSuperficialNight has time for.

Keep in mind that the mentioned PR could not get reviewed due to size. So if you bring it up to the point it can be merged to master it would still need to be split up*. At that point it might be easier to take some of the fixes move those in here and then follow up with more PR's moving in the rest bit by bit. Please aim for no more then 500L per PR.

If you chose to go that route Roderick can maybe suggest what would be good points to split it up at.

[*]: though there is an argument to be made that at that point the decoder code has been thoroughly reviewed by you and it can therefore be merged as a whole. Keep in mind though that it is about 7k lines. That is about a week of work to review. I am not able to split review work across multiple sessions since I tend to forget a lot in between, that limits things.

@roderickvd

Copy link
Copy Markdown
Member

I understand it grew beyond review capability. Neither of us fancies the time to put into review or to put into splitting. I could point Claude at it to automate the splitting, and it could take the Symphonia upgrade along in one swoop. The test suite is a blessing here.

But we should prioritize our efforts. Probably the new audio pipeline should come first?

@yara-blue

Copy link
Copy Markdown
Member

But we should prioritize our efforts. Probably the new audio pipeline should come first?

Yes, I think there are about two efforts/PR's that are soft blocked on that since it makes their work far easier. (An effect that then no longer needs to account for spans, and something else I forgot...)

I could point Claude at it to automate the splitting, and it could take the Symphonia upgrade along in one swoop.

I'm fine with you (specifically not other contributors) using LLM based tools to automate the splitting but ideally the upgrade happens non-agentically.

Maybe the best order here is:

@UnknownSuperficialNight

Copy link
Copy Markdown
Contributor Author

Maybe the best order here is:

That makes logical sense to me

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.

Update Symphonia to 0.6

3 participants