Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
authorArun Raghavan <arun@asymptotic.io>2022-12-14 02:37:06 +0300
committerArun Raghavan <arun@asymptotic.io>2022-12-14 18:35:28 +0300
commit473e7d951be27b2e5578e1c5654a9c6d967e5d8b (patch)
tree7ea4264cb245827054ea03552a031eb1133b9f7b /audio
parent3a8536b45efa41e5af6eec250e998f24bcc4018c (diff)
audiofx: Derive from AudioFilter where possible
Saves a little bit of code. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1013>
Diffstat (limited to 'audio')
-rw-r--r--audio/audiofx/src/audioecho/imp.rs69
-rw-r--r--audio/audiofx/src/audiornnoise/imp.rs112
-rw-r--r--audio/audiofx/src/ebur128level/imp.rs238
3 files changed, 196 insertions, 223 deletions
diff --git a/audio/audiofx/src/audioecho/imp.rs b/audio/audiofx/src/audioecho/imp.rs
index cdf553c27..a3f9423c0 100644
--- a/audio/audiofx/src/audioecho/imp.rs
+++ b/audio/audiofx/src/audioecho/imp.rs
@@ -9,7 +9,7 @@
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
-use gst_base::subclass::prelude::*;
+use gst_audio::subclass::prelude::*;
use std::sync::Mutex;
use std::{cmp, u64};
@@ -20,7 +20,7 @@ use num_traits::cast::{FromPrimitive, ToPrimitive};
use num_traits::float::Float;
use once_cell::sync::Lazy;
-static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
+static _CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new(
"rsaudioecho",
gst::DebugColorFlags::empty(),
@@ -89,7 +89,7 @@ impl AudioEcho {
impl ObjectSubclass for AudioEcho {
const NAME: &'static str = "GstRsAudioEcho";
type Type = super::AudioEcho;
- type ParentType = gst_base::BaseTransform;
+ type ParentType = gst_audio::AudioFilter;
}
impl ObjectImpl for AudioEcho {
@@ -194,32 +194,6 @@ impl ElementImpl for AudioEcho {
Some(&*ELEMENT_METADATA)
}
-
- fn pad_templates() -> &'static [gst::PadTemplate] {
- static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
- let caps = gst_audio::AudioCapsBuilder::new_interleaved()
- .format_list([gst_audio::AUDIO_FORMAT_F32, gst_audio::AUDIO_FORMAT_F64])
- .build();
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
-
- let sink_pad_template = gst::PadTemplate::new(
- "sink",
- gst::PadDirection::Sink,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- vec![src_pad_template, sink_pad_template]
- });
-
- PAD_TEMPLATES.as_ref()
- }
}
impl BaseTransformImpl for AudioEcho {
@@ -252,32 +226,35 @@ impl BaseTransformImpl for AudioEcho {
Ok(gst::FlowSuccess::Ok)
}
- fn set_caps(&self, incaps: &gst::Caps, outcaps: &gst::Caps) -> Result<(), gst::LoggableError> {
- if incaps != outcaps {
- return Err(gst::loggable_error!(
- CAT,
- "Input and output caps are not the same"
- ));
- }
+ fn stop(&self) -> Result<(), gst::ErrorMessage> {
+ // Drop state
+ let _ = self.state.lock().unwrap().take();
+
+ Ok(())
+ }
+}
+
+impl AudioFilterImpl for AudioEcho {
+ fn allowed_caps() -> &'static gst::Caps {
+ static CAPS: Lazy<gst::Caps> = Lazy::new(|| {
+ gst_audio::AudioCapsBuilder::new_interleaved()
+ .format_list([gst_audio::AUDIO_FORMAT_F32, gst_audio::AUDIO_FORMAT_F64])
+ .build()
+ });
+
+ &CAPS
+ }
- let info = gst_audio::AudioInfo::from_caps(incaps)
- .map_err(|_| gst::loggable_error!(CAT, "Failed to parse input caps"))?;
+ fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {
let max_delay = self.settings.lock().unwrap().max_delay;
let size = (max_delay * (info.rate() as u64)).seconds() as usize;
let buffer_size = size * (info.channels() as usize);
*self.state.lock().unwrap() = Some(State {
- info,
+ info: info.clone(),
buffer: RingBuffer::new(buffer_size),
});
Ok(())
}
-
- fn stop(&self) -> Result<(), gst::ErrorMessage> {
- // Drop state
- let _ = self.state.lock().unwrap().take();
-
- Ok(())
- }
}
diff --git a/audio/audiofx/src/audiornnoise/imp.rs b/audio/audiofx/src/audiornnoise/imp.rs
index 2eb66a6cc..8ebb9046c 100644
--- a/audio/audiofx/src/audiornnoise/imp.rs
+++ b/audio/audiofx/src/audiornnoise/imp.rs
@@ -12,10 +12,10 @@ use std::sync::Mutex;
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
+use gst_audio::subclass::prelude::*;
use gst_base::prelude::*;
use gst_base::subclass::base_transform::BaseTransformImplExt;
use gst_base::subclass::base_transform::GenerateOutputSuccess;
-use gst_base::subclass::prelude::*;
use nnnoiseless::DenoiseState;
@@ -227,7 +227,7 @@ impl AudioRNNoise {
impl ObjectSubclass for AudioRNNoise {
const NAME: &'static str = "GstAudioRNNoise";
type Type = super::AudioRNNoise;
- type ParentType = gst_base::BaseTransform;
+ type ParentType = gst_audio::AudioFilter;
}
impl ObjectImpl for AudioRNNoise {
@@ -282,34 +282,6 @@ impl ElementImpl for AudioRNNoise {
Some(&*ELEMENT_METADATA)
}
-
- fn pad_templates() -> &'static [gst::PadTemplate] {
- static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
- let caps = gst_audio::AudioCapsBuilder::new_interleaved()
- .format(gst_audio::AUDIO_FORMAT_F32)
- .rate(48000)
- .build();
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
-
- let sink_pad_template = gst::PadTemplate::new(
- "sink",
- gst::PadDirection::Sink,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
-
- vec![src_pad_template, sink_pad_template]
- });
-
- PAD_TEMPLATES.as_ref()
- }
}
impl BaseTransformImpl for AudioRNNoise {
@@ -318,44 +290,6 @@ impl BaseTransformImpl for AudioRNNoise {
const PASSTHROUGH_ON_SAME_CAPS: bool = false;
const TRANSFORM_IP_ON_PASSTHROUGH: bool = false;
- fn set_caps(&self, incaps: &gst::Caps, outcaps: &gst::Caps) -> Result<(), gst::LoggableError> {
- // Flush previous state
- if self.state.borrow_mut().is_some() {
- self.drain().map_err(|e| {
- gst::loggable_error!(CAT, "Error flushing previous state data {:?}", e)
- })?;
- }
- if incaps != outcaps {
- return Err(gst::loggable_error!(
- CAT,
- "Input and output caps are not the same"
- ));
- }
-
- gst::debug!(CAT, imp: self, "Set caps to {}", incaps);
-
- let in_info = gst_audio::AudioInfo::from_caps(incaps)
- .map_err(|e| gst::loggable_error!(CAT, "Failed to parse input caps {:?}", e))?;
-
- let mut denoisers = vec![];
- for _i in 0..in_info.channels() {
- denoisers.push(ChannelDenoiser {
- denoiser: DenoiseState::new(),
- frame_chunk: Box::new([0.0; FRAME_SIZE]),
- out_chunk: Box::new([0.0; FRAME_SIZE]),
- })
- }
-
- let mut state_lock = self.state.borrow_mut();
- *state_lock = Some(State {
- in_info,
- denoisers,
- adapter: gst_base::UniqueAdapter::new(),
- });
-
- Ok(())
- }
-
fn generate_output(&self) -> Result<GenerateOutputSuccess, gst::FlowError> {
// Check if there are enough data in the queued buffer and adapter,
// if it is not the case, just notify the parent class to not generate
@@ -427,3 +361,45 @@ impl BaseTransformImpl for AudioRNNoise {
Ok(())
}
}
+
+impl AudioFilterImpl for AudioRNNoise {
+ fn allowed_caps() -> &'static gst::Caps {
+ static CAPS: Lazy<gst::Caps> = Lazy::new(|| {
+ gst_audio::AudioCapsBuilder::new_interleaved()
+ .format(gst_audio::AUDIO_FORMAT_F32)
+ .rate(48000)
+ .build()
+ });
+
+ &CAPS
+ }
+
+ fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {
+ // Flush previous state
+ if self.state.borrow_mut().is_some() {
+ self.drain().map_err(|e| {
+ gst::loggable_error!(CAT, "Error flushing previous state data {:?}", e)
+ })?;
+ }
+
+ gst::debug!(CAT, imp: self, "Set caps to {:?}", info);
+
+ let mut denoisers = vec![];
+ for _i in 0..info.channels() {
+ denoisers.push(ChannelDenoiser {
+ denoiser: DenoiseState::new(),
+ frame_chunk: Box::new([0.0; FRAME_SIZE]),
+ out_chunk: Box::new([0.0; FRAME_SIZE]),
+ })
+ }
+
+ let mut state_lock = self.state.borrow_mut();
+ *state_lock = Some(State {
+ in_info: info.clone(),
+ denoisers,
+ adapter: gst_base::UniqueAdapter::new(),
+ });
+
+ Ok(())
+ }
+}
diff --git a/audio/audiofx/src/ebur128level/imp.rs b/audio/audiofx/src/ebur128level/imp.rs
index f61d55c3b..add9de309 100644
--- a/audio/audiofx/src/ebur128level/imp.rs
+++ b/audio/audiofx/src/ebur128level/imp.rs
@@ -9,8 +9,8 @@
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
+use gst_audio::subclass::prelude::*;
use gst_base::prelude::*;
-use gst_base::subclass::prelude::*;
use std::i32;
use std::sync::atomic;
@@ -118,7 +118,7 @@ pub struct EbuR128Level {
impl ObjectSubclass for EbuR128Level {
const NAME: &'static str = "GstEbuR128Level";
type Type = super::EbuR128Level;
- type ParentType = gst_base::BaseTransform;
+ type ParentType = gst_audio::AudioFilter;
}
impl ObjectImpl for EbuR128Level {
@@ -283,113 +283,6 @@ impl BaseTransformImpl for EbuR128Level {
const PASSTHROUGH_ON_SAME_CAPS: bool = true;
const TRANSFORM_IP_ON_PASSTHROUGH: bool = true;
- fn set_caps(&self, incaps: &gst::Caps, _outcaps: &gst::Caps) -> Result<(), gst::LoggableError> {
- let info = match gst_audio::AudioInfo::from_caps(incaps) {
- Err(_) => return Err(gst::loggable_error!(CAT, "Failed to parse input caps")),
- Ok(info) => info,
- };
-
- gst::debug!(CAT, imp: self, "Configured for caps {}", incaps,);
-
- let settings = *self.settings.lock().unwrap();
-
- let mut ebur128 = ebur128::EbuR128::new(info.channels(), info.rate(), settings.mode.into())
- .map_err(|err| gst::loggable_error!(CAT, "Failed to create EBU R128: {}", err))?;
-
- // Map channel positions if we can to give correct weighting
- if let Some(positions) = info.positions() {
- let channel_map = positions
- .iter()
- .map(|p| {
- match p {
- gst_audio::AudioChannelPosition::Mono => ebur128::Channel::DualMono,
- gst_audio::AudioChannelPosition::FrontLeft => ebur128::Channel::Left,
- gst_audio::AudioChannelPosition::FrontRight => ebur128::Channel::Right,
- gst_audio::AudioChannelPosition::FrontCenter => ebur128::Channel::Center,
- gst_audio::AudioChannelPosition::Lfe1
- | gst_audio::AudioChannelPosition::Lfe2 => ebur128::Channel::Unused,
- gst_audio::AudioChannelPosition::RearLeft => ebur128::Channel::Mp135,
- gst_audio::AudioChannelPosition::RearRight => ebur128::Channel::Mm135,
- gst_audio::AudioChannelPosition::FrontLeftOfCenter => {
- ebur128::Channel::MpSC
- }
- gst_audio::AudioChannelPosition::FrontRightOfCenter => {
- ebur128::Channel::MmSC
- }
- gst_audio::AudioChannelPosition::RearCenter => ebur128::Channel::Mp180,
- gst_audio::AudioChannelPosition::SideLeft => ebur128::Channel::Mp090,
- gst_audio::AudioChannelPosition::SideRight => ebur128::Channel::Mm090,
- gst_audio::AudioChannelPosition::TopFrontLeft => ebur128::Channel::Up030,
- gst_audio::AudioChannelPosition::TopFrontRight => ebur128::Channel::Um030,
- gst_audio::AudioChannelPosition::TopFrontCenter => ebur128::Channel::Up000,
- gst_audio::AudioChannelPosition::TopCenter => ebur128::Channel::Tp000,
- gst_audio::AudioChannelPosition::TopRearLeft => ebur128::Channel::Up135,
- gst_audio::AudioChannelPosition::TopRearRight => ebur128::Channel::Um135,
- gst_audio::AudioChannelPosition::TopSideLeft => ebur128::Channel::Up090,
- gst_audio::AudioChannelPosition::TopSideRight => ebur128::Channel::Um090,
- gst_audio::AudioChannelPosition::TopRearCenter => ebur128::Channel::Up180,
- gst_audio::AudioChannelPosition::BottomFrontCenter => {
- ebur128::Channel::Bp000
- }
- gst_audio::AudioChannelPosition::BottomFrontLeft => ebur128::Channel::Bp045,
- gst_audio::AudioChannelPosition::BottomFrontRight => {
- ebur128::Channel::Bm045
- }
- gst_audio::AudioChannelPosition::WideLeft => {
- ebur128::Channel::Mp135 // Mp110?
- }
- gst_audio::AudioChannelPosition::WideRight => {
- ebur128::Channel::Mm135 // Mm110?
- }
- gst_audio::AudioChannelPosition::SurroundLeft => {
- ebur128::Channel::Mp135 // Mp110?
- }
- gst_audio::AudioChannelPosition::SurroundRight => {
- ebur128::Channel::Mm135 // Mm110?
- }
- gst_audio::AudioChannelPosition::Invalid
- | gst_audio::AudioChannelPosition::None => ebur128::Channel::Unused,
- val => {
- gst::debug!(
- CAT,
- imp: self,
- "Unknown channel position {:?}, ignoring channel",
- val
- );
- ebur128::Channel::Unused
- }
- }
- })
- .collect::<Vec<_>>();
- ebur128
- .set_channel_map(&channel_map)
- .map_err(|err| gst::loggable_error!(CAT, "Failed to set channel map: {}", err))?;
- } else {
- // Weight all channels equally if we have no channel map
- let channel_map = std::iter::repeat(ebur128::Channel::Center)
- .take(info.channels() as usize)
- .collect::<Vec<_>>();
- ebur128
- .set_channel_map(&channel_map)
- .map_err(|err| gst::loggable_error!(CAT, "Failed to set channel map: {}", err))?;
- }
-
- let interval_frames = settings
- .interval
- .mul_div_floor(info.rate() as u64, *gst::ClockTime::SECOND)
- .unwrap();
-
- *self.state.borrow_mut() = Some(State {
- info,
- ebur128,
- num_frames: 0,
- interval_frames,
- interval_frames_remaining: interval_frames,
- });
-
- Ok(())
- }
-
fn stop(&self) -> Result<(), gst::ErrorMessage> {
// Drop state
let _ = self.state.borrow_mut().take();
@@ -587,6 +480,133 @@ impl BaseTransformImpl for EbuR128Level {
}
}
+impl AudioFilterImpl for EbuR128Level {
+ fn allowed_caps() -> &'static gst::Caps {
+ static CAPS: Lazy<gst::Caps> = Lazy::new(|| {
+ gst_audio::AudioCapsBuilder::new()
+ .format_list([
+ gst_audio::AUDIO_FORMAT_S16,
+ gst_audio::AUDIO_FORMAT_S32,
+ gst_audio::AUDIO_FORMAT_F32,
+ gst_audio::AUDIO_FORMAT_F64,
+ ])
+ // Limit from ebur128
+ .rate_range(1..2_822_400)
+ // Limit from ebur128
+ .channels_range(1..64)
+ .layout_list([
+ gst_audio::AudioLayout::Interleaved,
+ gst_audio::AudioLayout::NonInterleaved,
+ ])
+ .build()
+ });
+
+ &CAPS
+ }
+
+ fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {
+ gst::debug!(CAT, imp: self, "Configured for caps {:?}", info);
+
+ let settings = *self.settings.lock().unwrap();
+
+ let mut ebur128 = ebur128::EbuR128::new(info.channels(), info.rate(), settings.mode.into())
+ .map_err(|err| gst::loggable_error!(CAT, "Failed to create EBU R128: {}", err))?;
+
+ // Map channel positions if we can to give correct weighting
+ if let Some(positions) = info.positions() {
+ let channel_map = positions
+ .iter()
+ .map(|p| {
+ match p {
+ gst_audio::AudioChannelPosition::Mono => ebur128::Channel::DualMono,
+ gst_audio::AudioChannelPosition::FrontLeft => ebur128::Channel::Left,
+ gst_audio::AudioChannelPosition::FrontRight => ebur128::Channel::Right,
+ gst_audio::AudioChannelPosition::FrontCenter => ebur128::Channel::Center,
+ gst_audio::AudioChannelPosition::Lfe1
+ | gst_audio::AudioChannelPosition::Lfe2 => ebur128::Channel::Unused,
+ gst_audio::AudioChannelPosition::RearLeft => ebur128::Channel::Mp135,
+ gst_audio::AudioChannelPosition::RearRight => ebur128::Channel::Mm135,
+ gst_audio::AudioChannelPosition::FrontLeftOfCenter => {
+ ebur128::Channel::MpSC
+ }
+ gst_audio::AudioChannelPosition::FrontRightOfCenter => {
+ ebur128::Channel::MmSC
+ }
+ gst_audio::AudioChannelPosition::RearCenter => ebur128::Channel::Mp180,
+ gst_audio::AudioChannelPosition::SideLeft => ebur128::Channel::Mp090,
+ gst_audio::AudioChannelPosition::SideRight => ebur128::Channel::Mm090,
+ gst_audio::AudioChannelPosition::TopFrontLeft => ebur128::Channel::Up030,
+ gst_audio::AudioChannelPosition::TopFrontRight => ebur128::Channel::Um030,
+ gst_audio::AudioChannelPosition::TopFrontCenter => ebur128::Channel::Up000,
+ gst_audio::AudioChannelPosition::TopCenter => ebur128::Channel::Tp000,
+ gst_audio::AudioChannelPosition::TopRearLeft => ebur128::Channel::Up135,
+ gst_audio::AudioChannelPosition::TopRearRight => ebur128::Channel::Um135,
+ gst_audio::AudioChannelPosition::TopSideLeft => ebur128::Channel::Up090,
+ gst_audio::AudioChannelPosition::TopSideRight => ebur128::Channel::Um090,
+ gst_audio::AudioChannelPosition::TopRearCenter => ebur128::Channel::Up180,
+ gst_audio::AudioChannelPosition::BottomFrontCenter => {
+ ebur128::Channel::Bp000
+ }
+ gst_audio::AudioChannelPosition::BottomFrontLeft => ebur128::Channel::Bp045,
+ gst_audio::AudioChannelPosition::BottomFrontRight => {
+ ebur128::Channel::Bm045
+ }
+ gst_audio::AudioChannelPosition::WideLeft => {
+ ebur128::Channel::Mp135 // Mp110?
+ }
+ gst_audio::AudioChannelPosition::WideRight => {
+ ebur128::Channel::Mm135 // Mm110?
+ }
+ gst_audio::AudioChannelPosition::SurroundLeft => {
+ ebur128::Channel::Mp135 // Mp110?
+ }
+ gst_audio::AudioChannelPosition::SurroundRight => {
+ ebur128::Channel::Mm135 // Mm110?
+ }
+ gst_audio::AudioChannelPosition::Invalid
+ | gst_audio::AudioChannelPosition::None => ebur128::Channel::Unused,
+ val => {
+ gst::debug!(
+ CAT,
+ imp: self,
+ "Unknown channel position {:?}, ignoring channel",
+ val
+ );
+ ebur128::Channel::Unused
+ }
+ }
+ })
+ .collect::<Vec<_>>();
+ ebur128
+ .set_channel_map(&channel_map)
+ .map_err(|err| gst::loggable_error!(CAT, "Failed to set channel map: {}", err))?;
+ } else {
+ // Weight all channels equally if we have no channel map
+ let channel_map = std::iter::repeat(ebur128::Channel::Center)
+ .take(info.channels() as usize)
+ .collect::<Vec<_>>();
+ ebur128
+ .set_channel_map(&channel_map)
+ .map_err(|err| gst::loggable_error!(CAT, "Failed to set channel map: {}", err))?;
+ }
+
+ let interval_frames = settings
+ .interval
+ .mul_div_floor(info.rate() as u64, *gst::ClockTime::SECOND)
+ .unwrap();
+
+ *self.state.borrow_mut() = Some(State {
+ info: info.clone(),
+ ebur128,
+ num_frames: 0,
+ interval_frames,
+ interval_frames_remaining: interval_frames,
+ });
+
+ Ok(())
+ }
+}
+
/// Helper struct to handle the different sample formats and layouts generically.
enum Frames<'a> {
S16(&'a [i16], usize),