1use crate::{node::Node, output::*};
2use euphony_units::{pitch::frequency::Frequency, ratio::Ratio};
3
4#[derive(Clone, Debug)]
5pub struct Parameter(pub(crate) ParameterValue);
6
7impl Parameter {
8 pub(crate) fn set(&self, target_node: u64, target_parameter: u64) {
9 match &self.0 {
10 ParameterValue::Unset => emit(SetParameter {
11 target_node,
12 target_parameter,
13 value: 0.0f64.to_bits(),
14 }),
15 ParameterValue::Constant(value) => emit(SetParameter {
16 target_node,
17 target_parameter,
18 value: value.to_bits(),
19 }),
20 ParameterValue::Node(ref source) => emit(PipeParameter {
21 target_node,
22 target_parameter,
23 source_node: source.id(),
24 }),
25 }
26 }
27}
28
29#[derive(Clone, Debug)]
30pub struct Trigger(pub(crate) ParameterValue);
31
32#[derive(Clone, Debug)]
33pub(crate) enum ParameterValue {
34 Unset,
35 Constant(f64),
36 Node(Node),
37}
38
39impl From<Node> for Parameter {
40 #[inline]
41 fn from(node: Node) -> Self {
42 Self(ParameterValue::Node(node))
43 }
44}
45
46impl From<&Node> for Parameter {
47 #[inline]
48 fn from(node: &Node) -> Self {
49 Self(ParameterValue::Node(node.clone()))
50 }
51}
52
53impl From<Trigger> for Parameter {
54 #[inline]
55 fn from(value: Trigger) -> Self {
56 Self(value.0)
57 }
58}
59
60impl From<&Trigger> for Parameter {
61 #[inline]
62 fn from(value: &Trigger) -> Self {
63 Self(value.0.clone())
64 }
65}
66
67macro_rules! impl_convert {
68 ($name:ident) => {
69 impl From<f64> for $name {
70 #[inline]
71 fn from(value: f64) -> Self {
72 Self(ParameterValue::Constant(value))
73 }
74 }
75
76 impl From<u64> for $name {
77 #[inline]
78 fn from(value: u64) -> Self {
79 Self(ParameterValue::Constant(value as _))
80 }
81 }
82
83 impl From<Frequency> for $name {
84 #[inline]
85 fn from(value: Frequency) -> Self {
86 Self(ParameterValue::Constant(value.into()))
87 }
88 }
89
90 impl From<crate::prelude::Beat> for $name {
91 #[inline]
92 fn from(value: crate::prelude::Beat) -> Self {
93 (crate::time::tempo() * value).into()
94 }
95 }
96
97 impl From<core::time::Duration> for $name {
98 #[inline]
99 fn from(value: core::time::Duration) -> Self {
100 value.as_secs_f64().into()
101 }
102 }
103
104 impl From<crate::prelude::Interval> for $name {
105 #[inline]
106 fn from(value: crate::prelude::Interval) -> Self {
107 use crate::ext::*;
108 value.freq().into()
109 }
110 }
111
112 impl From<Ratio<u64>> for $name {
113 #[inline]
114 fn from(value: Ratio<u64>) -> Self {
115 (value.0 as f64 / value.1 as f64).into()
116 }
117 }
118 };
119}
120
121impl_convert!(Parameter);
122impl_convert!(Trigger);