RustAudio / rodio

Rust audio playback library
Apache License 2.0
1.77k stars 231 forks source link

User stories/usecases/experiences (please add!) #626

Open dvdsk opened 1 month ago

dvdsk commented 1 month ago

A collection of user stories/usecases & experiences to be used to inform (breaking) api changes.

Please add your own!

ugochukwu-850 commented 1 month ago

@dvdsk , should we add it here .

dvdsk commented 1 month ago

please do, we can always move it to its own issue if we have questions. And thank you very much!

dvdsk commented 2 weeks ago

Something that seems very hard/impossible with rodio now:

A user adds two songs to a queue some time after eachother. Then they enable cross-fade while the first song is almost at the end but just before adding the second song. Crossfade then works and the two songs fade into each-other.

The music plays without any stuttering while crossfade is toggled on and off.

I am trying to write an example on how to do this using the current API, maybe I am wrong and it is relatively doable. In that case an example would help out.

bluenote10 commented 2 weeks ago

I'm simply adding a few use cases I had in the past -- without re-checking if they would currently be possible already.

Sample perfect scheduling

Think of a metronome app that needs to schedule its click sound dynamically (the user can control bpm e.g. via a slider), but with utmost temporal precision (you don't want any fluctuation in a metronome). This requires a to have sample/frame perfect scheduling, i.e., one would need to express start playing this sound at sample index i=xxx.

Sample perfect looping

Sometimes I had to loop sounds also without any gap in the audio output (note that waiting for the sound to finish, and re-schedule it again introduces a gap). This would require to set up a loop information that specifies same (loop_sample_index_from, loop_sample_index_upto) so that the playback can implicitly wrapped-around once the "upto" sample is reached. Ideally the playback interface would expose e.g. a loop_counter to allow users to query once a loop-wrap occurred. The most obvious use case for that are "infinite" background sounds that are constructed in a way that they loop around seamlessly, and simply setting the loop specification to (0, last_sample) would repeat the entire sound indefinitely.

Low-latency scheduling

I was once trying to implement a kind of drum synthesizer in rodio, where certain key-presses triggered certain sounds. However I noticed that the input latency was way too large for musical purposes. I would assume that mainly comes down to the large default buffer size, and #512 should improve that.

dvdsk commented 2 weeks ago

I'm simply adding a few use cases I had in the past

Very helpful thank you!

nednoodlehead commented 2 weeks ago

My primary use case:

Rust-based music player (iced gui).

I got pretty much everything I need out of rodio, without too much hassle either. (All inside of this function).

The only thing that I am waiting on (or perhaps, I do not know how to implement. And frankly, haven't tried too much) is crossfade between songs. I do see the fade in / fade out stuff. But that applies more to a setup where you take source A, and source B, then add them into the sink or whatever, then apply it. I add my sources more 'dynamically'. Where once the playing song ends a new one is appended. So there is no point where I can apply it.

I had an idea for a potential workaround, but I have literally 0 clue how this library works under the hood (and not too much experience with this type of programming, so I don't think I could help too much). But be able to somehow change when sink.is_empty() returns true, and for example, if you choose to have a crossfade of 5 seconds, the sink would return true 5 seconds before it actually ends (and it is fading out during this time). Idk if this would create bugs or not, or if this is possible, but it is my first thought for making my idea work with my use case.

Also, weird bug, when music is playing, and I drag my scrubbing bar, the timer got reset to 0 nano seconds for a split second my comment here. Dunno if it is related at all.

dvdsk commented 2 weeks ago

Thanks for all the feedback!

I add my sources more 'dynamically'. Where once the playing song ends a new one is appended. So there is no point where I can apply it.

This is an issue I ran into myself too, good to hear others have trouble with it too. We should make this easy/doable and add a full example.