xsynth_core/channel/
params.rs

1use std::sync::{atomic::AtomicU64, Arc};
2
3use crate::AudioStreamParams;
4
5use super::{
6    channel_sf::{ChannelSoundfont, ProgramDescriptor},
7    ChannelConfigEvent,
8};
9
10/// Holds the statistics for an instance of VoiceChannel.
11#[derive(Debug, Clone)]
12pub struct VoiceChannelStats {
13    pub(super) voice_counter: Arc<AtomicU64>,
14}
15
16/// Reads the statistics of an instance of VoiceChannel in a usable way.
17pub struct VoiceChannelStatsReader {
18    stats: VoiceChannelStats,
19}
20
21#[derive(Debug, Clone)]
22pub struct VoiceChannelConst {
23    pub stream_params: AudioStreamParams,
24}
25
26pub struct VoiceChannelParams {
27    pub stats: VoiceChannelStats,
28    pub layers: Option<usize>,
29    pub channel_sf: ChannelSoundfont,
30    pub program: ProgramDescriptor,
31    pub constant: VoiceChannelConst,
32}
33
34impl VoiceChannelStats {
35    pub fn new() -> Self {
36        let voice_counter = Arc::new(AtomicU64::new(0));
37        Self { voice_counter }
38    }
39}
40
41impl Default for VoiceChannelStats {
42    fn default() -> Self {
43        Self::new()
44    }
45}
46
47impl VoiceChannelParams {
48    pub fn new(stream_params: AudioStreamParams) -> Self {
49        let channel_sf = ChannelSoundfont::new();
50
51        Self {
52            stats: VoiceChannelStats::new(),
53            layers: Some(4),
54            channel_sf,
55            program: Default::default(),
56            constant: VoiceChannelConst { stream_params },
57        }
58    }
59
60    pub fn process_config_event(&mut self, event: ChannelConfigEvent) {
61        match event {
62            ChannelConfigEvent::SetSoundfonts(soundfonts) => {
63                self.channel_sf.set_soundfonts(soundfonts)
64            }
65            ChannelConfigEvent::SetLayerCount(count) => {
66                self.layers = count;
67            }
68            ChannelConfigEvent::SetPercussionMode(set) => {
69                if set {
70                    self.program.bank = 128;
71                } else {
72                    self.program.bank = 0;
73                }
74                self.channel_sf.change_program(self.program);
75            }
76        }
77    }
78
79    pub fn set_bank(&mut self, bank: u8) {
80        if self.program.bank != 128 {
81            self.program.bank = bank.min(127);
82        }
83    }
84
85    pub fn set_preset(&mut self, preset: u8) {
86        self.program.preset = preset.min(127);
87    }
88
89    pub fn load_program(&mut self) {
90        self.channel_sf.change_program(self.program);
91    }
92}
93
94impl VoiceChannelStatsReader {
95    pub(super) fn new(stats: VoiceChannelStats) -> Self {
96        Self { stats }
97    }
98
99    /// The active voice count of the VoiceChannel.
100    pub fn voice_count(&self) -> u64 {
101        self.stats
102            .voice_counter
103            .load(std::sync::atomic::Ordering::Relaxed)
104    }
105}