Skip to content
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

Allow retrieving the queue signal in a sink when using crossbeam-channel feature #600

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

AlbanWS
Copy link

@AlbanWS AlbanWS commented Jul 31, 2024

Hi,
This commit creates a new Sink::append_with_signal method and make Sink::append a wrapper function without breaking change.
It only "works" with the crossbeam-channel feature flag because crossbeam::channel::Receiver implements Clone but not std::sync::mpsc::Receiver .
append_with_signal will be useful in case we have to do something at the end of a Source inside a Sink.

Copy link
Author

Choose a reason for hiding this comment

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

Modified because it did not pass CI with clippy error: doc list item missing indentation

@dvdsk
Copy link
Collaborator

dvdsk commented Aug 2, 2024

Hi,

Thanks for the PR. This Pr exposes more of Rodio's internals which will make it harder to make changes to rodio in the future, which makes me hesitant to merge this. Maybe there is another way. Could you explain why you need this?

@AlbanWS
Copy link
Author

AlbanWS commented Aug 2, 2024

Hi @dvdsk,

Thank you for your response, there are two cases, and I use both:

  1. With the current Sink API, we can't wait the end of a source which is not the last append

Currently, if I use Sink::sleep_until_end and then load and process data for this file, I get silences between my sources, due the time spent between Sink::sleep_until_end and Sink::append.

The new function Sink::append_with_signal become useful to lazily load the music file and process data for this file only when the sink will "soon" be ended (in my case when less than two sources are remaining).

It becomes faster starting up the program and make the program less memory consuming than loading all files at startup.

  1. With the current Sink API, we can't use crossbeam::channel::select!

crossbeam allows to do something with the fastest ready receiver (https://docs.rs/crossbeam/latest/crossbeam/channel/struct.Select.html).

In my case, I can now use Sink::append_with_signal with my source, and then do, for example:

crossbeam::channel::select! {
    recv(receiver_from_append_with_signal) -> msg => receiver_from_append_with_signal = my_sink.append_with_signal(MySource::load()),
    recv(receiver_from_another_thread_sending_messages) -> msg => my_sink.set_volume(0.5),
}

In this case, it is possible to block the thread as with Sink::sleep_until_end, while still being able to communicate.

This also means we could have two sinks, in two different threads, where the first could send a message to the second to lower the volume of the second until the first ended playing.

@dvdsk
Copy link
Collaborator

dvdsk commented Aug 2, 2024

Your first use case (a good one) is in the same category to #506. It seems a good idea to overhaul/redesign the Sink to better support these use-cases.

Regarding the second use-case, can you give me a a little more information? Are you trying to do a cross-fade effect?

@AlbanWS
Copy link
Author

AlbanWS commented Aug 2, 2024

Ok, I will explain my own use case if it helps understand it better.

First of all, this is not to do a cross-fade effect, I already use Sink::take_crossfade_with to cross-fade between my sources.

My application works with at least two Sinks working in different threads (It can't be synchronous for reasons not linked with rodio).

The first thread will handle music in the background, the Sink will continuously play.

The second thread will handle the "event" music, the Sink will play only several sounds and will last like 30 seconds each time when something is triggered by my users.

The "event"s are more important than the music in the background, therefore I want at this moment, the first thread Sink volume can be set to 0.5, but not stopping playing, and at the end of the "event", the background can be set back to volume 1.0.

In fact, my overall issue is to make both first case and second case work together, I need both in my project, and I found out the little change I made here made it easy.

Hope it is more understandable with that case !

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.

2 participants