diff --git a/Gir_GstAudio.toml b/Gir_GstAudio.toml index 5cec5b2aa..6f6d50279 100644 --- a/Gir_GstAudio.toml +++ b/Gir_GstAudio.toml @@ -18,6 +18,9 @@ external_libraries = [ ] generate = [ + "GstAudio.AudioDitherMethod", + "GstAudio.AudioNoiseShapingMethod", + "GstAudio.AudioResamplerMethod", "GstAudio.AudioFormatFlags", "GstAudio.AudioLayout", "GstAudio.AudioChannelPosition", diff --git a/gstreamer-audio/src/audio_converter.rs b/gstreamer-audio/src/audio_converter.rs new file mode 100644 index 000000000..73dc2d85d --- /dev/null +++ b/gstreamer-audio/src/audio_converter.rs @@ -0,0 +1,167 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use glib::prelude::*; + +use std::convert; +use std::ops; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct AudioConverterConfig(gst::Structure); + +impl ops::Deref for AudioConverterConfig { + type Target = gst::StructureRef; + + fn deref(&self) -> &gst::StructureRef { + self.0.deref() + } +} + +impl ops::DerefMut for AudioConverterConfig { + fn deref_mut(&mut self) -> &mut gst::StructureRef { + self.0.deref_mut() + } +} + +impl AsRef for AudioConverterConfig { + fn as_ref(&self) -> &gst::StructureRef { + self.0.as_ref() + } +} + +impl AsMut for AudioConverterConfig { + fn as_mut(&mut self) -> &mut gst::StructureRef { + self.0.as_mut() + } +} + +impl Default for AudioConverterConfig { + fn default() -> Self { + AudioConverterConfig::new() + } +} + +impl convert::TryFrom for AudioConverterConfig { + type Error = glib::BoolError; + + fn try_from(v: gst::Structure) -> Result { + skip_assert_initialized!(); + if v.get_name() == "GstAudioConverter" { + Ok(AudioConverterConfig(v)) + } else { + Err(glib_bool_error!("Structure is no AudioConverterConfig")) + } + } +} + +impl<'a> convert::TryFrom<&'a gst::StructureRef> for AudioConverterConfig { + type Error = glib::BoolError; + + fn try_from(v: &'a gst::StructureRef) -> Result { + skip_assert_initialized!(); + AudioConverterConfig::try_from(v.to_owned()) + } +} + +impl From for gst::Structure { + fn from(v: AudioConverterConfig) -> gst::Structure { + skip_assert_initialized!(); + v.0 + } +} + +impl AudioConverterConfig { + pub fn new() -> Self { + AudioConverterConfig(gst::Structure::new_empty("GstAudioConverter")) + } + + pub fn set_dither_method(&mut self, v: crate::AudioDitherMethod) { + self.0.set("GstAudioConverter.dither-method", &v); + } + + pub fn get_dither_method(&self) -> crate::AudioDitherMethod { + self.0 + .get_optional("GstAudioConverter.dither-method") + .expect("Wrong type") + .unwrap_or(crate::AudioDitherMethod::None) + } + + pub fn set_noise_shaping_method(&mut self, v: crate::AudioNoiseShapingMethod) { + self.0.set("GstAudioConverter.noise-shaping-method", &v); + } + + pub fn get_noise_shaping_method(&self) -> crate::AudioNoiseShapingMethod { + self.0 + .get_optional("GstAudioConverter.noise-shaping-method") + .expect("Wrong type") + .unwrap_or(crate::AudioNoiseShapingMethod::None) + } + + pub fn set_quantization(&mut self, v: u32) { + self.0.set("GstAudioConverter.dither-quantization", &v); + } + + pub fn get_quantization(&self) -> u32 { + self.0 + .get_optional("GstAudioConverter.quantization") + .expect("Wrong type") + .unwrap_or(1) + } + + #[cfg(any(feature = "v1_10", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))] + pub fn set_resampler_method(&mut self, v: crate::AudioResamplerMethod) { + self.0.set("GstAudioConverter.resampler-method", &v); + } + + #[cfg(any(feature = "v1_10", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_10")))] + pub fn get_resampler_method(&self) -> crate::AudioResamplerMethod { + self.0 + .get_optional("GstAudioConverter.resampler-method") + .expect("Wrong type") + .unwrap_or(crate::AudioResamplerMethod::BlackmanNuttall) + } + + pub fn set_mix_matrix(&mut self, v: &[&[f64]]) { + let length = v.get(0).map(|v| v.len()).unwrap_or(0); + let array = gst::Array::from_owned( + v.iter() + .map(|val| { + assert_eq!(val.len(), length); + gst::Array::from_owned( + val.iter() + .map(|val| val.to_send_value()) + .collect::>(), + ) + .to_send_value() + }) + .collect::>(), + ); + self.0.set("GstAudioConverter.mix-matrix", &array); + } + + pub fn get_mix_matrix(&self) -> Vec> { + self.0 + .get_optional::("GstAudioConverter.mix-matrix") + .expect("Wrong type") + .map(|array| { + array + .as_slice() + .iter() + .map(|val| { + let array = val + .get::() + .expect("Wrong type") + .unwrap_or_else(|| gst::Array::from_owned(Vec::new())); + + array + .as_slice() + .iter() + .map(|val| val.get_some::().expect("Wrong type")) + .collect::>() + }) + .collect::>() + }) + .unwrap_or_else(Vec::new) + } +} diff --git a/gstreamer-audio/src/auto/enums.rs b/gstreamer-audio/src/auto/enums.rs index ec86ccdfb..7c2869a19 100644 --- a/gstreamer-audio/src/auto/enums.rs +++ b/gstreamer-audio/src/auto/enums.rs @@ -193,6 +193,70 @@ impl SetValue for AudioChannelPosition { } } +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +pub enum AudioDitherMethod { + None, + Rpdf, + Tpdf, + TpdfHf, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for AudioDitherMethod { + type GlibType = gst_audio_sys::GstAudioDitherMethod; + + fn to_glib(&self) -> gst_audio_sys::GstAudioDitherMethod { + match *self { + AudioDitherMethod::None => gst_audio_sys::GST_AUDIO_DITHER_NONE, + AudioDitherMethod::Rpdf => gst_audio_sys::GST_AUDIO_DITHER_RPDF, + AudioDitherMethod::Tpdf => gst_audio_sys::GST_AUDIO_DITHER_TPDF, + AudioDitherMethod::TpdfHf => gst_audio_sys::GST_AUDIO_DITHER_TPDF_HF, + AudioDitherMethod::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for AudioDitherMethod { + fn from_glib(value: gst_audio_sys::GstAudioDitherMethod) -> Self { + skip_assert_initialized!(); + match value { + 0 => AudioDitherMethod::None, + 1 => AudioDitherMethod::Rpdf, + 2 => AudioDitherMethod::Tpdf, + 3 => AudioDitherMethod::TpdfHf, + value => AudioDitherMethod::__Unknown(value), + } + } +} + +impl StaticType for AudioDitherMethod { + fn static_type() -> Type { + unsafe { from_glib(gst_audio_sys::gst_audio_dither_method_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for AudioDitherMethod { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for AudioDitherMethod { + unsafe fn from_value(value: &Value) -> Self { + from_glib(gobject_sys::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl SetValue for AudioDitherMethod { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_sys::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib()) + } +} + #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)] #[non_exhaustive] pub enum AudioFormat { @@ -399,6 +463,151 @@ impl SetValue for AudioLayout { } } +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +pub enum AudioNoiseShapingMethod { + None, + ErrorFeedback, + Simple, + Medium, + High, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for AudioNoiseShapingMethod { + type GlibType = gst_audio_sys::GstAudioNoiseShapingMethod; + + fn to_glib(&self) -> gst_audio_sys::GstAudioNoiseShapingMethod { + match *self { + AudioNoiseShapingMethod::None => gst_audio_sys::GST_AUDIO_NOISE_SHAPING_NONE, + AudioNoiseShapingMethod::ErrorFeedback => { + gst_audio_sys::GST_AUDIO_NOISE_SHAPING_ERROR_FEEDBACK + } + AudioNoiseShapingMethod::Simple => gst_audio_sys::GST_AUDIO_NOISE_SHAPING_SIMPLE, + AudioNoiseShapingMethod::Medium => gst_audio_sys::GST_AUDIO_NOISE_SHAPING_MEDIUM, + AudioNoiseShapingMethod::High => gst_audio_sys::GST_AUDIO_NOISE_SHAPING_HIGH, + AudioNoiseShapingMethod::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for AudioNoiseShapingMethod { + fn from_glib(value: gst_audio_sys::GstAudioNoiseShapingMethod) -> Self { + skip_assert_initialized!(); + match value { + 0 => AudioNoiseShapingMethod::None, + 1 => AudioNoiseShapingMethod::ErrorFeedback, + 2 => AudioNoiseShapingMethod::Simple, + 3 => AudioNoiseShapingMethod::Medium, + 4 => AudioNoiseShapingMethod::High, + value => AudioNoiseShapingMethod::__Unknown(value), + } + } +} + +impl StaticType for AudioNoiseShapingMethod { + fn static_type() -> Type { + unsafe { from_glib(gst_audio_sys::gst_audio_noise_shaping_method_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for AudioNoiseShapingMethod { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for AudioNoiseShapingMethod { + unsafe fn from_value(value: &Value) -> Self { + from_glib(gobject_sys::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl SetValue for AudioNoiseShapingMethod { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_sys::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib()) + } +} + +#[cfg(any(feature = "v1_10", feature = "dox"))] +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +pub enum AudioResamplerMethod { + Nearest, + Linear, + Cubic, + BlackmanNuttall, + Kaiser, + #[doc(hidden)] + __Unknown(i32), +} + +#[cfg(any(feature = "v1_10", feature = "dox"))] +#[doc(hidden)] +impl ToGlib for AudioResamplerMethod { + type GlibType = gst_audio_sys::GstAudioResamplerMethod; + + fn to_glib(&self) -> gst_audio_sys::GstAudioResamplerMethod { + match *self { + AudioResamplerMethod::Nearest => gst_audio_sys::GST_AUDIO_RESAMPLER_METHOD_NEAREST, + AudioResamplerMethod::Linear => gst_audio_sys::GST_AUDIO_RESAMPLER_METHOD_LINEAR, + AudioResamplerMethod::Cubic => gst_audio_sys::GST_AUDIO_RESAMPLER_METHOD_CUBIC, + AudioResamplerMethod::BlackmanNuttall => { + gst_audio_sys::GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL + } + AudioResamplerMethod::Kaiser => gst_audio_sys::GST_AUDIO_RESAMPLER_METHOD_KAISER, + AudioResamplerMethod::__Unknown(value) => value, + } + } +} + +#[cfg(any(feature = "v1_10", feature = "dox"))] +#[doc(hidden)] +impl FromGlib for AudioResamplerMethod { + fn from_glib(value: gst_audio_sys::GstAudioResamplerMethod) -> Self { + skip_assert_initialized!(); + match value { + 0 => AudioResamplerMethod::Nearest, + 1 => AudioResamplerMethod::Linear, + 2 => AudioResamplerMethod::Cubic, + 3 => AudioResamplerMethod::BlackmanNuttall, + 4 => AudioResamplerMethod::Kaiser, + value => AudioResamplerMethod::__Unknown(value), + } + } +} + +#[cfg(any(feature = "v1_10", feature = "dox"))] +impl StaticType for AudioResamplerMethod { + fn static_type() -> Type { + unsafe { from_glib(gst_audio_sys::gst_audio_resampler_method_get_type()) } + } +} + +#[cfg(any(feature = "v1_10", feature = "dox"))] +impl<'a> FromValueOptional<'a> for AudioResamplerMethod { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +#[cfg(any(feature = "v1_10", feature = "dox"))] +impl<'a> FromValue<'a> for AudioResamplerMethod { + unsafe fn from_value(value: &Value) -> Self { + from_glib(gobject_sys::g_value_get_enum(value.to_glib_none().0)) + } +} + +#[cfg(any(feature = "v1_10", feature = "dox"))] +impl SetValue for AudioResamplerMethod { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_sys::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib()) + } +} + #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] #[non_exhaustive] pub enum AudioRingBufferFormatType { diff --git a/gstreamer-audio/src/auto/mod.rs b/gstreamer-audio/src/auto/mod.rs index bbe36b9c6..e24b30394 100644 --- a/gstreamer-audio/src/auto/mod.rs +++ b/gstreamer-audio/src/auto/mod.rs @@ -35,8 +35,12 @@ pub use self::audio_stream_align::AudioStreamAlign; mod enums; pub use self::enums::AudioChannelPosition; +pub use self::enums::AudioDitherMethod; pub use self::enums::AudioFormat; pub use self::enums::AudioLayout; +pub use self::enums::AudioNoiseShapingMethod; +#[cfg(any(feature = "v1_10", feature = "dox"))] +pub use self::enums::AudioResamplerMethod; pub use self::enums::AudioRingBufferFormatType; pub use self::enums::StreamVolumeFormat; diff --git a/gstreamer-audio/src/lib.rs b/gstreamer-audio/src/lib.rs index 80be9063d..f7f7160b6 100644 --- a/gstreamer-audio/src/lib.rs +++ b/gstreamer-audio/src/lib.rs @@ -69,6 +69,9 @@ pub use audio_decoder::AudioDecoderExtManual; mod audio_encoder; pub use audio_encoder::AudioEncoderExtManual; +mod audio_converter; +pub use crate::audio_converter::AudioConverterConfig; + // Re-export all the traits in a prelude module, so that applications // can always "use gst::prelude::*" without getting conflicts pub mod prelude {