Commit Graph

9 Commits

Author SHA1 Message Date
Kyle Simpson
ec665a8f87 Fix: Ringbuf patch release requires explicit type param
Ringbuf 0.4.2 onwards adds in a new storage type for `SharedRb`.
Unfortunately, this is handled in such a way that we fail to
compile because an explicit type parameter is required to
disambiguate the method in question.
2024-08-17 23:01:51 +01:00
Kyle Simpson
93f2e0b636 chore(deps): Update ringbuf -> 0.4 2024-07-08 11:46:08 +01:00
Gnome!
3d307aaa8b Fix clippy pedantic warnings (#204) 2023-11-20 00:02:58 +00:00
Kyle Simpson
9fa063ff0e Chore: Clippy fixes to match new MSRV. 2023-11-20 00:02:57 +00:00
Kyle Simpson
3daf11f5d1 Driver: Implement audio scheduler (#179)
This PR implements a custom scheduler for audio threads, which reduces thread use and (often) memory consumption.

To save threads and memory (e.g., packet buffer allocations), Songbird parks Mixer tasks which do not have any live Tracks.
These are now all co-located on a single async 'Idle' task.
This task is responsible for managing UDP keepalive messages for each task, maintaining event state, and executing any Mixer task messages.
Whenever any message arrives which adds a `Track`, the mixer task is moved to a live thread.
The Idle task inspects task counts and execution time on each thread, choosing the first live thread with room, and creating a new one if needed.

Each live thread is responsible for running as many live mixers as it can in a single tick every 20ms: this currently defaults to 16 mixers per thread, but is user-configurable.
A live thread also stores RTP packet blocks to be written into by each sub-task.
Each live thread has a conservative limit of 18ms that it will aim to stay under: if all work takes longer than this, it will offload the task with the highest mixing cost once per tick onto another (possibly new) live worker thread.
2023-11-20 00:02:57 +00:00
Kyle Simpson
50fa17fb59 Input: Fix high CPU use when initialising long files over HTTP (#163)
Fixes the possibility of a spinlock while reading bytes from an async->sync adapter. This case can be observed with long (e.g., 10 hours of silence) videos which seem to be served slower than we would like to parse their headers.

The fix moves most communication to blocking: `read` calls first parse all messages form the async context in a non-blocking way, then swap to blocking if no bytes are available.

Tested using `cargo make ready` and "examples/serenity/voice" against the URL https://www.youtube.com/watch?v=g4mHPeMGTJM.
2023-11-20 00:02:56 +00:00
Kyle Simpson
125c803fa7 Chore: Apply latest nightly clippy lints 2023-11-20 00:02:55 +00:00
Kyle Simpson
6a38fc82f4 Deps: Update Ringbuf, Serde-Aux, Simd-Json, Typemap 2023-11-20 00:02:55 +00:00
Kyle Simpson
8cc7a22b0b Driver/Input: Migrate audio backend to Symphonia (#89)
This extensive PR rewrites the internal mixing logic of the driver to use symphonia for parsing and decoding audio data, and rubato to resample audio. Existing logic to decode DCA and Opus formats/data have been reworked as plugins for symphonia. The main benefit is that we no longer need to keep yt-dlp and ffmpeg processes alive, saving a lot of memory and CPU: all decoding can be done in Rust! In exchange, we now need to do a lot of the HTTP handling and resumption ourselves, but this is still a huge net positive.

`Input`s have been completely reworked such that all default (non-cached) sources are lazy by default, and are no longer covered by a special-case `Restartable`. These now span a gamut from a `Compose` (lazy), to a live source, to a fully `Parsed` source. As mixing is still sync, this includes adapters for `AsyncRead`/`AsyncSeek`, and HTTP streams.

`Track`s have been reworked so that they only contain initialisation state for each track. `TrackHandles` are only created once a `Track`/`Input` has been handed over to the driver, replacing `create_player` and related functions. `TrackHandle::action` now acts on a `View` of (im)mutable state, and can request seeks/readying via `Action`.

Per-track event handling has also been improved -- we can now determine and propagate the reason behind individual track errors due to the new backend. Some `TrackHandle` commands (seek etc.) benefit from this, and now use internal callbacks to signal completion.

Due to associated PRs on felixmcfelix/songbird from avid testers, this includes general clippy tweaks, API additions, and other repo-wide cleanup. Thanks go out to the below co-authors.

Co-authored-by: Gnome! <45660393+GnomedDev@users.noreply.github.com>
Co-authored-by: Alakh <36898190+alakhpc@users.noreply.github.com>
2023-11-19 23:58:34 +00:00