roc-streaming / roc-toolkit

Real-time audio streaming over the network.
https://roc-streaming.org
Mozilla Public License 2.0
1.06k stars 213 forks source link

Refine sound I/O backend initialization #427

Closed gavv closed 1 year ago

gavv commented 4 years ago

Problem

In roc_sndio module, we have support for multiple audio backends, employing different external libraries. Currently they are PulseaudioBackend and SoxBackend.

SoxBackend uses SoX library, which have global initialization function (sox_init) and global configuration set (sox_globals). These facilities are not thread safe. sox_init() should be called once before using SoX, multiple and concurrent calls are not allowed. sox_globals can't be modified concurrently.

This limitation is OK for command-line tools, since we can perform necessary initialization in main() before everything else. Currently we don't provide C API for roc_sndio, so SoX is used only in command-line tools and everything is OK.

However, in future we will provide such an API, and this will cause problems if the user employs both Roc and SoX libraries (directly or indirectly). In this case, there is a need to ensure that SoX setup happens only once.

Solution

Implementation

Earlier, sndio::BackendDispatcher and sndio::SoxBackend were both singletons. When BackendDispatcher was used first time, it accessed SoxBackend, and it called sox_init(). BackendDispatcher also has set_frame_size() method, which calls SoxBackend::set_frame_size(), which updates sox_globals. It's called in command-line tools from main().

In #417, we had to make BackendDispatcher non-singleton, while still keeping SoxBackend a singleton.

Note that this issue should be started only after merging #417.

The following improvement is suggested:

Tigojiang commented 3 years ago

@gavv Hi, do you still need help with this issue? I can take over it. Sorry, I am new here, could you please give me some insights about the files that need to be modified?

gavv commented 3 years ago

@Tigojiang Hi! Yes, this issue is still help-wanted, but it should be done only after merging #417, which was not finished. If you would like to, you could try to pick up #417 and prepare a new PR taking into account unresolved discussions there.

Since the PR was not rebased quite some time, the "Files changed" tab is a bit of a mess, but you can find individual commits by @enigmaro in his fork: https://github.com/enigmaro/roc-toolkit/commits/develop (last 12 commits). I hope it's possible to cherry-pick most of those commits without conflicts.