Skip to main content

xsynth_core/channel_group/
config.rs

1use crate::{channel::ChannelInitOptions, AudioStreamParams};
2
3/// Controls the channel format that will be used in the synthesizer.
4#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
5#[cfg_attr(
6    feature = "serde",
7    derive(serde::Deserialize, serde::Serialize),
8    serde(rename_all = "snake_case")
9)]
10pub enum SynthFormat {
11    /// Standard MIDI format with 16 channels. Channel 10 will be used for percussion.
12    #[default]
13    Midi,
14
15    /// Creates a custom number of channels with the default settings.
16    Custom { channels: u32 },
17}
18
19/// Defines the multithreading options for each task that supports it.
20#[derive(Clone, Copy, Debug, Eq, PartialEq)]
21#[cfg_attr(
22    feature = "serde",
23    derive(serde::Deserialize, serde::Serialize),
24    serde(rename_all = "snake_case")
25)]
26pub enum ThreadCount {
27    /// No multithreading. Run everything on the same thread.
28    None,
29
30    /// Run with multithreading, with an automatically determined thread count.
31    /// Please read
32    /// [this](https://docs.rs/rayon-core/1.5.0/rayon_core/struct.ThreadPoolBuilder.html#method.num_threads)
33    /// for more information about the thread count selection.
34    Auto,
35
36    /// Run with multithreading, with the specified thread count.
37    Manual(usize),
38}
39
40/// Options regarding which parts of the ChannelGroup should be multithreaded.
41///
42/// Responsibilities of a channel: processing input events for the channel,
43/// dispatching per-key rendering of audio, applying filters to the final channel's audio
44///
45/// Responsibilities of a key: Rendering per-voice audio for all the voices stored in a
46/// key for a channel. This is generally the most compute intensive part of the synth.
47///
48/// Best practices:
49/// - As there are often 16 channels in MIDI, per-key multithreading can balance out the
50///   load more evenly between CPU cores.
51/// - However, per-key multithreading adds some overhead, so if the synth is invoked to
52///   render very small sample counts each time (e.g. sub 1 millisecond), not using per-key
53///   multithreading becomes more efficient.
54#[derive(Clone, Copy, Debug, PartialEq)]
55#[cfg_attr(
56    feature = "serde",
57    derive(serde::Deserialize, serde::Serialize),
58    serde(default)
59)]
60pub struct ParallelismOptions {
61    /// Render the MIDI channels parallel in a threadpool with the specified
62    /// thread count.
63    pub channel: ThreadCount,
64
65    /// Render the individisual keys of each channel parallel in a threadpool
66    /// with the specified thread count.
67    pub key: ThreadCount,
68}
69
70impl ParallelismOptions {
71    pub const AUTO_PER_KEY: Self = ParallelismOptions {
72        channel: ThreadCount::Auto,
73        key: ThreadCount::Auto,
74    };
75
76    pub const AUTO_PER_CHANNEL: Self = ParallelismOptions {
77        channel: ThreadCount::Auto,
78        key: ThreadCount::None,
79    };
80}
81
82impl Default for ParallelismOptions {
83    fn default() -> Self {
84        Self::AUTO_PER_KEY
85    }
86}
87
88/// Options for initializing a new ChannelGroup.
89#[derive(Clone, Debug, PartialEq)]
90#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
91pub struct ChannelGroupConfig {
92    /// Channel initialization options (same for all channels).
93    /// See the `ChannelInitOptions` documentation for more information.
94    pub channel_init_options: ChannelInitOptions,
95
96    /// Defines the format that the synthesizer will use. See the `SynthFormat`
97    /// documentation for more information.
98    ///
99    /// Default: `SynthFormat::Midi`
100    pub format: SynthFormat,
101
102    /// Parameters of the output audio.
103    /// See the `AudioStreamParams` documentation for more information.
104    pub audio_params: AudioStreamParams,
105
106    /// Options about the `ChannelGroup` instance's parallelism. See the `ParallelismOptions`
107    /// documentation for more information.
108    pub parallelism: ParallelismOptions,
109}