sim_lib_stream_host/placement/
device.rs1use sim_kernel::Symbol;
4
5use crate::model::{
6 HostOpenPlan, stream_host_capability, stream_host_device_read_effect_kind,
7 stream_host_device_write_effect_kind,
8};
9
10use super::AudioDeviceCard;
11
12#[derive(Clone, Debug, PartialEq, Eq)]
14pub enum Placement {
15 Modeled,
17 Hardware {
19 transport: Symbol,
21 },
22}
23
24#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26pub enum DeviceKind {
27 Audio,
29 Midi,
31}
32
33#[derive(Clone, Copy, Debug, PartialEq, Eq)]
35pub enum DeviceDirection {
36 Input,
38 Output,
40 Duplex,
42}
43
44impl DeviceDirection {
45 pub fn effect_kinds(self) -> Vec<Symbol> {
47 match self {
48 Self::Input => vec![stream_host_device_read_effect_kind()],
49 Self::Output => vec![stream_host_device_write_effect_kind()],
50 Self::Duplex => vec![
51 stream_host_device_read_effect_kind(),
52 stream_host_device_write_effect_kind(),
53 ],
54 }
55 }
56}
57
58#[derive(Clone, Debug, PartialEq, Eq)]
60pub struct DeviceRecord {
61 pub id: Symbol,
63 pub display_name: String,
65 pub kind: DeviceKind,
67 pub direction: DeviceDirection,
69 pub placement: Placement,
71}
72
73impl DeviceRecord {
74 pub fn modeled_midi_input(id: &str, name: impl Into<String>) -> Self {
76 Self::modeled(id, name, DeviceKind::Midi, DeviceDirection::Input)
77 }
78
79 pub fn modeled_midi_output(id: &str, name: impl Into<String>) -> Self {
81 Self::modeled(id, name, DeviceKind::Midi, DeviceDirection::Output)
82 }
83
84 pub fn modeled_audio_output(id: &str, name: impl Into<String>) -> Self {
86 Self::modeled(id, name, DeviceKind::Audio, DeviceDirection::Output)
87 }
88
89 pub fn modeled_audio_from_card(card: &AudioDeviceCard) -> Self {
91 Self::audio_from_card(card, Placement::Modeled)
92 }
93
94 pub fn audio_from_card(card: &AudioDeviceCard, placement: Placement) -> Self {
96 let direction = match (card.channels_in > 0, card.channels_out > 0) {
97 (true, true) => DeviceDirection::Duplex,
98 (true, false) => DeviceDirection::Input,
99 (false, true) | (false, false) => DeviceDirection::Output,
100 };
101 Self {
102 id: card.key.0.clone(),
103 display_name: card.display_name.clone(),
104 kind: DeviceKind::Audio,
105 direction,
106 placement,
107 }
108 }
109
110 pub fn open_plan(&self) -> HostOpenPlan {
112 HostOpenPlan::new(
113 self.plan_backend_symbol(),
114 self.id.clone(),
115 self.direction.effect_kinds(),
116 vec![stream_host_capability()],
117 )
118 }
119
120 fn modeled(
121 id: &str,
122 name: impl Into<String>,
123 kind: DeviceKind,
124 direction: DeviceDirection,
125 ) -> Self {
126 Self {
127 id: Symbol::new(id),
128 display_name: name.into(),
129 kind,
130 direction,
131 placement: Placement::Modeled,
132 }
133 }
134
135 fn plan_backend_symbol(&self) -> Symbol {
136 match &self.placement {
137 Placement::Modeled => Symbol::qualified("stream/host", "modeled-catalog"),
138 Placement::Hardware { transport } => transport.clone(),
139 }
140 }
141}