gstreamer_audio/
audio_converter.rs
1use std::ops;
4
5use glib::prelude::*;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct AudioConverterConfig(gst::Structure);
9
10impl ops::Deref for AudioConverterConfig {
11 type Target = gst::StructureRef;
12
13 #[inline]
14 fn deref(&self) -> &gst::StructureRef {
15 self.0.deref()
16 }
17}
18
19impl ops::DerefMut for AudioConverterConfig {
20 #[inline]
21 fn deref_mut(&mut self) -> &mut gst::StructureRef {
22 self.0.deref_mut()
23 }
24}
25
26impl AsRef<gst::StructureRef> for AudioConverterConfig {
27 #[inline]
28 fn as_ref(&self) -> &gst::StructureRef {
29 self.0.as_ref()
30 }
31}
32
33impl AsMut<gst::StructureRef> for AudioConverterConfig {
34 #[inline]
35 fn as_mut(&mut self) -> &mut gst::StructureRef {
36 self.0.as_mut()
37 }
38}
39
40impl Default for AudioConverterConfig {
41 #[inline]
42 fn default() -> Self {
43 Self::new()
44 }
45}
46
47impl TryFrom<gst::Structure> for AudioConverterConfig {
48 type Error = glib::BoolError;
49
50 fn try_from(v: gst::Structure) -> Result<Self, Self::Error> {
51 skip_assert_initialized!();
52 if v.name() == "GstAudioConverter" {
53 Ok(Self(v))
54 } else {
55 Err(glib::bool_error!("Structure is no AudioConverterConfig"))
56 }
57 }
58}
59
60impl<'a> TryFrom<&'a gst::StructureRef> for AudioConverterConfig {
61 type Error = glib::BoolError;
62
63 fn try_from(v: &'a gst::StructureRef) -> Result<Self, Self::Error> {
64 skip_assert_initialized!();
65 Self::try_from(v.to_owned())
66 }
67}
68
69impl From<AudioConverterConfig> for gst::Structure {
70 fn from(v: AudioConverterConfig) -> Self {
71 skip_assert_initialized!();
72 v.0
73 }
74}
75
76impl glib::value::ToValue for AudioConverterConfig {
77 fn to_value(&self) -> glib::Value {
78 self.0.to_value()
79 }
80
81 fn value_type(&self) -> glib::Type {
82 self.0.value_type()
83 }
84}
85
86impl glib::value::ToValueOptional for AudioConverterConfig {
87 fn to_value_optional(s: Option<&Self>) -> glib::Value {
88 skip_assert_initialized!();
89 s.map(|s| &s.0).to_value()
90 }
91}
92
93impl From<AudioConverterConfig> for glib::Value {
94 fn from(s: AudioConverterConfig) -> glib::Value {
95 skip_assert_initialized!();
96 s.0.into()
97 }
98}
99
100impl AudioConverterConfig {
101 pub fn new() -> Self {
102 Self(gst::Structure::new_empty("GstAudioConverter"))
103 }
104
105 pub fn set_dither_method(&mut self, v: crate::AudioDitherMethod) {
106 self.0
107 .set(glib::gstr!("GstAudioConverter.dither-method"), v);
108 }
109
110 #[doc(alias = "get_dither_method")]
111 pub fn dither_method(&self) -> crate::AudioDitherMethod {
112 self.0
113 .get_optional(glib::gstr!("GstAudioConverter.dither-method"))
114 .expect("Wrong type")
115 .unwrap_or(crate::AudioDitherMethod::None)
116 }
117
118 pub fn set_noise_shaping_method(&mut self, v: crate::AudioNoiseShapingMethod) {
119 self.0
120 .set(glib::gstr!("GstAudioConverter.noise-shaping-method"), v);
121 }
122
123 #[doc(alias = "get_noise_shaping_method")]
124 pub fn noise_shaping_method(&self) -> crate::AudioNoiseShapingMethod {
125 self.0
126 .get_optional(glib::gstr!("GstAudioConverter.noise-shaping-method"))
127 .expect("Wrong type")
128 .unwrap_or(crate::AudioNoiseShapingMethod::None)
129 }
130
131 pub fn set_quantization(&mut self, v: u32) {
132 self.0.set(glib::gstr!("GstAudioConverter.quantization"), v);
133 }
134
135 #[doc(alias = "get_quantization")]
136 pub fn quantization(&self) -> u32 {
137 self.0
138 .get_optional(glib::gstr!("GstAudioConverter.quantization"))
139 .expect("Wrong type")
140 .unwrap_or(1)
141 }
142
143 pub fn set_resampler_method(&mut self, v: crate::AudioResamplerMethod) {
144 self.0
145 .set(glib::gstr!("GstAudioConverter.resampler-method"), v);
146 }
147
148 #[doc(alias = "get_resampler_method")]
149 pub fn resampler_method(&self) -> crate::AudioResamplerMethod {
150 self.0
151 .get_optional(glib::gstr!("GstAudioConverter.resampler-method"))
152 .expect("Wrong type")
153 .unwrap_or(crate::AudioResamplerMethod::BlackmanNuttall)
154 }
155
156 pub fn set_mix_matrix(&mut self, v: &[impl AsRef<[f32]>]) {
157 let length = v.first().map(|v| v.as_ref().len()).unwrap_or(0);
158 let array = gst::Array::from_values(v.iter().map(|val| {
159 let val = val.as_ref();
160 assert_eq!(val.len(), length);
161 gst::Array::from_values(val.iter().map(|val| val.to_send_value())).to_send_value()
162 }));
163 self.0
164 .set(glib::gstr!("GstAudioConverter.mix-matrix"), array);
165 }
166
167 #[doc(alias = "get_mix_matrix")]
168 pub fn mix_matrix(&self) -> Vec<Vec<f32>> {
169 self.0
170 .get_optional::<gst::Array>(glib::gstr!("GstAudioConverter.mix-matrix"))
171 .expect("Wrong type")
172 .map(|array| {
173 array
174 .as_slice()
175 .iter()
176 .map(|val| {
177 let array = val.get::<gst::Array>().expect("Wrong type");
178
179 array
180 .as_slice()
181 .iter()
182 .map(|val| val.get::<f32>().expect("Wrong type"))
183 .collect::<Vec<_>>()
184 })
185 .collect::<Vec<_>>()
186 })
187 .unwrap_or_default()
188 }
189
190 #[cfg(feature = "v1_22")]
191 #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
192 pub fn set_dither_threshold(&mut self, v: u32) {
193 self.0
194 .set(glib::gstr!("GstAudioConverter.dither-threshold"), v);
195 }
196
197 #[cfg(feature = "v1_22")]
198 #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
199 #[doc(alias = "get_dither_threshold")]
200 pub fn dither_threshold(&self) -> u32 {
201 self.0
202 .get_optional(glib::gstr!("GstAudioConverter.dither-threshold"))
203 .expect("Wrong type")
204 .unwrap_or(20)
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211
212 #[test]
213 fn test_mix_matrix() {
214 const MATRIX: &[&[f32]] = &[&[1.2, 0.3], &[0.2, 0.8]];
215
216 gst::init().unwrap();
217
218 let mut config = AudioConverterConfig::new();
219 config.set_mix_matrix(MATRIX);
220
221 let matrix = config.mix_matrix();
222 assert_eq!(matrix, MATRIX);
223
224 config.set_mix_matrix(&matrix);
225 }
226}