mittens_engine/engine/ecs/component/
audio_oscillator.rs1use super::Component;
2use crate::engine::ecs::ComponentId;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
5#[serde(rename_all = "lowercase")]
6pub enum OscillatorType {
7 Sin,
8 Triangle,
9 Square,
10 #[serde(rename = "square_3")]
11 Square3,
12 Drum,
13 Saw,
14 Noise,
15}
16
17#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
18pub struct AudioOscillator {
19 #[serde(rename = "type")]
20 pub oscillator_type: OscillatorType,
21 pub frequency: f32,
22 pub amplitude: f32,
23 pub enabled: bool,
24}
25
26impl AudioOscillator {
27 pub fn new(oscillator_type: OscillatorType) -> Self {
28 Self {
29 oscillator_type,
30 ..Self::default()
31 }
32 }
33
34 pub fn sin() -> Self {
35 Self::new(OscillatorType::Sin)
36 }
37
38 pub fn triangle() -> Self {
39 Self::new(OscillatorType::Triangle)
40 }
41
42 pub fn square() -> Self {
43 Self::new(OscillatorType::Square)
44 }
45
46 pub fn saw() -> Self {
47 Self::new(OscillatorType::Saw)
48 }
49
50 pub fn noise() -> Self {
51 Self::new(OscillatorType::Noise)
52 }
53
54 pub fn drum() -> Self {
55 Self::new(OscillatorType::Drum)
56 }
57
58 pub fn with_frequency(mut self, frequency_hz: f32) -> Self {
60 self.frequency = frequency_hz;
61 self
62 }
63
64 pub fn with_amplitude(mut self, amplitude: f32) -> Self {
66 self.amplitude = amplitude;
67 self
68 }
69
70 pub fn with_enabled(mut self, enabled: bool) -> Self {
72 self.enabled = enabled;
73 self
74 }
75}
76
77impl Default for AudioOscillator {
78 fn default() -> Self {
79 Self {
80 oscillator_type: OscillatorType::Sin,
81 frequency: 440.0,
82 amplitude: 0.2,
83 enabled: true,
84 }
85 }
86}
87
88#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
89pub struct AudioOscillatorComponent {
90 pub oscillators: Vec<AudioOscillator>,
91
92 #[serde(skip)]
93 component: Option<ComponentId>,
94}
95
96impl AudioOscillatorComponent {
97 pub fn new(oscillators: Vec<AudioOscillator>) -> Self {
98 Self {
99 oscillators,
100 component: None,
101 }
102 }
103
104 pub fn single(osc: AudioOscillator) -> Self {
105 Self::new(vec![osc])
106 }
107
108 pub fn id(&self) -> Option<ComponentId> {
109 self.component
110 }
111}
112
113impl Default for AudioOscillatorComponent {
114 fn default() -> Self {
115 Self::new(vec![AudioOscillator::default()])
116 }
117}
118
119impl Component for AudioOscillatorComponent {
120 fn set_id(&mut self, component: ComponentId) {
121 self.component = Some(component);
122 }
123
124 fn name(&self) -> &'static str {
125 "audio_oscillator"
126 }
127
128 fn init(&mut self, emit: &mut dyn crate::engine::ecs::SignalEmitter, component: ComponentId) {
129 emit.push_intent_now(
130 component,
131 crate::engine::ecs::IntentValue::RegisterAudioOscillator {
132 component_ids: vec![component],
133 },
134 );
135 emit.push_intent_now(
136 component,
137 crate::engine::ecs::IntentValue::AudioGraphDirtyImmediate {
138 component_ids: vec![component],
139 },
140 );
141 }
142
143 fn as_any(&self) -> &dyn std::any::Any {
144 self
145 }
146
147 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
148 self
149 }
150
151 fn encode(&self) -> std::collections::HashMap<String, serde_json::Value> {
152 let mut map = std::collections::HashMap::new();
153 map.insert(
154 "oscillators".to_string(),
155 serde_json::to_value(&self.oscillators).unwrap_or_else(|_| serde_json::json!([])),
156 );
157 map
158 }
159
160 fn decode(
161 &mut self,
162 data: &std::collections::HashMap<String, serde_json::Value>,
163 ) -> Result<(), String> {
164 if let Some(v) = data.get("oscillators") {
165 self.oscillators = serde_json::from_value(v.clone())
166 .map_err(|e| format!("Failed to decode oscillators: {}", e))?;
167 }
168 Ok(())
169 }
170}